changeset 6729:1398f0041235

Basic language support for Fennel. Might even work. (#13260) Co-authored-by: uncenter <[email protected]> Co-authored-by: Simon Heath <[email protected]>
author icefoxen <icefox@dreamquest.io>
date Tue, 15 Apr 2025 19:05:44 -0400
parents 335d60c0b8cf
children 5ceeac022f31
files book/src/generated/lang-support.md languages.toml runtime/queries/fennel/highlights.scm
diffstat 3 files changed, 209 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/book/src/generated/lang-support.md	Tue Apr 15 08:23:27 2025 -0500
+++ b/book/src/generated/lang-support.md	Tue Apr 15 19:05:44 2025 -0400
@@ -58,6 +58,7 @@
 | erb | ✓ |  |  |  |
 | erlang | ✓ | ✓ |  | `erlang_ls`, `elp` |
 | esdl | ✓ |  |  |  |
+| fennel | ✓ |  |  | `fennel-ls` |
 | fga | ✓ | ✓ | ✓ |  |
 | fidl | ✓ |  |  |  |
 | fish | ✓ | ✓ | ✓ | `fish-lsp` |
--- a/languages.toml	Tue Apr 15 08:23:27 2025 -0500
+++ b/languages.toml	Tue Apr 15 19:05:44 2025 -0400
@@ -39,6 +39,7 @@
 elp = { command = "elp", args = ["server"] }
 elvish = { command = "elvish", args = ["-lsp"] }
 erlang-ls = { command = "erlang_ls" }
+fennel-ls = { command = "fennel-ls" }
 fish-lsp = { command = "fish-lsp", args = ["start"], environment = { fish_lsp_show_client_popups = "false" } }
 forc = { command = "forc", args = ["lsp"] }
 forth-lsp = { command = "forth-lsp" }
@@ -398,6 +399,20 @@
 source = { git = "https://github.com/elixir-lang/tree-sitter-elixir", rev = "02a6f7fd4be28dd94ee4dd2ca19cb777053ea74e" }
 
 [[language]]
+name = "fennel"
+scope = "source.fennel"
+file-types = ["fnl", "fnlm"]
+shebangs = ["fennel"]
+comment-token = ";"
+language-servers = ["fennel-ls"]
+formatter = { command = "fnlfmt", args = ["-"]}
+indent = { tab-width = 2, unit = "  " }
+
+[[grammar]]
+name = "fennel"
+source = { git = "https://github.com/alexmozaidze/tree-sitter-fennel", rev = "cfbfa478dc2dbef267ee94ae4323d9c886f45e94" }
+
+[[language]]
 name = "fish"
 scope = "source.fish"
 injection-regex = "fish"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/runtime/queries/fennel/highlights.scm	Tue Apr 15 19:05:44 2025 -0400
@@ -0,0 +1,193 @@
+; Most primitive nodes
+(shebang) @keyword.directive
+
+(comment) @comment
+
+(fn_form
+  name: [
+    (symbol) @function
+    (multi_symbol
+      member: (symbol_fragment) @function .)
+  ])
+
+(lambda_form
+  name: [
+    (symbol) @function
+    (multi_symbol
+      member: (symbol_fragment) @function .)
+  ])
+
+((symbol) @operator
+  (#any-of? @operator
+    ; arithmetic
+    "+" "-" "*" "/" "//" "%" "^"
+    ; comparison
+    ">" "<" ">=" "<=" "=" "~="
+    ; other
+    "#" "." "?." ".."))
+
+((symbol) @keyword.operator
+  (#any-of? @keyword.operator
+    ; comparison
+    "not="
+    ; boolean
+    "and" "or" "not"
+    ; bitwise
+    "lshift" "rshift" "band" "bor" "bxor" "bnot"
+    ; other
+    "length"))
+
+(case_guard
+  call: (_) @keyword.control.conditional)
+
+(case_guard_or_special
+  call: (_) @keyword.control.conditional)
+
+(case_catch
+  call: (symbol) @keyword)
+
+(import_macros_form
+  imports: (table_binding
+    (table_binding_pair
+      value: (symbol_binding) @function.macro)))
+
+
+((symbol) @keyword.function
+  (#any-of? @keyword.function "fn" "lambda" "λ" "hashfn"))
+
+((symbol) @keyword.control.repeat
+  (#any-of? @keyword.control.repeat "for" "each" "while"))
+
+((symbol) @keyword.control.conditional
+  (#any-of? @keyword.control.conditional "if" "when" "match" "case" "match-try" "case-try"))
+
+((symbol) @keyword
+  (#any-of? @keyword
+    "global" "local" "let" "set" "var" "comment" "do" "doc" "eval-compiler" "lua" "macros" "unquote"
+    "quote" "tset" "values" "tail!"))
+
+((symbol) @keyword.control.import
+  (#any-of? @keyword.control.import "require" "require-macros" "import-macros" "include"))
+
+((symbol) @function.macro
+  (#any-of? @function.macro
+    "collect" "icollect" "fcollect" "accumulate" "faccumulate" "->" "->>" "-?>" "-?>>" "?." "doto"
+    "macro" "macrodebug" "partial" "pick-args" "pick-values" "with-open"))
+
+((symbol) @variable.builtin
+  (#eq? @variable.builtin "..."))
+
+((symbol) @constant.builtin
+  (#eq? @constant.builtin "_VERSION"))
+
+((symbol) @function.builtin
+  (#any-of? @function.builtin
+    "assert" "collectgarbage" "dofile" "error" "getmetatable" "ipairs" "load" "loadfile" "next"
+    "pairs" "pcall" "print" "rawequal" "rawget" "rawlen" "rawset" "require" "select" "setmetatable"
+    "tonumber" "tostring" "type" "warn" "xpcall" "module" "setfenv" "loadstring" "unpack"))
+
+; TODO: Highlight builtin methods (`table.unpack`, etc) as @function.builtin
+([
+  (symbol) @variable.builtin
+  (multi_symbol
+    base: (symbol_fragment) @variable.builtin)
+]
+  (#any-of? @variable.builtin
+    "vim" "_G" "_ENV" "debug" "io" "jit" "math" "os" "package" "string" "table" "utf8"))
+
+([
+  (symbol) @variable.builtin
+  (multi_symbol
+    .
+    (symbol_fragment) @variable.builtin)
+]
+  (#eq? @variable.builtin "arg"))
+(symbol_option) @keyword.directive
+
+(escape_sequence) @constant.character.escape
+
+(multi_symbol
+  "." @punctuation.delimiter
+  member: (symbol_fragment) @variable.other.member)
+
+(list
+  call: (symbol) @function)
+
+(list
+  call: (multi_symbol
+    member: (symbol_fragment) @function .))
+
+(multi_symbol_method
+  ":" @punctuation.delimiter
+  method: (symbol_fragment) @function.method)
+
+(quasi_quote_reader_macro
+  macro: _ @punctuation.special)
+
+(quote_reader_macro
+  macro: _ @punctuation.special)
+
+(unquote_reader_macro
+  macro: _ @punctuation.special)
+
+(hashfn_reader_macro
+  macro: _ @keyword.function)
+
+(docstring) @comment.block.documentation
+
+; NOTE: The macro name is highlighted as @variable because it
+; gives a nicer contrast instead of everything being the same
+; color. Rust queries use this workaround too for `macro_rules!`.
+(macro_form
+  name: [
+    (symbol) @variable
+    (multi_symbol
+      member: (symbol_fragment) @variable .)
+  ])
+
+[
+  "("
+  ")"
+  "{"
+  "}"
+  "["
+  "]"
+] @punctuation.bracket
+
+(sequence_arguments
+  (symbol_binding) @variable.parameter)
+
+(sequence_arguments
+  (rest_binding
+    rhs: (symbol_binding) @variable.parameter))
+
+((symbol) @variable.parameter
+  (#any-of? @variable.parameter "$" "$..."))
+
+((symbol) @variable.parameter
+  (#any-of? @variable.parameter "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9"))
+
+[
+  (nil)
+  (nil_binding)
+] @constant.builtin
+
+[
+  (boolean)
+  (boolean_binding)
+] @constant.builtin.boolean
+
+[
+  (number)
+  (number_binding)
+] @constant.numeric
+
+[
+  (string)
+  (string_binding)
+] @string
+
+[
+  (symbol)
+  (symbol_binding)
+] @variable