-- mod-version:3 -- Support for the Fennel programming language: https://fennel-lang.org -- Covers all the keywords up to Fennel version 1.2.0 -- Currently only covers highlighting, not indentation, delimiter -- matching, or evaluation. local syntax = require("core.syntax") syntax.add({ comment = ";", files = "%.fnl$", name = "Fennel", patterns = { { pattern = ";.-\n", type = "comment" }, { pattern = { '"', '"', "\\" }, type = "string" }, { pattern = "0x[%da-fA-F]+", type = "number" }, { pattern = "-?%d+[%d%.]*", type = "number" }, { pattern = "-?%.?%d+", type = "number" }, { pattern = "%f[^(][^()'%s\"]+", type = "function" }, { pattern = "[^()'%s\"]+", type = "symbol" }, }, symbols = { ["#"] = "keyword", ["%"] = "keyword", ["*"] = "keyword", ["+"] = "keyword", ["-"] = "keyword", ["->"] = "keyword", ["->>"] = "keyword", ["-?>"] = "keyword", ["-?>>"] = "keyword", ["."] = "keyword", [".."] = "keyword", ["/"] = "keyword", ["//"] = "keyword", [":"] = "keyword", ["<"] = "keyword", ["<="] = "keyword", ["="] = "keyword", [">"] = "keyword", [">="] = "keyword", ["?."] = "keyword", ["^"] = "keyword", _G = "keyword", accumulate = "keyword2", ["and"] = "keyword2", arg = "keyword2", assert = "keyword2", band = "keyword2", bit32 = "keyword2", ["bit32.arshift"] = "keyword2", ["bit32.band"] = "keyword2", ["bit32.bnot"] = "keyword2", ["bit32.bor"] = "keyword2", ["bit32.btest"] = "keyword2", ["bit32.bxor"] = "keyword2", ["bit32.extract"] = "keyword2", ["bit32.lrotate"] = "keyword2", ["bit32.lshift"] = "keyword2", ["bit32.replace"] = "keyword2", ["bit32.rrotate"] = "keyword2", ["bit32.rshift"] = "keyword2", bnot = "keyword2", bor = "keyword2", bxor = "keyword2", collect = "keyword2", collectgarbage = "keyword2", comment = "keyword2", coroutine = "keyword2", ["coroutine.create"] = "keyword2", ["coroutine.resume"] = "keyword2", ["coroutine.running"] = "keyword2", ["coroutine.status"] = "keyword2", ["coroutine.wrap"] = "keyword2", ["coroutine.yield"] = "keyword2", debug = "keyword2", ["debug.debug"] = "keyword2", ["debug.gethook"] = "keyword2", ["debug.getinfo"] = "keyword2", ["debug.getlocal"] = "keyword2", ["debug.getmetatable"] = "keyword2", ["debug.getregistry"] = "keyword2", ["debug.getupvalue"] = "keyword2", ["debug.getuservalue"] = "keyword2", ["debug.sethook"] = "keyword2", ["debug.setlocal"] = "keyword2", ["debug.setmetatable"] = "keyword2", ["debug.setupvalue"] = "keyword2", ["debug.setuservalue"] = "keyword2", ["debug.traceback"] = "keyword2", ["debug.upvalueid"] = "keyword2", ["debug.upvaluejoin"] = "keyword2", ["do"] = "keyword2", dofile = "keyword2", doto = "keyword2", each = "keyword2", error = "keyword2", ["eval-compiler"] = "keyword2", ["false"] = "literal", fcollect = "keyword2", fn = "keyword2", ["for"] = "keyword2", getmetatable = "keyword2", global = "keyword2", hashfn = "keyword2", icollect = "keyword2", ["if"] = "keyword2", ["import-macros"] = "keyword2", include = "keyword2", io = "keyword2", ["io.close"] = "keyword2", ["io.flush"] = "keyword2", ["io.input"] = "keyword2", ["io.lines"] = "keyword2", ["io.open"] = "keyword2", ["io.output"] = "keyword2", ["io.popen"] = "keyword2", ["io.read"] = "keyword2", ["io.tmpfile"] = "keyword2", ["io.type"] = "keyword2", ["io.write"] = "keyword2", ipairs = "keyword2", lambda = "keyword2", length = "keyword2", let = "keyword2", load = "keyword2", loadfile = "keyword2", loadstring = "keyword2", ["local"] = "keyword2", lshift = "keyword2", lua = "keyword2", macro = "keyword2", macrodebug = "keyword2", macros = "keyword2", match = "keyword2", ["match-try"] = "keyword2", math = "keyword2", ["math.abs"] = "keyword2", ["math.acos"] = "keyword2", ["math.asin"] = "keyword2", ["math.atan"] = "keyword2", ["math.atan2"] = "keyword2", ["math.ceil"] = "keyword2", ["math.cos"] = "keyword2", ["math.cosh"] = "keyword2", ["math.deg"] = "keyword2", ["math.exp"] = "keyword2", ["math.floor"] = "keyword2", ["math.fmod"] = "keyword2", ["math.frexp"] = "keyword2", ["math.ldexp"] = "keyword2", ["math.log"] = "keyword2", ["math.log10"] = "keyword2", ["math.max"] = "keyword2", ["math.min"] = "keyword2", ["math.modf"] = "keyword2", ["math.pow"] = "keyword2", ["math.rad"] = "keyword2", ["math.random"] = "keyword2", ["math.randomseed"] = "keyword2", ["math.sin"] = "keyword2", ["math.sinh"] = "keyword2", ["math.sqrt"] = "keyword2", ["math.tan"] = "keyword2", ["math.tanh"] = "keyword2", module = "keyword2", next = "keyword2", ["nil"] = "literal", ["not"] = "keyword2", ["not="] = "keyword2", ["or"] = "keyword2", os = "keyword2", ["os.clock"] = "keyword2", ["os.date"] = "keyword2", ["os.difftime"] = "keyword2", ["os.execute"] = "keyword2", ["os.exit"] = "keyword2", ["os.getenv"] = "keyword2", ["os.remove"] = "keyword2", ["os.rename"] = "keyword2", ["os.setlocale"] = "keyword2", ["os.time"] = "keyword2", ["os.tmpname"] = "keyword2", package = "keyword2", ["package.loadlib"] = "keyword2", ["package.searchpath"] = "keyword2", ["package.seeall"] = "keyword2", pairs = "keyword2", partial = "keyword2", pcall = "keyword2", ["pick-args"] = "keyword2", ["pick-values"] = "keyword2", print = "keyword2", quote = "keyword2", rawequal = "keyword2", rawget = "keyword2", rawlen = "keyword2", rawset = "keyword2", require = "keyword2", ["require-macros"] = "keyword2", rshift = "keyword2", select = "keyword2", set = "keyword2", ["set-forcibly!"] = "keyword2", setmetatable = "keyword2", string = "keyword2", ["string.byte"] = "keyword2", ["string.char"] = "keyword2", ["string.dump"] = "keyword2", ["string.find"] = "keyword2", ["string.format"] = "keyword2", ["string.gmatch"] = "keyword2", ["string.gsub"] = "keyword2", ["string.len"] = "keyword2", ["string.lower"] = "keyword2", ["string.match"] = "keyword2", ["string.rep"] = "keyword2", ["string.reverse"] = "keyword2", ["string.sub"] = "keyword2", ["string.upper"] = "keyword2", table = "keyword2", ["table.concat"] = "keyword2", ["table.insert"] = "keyword2", ["table.maxn"] = "keyword2", ["table.pack"] = "keyword2", ["table.remove"] = "keyword2", ["table.sort"] = "keyword2", ["table.unpack"] = "keyword2", tonumber = "keyword2", tostring = "keyword2", ["true"] = "literal", tset = "keyword2", type = "keyword2", unpack = "keyword2", values = "keyword2", var = "keyword2", when = "keyword2", ["while"] = "keyword2", ["with-open"] = "keyword2", xpcall = "keyword2", ["~="] = "keyword", ["λ"] = "keyword", }, }) -- To regenerate the syntax from the compiler: -- (macro s [] -- (let [{: syntax} (require :fennel) -- symbols {:nil :literal -- :true :literal -- :false :literal}] -- `(syntax.add {:name "Fennel" -- :files "%.fnl$" -- :comment ";" -- :patterns [{:type :comment :pattern ";.-\n"} -- {:type :string :pattern {1 "\"" 2 "\"" 3 "\\"}} -- {:type :number :pattern "0x[%da-fA-F]+"} -- {:type :number :pattern "-?%d+[%d%.]*"} -- {:type :number :pattern "-?%.?%d+"} -- {:type :function :pattern "%f[^(][^()'%s\"]+"} -- {:type :symbol :pattern "[^()'%s\"]+"}] -- :symbols ,(collect [name (pairs (syntax)) :into symbols] -- (values name -- (if (name:find "[a-z]") -- :keyword2 :keyword)))}))) (s) -- and reformat the output, of course