Unnamed repository; edit this file 'description' to name the repository.
feat: Add vimscript language support (#13062)
Daniel Fichtinger 7 months ago
parent 94c96cf · commit 4fd4588
-rw-r--r--book/src/generated/lang-support.md1
-rw-r--r--languages.toml16
-rw-r--r--runtime/queries/vim/folds.scm4
-rw-r--r--runtime/queries/vim/highlights.scm350
-rw-r--r--runtime/queries/vim/injections.scm44
5 files changed, 415 insertions, 0 deletions
diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md
index de413fb1..e00eba03 100644
--- a/book/src/generated/lang-support.md
+++ b/book/src/generated/lang-support.md
@@ -265,6 +265,7 @@
| verilog | ✓ | ✓ | | | `svlangserver` |
| vhdl | ✓ | | | | `vhdl_ls` |
| vhs | ✓ | | | | |
+| vim | ✓ | | | | |
| vue | ✓ | | | | `vue-language-server` |
| wast | ✓ | | | | |
| wat | ✓ | | | | `wat_server` |
diff --git a/languages.toml b/languages.toml
index 7313d746..05781f81 100644
--- a/languages.toml
+++ b/languages.toml
@@ -4419,6 +4419,22 @@ language-servers = ["sourcepawn-studio"]
name = "sourcepawn"
source = { git = "https://github.com/nilshelmig/tree-sitter-sourcepawn", rev = "f2af8d0dc14c6790130cceb2a20027eb41a8297c" }
+
+[[grammar]]
+name = "vim"
+source = { git = "https://github.com/tree-sitter-grammars/tree-sitter-vim", rev = "f3cd62d8bd043ef20507e84bb6b4b53731ccf3a7" }
+
+[[language]]
+name = "vim"
+scope = "source.vim"
+injection-regex = "vim"
+comment-token = '"'
+indent = { tab-width = 4, unit = "\t" }
+file-types = [
+ "vim",
+ { glob = ".vimrc" },
+]
+
[[language]]
name = "tlaplus"
scope = "scope.tlaplus"
diff --git a/runtime/queries/vim/folds.scm b/runtime/queries/vim/folds.scm
new file mode 100644
index 00000000..0a1fb695
--- /dev/null
+++ b/runtime/queries/vim/folds.scm
@@ -0,0 +1,4 @@
+[
+ (if_statement)
+ (function_definition)
+] @fold
diff --git a/runtime/queries/vim/highlights.scm b/runtime/queries/vim/highlights.scm
new file mode 100644
index 00000000..d2686241
--- /dev/null
+++ b/runtime/queries/vim/highlights.scm
@@ -0,0 +1,350 @@
+(identifier) @variable
+
+((identifier) @constant
+ (#match? @constant "^[A-Z][A-Z_0-9]*$"))
+
+; Keywords
+[
+ "if"
+ "else"
+ "elseif"
+ "endif"
+] @keyword.control.conditional
+
+[
+ "try"
+ "catch"
+ "finally"
+ "endtry"
+ "throw"
+] @keyword.control.except
+
+[
+ "for"
+ "endfor"
+ "in"
+ "while"
+ "endwhile"
+ "break"
+ "continue"
+] @keyword.control.repeat
+
+[
+ "function"
+ "endfunction"
+] @keyword.function
+
+; Function related
+(function_declaration
+ name: (_) @function)
+
+(call_expression
+ function: (identifier) @function)
+
+(call_expression
+ function:
+ (scoped_identifier
+ (identifier) @function))
+
+(parameters
+ (identifier) @variable.parameter)
+
+(default_parameter
+ (identifier) @variable.parameter)
+
+[
+ (bang)
+ (spread)
+] @punctuation.special
+
+[
+ (no_option)
+ (inv_option)
+ (default_option)
+ (option_name)
+] @variable.builtin
+
+[
+ (scope)
+ "a:"
+ "$"
+] @namespace
+
+; Commands and user defined commands
+[
+ "let"
+ "unlet"
+ "const"
+ "call"
+ "execute"
+ "normal"
+ "set"
+ "setfiletype"
+ "setlocal"
+ "silent"
+ "echo"
+ "echon"
+ "echohl"
+ "echomsg"
+ "echoerr"
+ "autocmd"
+ "augroup"
+ "return"
+ "syntax"
+ "filetype"
+ "source"
+ "lua"
+ "ruby"
+ "perl"
+ "python"
+ "highlight"
+ "command"
+ "delcommand"
+ "comclear"
+ "colorscheme"
+ "scriptencoding"
+ "startinsert"
+ "stopinsert"
+ "global"
+ "runtime"
+ "wincmd"
+ "cnext"
+ "cprevious"
+ "cNext"
+ "vertical"
+ "leftabove"
+ "aboveleft"
+ "rightbelow"
+ "belowright"
+ "topleft"
+ "botright"
+ (unknown_command_name)
+ "edit"
+ "enew"
+ "find"
+ "ex"
+ "visual"
+ "view"
+ "eval"
+ "sign"
+] @keyword
+
+(map_statement
+ cmd: _ @keyword)
+
+(keycode) @constant.character.escape
+
+(command_name) @function.macro
+
+; Filetype command
+(filetype_statement
+ [
+ "detect"
+ "plugin"
+ "indent"
+ "on"
+ "off"
+ ] @keyword)
+
+; Syntax command
+(syntax_statement
+ (keyword) @string)
+
+(syntax_statement
+ [
+ "enable"
+ "on"
+ "off"
+ "reset"
+ "case"
+ "spell"
+ "foldlevel"
+ "iskeyword"
+ "keyword"
+ "match"
+ "cluster"
+ "region"
+ "clear"
+ "include"
+ ] @keyword)
+
+(syntax_argument
+ name: _ @keyword)
+
+[
+ "<buffer>"
+ "<nowait>"
+ "<silent>"
+ "<script>"
+ "<expr>"
+ "<unique>"
+] @constant.builtin
+
+(augroup_name) @namespace
+
+(au_event) @constant
+
+(normal_statement
+ (commands) @constant)
+
+; Highlight command
+(hl_attribute
+ key: _ @variable.parameter
+ val: _ @constant)
+
+(hl_group) @type
+
+(highlight_statement
+ [
+ "default"
+ "link"
+ "clear"
+ ] @keyword)
+
+; Command command
+(command) @string
+
+(command_attribute
+ name: _ @variable.parameter)
+
+(command_attribute
+ val: (behavior
+ _ @constant))
+
+; Edit command
+(plus_plus_opt
+ val: _? @constant) @variable.parameter
+
+(plus_cmd
+ "+" @variable.parameter) @variable.parameter
+
+; Runtime command
+(runtime_statement
+ (where) @keyword.operator)
+
+; Colorscheme command
+(colorscheme_statement
+ (name) @string)
+
+; Scriptencoding command
+(scriptencoding_statement
+ (encoding) @string.special)
+
+; Literals
+(string_literal) @string
+
+(integer_literal) @constant.numeric.integer
+
+(float_literal) @constant.numeric.float
+
+(comment) @comment
+
+(line_continuation_comment) @comment
+
+(pattern) @string.special
+
+(pattern_multi) @string.regexp
+
+(filename) @string.special.path
+
+(heredoc
+ (body) @string)
+
+(heredoc
+ (parameter) @keyword)
+
+[
+ (marker_definition)
+ (endmarker)
+] @label
+
+(literal_dictionary
+ (literal_key) @variable.parameter)
+
+((scoped_identifier
+ (scope) @_scope
+ .
+ (identifier) @constant.builtin.boolean)
+ (#eq? @_scope "v:")
+ (#any-of? @constant.builtin.boolean "true" "false"))
+
+; Operators
+[
+ "||"
+ "&&"
+ "&"
+ "+"
+ "-"
+ "*"
+ "/"
+ "%"
+ ".."
+ "is"
+ "isnot"
+ "=="
+ "!="
+ ">"
+ ">="
+ "<"
+ "<="
+ "=~"
+ "!~"
+ "="
+ "+="
+ "-="
+ "*="
+ "/="
+ "%="
+ ".="
+ "..="
+ "<<"
+ "=<<"
+ (match_case)
+] @operator
+
+; Some characters have different meanings based on the context
+(unary_operation
+ "!" @operator)
+
+(binary_operation
+ "." @operator)
+
+; Punctuation
+[
+ "("
+ ")"
+ "{"
+ "}"
+ "["
+ "]"
+ "#{"
+] @punctuation.bracket
+
+(field_expression
+ "." @punctuation.delimiter)
+
+[
+ ","
+ ":"
+] @punctuation.delimiter
+
+(ternary_expression
+ [
+ "?"
+ ":"
+ ] @keyword.operator)
+
+; Options
+((set_value) @constant.numeric
+ (#match? @constant.numeric "^[0-9]+([.][0-9]+)?$"))
+
+(inv_option
+ "!" @operator)
+
+(set_item
+ "?" @operator)
+
+((set_item
+ option: (option_name) @_option
+ value: (set_value) @function)
+ (#any-of? @_option "tagfunc" "tfu" "completefunc" "cfu" "omnifunc" "ofu" "operatorfunc" "opfunc"))
diff --git a/runtime/queries/vim/injections.scm b/runtime/queries/vim/injections.scm
new file mode 100644
index 00000000..30d11cbb
--- /dev/null
+++ b/runtime/queries/vim/injections.scm
@@ -0,0 +1,44 @@
+(lua_statement
+ (script
+ (body) @injection.content
+ (#set! injection.language "lua")))
+
+(lua_statement
+ (chunk) @injection.content
+ (#set! injection.language "lua"))
+
+(ruby_statement
+ (script
+ (body) @injection.content
+ (#set! injection.language "ruby")))
+
+(ruby_statement
+ (chunk) @injection.content
+ (#set! injection.language "ruby"))
+
+(python_statement
+ (script
+ (body) @injection.content
+ (#set! injection.language "python")))
+
+(python_statement
+ (chunk) @injection.content
+ (#set! injection.language "python"))
+
+; If we support perl at some point...
+; (perl_statement (script (body) @perl))
+; (perl_statement (chunk) @perl)
+(autocmd_statement
+ (pattern) @injection.content
+ (#set! injection.language "regex"))
+
+((set_item
+ option: (option_name) @_option
+ value: (set_value) @injection.content)
+ (#any-of? @_option
+ "includeexpr" "inex" "printexpr" "pexpr" "formatexpr" "fex" "indentexpr" "inde" "foldtext" "fdt"
+ "foldexpr" "fde" "diffexpr" "dex" "patchexpr" "pex" "charconvert" "ccv")
+ (#set! injection.language "vim"))
+
+((comment) @injection.content
+ (#set! injection.language "comment"))