diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--custom/extensions/syntax-highlight.lua67
1 file changed, 35 insertions, 32 deletions
diff --git a/custom/extensions/syntax-highlight.lua b/custom/extensions/syntax-highlight.lua
index 862965a..e2032aa 100644
--- a/custom/extensions/syntax-highlight.lua
+++ b/custom/extensions/syntax-highlight.lua
@@ -1,16 +1,13 @@
--- Server-side syntax highlighting for cgit's tree and blob views, run inside
--- cgit's embedded Lua interpreter so a coloured blob costs no extra process
--- per request. Colouring is deliberately left out of cgit itself, which
--- serves plain escaped text on its own, so this filter is named by the
--- source-filter setting and any other program could take its place. Tokens
--- come from the Scintillua lexers and reach the page wrapped in span elements
--- carrying the hl- classes that assets/cgit.css styles. Whenever a piece is
--- missing or will not load, from lpeg down to a single lexer, the file falls
--- back to plain escaped text instead of failing, so uncoloured code means a
--- missing dependency rather than an error. It runs on Lua 5.1 through 5.5 and
+-- Server-side syntax highlighting for cgit's tree and blob views, 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
+-- hl- classes that assets/cgit.css styles. Whenever a piece is missing or
+-- will not load, from lpeg down to a single lexer, the filter falls back to
+-- plain escaped text instead of failing. It runs on Lua 5.1 through 5.5 and
-- LuaJIT.
--
--- source-filter=lua:/usr/lib/cgit/extensions/syntax-highlight.lua
+-- source-filter=lua:/usr/local/lib/cgit/filters/syntax-highlight.lua
-- Files larger than this many bytes are served escaped but unhighlighted, so
@@ -28,12 +25,10 @@ local scintillua_env = "CGIT_SCINTILLUA_PATH"
-- Directories probed for the lexers when that variable is not set, tried
-- after the directory of $CGIT_CONFIG, so placing or symlinking a scintillua
--- directory next to cgitrc is enough to be found. Scintillua is the lexer
--- collection from the Textadept editor, around 160 languages as plain .lua
--- files with nothing to compile, from
--- https://orbitalquark.github.io/scintillua/. It does not bundle lpeg, which
--- it needs and which has to be built for the Lua cgit is linked against, and
--- forgetting that is the usual reason nothing is coloured.
+-- 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.
--
-- # Debian and Ubuntu
-- sudo apt install lua-lpeg
@@ -76,15 +71,23 @@ local css = {
["function"] = "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. A wrong guess only falls back to
--- plain text, so a best-effort entry costs nothing.
+-- 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",
+ 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",
}
@@ -108,7 +111,8 @@ local function scintillua_path()
if config then
local dir = string.match(config, "^(.*)/[^/]+$")
if dir then
- candidates[#candidates + 1] = dir .. "/scintillua/lexers"
+ candidates[#candidates + 1] =
+ dir .. "/scintillua/lexers"
end
end
for _, dir in ipairs(scintillua_dirs) do
@@ -159,9 +163,6 @@ local function load_lexer_name(name)
return nil
end
--- Resolve a lexer for the file, preferring Scintillua's own filename
--- detection where this version provides it, then the extension map above,
--- then the raw extension.
local function lexer_for(name)
if type(scintillua.detect) == "function" then
local ok, lang = pcall(scintillua.detect, name)
@@ -200,7 +201,8 @@ local function highlight(text)
local part = escape(string.sub(text, pos, stop - 1))
local class = css[string.match(tag, "^[%w_]+")]
if class and part ~= "" then
- part = "<span class='" .. class .. "'>" .. part .. "</span>"
+ part = "<span class='" .. class .. "'>"
+ .. part .. "</span>"
end
out[#out + 1] = part
pos = stop
@@ -223,8 +225,9 @@ function filter_write(str)
end
-- cgit takes filter output through a C string sink that stops at the first
--- NUL byte, so a blob holding one is truncated there. That reaches binary
--- files which slip past cgit's text detection, not ordinary source.
+-- NUL byte, so a write holding one loses everything from the NUL on. That
+-- reaches binary files which slip past cgit's text detection, not ordinary
+-- source.
function filter_close()
local text = table.concat(chunks)
chunks = {}