lite-xl/data/plugins/language_js.lua

125 lines
4.8 KiB
Lua
Raw Normal View History

2022-05-31 22:34:14 +02:00
-- mod-version:3
2019-12-28 12:16:32 +01:00
local syntax = require "core.syntax"
-- Regex pattern explanation:
-- This will match / and will look ahead for something that looks like a regex.
--
-- (?!/) Don't match empty regexes.
--
-- (?>...) this is using an atomic group to minimize backtracking, as that'd
-- cause "Catastrophic Backtracking" in some cases.
--
-- [^\\[\/]++ will match anything that's isn't an escape, a start of character
-- class or an end of pattern, without backtracking (the second +).
--
-- \\. will match anything that's escaped.
--
-- \[(?:[^\\\]++]|\\.)*+\] will match character classes.
--
-- /[gmiyuvsd]*\s*[\n,;\)\]\}\.]) will match the end of pattern delimiter, optionally
-- followed by pattern options, and anything that can
-- be after a pattern.
--
-- Demo with some unit tests (click on the Unit Tests entry): https://regex101.com/r/R0w8Qw/1
-- Note that it has a couple of changes to make it work on that platform.
local regex_pattern = {
[=[/(?=(?!/)(?:(?>[^\\[\/]++|\\.|\[(?:[^\\\]]++|\\.)*+\])*+)++/[gmiyuvsd]*\s*[\n,;\)\]\}\.])()]=],
"/()[gmiyuvsd]*", "\\"
}
-- For the moment let's not actually differentiate the insides of the regex,
-- as this will need new token types...
local inner_regex_syntax = {
patterns = {
{ pattern = "%(()%?[:!=><]", type = { "string", "string" } },
{ pattern = "[.?+*%(%)|]", type = "string" },
{ pattern = "{%d*,?%d*}", type = "string" },
{ regex = { [=[\[()\^?]=], [=[(?:\]|(?=\n))()]=], "\\" },
type = { "string", "string" },
syntax = { -- Inside character class
patterns = {
{ pattern = "\\\\", type = "string" },
{ pattern = "\\%]", type = "string" },
{ pattern = "[^%]\n]", type = "string" }
},
symbols = {}
}
},
{ regex = "\\/", type = "string" },
{ regex = "[^/\n]", type = "string" },
},
symbols = {}
}
2019-12-28 12:16:32 +01:00
syntax.add {
2021-11-21 03:46:43 +01:00
name = "JavaScript",
files = { "%.js$", "%.json$", "%.cson$", "%.mjs$", "%.cjs$" },
2019-12-28 12:16:32 +01:00
comment = "//",
block_comment = { "/*", "*/" },
2019-12-28 12:16:32 +01:00
patterns = {
{ pattern = "//.*", type = "comment" },
{ pattern = { "/%*", "%*/" }, type = "comment" },
{ regex = regex_pattern, syntax = inner_regex_syntax, type = {"string", "string"} },
{ pattern = { '"', '"', '\\' }, type = "string" },
{ pattern = { "'", "'", '\\' }, type = "string" },
{ pattern = { "`", "`", '\\' }, type = "string" },
-- Use (?:\/(?!\/))? to avoid that a regex can start after a number, while also allowing // comments
{ regex = [[-?0[xXbBoO][\da-fA-F_]+n?()\s*()(?:\/(?!\/))?]], type = {"number", "normal", "operator"} },
{ regex = [[-?\d+[0-9.eE_n]*()\s*()(?:\/(?!\/))?]], type = {"number", "normal", "operator"} },
{ regex = [[-?\.?\d+()\s*()(?:\/(?!\/))?]], type = {"number", "normal", "operator"} },
{ pattern = "[%+%-=/%*%^%%<>!~|&]", type = "operator" },
{ pattern = "[%a_][%w_]*%f[(]", type = "function" },
{ regex = [=[[a-zA-Z_]\w*()\s*()(?:\/(?!\/))?]=], type = {"symbol", "normal", "operator"} },
2019-12-28 12:16:32 +01:00
},
symbols = {
2020-05-10 10:51:45 +02:00
["async"] = "keyword",
["await"] = "keyword",
["break"] = "keyword",
["case"] = "keyword",
["catch"] = "keyword",
["class"] = "keyword",
["const"] = "keyword",
["continue"] = "keyword",
["debugger"] = "keyword",
["default"] = "keyword",
["delete"] = "keyword",
["do"] = "keyword",
["else"] = "keyword",
["export"] = "keyword",
["extends"] = "keyword",
["finally"] = "keyword",
["for"] = "keyword",
["function"] = "keyword",
2020-05-10 10:56:28 +02:00
["get"] = "keyword",
2020-05-10 10:51:45 +02:00
["if"] = "keyword",
["import"] = "keyword",
2024-03-24 19:25:44 +01:00
["from"] = "keyword",
2020-05-10 10:51:45 +02:00
["in"] = "keyword",
["of"] = "keyword",
2020-05-10 10:51:45 +02:00
["instanceof"] = "keyword",
["let"] = "keyword",
["new"] = "keyword",
["return"] = "keyword",
2020-05-10 10:56:28 +02:00
["set"] = "keyword",
2020-06-05 23:37:51 +02:00
["static"] = "keyword",
2020-05-10 10:51:45 +02:00
["super"] = "keyword",
["switch"] = "keyword",
["throw"] = "keyword",
["try"] = "keyword",
["typeof"] = "keyword",
["var"] = "keyword",
["void"] = "keyword",
["while"] = "keyword",
["with"] = "keyword",
["yield"] = "keyword",
2020-06-05 23:37:51 +02:00
["true"] = "literal",
["false"] = "literal",
["null"] = "literal",
["undefined"] = "literal",
["arguments"] = "keyword2",
["Infinity"] = "keyword2",
["NaN"] = "keyword2",
["this"] = "keyword2",
2019-12-28 12:16:32 +01:00
},
}