Diff options
Diffstat (limited to 'custom/extensions/syntax-highlight.lua')
-rw-r--r--custom/extensions/syntax-highlight.lua67
1 file changed, 14 insertions, 53 deletions
diff --git a/custom/extensions/syntax-highlight.lua b/custom/extensions/syntax-highlight.lua
index 8a1e7ab..7414b63 100644
--- a/custom/extensions/syntax-highlight.lua
+++ b/custom/extensions/syntax-highlight.lua
@@ -1,4 +1,4 @@
--- Server-side syntax highlighting for cgit's tree and blob views, named by
+-- Server-side syntax highlighting for cgit's tree and blame pages, named by
-- the source-filter setting and run inside cgit's embedded Lua interpreter
-- so a coloured blob costs no extra process per request. Tokens come from the
-- Scintillua lexers and reach the page wrapped in span elements carrying the
@@ -28,7 +28,8 @@ local scintillua_env = "CGIT_SCINTILLUA_PATH"
-- directory next to cgitrc is enough for it to be found. The lexers come
-- from https://orbitalquark.github.io/scintillua/ and need lpeg, built for
-- the Lua cgit is linked against. Forgetting that is the usual reason
--- nothing is coloured.
+-- nothing is coloured. A file is coloured only when Scintillua's detect()
+-- names its lexer, so an older Scintillua without detect() colours nothing.
--
-- # Debian and Ubuntu
-- sudo apt install lua-lpeg
@@ -74,25 +75,6 @@ local css = {
pseudoelement = "hl-func",
}
--- Extension to lexer name fixes for the fallback path, reached only when
--- this Scintillua has no detect(). Most extensions already equal their lexer
--- name and these are the frequent exceptions.
-local ext_lexer = {
- py = "python",
- js = "javascript",
- ts = "typescript",
- rb = "ruby",
- pl = "perl",
- pm = "perl",
- sh = "bash",
- md = "markdown",
- htm = "html",
- yml = "yaml",
- rs = "rust",
- c = "ansi_c",
- h = "ansi_c",
-}
-
local scintillua = nil
local filename = ""
@@ -170,37 +152,13 @@ local function load_scintillua()
return nil
end
--- Loading a lexer runs its Lua, and one written for another Scintillua can
--- raise, so a failure here just leaves this file uncoloured.
-local function load_lexer_name(name)
- if name == nil then
- return nil
- end
- local ok, lexer = pcall(scintillua.load, name)
- if ok and lexer then
- return lexer
- end
- return nil
-end
-
+-- The first line goes along to detect(), so a script with no extension is
+-- still known by its shebang. detect() matches an extension by its case, so
+-- a name in capitals such as MAIN.C is tried again in lower case.
local function lexer_for(name, text)
- if type(scintillua.detect) == "function" then
- -- The first line goes along, so a script with no extension is still
- -- known by its shebang.
- local ok, lang = pcall(scintillua.detect, name, text:match("^[^\n]*"))
- if ok and lang then
- local lexer = load_lexer_name(lang)
- if lexer then
- return lexer
- end
- end
- end
- local ext = string.match(name, "%.([^.]+)$")
- if not ext then
- return nil
- end
- ext = string.lower(ext)
- return load_lexer_name(ext_lexer[ext]) or load_lexer_name(ext)
+ local first = string.match(text, "^[^\n]*")
+ local lang = scintillua.detect(name, first) or scintillua.detect(string.lower(name), first)
+ return lang and scintillua.load(lang)
end
local function highlight(text)
@@ -208,8 +166,8 @@ local function highlight(text)
if not lexer then
return nil
end
- local ok, tokens = pcall(lexer.lex, lexer, text)
- if not ok or type(tokens) ~= "table" then
+ local tokens = lexer:lex(text)
+ if type(tokens) ~= "table" then
return nil
end
local out = {}
@@ -262,6 +220,9 @@ function filter_close()
scintillua = load_scintillua() or false
end
if scintillua then
+ -- Every step of highlight runs Scintillua's own Lua, and code
+ -- written for another version of it can raise, so a failure
+ -- anywhere there just leaves this file uncoloured.
local ok, marked = pcall(highlight, text)
if ok and marked then
html(marked)