-- A miniature stand-in for the Scintillua lexer module, just enough for the -- syntax-highlight checks to drive every path through the filter without the -- real collection installed. load() hands out one of the toy lexers below by -- name and detect() recognises a single filename suffix or a shebang naming -- fake, so a check can tell the detection path apart from the extension path -- by which lexer ends up running. Anything the filter treats as optional, a lexer that will not -- load or one that raises while lexing, has a name here too. local M = {} -- Tokens come back the way Scintillua returns them, one flat list of a tag -- name and the position just past the token it names. Letter runs are -- keywords, digit runs are numbers, a single quoted run carries a dotted tag -- so the dotted first component lookup gets exercised, a run after a colon or -- a dollar sign takes one of the tags only the css lexer uses, and any other -- byte is whitespace, which maps to no css class. local patterns = { { "^:%a+", "pseudoclass" }, { "^%$%a+", "property" }, { "^%a+", "keyword" }, { "^%d+", "number" }, { "^'[^']*'", "string.double" }, } local function lex_words(self, text) local tokens = {} local pos = 1 while pos <= #text do local tag, stop = "whitespace", pos for _, pattern in ipairs(patterns) do local start, finish = text:find(pattern[1], pos) if start then tag, stop = pattern[2], finish break end end tokens[#tokens + 1] = tag tokens[#tokens + 1] = stop + 1 pos = stop + 1 end return tokens end -- Tags only the first four bytes and stops, so the filter has to append the -- untagged tail itself or the check for it fails. local function lex_short(self, text) if #text < 5 then return {} end return { "keyword", 5 } end local function lex_raise(self, text) error("this lexer always raises") end local lexers = { fake = { lex = lex_words }, short = { lex = lex_short }, badlex = { lex = lex_raise }, } function M.load(name) local lexer = lexers[name] if lexer == nil then error("no fake lexer named " .. tostring(name)) end return lexer end function M.detect(filename, line) if filename:match("%.viadetect$") then return "fake" end if line ~= nil and line:match("^#!.*fake") then return "fake" end return nil end return M