summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTING.md19
-rw-r--r--README.md3
-rw-r--r--lockfile.json53
-rw-r--r--lua/nvim-treesitter/configs.lua207
-rw-r--r--lua/nvim-treesitter/fold.lua2
-rw-r--r--lua/nvim-treesitter/highlight.lua12
-rw-r--r--lua/nvim-treesitter/install.lua35
-rw-r--r--lua/nvim-treesitter/parsers.lua34
-rw-r--r--lua/nvim-treesitter/query.lua99
-rw-r--r--lua/nvim-treesitter/shell_command_selectors.lua1
-rw-r--r--lua/nvim-treesitter/utils.lua6
-rw-r--r--queries/awk/highlights.scm154
-rw-r--r--queries/awk/injections.scm2
-rw-r--r--queries/help/highlights.scm13
-rw-r--r--queries/julia/folds.scm2
-rw-r--r--queries/julia/highlights.scm232
-rw-r--r--queries/julia/indents.scm2
-rw-r--r--queries/julia/locals.scm84
-rw-r--r--queries/lua/highlights.scm5
-rw-r--r--queries/markdown/highlights.scm9
-rw-r--r--queries/ql/folds.scm7
-rw-r--r--queries/rego/highlights.scm70
-rw-r--r--queries/rust/folds.scm1
-rw-r--r--queries/rust/highlights.scm45
-rw-r--r--queries/rust/locals.scm3
-rw-r--r--queries/scheme/highlights.scm2
-rw-r--r--queries/vhs/highlights.scm38
-rw-r--r--scripts/ci-install-macos-latest.sh1
-rw-r--r--scripts/ci-install-ubuntu-latest.sh9
29 files changed, 822 insertions, 328 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index ea3cbc40..5a6fd71e 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -156,15 +156,16 @@ effect on highlighting. We will work on improving highlighting in the near futur
#### Types
```scheme
-@type ; type or class definitions and annotations
-@type.builtin ; built-in types
-@type.definition ; type definitions (e.g. `typedef` in C)
-@type.qualifier ; type qualifiers (e.g. `const`)
-
-@storageclass ; visibility/life-time/etc. modifiers (e.g. `static`)
-@attribute ; attribute annotations (e.g. Python decorators)
-@field ; object and struct fields
-@property ; similar to `@field`
+@type ; type or class definitions and annotations
+@type.builtin ; built-in types
+@type.definition ; type definitions (e.g. `typedef` in C)
+@type.qualifier ; type qualifiers (e.g. `const`)
+
+@storageclass ; visibility/life-time modifiers
+@storageclass.lifetime ; life-time modifiers (e.g. `static`)
+@attribute ; attribute annotations (e.g. Python decorators)
+@field ; object and struct fields
+@property ; similar to `@field`
```
#### Identifiers
diff --git a/README.md b/README.md
index 505caa19..cc6742cd 100644
--- a/README.md
+++ b/README.md
@@ -174,6 +174,7 @@ We are looking for maintainers to add more parsers and to write query files for
<!--parserinfo-->
- [x] [agda](https://github.com/AusCyberman/tree-sitter-agda) (maintained by @Decodetalkers)
- [x] [astro](https://github.com/virchau13/tree-sitter-astro) (maintained by @virchau13)
+- [ ] [awk](https://github.com/Beaglefoot/tree-sitter-awk)
- [x] [bash](https://github.com/tree-sitter/tree-sitter-bash) (maintained by @TravonteD)
- [x] [beancount](https://github.com/polarmutex/tree-sitter-beancount) (maintained by @polarmutex)
- [x] [bibtex](https://github.com/latex-lsp/tree-sitter-bibtex) (maintained by @theHamsta, @clason)
@@ -300,6 +301,7 @@ We are looking for maintainers to add more parsers and to write query files for
- [x] [v](https://github.com/vlang/vls) (maintained by @tami5)
- [x] [vala](https://github.com/vala-lang/tree-sitter-vala) (maintained by @Prince781, @vala-lang)
- [x] [verilog](https://github.com/tree-sitter/tree-sitter-verilog) (maintained by @zegervdv)
+- [x] [vhs](https://github.com/charmbracelet/tree-sitter-vhs) (maintained by @caarlos0, @maaslalani)
- [x] [vim](https://github.com/vigoux/tree-sitter-viml) (maintained by @vigoux)
- [x] [vue](https://github.com/ikatyang/tree-sitter-vue) (maintained by @WhyNotHugo)
- [x] [wgsl](https://github.com/szebniok/tree-sitter-wgsl) (maintained by @szebniok)
@@ -388,6 +390,7 @@ Tree-sitter based folding. *(Technically not a module because it's per windows a
```vim
set foldmethod=expr
set foldexpr=nvim_treesitter#foldexpr()
+set nofoldenable " Disable folding at startup.
```
This will respect your `foldminlines` and `foldnestmax` settings.
diff --git a/lockfile.json b/lockfile.json
index d53211c2..df48b75c 100644
--- a/lockfile.json
+++ b/lockfile.json
@@ -5,8 +5,11 @@
"astro": {
"revision": "947e93089e60c66e681eba22283f4037841451e7"
},
+ "awk": {
+ "revision": "a799bc5da7c2a84bc9a06ba5f3540cf1191e4ee3"
+ },
"bash": {
- "revision": "f1a86d3cc5aeeb67e0e52442e893af7f813025b4"
+ "revision": "77cf8a7cab8904baf1a721762e012644ac1d4c7b"
},
"beancount": {
"revision": "4cbd1f09cd07c1f1fabf867c2cf354f9da53cc4c"
@@ -21,7 +24,7 @@
"revision": "7175a6dd5fc1cee660dce6fe23f6043d75af424a"
},
"c_sharp": {
- "revision": "5b60f99545fea00a33bbfae5be956f684c4c69e2"
+ "revision": "3ef3f7f99e16e528e6689eae44dff35150993307"
},
"clojure": {
"revision": "087bac78c53fe1387756cd5b8e68a69b3f6d7244"
@@ -60,7 +63,7 @@
"revision": "330eb648bbc257b4e91621e82a85372be7dde27a"
},
"dockerfile": {
- "revision": "25c71d6a24cdba8f0c74ef40d4d2d93defd7e196"
+ "revision": "f913be9bb8689af22114605012693146fbe9ddaa"
},
"dot": {
"revision": "9ab85550c896d8b294d9b9ca1e30698736f08cea"
@@ -77,11 +80,8 @@
"elvish": {
"revision": "f32711e31e987fd5c2c002f3daba02f25c68672f"
},
- "embdedded_template": {
- "revision": "d21df11b0ecc6fd211dbe11278e92ef67bd17e97"
- },
"embedded_template": {
- "revision": "1a538da253d73f896b9f6c0c7d79cda58791ac5c"
+ "revision": "91fc5ae1140d5c9d922312431f7d251a48d7b8ce"
},
"erlang": {
"revision": "3a9c769444f08bbccce03845270efac0c641c5e7"
@@ -150,7 +150,7 @@
"revision": "52b804b1cb2d57e58d90090326d3ef9bd19cf16c"
},
"help": {
- "revision": "8df3266b423d24c9ac3f3b4b9928e65eb1e5e741"
+ "revision": "49cdef52ded4a886bf34bc474876b09f9270d48f"
},
"hjson": {
"revision": "02fa3b79b3ff9a296066da6277adfc3f26cbc9e0"
@@ -159,7 +159,7 @@
"revision": "384b26ec65e10f26cf147bfcde772c50ca5ef0d0"
},
"hocon": {
- "revision": "bb412e2633f4a3611a4e16efe58d917093bb4782"
+ "revision": "c390f10519ae69fdb03b3e5764f5592fb6924bcc"
},
"html": {
"revision": "29f53d8f4f2335e61bf6418ab8958dac3282077a"
@@ -189,10 +189,10 @@
"revision": "0475a5017ad7dc84845d1d33187f2321abcb261d"
},
"julia": {
- "revision": "0572cebf7b8e8ef5990b4d1e7f44f0b36f62922c"
+ "revision": "628713553c42f30595a3b0085bb587e9359b986a"
},
"kotlin": {
- "revision": "a4f71eb9b8c9b19ded3e0e9470be4b1b77c2b569"
+ "revision": "b953dbdd05257fcb2b64bc4d9c1578fac12e3c28"
},
"lalrpop": {
"revision": "7744b56f03ac1e5643fad23c9dd90837fe97291e"
@@ -207,7 +207,7 @@
"revision": "e9948edc41e9e5869af99dddb2b5ff5cc5581af6"
},
"lua": {
- "revision": "887dfd4e83c469300c279314ff1619b1d0b85b91"
+ "revision": "fb30e8cb605e2ebd6c643e6981325a63fbbde320"
},
"m68k": {
"revision": "d097b123f19c6eaba2bf181c05420d88b9fc489d"
@@ -255,7 +255,7 @@
"revision": "2fd40f477d3e2794af152618ccfac8d92eb72a66"
},
"perl": {
- "revision": "ff5c3108083af6fcb7575e32a7558b8165a05bcd"
+ "revision": "749d26fe13fb131b92e6515416096e572575b981"
},
"php": {
"revision": "ab2e72179ceb8bb0b249c8ac9162a148e911b3dc"
@@ -288,10 +288,10 @@
"revision": "0695cd0760532de7b54f23c667d459b5d1332b44"
},
"r": {
- "revision": "0f4f66e5050037b759ea040dafd596bcdda1de94"
+ "revision": "80efda55672d1293aa738f956c7ae384ecdc31b4"
},
"racket": {
- "revision": "b9b2e7454d7098e44595dd8c1b471b9d1518b910"
+ "revision": "09cb27a06415bce529a26774a842f5a80d50d362"
},
"rasi": {
"revision": "12391343979463a2484e6353e5afb6dcb8c31e8b"
@@ -300,7 +300,7 @@
"revision": "e1cfca3c79896ff79842f057ea13e529b66af636"
},
"rego": {
- "revision": "6d70da3a998fd0081efc5d1019c71e74cc1568e9"
+ "revision": "6174f05f58e8c35d8c82323dd8c599b90b3171b3"
},
"rnoweb": {
"revision": "502c1126dc6777f09af5bef16e72a42f75bd081e"
@@ -309,16 +309,16 @@
"revision": "25e6328872ac3a764ba8b926aea12719741103f1"
},
"ruby": {
- "revision": "252ca18be76b0918fb6b34c302292b6931876c25"
+ "revision": "c91960320d0f337bdd48308a8ad5500bd2616979"
},
"rust": {
- "revision": "47b061c1e1ba3a7e9c2f450363a50e87de3f7c61"
+ "revision": "0431a2c60828731f27491ee9fdefe25e250ce9c9"
},
"scala": {
"revision": "140c96cf398693189d4e50f76d19ddfcd8a018f8"
},
"scheme": {
- "revision": "af0fd1fa452cb2562dc7b5c8a8c55551c39273b9"
+ "revision": "bdcd2c8496701153506a9e3e1b76dfed852873ba"
},
"scss": {
"revision": "c478c6868648eff49eb04a4df90d703dc45b312a"
@@ -333,7 +333,7 @@
"revision": "05f949d3c1c15e3261473a244d3ce87777374dec"
},
"sql": {
- "revision": "2743c7b5e710e6854d4e8c14c302548b436e2a1f"
+ "revision": "70c50264ae022193adb364ffa7a767d765ed9857"
},
"supercollider": {
"revision": "90c6d9f777d2b8c4ce497c48b5f270a44bcf3ea0"
@@ -345,7 +345,7 @@
"revision": "52e122ae68b316d3aa960a0a422d3645ba717f42"
},
"swift": {
- "revision": "c88b5d73f193f5b0762b1a5f0299a275e6a728fb"
+ "revision": "25f8de356e3c33099ed691bd3b8b5c0fe3a11e15"
},
"sxhkdrc": {
"revision": "440d5f913d9465c9c776a1bd92334d32febcf065"
@@ -372,13 +372,13 @@
"revision": "085437f5cb117703b7f520dd92161140a684f092"
},
"twig": {
- "revision": "6a01f20e73038300d205d370212c361949be3035"
+ "revision": "035f549ec8c043e734f04341d7ccdc669bb2ba91"
},
"typescript": {
"revision": "0ab9d99867435a7667c5548a6617a6bf73dbd830"
},
"v": {
- "revision": "d0e7c755193c762eb1521e3b4740b22929cc91cc"
+ "revision": "66b92a89ef1e149300df79c0b2a934ad959c8eec"
},
"vala": {
"revision": "8f690bfa639f2b83d1fb938ed3dd98a7ba453e8b"
@@ -386,8 +386,11 @@
"verilog": {
"revision": "4457145e795b363f072463e697dfe2f6973c9a52"
},
+ "vhs": {
+ "revision": "2f87b9d973597e69552ecf6a4fe16470fbd8c44e"
+ },
"vim": {
- "revision": "9736af8ef0a7f20b4c45f6474342c8f5b473e2cc"
+ "revision": "4ae7bd67706d7e10afed827ce2ded884ab41650f"
},
"vue": {
"revision": "91fe2754796cd8fba5f229505a23fa08f3546c06"
@@ -402,6 +405,6 @@
"revision": "8e9d175982afcefa3dac8ca20d40d1643accd2bd"
},
"zig": {
- "revision": "b1803f2a665d228f968a831eac4fcc07a377c7bc"
+ "revision": "d90d38d28ce8cc27bfea8b4e0c75211e9e2398ca"
}
}
diff --git a/lua/nvim-treesitter/configs.lua b/lua/nvim-treesitter/configs.lua
index 87bb8d1a..6db2935a 100644
--- a/lua/nvim-treesitter/configs.lua
+++ b/lua/nvim-treesitter/configs.lua
@@ -8,6 +8,16 @@ local caching = require "nvim-treesitter.caching"
local M = {}
+---@class TSConfig
+---@field modules {[string]:TSModule}
+---@field sync_install boolean
+---@field ensure_installed string[]|string
+---@field ignore_install string[]
+---@field auto_install boolean
+---@field update_strategy string
+---@field parser_install_dir string|nil
+
+---@type TSConfig
local config = {
modules = {},
sync_install = false,
@@ -21,6 +31,17 @@ local config = {
local queued_modules_defs = {}
-- Whether we've initialized the plugin yet.
local is_initialized = false
+
+---@class TSModule
+---@field module_path string
+---@field enable boolean|string[]|function(string): boolean
+---@field disable boolean|string[]|function(string): boolean
+---@field is_supported function(string): boolean
+---@field attach function(string)
+---@field detach function(string)
+---@field enabled_buffers table<integer, boolean>
+
+---@type {[string]: TSModule}
local builtin_modules = {
highlight = {
module_path = "nvim-treesitter.highlight",
@@ -54,7 +75,9 @@ local builtin_modules = {
local attached_buffers_by_module = caching.create_buffer_cache()
--- Resolves a module by requiring the `module_path` or using the module definition.
+---Resolves a module by requiring the `module_path` or using the module definition.
+---@param mod_name string
+---@return TSModule|nil
local function resolve_module(mod_name)
local config_mod = M.get_module(mod_name)
@@ -69,10 +92,10 @@ local function resolve_module(mod_name)
end
end
--- Enables and attaches the module to a buffer for lang.
--- @param mod path to module
--- @param bufnr buffer number, defaults to current buffer
--- @param lang language, defaults to current language
+---Enables and attaches the module to a buffer for lang.
+---@param mod string path to module
+---@param bufnr integer|nil buffer number, defaults to current buffer
+---@param lang string|nil language, defaults to current language
local function enable_module(mod, bufnr, lang)
local module = M.get_module(mod)
if not module then
@@ -93,9 +116,9 @@ local function enable_module(mod, bufnr, lang)
M.attach_module(mod, bufnr, lang)
end
--- Enables autocomands for the module.
--- After the module is loaded `loaded` will be set to true for the module.
--- @param mod path to module
+---Enables autocomands for the module.
+---After the module is loaded `loaded` will be set to true for the module.
+---@param mod string path to module
local function enable_mod_conf_autocmd(mod)
local config_mod = M.get_module(mod)
if not config_mod or config_mod.loaded then
@@ -113,9 +136,9 @@ local function enable_mod_conf_autocmd(mod)
config_mod.loaded = true
end
--- Enables the module globally and for all current buffers.
--- After enabled, `enable` will be set to true for the module.
--- @param mod path to module
+---Enables the module globally and for all current buffers.
+---After enabled, `enable` will be set to true for the module.
+---@param mod string path to module
local function enable_all(mod)
local config_mod = M.get_module(mod)
if not config_mod then
@@ -131,9 +154,9 @@ local function enable_all(mod)
end
end
--- Disables and detaches the module for a buffer.
--- @param mod path to module
--- @param bufnr buffer number, defaults to current buffer
+---Disables and detaches the module for a buffer.
+---@param mod string path to module
+---@param bufnr integer buffer number, defaults to current buffer
local function disable_module(mod, bufnr)
local module = M.get_module(mod)
if not module then
@@ -147,9 +170,9 @@ local function disable_module(mod, bufnr)
M.detach_module(mod, bufnr)
end
--- Disables autocomands for the module.
--- After the module is unloaded `loaded` will be set to false for the module.
--- @param mod path to module
+---Disables autocomands for the module.
+---After the module is unloaded `loaded` will be set to false for the module.
+---@param mod string path to module
local function disable_mod_conf_autocmd(mod)
local config_mod = M.get_module(mod)
if not config_mod or not config_mod.loaded then
@@ -159,9 +182,9 @@ local function disable_mod_conf_autocmd(mod)
config_mod.loaded = false
end
--- Disables the module globally and for all current buffers.
--- After disabled, `enable` will be set to false for the module.
--- @param mod path to module
+---Disables the module globally and for all current buffers.
+---After disabled, `enable` will be set to false for the module.
+---@param mod string path to module
local function disable_all(mod)
local config_mod = M.get_module(mod)
if not config_mod then
@@ -177,10 +200,10 @@ local function disable_all(mod)
end
end
--- Toggles a module for a buffer
--- @param mod path to module
--- @param bufnr buffer number, defaults to current buffer
--- @param lang language, defaults to current language
+---Toggles a module for a buffer
+---@param mod string path to module
+---@param bufnr integer buffer number, defaults to current buffer
+---@param lang string language, defaults to current language
local function toggle_module(mod, bufnr, lang)
bufnr = bufnr or api.nvim_get_current_buf()
lang = lang or parsers.get_buf_lang(bufnr)
@@ -207,10 +230,10 @@ local function toggle_all(mod)
end
end
--- Recurses through all modules including submodules
--- @param accumulator function called for each module
--- @param root root configuration table to start at
--- @param path prefix path
+---Recurses through all modules including submodules
+---@param accumulator function called for each module
+---@param root {[string]: TSModule} root configuration table to start at
+---@param path string|nil prefix path
local function recurse_modules(accumulator, root, path)
root = root or config.modules
@@ -225,9 +248,9 @@ local function recurse_modules(accumulator, root, path)
end
end
--- Shows current configuration of all nvim-treesitter modules
--- @param process_function function used as the `process` parameter
--- for vim.inspect (https://github.com/kikito/inspect.lua#optionsprocess)
+---Shows current configuration of all nvim-treesitter modules
+---@param process_function function used as the `process` parameter
+--- for vim.inspect (https://github.com/kikito/inspect.lua#optionsprocess)
local function config_info(process_function)
process_function = process_function
or function(item, path)
@@ -242,6 +265,8 @@ local function config_info(process_function)
print(vim.inspect(config, { process = process_function }))
end
+---@param query_group string
+---@param lang string
function M.edit_query_file(query_group, lang)
lang = lang or parsers.get_buf_lang()
local files = ts_query.get_query_files(lang, query_group, true)
@@ -259,6 +284,8 @@ function M.edit_query_file(query_group, lang)
end
end
+---@param query_group string
+---@param lang string
function M.edit_query_file_user_after(query_group, lang)
lang = lang or parsers.get_buf_lang()
local folder = utils.join_path(vim.fn.stdpath "config", "after", "queries", lang)
@@ -340,9 +367,9 @@ M.commands = {
},
}
--- @param mod: module (string)
--- @param lang: the language of the buffer (string)
--- @param bufnr: the bufnr (number)
+---@param mod string module
+---@param lang string the language of the buffer
+---@param bufnr integer the bufnr
function M.is_enabled(mod, lang, bufnr)
if not parsers.has_parser(lang) then
return false
@@ -376,8 +403,8 @@ function M.is_enabled(mod, lang, bufnr)
return true
end
--- Setup call for users to override module configurations.
--- @param user_data module overrides
+---Setup call for users to override module configurations.
+---@param user_data TSConfig module overrides
function M.setup(user_data)
config.modules = vim.tbl_deep_extend("force", config.modules, user_data)
config.ignore_install = user_data.ignore_install or {}
@@ -411,32 +438,33 @@ function M.setup(user_data)
end, config.modules)
end
--- Defines a table of modules that can be attached/detached to buffers
--- based on language support. A module consist of the following properties:
--- * @enable Whether the modules is enabled. Can be true or false.
--- * @disable A list of languages to disable the module for. Only relevant if enable is true.
--- * @keymaps A list of user mappings for a given module if relevant.
--- * @is_supported A function which, given a ft, will return true if the ft works on the module.
--- * @module_path A string path to a module file using `require`. The exported module must contain
--- an `attach` and `detach` function. This path is not required if `attach` and `detach`
--- functions are provided directly on the module definition.
--- * @attach An attach function that is called for each buffer that the module is enabled for. This is required
--- if a `module_path` is not specified.
--- * @detach A detach function that is called for each buffer that the module is enabled for. This is required
--- if a `module_path` is not specified.
--- Modules are not setup until `init` is invoked by the plugin. This allows modules to be defined in any order
--- and can be loaded lazily.
--- @example
--- require"nvim-treesitter".define_modules {
--- my_cool_module = {
--- attach = function()
--- do_some_cool_setup()
--- end,
--- detach = function()
--- do_some_cool_teardown()
--- end
--- }
--- }
+---Defines a table of modules that can be attached/detached to buffers
+---based on language support. A module consist of the following properties:
+---* @enable Whether the modules is enabled. Can be true or false.
+---* @disable A list of languages to disable the module for. Only relevant if enable is true.
+---* @keymaps A list of user mappings for a given module if relevant.
+---* @is_supported A function which, given a ft, will return true if the ft works on the module.
+---* @module_path A string path to a module file using `require`. The exported module must contain
+--- an `attach` and `detach` function. This path is not required if `attach` and `detach`
+--- functions are provided directly on the module definition.
+---* @attach An attach function that is called for each buffer that the module is enabled for. This is required
+--- if a `module_path` is not specified.
+---* @detach A detach function that is called for each buffer that the module is enabled for. This is required
+--- if a `module_path` is not specified.
+---Modules are not setup until `init` is invoked by the plugin. This allows modules to be defined in any order
+---and can be loaded lazily.
+---@example
+---require"nvim-treesitter".define_modules {
+--- my_cool_module = {
+--- attach = function()
+--- do_some_cool_setup()
+--- end,
+--- detach = function()
+--- do_some_cool_teardown()
+--- end
+--- }
+---}
+---@param mod_defs TSModule[]
function M.define_modules(mod_defs)
if not is_initialized then
table.insert(queued_modules_defs, mod_defs)
@@ -463,10 +491,10 @@ function M.define_modules(mod_defs)
end
end
--- Attaches a module to a buffer
--- @param mod_name the module name
--- @param bufnr the bufnr
--- @param lang the language of the buffer
+---Attaches a module to a buffer
+---@param mod_name string the module name
+---@param bufnr integer the bufnr
+---@param lang string the language of the buffer
function M.attach_module(mod_name, bufnr, lang)
bufnr = bufnr or api.nvim_get_current_buf()
lang = lang or parsers.get_buf_lang(bufnr)
@@ -478,9 +506,9 @@ function M.attach_module(mod_name, bufnr, lang)
end
end
--- Detaches a module to a buffer
--- @param mod_name the module name
--- @param bufnr the bufnr
+---Detaches a module to a buffer
+---@param mod_name string the module name
+---@param bufnr integer the bufnr
function M.detach_module(mod_name, bufnr)
local resolved_mod = resolve_module(mod_name)
bufnr = bufnr or api.nvim_get_current_buf()
@@ -491,17 +519,17 @@ function M.detach_module(mod_name, bufnr)
end
end
--- Same as attach_module, but if the module is already attached, detach it first.
--- @param mod_name the module name
--- @param bufnr the bufnr
--- @param lang the language of the buffer
+---Same as attach_module, but if the module is already attached, detach it first.
+---@param mod_name string the module name
+---@param bufnr integer the bufnr
+---@param lang string the language of the buffer
function M.reattach_module(mod_name, bufnr, lang)
M.detach_module(mod_name, bufnr)
M.attach_module(mod_name, bufnr, lang)
end
--- Gets available modules
--- @param root root table to find modules
+---Gets available modules
+---@param root {[string]:TSModule} table to find modules
function M.available_modules(root)
local modules = {}
@@ -512,25 +540,26 @@ function M.available_modules(root)
return modules
end
--- Gets a module config by path
--- @param mod_path path to the module
--- @returns the module or nil
+---Gets a module config by path
+---@param mod_path string path to the module
+---@return TSModule|nil the module or nil
function M.get_module(mod_path)
local mod = utils.get_at_path(config.modules, mod_path)
return M.is_module(mod) and mod or nil
end
--- Determines whether the provided table is a module.
--- A module should contain an attach and detach function.
--- @param mod the module table
+---Determines whether the provided table is a module.
+---A module should contain an attach and detach function.
+---@param mod table the module table
+---@return boolean
function M.is_module(mod)
return type(mod) == "table"
and ((type(mod.attach) == "function" and type(mod.detach) == "function") or type(mod.module_path) == "string")
end
--- Initializes built-in modules and any queued modules
--- registered by plugins or the user.
+---Initializes built-in modules and any queued modules
+---registered by plugins or the user.
function M.init()
is_initialized = true
M.define_modules(builtin_modules)
@@ -540,11 +569,13 @@ function M.init()
end
end
--- If parser_install_dir is not nil is used or created.
--- If parser_install_dir is nil try the package dir of the nvim-treesitter
--- plugin first, followed by the "site" dir from "runtimepath". "site" dir will
--- be created if it doesn't exist. Using only the package dir won't work when
--- the plugin is installed with Nix, since the "/nix/store" is read-only.
+---If parser_install_dir is not nil is used or created.
+---If parser_install_dir is nil try the package dir of the nvim-treesitter
+---plugin first, followed by the "site" dir from "runtimepath". "site" dir will
+---be created if it doesn't exist. Using only the package dir won't work when
+---the plugin is installed with Nix, since the "/nix/store" is read-only.
+---@param folder_name string
+---@return string|nil, string|nil
function M.get_parser_install_dir(folder_name)
folder_name = folder_name or "parser"
diff --git a/lua/nvim-treesitter/fold.lua b/lua/nvim-treesitter/fold.lua
index 1f417414..50272622 100644
--- a/lua/nvim-treesitter/fold.lua
+++ b/lua/nvim-treesitter/fold.lua
@@ -102,6 +102,8 @@ local folds_levels = tsutils.memoize_by_buf_tick(function(bufnr)
return levels
end)
+---@param lnum integer
+---@return string
function M.get_fold_indic(lnum)
if not parsers.has_parser() or not lnum then
return "0"
diff --git a/lua/nvim-treesitter/highlight.lua b/lua/nvim-treesitter/highlight.lua
index 502914fe..5f7dead6 100644
--- a/lua/nvim-treesitter/highlight.lua
+++ b/lua/nvim-treesitter/highlight.lua
@@ -6,6 +6,9 @@ local configs = require "nvim-treesitter.configs"
local M = {}
+---@param config table
+---@param lang string
+---@return boolean
local function should_enable_vim_regex(config, lang)
local additional_hl = config.additional_vim_regex_highlighting
local is_table = type(additional_hl) == "table"
@@ -13,29 +16,36 @@ local function should_enable_vim_regex(config, lang)
return additional_hl and (not is_table or vim.tbl_contains(additional_hl, lang))
end
+---@param bufnr integer
local function enable_syntax(bufnr)
api.nvim_buf_set_option(bufnr, "syntax", "ON")
end
+---@param bufnr integer
function M.stop(bufnr)
if ts.highlighter.active[bufnr] then
ts.highlighter.active[bufnr]:destroy()
end
end
+---@param bufnr integer
+---@param lang string
function M.start(bufnr, lang)
local parser = parsers.get_parser(bufnr, lang)
ts.highlighter.new(parser, {})
end
+---@param bufnr integer
+---@param lang string
function M.attach(bufnr, lang)
local config = configs.get_module "highlight"
M.start(bufnr, lang)
- if should_enable_vim_regex(config, lang) then
+ if config and should_enable_vim_regex(config, lang) then
enable_syntax(bufnr)
end
end
+---@param bufnr integer
function M.detach(bufnr)
M.stop(bufnr)
enable_syntax(bufnr)
diff --git a/lua/nvim-treesitter/install.lua b/lua/nvim-treesitter/install.lua
index 95a8a9f9..48810b1e 100644
--- a/lua/nvim-treesitter/install.lua
+++ b/lua/nvim-treesitter/install.lua
@@ -42,11 +42,14 @@ local function get_job_status()
.. "]"
end
+---@param lang string
+---@param validate boolean|nil
+---@return InstallInfo
local function get_parser_install_info(lang, validate)
local parser_config = parsers.get_parser_configs()[lang]
if not parser_config then
- return error('Parser not available for language "' .. lang .. '"')
+ error('Parser not available for language "' .. lang .. '"')
end
local install_info = parser_config.install_info
@@ -79,6 +82,8 @@ local function get_revision(lang)
return (lockfile[lang] and lockfile[lang].revision)
end
+---@param lang string
+---@return string|nil
local function get_installed_revision(lang)
local lang_file = utils.join_path(configs.get_parser_info_dir(), lang .. ".revision")
if vim.fn.filereadable(lang_file) == 1 then
@@ -86,23 +91,30 @@ local function get_installed_revision(lang)
end
end
+---@param lang string
+---@return boolean
local function is_installed(lang)
return #api.nvim_get_runtime_file("parser/" .. lang .. ".so", false) > 0
end
+---@param lang string
+---@return boolean
local function needs_update(lang)
local revision = get_revision(lang)
return not revision or revision ~= get_installed_revision(lang)
end
+---@return table
local function outdated_parsers()
return vim.tbl_filter(function(lang)
return needs_update(lang)
end, info.installed_parsers())
end
+---@param handle userdata
+---@param is_stderr boolean
local function onread(handle, is_stderr)
- return function(err, data)
+ return function(_, data)
if data then
if is_stderr then
complete_error_output[handle] = (complete_error_output[handle] or "") .. data
@@ -147,6 +159,7 @@ function M.iter_cmd(cmd_list, i, lang, success_message)
local stdout = luv.new_pipe(false)
local stderr = luv.new_pipe(false)
attr.opts.stdio = { nil, stdout, stderr }
+ ---@type userdata
handle = luv.spawn(
attr.cmd,
attr.opts,
@@ -225,6 +238,12 @@ local function iter_cmd_sync(cmd_list)
return true
end
+---@param cache_folder string
+---@param install_folder string
+---@param lang string
+---@param repo InstallInfo
+---@param with_sync boolean
+---@param generate_from_grammar boolean
local function run_install(cache_folder, install_folder, lang, repo, with_sync, generate_from_grammar)
parsers.reset_cache()
@@ -361,6 +380,12 @@ local function run_install(cache_folder, install_folder, lang, repo, with_sync,
end
end
+---@param lang string
+---@param ask_reinstall boolean
+---@param cache_folder string
+---@param install_folder string
+---@param with_sync boolean
+---@param generate_from_grammar boolean
local function install_lang(lang, ask_reinstall, cache_folder, install_folder, with_sync, generate_from_grammar)
if is_installed(lang) and ask_reinstall ~= "force" then
if not ask_reinstall then
@@ -389,6 +414,7 @@ local function install_lang(lang, ask_reinstall, cache_folder, install_folder, w
run_install(cache_folder, install_folder, lang, install_info, with_sync, generate_from_grammar)
end
+---@return function
local function install(options)
options = options or {}
local with_sync = options.with_sync
@@ -405,11 +431,14 @@ local function install(options)
if err then
return api.nvim_err_writeln(err)
end
+ assert(cache_folder)
- local install_folder, err = configs.get_parser_install_dir()
+ local install_folder
+ install_folder, err = configs.get_parser_install_dir()
if err then
return api.nvim_err_writeln(err)
end
+ assert(install_folder)
local languages
local ask
diff --git a/lua/nvim-treesitter/parsers.lua b/lua/nvim-treesitter/parsers.lua
index ee79c09d..e2e52122 100644
--- a/lua/nvim-treesitter/parsers.lua
+++ b/lua/nvim-treesitter/parsers.lua
@@ -18,8 +18,25 @@ local filetype_to_parsername = {
pandoc = "markdown",
rmd = "markdown",
cs = "c_sharp",
+ tape = "vhs",
}
+---@class InstallInfo
+---@field url string
+---@field branch string|nil
+---@field revision string|nil
+---@field files string[]
+---@field generate_requires_npm boolean|nil
+---@field requires_generate_from_grammar boolean|nil
+---@field location string|nil
+
+---@class ParserInfo
+---@field install_info InstallInfo
+---@field filetype string
+---@field maintainers string[]
+---@field experimental boolean|nil
+
+---@type ParserInfo[]
local list = setmetatable({}, {
__newindex = function(table, parsername, parserconfig)
rawset(
@@ -1266,6 +1283,23 @@ list.diff = {
filetype = "gitdiff",
}
+list.vhs = {
+ install_info = {
+ url = "https://github.com/charmbracelet/tree-sitter-vhs",
+ branch = "main",
+ files = { "src/parser.c" },
+ },
+ maintainers = { "@caarlos0", "@maaslalani" },
+ filetype = "tape",
+}
+
+list.awk = {
+ install_info = {
+ url = "https://github.com/Beaglefoot/tree-sitter-awk",
+ files = { "src/parser.c", "src/scanner.c" },
+ },
+}
+
local M = {
list = list,
filetype_to_parsername = filetype_to_parsername,
diff --git a/lua/nvim-treesitter/query.lua b/lua/nvim-treesitter/query.lua
index aeaa683b..bc80d51e 100644
--- a/lua/nvim-treesitter/query.lua
+++ b/lua/nvim-treesitter/query.lua
@@ -11,8 +11,10 @@ local EMPTY_ITER = function() end
M.built_in_query_groups = { "highlights", "locals", "folds", "indents", "injections" }
--- Creates a function that checks whether a given query exists
--- for a specific language.
+--- Creates a function that checks whether a given query exists
+--- for a specific language.
+---@param query string
+---@return function(string): boolean
local function get_query_guard(query)
return function(lang)
return M.has_query_files(lang, query)
@@ -23,6 +25,7 @@ for _, query in ipairs(M.built_in_query_groups) do
M["has_" .. query] = get_query_guard(query)
end
+---@return string[]
function M.available_query_groups()
local query_files = api.nvim_get_runtime_file("queries/*/*.scm", true)
local groups = {}
@@ -57,11 +60,19 @@ do
end
end
+---@param lang string
+---@param query_name string
+---@return string[]
local function runtime_queries(lang, query_name)
return api.nvim_get_runtime_file(string.format("queries/%s/%s.scm", lang, query_name), true) or {}
end
+---@type table<string, table<string, boolean>>
local query_files_cache = {}
+
+---@param lang string
+---@param query_name string
+---@return boolean
function M.has_query_files(lang, query_name)
if not query_files_cache[lang] then
query_files_cache[lang] = {}
@@ -86,6 +97,8 @@ do
local cache = setmetatable({}, mt)
--- Same as `vim.treesitter.query` except will return cached values
+ ---@param lang string
+ ---@param query_name string
function M.get_query(lang, query_name)
if cache[lang][query_name] == nil then
cache[lang][query_name] = tsq.get_query(lang, query_name)
@@ -98,6 +111,8 @@ do
--- If lang and query_name is both present, will reload for only the lang and query_name.
--- If only lang is present, will reload all query_names for that lang
--- If none are present, will reload everything
+ ---@param lang string
+ ---@param query_name string
function M.invalidate_query_cache(lang, query_name)
if lang and query_name then
cache[lang][query_name] = nil
@@ -106,14 +121,14 @@ do
end
elseif lang and not query_name then
query_files_cache[lang] = nil
- for query_name, _ in pairs(cache[lang]) do
- M.invalidate_query_cache(lang, query_name)
+ for query_name0, _ in pairs(cache[lang]) do
+ M.invalidate_query_cache(lang, query_name0)
end
elseif not lang and not query_name then
query_files_cache = {}
- for lang, _ in pairs(cache) do
- for query_name, _ in pairs(cache[lang]) do
- M.invalidate_query_cache(lang, query_name)
+ for lang0, _ in pairs(cache) do
+ for query_name0, _ in pairs(cache[lang0]) do
+ M.invalidate_query_cache(lang0, query_name0)
end
end
else
@@ -123,11 +138,23 @@ do
end
--- This function is meant for an autocommand and not to be used. Only use if file is a query file.
+---@param fname string
function M.invalidate_query_file(fname)
local fnamemodify = vim.fn.fnamemodify
M.invalidate_query_cache(fnamemodify(fname, ":p:h:t"), fnamemodify(fname, ":t:r"))
end
+---@class QueryInfo
+---@field root LanguageTree
+---@field source integer
+---@field start integer
+---@field stop integer
+
+---@param bufnr integer
+---@param query_name string
+---@param root LanguageTree
+---@param root_lang string|nil
+---@return Query|nil, QueryInfo|nil
local function prepare_query(bufnr, query_name, root, root_lang)
local buf_lang = parsers.get_buf_lang(bufnr)
@@ -181,6 +208,10 @@ local function prepare_query(bufnr, query_name, root, root_lang)
}
end
+---@param query Query
+---@param bufnr integer
+---@param start_row integer
+---@param end_row integer
function M.iter_prepared_matches(query, qnode, bufnr, start_row, end_row)
-- A function that splits a string on '.'
local function split(string)
@@ -249,15 +280,16 @@ function M.iter_prepared_matches(query, qnode, bufnr, start_row, end_row)
end
--- Return all nodes corresponding to a specific capture path (like @definition.var, @reference.type)
--- Works like M.get_references or M.get_scopes except you can choose the capture
--- Can also be a nested capture like @definition.function to get all nodes defining a function.
---
--- @param bufnr the buffer
--- @param captures a single string or a list of strings
--- @param query_group the name of query group (highlights or injections for example)
--- @param root (optional) node from where to start the search
--- @param lang (optional) the language from where to get the captures.
--- Root nodes can have several languages.
+---Works like M.get_references or M.get_scopes except you can choose the capture
+---Can also be a nested capture like @definition.function to get all nodes defining a function.
+---
+---@param bufnr integer the buffer
+---@param captures string|string[]
+---@param query_group string the name of query group (highlights or injections for example)
+---@param root LanguageTree|nil node from where to start the search
+---@param lang string|nil the language from where to get the captures.
+--- Root nodes can have several languages.
+---@return table|nil
function M.get_capture_matches(bufnr, captures, query_group, root, lang)
if type(captures) == "string" then
captures = { captures }
@@ -289,6 +321,7 @@ function M.iter_captures(bufnr, query_name, root, lang)
if not query then
return EMPTY_ITER
end
+ assert(params)
local iter = query:iter_captures(params.root, params.source, params.start, params.stop)
@@ -336,16 +369,17 @@ function M.find_best_match(bufnr, capture_string, query_group, filter_predicate,
return best
end
--- Iterates matches from a query file.
--- @param bufnr the buffer
--- @param query_group the query file to use
--- @param root the root node
--- @param root the root node lang, if known
+---Iterates matches from a query file.
+---@param bufnr integer the buffer
+---@param query_group string the query file to use
+---@param root LanguageTree the root node
+---@param root_lang string|nil the root node lang, if known
function M.iter_group_results(bufnr, query_group, root, root_lang)
local query, params = prepare_query(bufnr, query_group, root, root_lang)
if not query then
return EMPTY_ITER
end
+ assert(params)
return M.iter_prepared_matches(query, params.root, params.source, params.start, params.stop)
end
@@ -360,18 +394,25 @@ function M.collect_group_results(bufnr, query_group, root, lang)
return matches
end
+---@alias CaptureResFn function(string, LanguageTree, LanguageTree): string, string
+
--- Same as get_capture_matches except this will recursively get matches for every language in the tree.
--- @param bufnr The bufnr
--- @param capture_or_fn The capture to get. If a function is provided then that
--- function will be used to resolve both the capture and query argument.
--- The function can return `nil` to ignore that tree.
--- @param query_type The query to get the capture from. This is ignore if a function is provided
--- for the captuer argument.
+---@param bufnr integer The bufnr
+---@param capture_or_fn string|CaptureResFn The capture to get. If a function is provided then that
+--- function will be used to resolve both the capture and query argument.
+--- The function can return `nil` to ignore that tree.
+---@param query_type string The query to get the capture from. This is ignore if a function is provided
+--- for the captuer argument.
function M.get_capture_matches_recursively(bufnr, capture_or_fn, query_type)
- local type_fn = type(capture_or_fn) == "function" and capture_or_fn
- or function()
+ ---@type CaptureResFn
+ local type_fn
+ if type(capture_or_fn) == "function" then
+ type_fn = capture_or_fn
+ else
+ type_fn = function(_, _, _)
return capture_or_fn, query_type
end
+ end
local parser = parsers.get_parser(bufnr)
local matches = {}
diff --git a/lua/nvim-treesitter/shell_command_selectors.lua b/lua/nvim-treesitter/shell_command_selectors.lua
index 522ac727..59bbb0e4 100644
--- a/lua/nvim-treesitter/shell_command_selectors.lua
+++ b/lua/nvim-treesitter/shell_command_selectors.lua
@@ -49,6 +49,7 @@ function M.select_rm_file_cmd(file, info_msg)
end
end
+---@return string|nil
function M.select_executable(executables)
return vim.tbl_filter(function(c)
return c ~= vim.NIL and fn.executable(c) == 1
diff --git a/lua/nvim-treesitter/utils.lua b/lua/nvim-treesitter/utils.lua
index 81ce7017..156ba9c3 100644
--- a/lua/nvim-treesitter/utils.lua
+++ b/lua/nvim-treesitter/utils.lua
@@ -11,6 +11,7 @@ function M.notify(msg, log_level, opts)
end
-- Returns the system specific path seperator.
+---@return string
function M.get_path_sep()
return fn.has "win32" == 1 and "\\" or "/"
end
@@ -82,6 +83,10 @@ function M.setup_commands(mod, commands)
end
end
+---@param dir string
+---@param create_err string
+---@param writeable_err string
+---@return string|nil, string|nil
function M.create_or_reuse_writable_dir(dir, create_err, writeable_err)
create_err = create_err or M.join_space("Could not create dir '", dir, "': ")
writeable_err = writeable_err or M.join_space("Invalid rights, '", dir, "' should be read/write")
@@ -201,6 +206,7 @@ function M.to_func(a)
return type(a) == "function" and a or M.constant(a)
end
+---@return string|nil
function M.ts_cli_version()
if fn.executable "tree-sitter" == 1 then
local handle = io.popen "tree-sitter -V"
diff --git a/queries/awk/highlights.scm b/queries/awk/highlights.scm
new file mode 100644
index 00000000..918d0116
--- /dev/null
+++ b/queries/awk/highlights.scm
@@ -0,0 +1,154 @@
+; adapted from https://github.com/Beaglefoot/tree-sitter-awk
+
+[
+ (identifier)
+ (field_ref)
+] @variable
+(field_ref (_) @variable)
+
+(number) @number
+
+(string) @string
+(regex) @string.regex
+(escape_sequence) @string.escape
+
+(comment) @comment @spell
+
+(ns_qualified_name (namespace) @namespace)
+(ns_qualified_name "::" @punctuation.delimiter)
+
+(func_def name: (_ (identifier) @function) @function)
+(func_call name: (_ (identifier) @function) @function)
+
+(func_def (param_list (identifier) @parameter))
+
+[
+ "print"
+ "printf"
+ "getline"
+] @function.builtin
+
+[
+ (delete_statement)
+ (break_statement)
+ (continue_statement)
+ (next_statement)
+ (nextfile_statement)
+] @keyword
+
+[
+ "func"
+ "function"
+] @keyword.function
+
+[
+ "return"
+ "exit"
+] @keyword.return
+
+[
+ "do"
+ "while"
+ "for"
+ "in"
+] @repeat
+
+[
+ "if"
+ "else"
+ "switch"
+ "case"
+ "default"
+] @conditional
+
+[
+ "@include"
+ "@load"
+] @include
+
+"@namespace" @preproc
+
+[
+ "BEGIN"
+ "END"
+ "BEGINFILE"
+ "ENDFILE"
+] @label
+
+(binary_exp [
+ "^"
+ "**"
+ "*"
+ "/"
+ "%"
+ "+"
+ "-"
+ "<"
+ ">"
+ "<="
+ ">="
+ "=="
+ "!="
+ "~"
+ "!~"
+ "in"
+ "&&"
+ "||"
+] @operator)
+
+(unary_exp [
+ "!"
+ "+"
+ "-"
+] @operator)
+
+(assignment_exp [
+ "="
+ "+="
+ "-="
+ "*="
+ "/="
+ "%="
+ "^="
+] @operator)
+
+(ternary_exp [
+ "?"
+ ":"
+] @operator)
+
+(update_exp [
+ "++"
+ "--"
+] @operator)
+
+(redirected_io_statement [
+ ">"
+ ">>"
+] @operator)
+
+(piped_io_statement [
+ "|"
+ "|&"
+] @operator)
+
+(piped_io_exp [
+ "|"
+ "|&"
+] @operator)
+
+(field_ref "$" @punctuation.delimiter)
+
+(regex "/" @punctuation.delimiter)
+(regex_constant "@" @punctuation.delimiter)
+
+[ ";" "," ] @punctuation.delimiter
+
+[
+ "("
+ ")"
+ "["
+ "]"
+ "{"
+ "}"
+] @punctuation.bracket
diff --git a/queries/awk/injections.scm b/queries/awk/injections.scm
new file mode 100644
index 00000000..8cbffc62
--- /dev/null
+++ b/queries/awk/injections.scm
@@ -0,0 +1,2 @@
+(comment) @comment
+(regex) @regex
diff --git a/queries/help/highlights.scm b/queries/help/highlights.scm
index 6be4e49c..b2ed3903 100644
--- a/queries/help/highlights.scm
+++ b/queries/help/highlights.scm
@@ -2,6 +2,8 @@
(h2) @text.title
(h3) @text.title
(column_heading) @text.title
+(column_heading
+ "~" @conceal (#set! conceal ""))
(tag
"*" @conceal (#set! conceal "")
text: (_) @label)
@@ -9,8 +11,15 @@
"|" @conceal (#set! conceal "")
text: (_) @text.reference)
(optionlink
- text: (_) @text.literal)
+ text: (_) @text.reference)
(codespan
"`" @conceal (#set! conceal "")
- text: (_) @string)
+ text: (_) @text.literal)
+(codeblock) @text.literal
+(codeblock
+ ">" @conceal (#set! conceal ""))
+(block
+ "<" @conceal (#set! conceal ""))
(argument) @parameter
+(keycode) @string.special
+(url) @text.uri
diff --git a/queries/julia/folds.scm b/queries/julia/folds.scm
index a8cfc940..61718215 100644
--- a/queries/julia/folds.scm
+++ b/queries/julia/folds.scm
@@ -12,6 +12,6 @@
(quote_statement)
(do_clause)
- (compound_expression)
+ (compound_statement)
] @fold
diff --git a/queries/julia/highlights.scm b/queries/julia/highlights.scm
index 1b7e5b72..8d30ff55 100644
--- a/queries/julia/highlights.scm
+++ b/queries/julia/highlights.scm
@@ -1,106 +1,110 @@
-(identifier) @variable
+;;; Identifiers
-(operator) @operator
-(range_expression ":" @operator)
-(pair_expression "=>" @operator)
+(identifier) @variable
-;; In case you want type highlighting based on Julia naming conventions (this might collide with mathematical notation)
-;((identifier) @type ; exception: mark `A_foo` sort of identifiers as variables
- ;(match? @type "^[A-Z][^_]"))
+; ;; If you want type highlighting based on Julia naming conventions (this might collide with mathematical notation)
+; ((identifier) @type
+; (match? @type "^[A-Z][^_]")) ; exception: Highlight `A_foo` sort of identifiers as variables
(macro_identifier) @function.macro
-(macro_identifier (identifier) @function.macro) ; for any one using the variable highlight
+(macro_identifier
+ (identifier) @function.macro) ; for any one using the variable highlight
+
(macro_definition
- name: (identifier) @function.macro
- ["macro" "end" @keyword])
+ name: (identifier) @function.macro)
+
+(quote_expression ":" (identifier)) @symbol
+
+
+;;; Fields and indexes
(field_expression
- (identifier)
(identifier) @field .)
+(index_expression
+ (_)
+ (range_expression
+ (identifier) @constant.builtin .)
+ (#eq? @constant.builtin "end"))
+
+
+;;; Function names
+
+;; definitions
+
(function_definition
name: (identifier) @function)
+(short_function_definition
+ name: (identifier) @function)
+
+(function_definition
+ name: (scoped_identifier (identifier) @function .))
+(short_function_definition
+ name: (scoped_identifier (identifier) @function .))
+
+;; calls
+
(call_expression
(identifier) @function.call)
(call_expression
- (field_expression (identifier) @method.call .))
+ (field_expression (identifier) @function.call .))
+
(broadcast_call_expression
(identifier) @function.call)
(broadcast_call_expression
- (field_expression (identifier) @method.call .))
+ (field_expression (identifier) @function.call .))
+
+
+;;; Parameters
+
(parameter_list
(identifier) @parameter)
-(parameter_list
- (optional_parameter .
- (identifier) @parameter))
+(optional_parameter .
+ (identifier) @parameter)
+(slurp_parameter
+ (identifier) @parameter)
+
(typed_parameter
- (identifier) @parameter
- (identifier) @type)
-(type_parameter_list
- (identifier) @type)
+ parameter: (identifier) @parameter
+ type: (_) @type)
(typed_parameter
- (identifier) @parameter
- (parameterized_identifier) @type)
+ type: (_) @type)
+
(function_expression
- . (identifier) @parameter)
-(spread_parameter) @parameter
-(spread_parameter
- (identifier) @parameter)
-(named_argument
- . (identifier) @parameter)
-(argument_list
- (typed_expression
- (identifier) @parameter
- (identifier) @type))
-(argument_list
- (typed_expression
- (identifier) @parameter
- (parameterized_identifier) @type))
-
-;; Symbol expressions (:my-wanna-be-lisp-keyword)
-(quote_expression
- (identifier)) @symbol
-
-;; Parsing error! foo (::Type) gets parsed as two quote expressions
-(argument_list
- (quote_expression
- (quote_expression
- (identifier) @type)))
-
-(type_argument_list
- (identifier) @type)
-(parameterized_identifier (_)) @type
-(argument_list
- (typed_expression . (identifier) @parameter))
+ . (identifier) @parameter) ; Single parameter arrow functions
-(typed_expression
- (identifier) @type .)
-(typed_expression
- (parameterized_identifier) @type .)
+
+;;; Types
+
+;; Definitions
(abstract_definition
name: (identifier) @type)
+(primitive_definition
+ name: (identifier) @type)
(struct_definition
name: (identifier) @type)
-(subscript_expression
- (_)
- (range_expression
- (identifier) @constant.builtin .)
- (#eq? @constant.builtin "end"))
+;; Annotations
-"end" @keyword
+(parametrized_type_expression (_) @type)
-(if_statement
- ["if" "end"] @conditional)
-(elseif_clause
- ["elseif"] @conditional)
-(else_clause
- ["else"] @conditional)
-(ternary_expression
- ["?" ":"] @conditional)
+(type_parameter_list
+ (identifier) @type)
+
+(typed_expression
+ (identifier) @type .)
+
+(function_definition
+ return_type: (identifier) @type)
+(short_function_definition
+ return_type: (identifier) @type)
+
+(where_clause
+ (identifier) @type) ; where clause without braces
-(function_definition ["function" "end"] @keyword.function)
+
+;;; Keywords
[
"abstract"
@@ -110,51 +114,91 @@
"struct"
"type"
"mutable"
+ "where"
] @keyword
-"return" @keyword.return
+"end" @keyword
-((identifier) @keyword (#any-of? @keyword "global" "local"))
+((identifier) @keyword (#any-of? @keyword "global" "local")) ; Grammar error
-(compound_expression
+(compound_statement
["begin" "end"] @keyword)
+(quote_statement
+ ["quote" "end"] @keyword)
+(let_statement
+ ["let" "end"] @keyword)
+
+(if_statement
+ ["if" "end"] @conditional)
+(elseif_clause
+ ["elseif"] @conditional)
+(else_clause
+ ["else"] @conditional)
+(ternary_expression
+ ["?" ":"] @conditional)
+
(try_statement
- ["try" "end" ] @exception)
+ ["try" "end"] @exception)
(finally_clause
"finally" @exception)
(catch_clause
"catch" @exception)
-(quote_statement
- ["quote" "end"] @keyword)
-(let_statement
- ["let" "end"] @keyword)
+
(for_statement
["for" "end"] @repeat)
(while_statement
["while" "end"] @repeat)
-(break_statement) @repeat
-(continue_statement) @repeat
(for_clause
"for" @repeat)
+[
+ (break_statement)
+ (continue_statement)
+] @repeat
+
+(module_definition
+ ["module" "baremodule" "end"] @include)
+(import_statement
+ ["import" "using"] @include)
+(export_statement
+ "export" @include)
+
+(macro_definition
+ ["macro" "end" @keyword])
+
+(function_definition
+ ["function" "end"] @keyword.function)
(do_clause
- ["do" "end"] @keyword)
+ ["do" "end"] @keyword.function)
+(function_expression
+ "->" @keyword.function)
+(return_statement
+ "return" @keyword.return)
-"in" @keyword.operator
-(export_statement
- ["export"] @include)
+;;; Operators & Punctuation
-(import_statement
- ["import" "using"] @include)
+(operator) @operator
+(for_binding ["in" "=" "∈"] @operator)
+(pair_expression "=>" @operator)
+(range_expression ":" @operator)
-(module_definition
- ["module" "end"] @include)
+(slurp_parameter "..." @operator)
+(spread_expression "..." @operator)
+
+"." @operator
+["::" "<:"] @operator
-((identifier) @include (#eq? @include "baremodule"))
+["," ";"] @punctuation.delimiter
+["(" ")" "[" "]" "{" "}"] @punctuation.bracket
;;; Literals
+[
+ (true)
+ (false)
+] @boolean
+
(integer_literal) @number
(float_literal) @float
@@ -162,9 +206,6 @@
(#any-of? @float "NaN" "NaN16" "NaN32"
"Inf" "Inf16" "Inf32"))
-((identifier) @boolean
- (#any-of? @boolean "true" "false"))
-
((identifier) @constant.builtin
(#any-of? @constant.builtin "nothing" "missing"))
@@ -184,8 +225,3 @@
(block_comment)
] @comment
-;;; Punctuation
-
-(quote_expression ":" @symbol)
-["::" "." "," "..."] @punctuation.delimiter
-["[" "]" "(" ")" "{" "}"] @punctuation.bracket
diff --git a/queries/julia/indents.scm b/queries/julia/indents.scm
index e6423d34..9cfdc407 100644
--- a/queries/julia/indents.scm
+++ b/queries/julia/indents.scm
@@ -11,7 +11,7 @@
(quote_statement)
(do_clause)
- (compound_expression)
+ (compound_statement)
(assignment_expression)
(binary_expression)
diff --git a/queries/julia/locals.scm b/queries/julia/locals.scm
index f8b34f71..655affe0 100644
--- a/queries/julia/locals.scm
+++ b/queries/julia/locals.scm
@@ -1,59 +1,79 @@
+;;; Variables
+(assignment_expression
+ (identifier) @definition.var)
+(assignment_expression
+ (tuple_expression
+ (identifier) @definition.var))
-(import_statement
- (identifier) @definition.import)
+;;; let/const bindings
(variable_declaration
(identifier) @definition.var)
(variable_declaration
(tuple_expression
(identifier) @definition.var))
+
+
+;;; For bindings
(for_binding
- (identifier) @definition.var)
+ (identifier) @definition.var)
(for_binding
- (tuple_expression
- (identifier) @definition.var))
+ (tuple_expression
+ (identifier) @definition.var))
-(assignment_expression
- (tuple_expression
- (identifier) @definition.var))
-(assignment_expression
- (bare_tuple_expression
- (identifier) @definition.var))
-(assignment_expression
- (identifier) @definition.var)
-(type_parameter_list
- (identifier) @definition.type)
-(type_argument_list
- (identifier) @definition.type)
+;;; Types
+
(struct_definition
name: (identifier) @definition.type)
+(abstract_definition
+ name: (identifier) @definition.type)
+(abstract_definition
+ name: (identifier) @definition.type)
+
+(type_parameter_list
+ (identifier) @definition.type)
+
+;;; Module imports
+
+(import_statement
+ (identifier) @definition.import)
+
+
+;;; Parameters
(parameter_list
- (identifier) @definition.parameter)
+ (identifier) @definition.parameter)
+(optional_parameter .
+ (identifier) @definition.parameter)
+(slurp_parameter
+ (identifier) @definition.parameter)
+
(typed_parameter
- (identifier) @definition.parameter
- (identifier))
+ parameter: (identifier) @definition.parameter
+ (_))
+
(function_expression
- . (identifier) @definition.parameter)
-(argument_list
- (typed_expression
- (identifier) @definition.parameter
- (identifier)))
-(spread_parameter
- (identifier) @definition.parameter)
+ . (identifier) @definition.parameter) ;; Single parameter arrow function
+
+
+;;; Function/macro definitions
(function_definition
- name: (identifier) @definition.function) @scope
+ name: (identifier) @definition.function) @scope
+(short_function_definition
+ name: (identifier) @definition.function) @scope
(macro_definition
- name: (identifier) @definition.macro) @scope
+ name: (identifier) @definition.macro) @scope
(identifier) @reference
[
+ (for_statement)
+ (while_statement)
(try_statement)
+ (catch_clause)
(finally_clause)
- (quote_statement)
(let_statement)
- (compound_expression)
- (for_statement)
+ (quote_statement)
+ (do_clause)
] @scope
diff --git a/queries/lua/highlights.scm b/queries/lua/highlights.scm
index 50069258..48aed052 100644
--- a/queries/lua/highlights.scm
+++ b/queries/lua/highlights.scm
@@ -131,6 +131,11 @@
((identifier) @variable.builtin
(#eq? @variable.builtin "self"))
+(variable_list
+ attribute: (attribute
+ (["<" ">"] @punctuation.bracket
+ (identifier) @attribute)))
+
;; Constants
((identifier) @constant
diff --git a/queries/markdown/highlights.scm b/queries/markdown/highlights.scm
index 70c35b39..81cb5a5b 100644
--- a/queries/markdown/highlights.scm
+++ b/queries/markdown/highlights.scm
@@ -20,11 +20,10 @@
] @text.literal
(pipe_table_header (pipe_table_cell) @text.title)
-[
- (pipe_table_row)
- (pipe_table_delimiter_row)
- (pipe_table_header)
-] "|" @punctuation.special
+
+(pipe_table_header "|" @punctuation.special)
+(pipe_table_row "|" @punctuation.special)
+(pipe_table_delimiter_row "|" @punctuation.special)
(pipe_table_delimiter_cell) @punctuation.special
[
diff --git a/queries/ql/folds.scm b/queries/ql/folds.scm
new file mode 100644
index 00000000..1a31eeb2
--- /dev/null
+++ b/queries/ql/folds.scm
@@ -0,0 +1,7 @@
+[
+ (module)
+ (classlessPredicate)
+ (dataclass)
+ (charpred)
+ (memberPredicate)
+] @fold
diff --git a/queries/rego/highlights.scm b/queries/rego/highlights.scm
index 70bf849a..42d276cd 100644
--- a/queries/rego/highlights.scm
+++ b/queries/rego/highlights.scm
@@ -1,16 +1,64 @@
; highlights.scm
-"import" @include
-"package" @include
+[
+ (import)
+ (package)
+] @include
+[
+ (with)
+ (as)
+ (every)
+ (some)
+ (in)
+ (not)
+ (if)
+ (contains)
+ (else)
+ (default)
+ "null"
+] @keyword
+
+[
+ "true"
+ "false"
+] @boolean
+
+[
+ (assignment_operator)
+ (bool_operator)
+ (arith_operator)
+ (bin_operator)
+] @operator
+
+[
+ (string)
+ (raw_string)
+] @string
+
+(term (ref (var))) @variable
-(reserved_keywords) @keyword
(comment) @comment
-(rego_block rego_rule_name: (identifier) @function)
-(builtin_function function_name: (function_name) @function.builtin)
-(opening_parameter) @punctuation.bracket
-(closing_parameter) @punctuation.bracket
-(string_definition) @string
+
(number) @number
-(operator) @operator
-(true) @boolean
-(false) @boolean
+
+(expr_call func_name: (fn_name (var) @function .))
+
+(expr_call func_arguments: (fn_args (expr) @parameter))
+
+(rule_args (term) @parameter)
+
+[
+ (open_paren)
+ (close_paren)
+ (open_bracket)
+ (close_bracket)
+ (open_curly)
+ (close_curly)
+] @punctuation.bracket
+
+(rule (rule_head (var) @method))
+
+(rule
+ (rule_head (term (ref (var) @namespace)))
+ (rule_body (query (literal (expr (expr_infix (expr (term (ref (var)) @_output)))))) (#eq? @_output @namespace))
+)
diff --git a/queries/rust/folds.scm b/queries/rust/folds.scm
index d83351cb..97cf2eaf 100644
--- a/queries/rust/folds.scm
+++ b/queries/rust/folds.scm
@@ -14,7 +14,6 @@
(for_expression)
(while_expression)
(if_expression)
- (if_let_expression)
(match_expression)
(call_expression)
diff --git a/queries/rust/highlights.scm b/queries/rust/highlights.scm
index c08912be..c7cd1174 100644
--- a/queries/rust/highlights.scm
+++ b/queries/rust/highlights.scm
@@ -25,7 +25,6 @@
(self) @variable.builtin
-(lifetime ["'" (identifier)] @label)
(loop_label ["'" (identifier)] @label)
@@ -72,6 +71,9 @@
(scoped_type_identifier
path: (identifier) @namespace)
(scoped_type_identifier
+ path: (identifier) @type
+ (#lua-match? @type "^[A-Z]"))
+(scoped_type_identifier
(scoped_identifier
name: (identifier) @namespace))
((scoped_identifier
@@ -121,14 +123,14 @@
(macro_definition "macro_rules!" @function.macro)
;; Attribute macros
-(attribute_item (meta_item (identifier) @function.macro))
-(meta_item (scoped_identifier (identifier) @function.macro .))
+(attribute_item (attribute (identifier) @function.macro))
+(attribute (scoped_identifier (identifier) @function.macro .))
;; Derive macros (assume all arguments are types)
-(meta_item
- (identifier) @_name
- arguments: (meta_arguments (meta_item (identifier) @type))
- (#eq? @_name "derive"))
+; (attribute
+; (identifier) @_name
+; arguments: (attribute (attribute (identifier) @type))
+; (#eq? @_name "derive"))
;; Function-like macros
(macro_invocation
@@ -169,7 +171,6 @@
[
"async"
"await"
- "const"
"default"
"dyn"
"enum"
@@ -179,17 +180,26 @@
"match"
"move"
"pub"
- "ref"
- "static"
"struct"
"trait"
"type"
"union"
"unsafe"
"where"
- (mutable_specifier)
] @keyword
+[
+ "ref"
+ (mutable_specifier)
+] @type.qualifier
+
+[
+ "const"
+ "static"
+] @storageclass
+
+(lifetime ["'" (identifier)] @storageclass.lifetime)
+
"fn" @keyword.function
[
"return"
@@ -201,7 +211,8 @@
(use_list (self) @keyword)
(scoped_use_list (self) @keyword)
-(scoped_identifier (self) @keyword)
+(scoped_identifier [(crate) (super) (self)] @keyword)
+(visibility_modifier [(crate) (super) (self)] @keyword)
[
"else"
@@ -216,8 +227,7 @@
"while"
] @repeat
-(impl_item
- "for" @keyword)
+"for" @keyword
(for_expression
"for" @repeat)
@@ -266,6 +276,8 @@
(closure_parameters "|" @punctuation.bracket)
(type_arguments ["<" ">"] @punctuation.bracket)
(type_parameters ["<" ">"] @punctuation.bracket)
+(bracketed_type ["<" ">"] @punctuation.bracket)
+(for_lifetimes ["<" ">"] @punctuation.bracket)
["," "." ":" "::" ";"] @punctuation.delimiter
@@ -273,3 +285,8 @@
(inner_attribute_item ["!" "#"] @punctuation.special)
(macro_invocation "!" @function.macro)
(empty_type "!" @type.builtin)
+
+(macro_invocation macro: (identifier) @_ident @exception "!" @exception
+ (#eq? @_ident "panic"))
+(macro_invocation macro: (identifier) @_ident @exception "!" @exception
+ (#contains? @_ident "assert"))
diff --git a/queries/rust/locals.scm b/queries/rust/locals.scm
index 010bf4af..1cefcabf 100644
--- a/queries/rust/locals.scm
+++ b/queries/rust/locals.scm
@@ -34,7 +34,7 @@
(tuple_pattern
(identifier) @definition.var)
-(if_let_expression
+(let_condition
pattern: (_
(identifier) @definition.var))
@@ -93,7 +93,6 @@
(for_expression)
(loop_expression)
(if_expression)
- (if_let_expression)
(match_expression)
(match_arm)
diff --git a/queries/scheme/highlights.scm b/queries/scheme/highlights.scm
index 4a7393eb..497512b8 100644
--- a/queries/scheme/highlights.scm
+++ b/queries/scheme/highlights.scm
@@ -81,7 +81,7 @@
;; quote
-(abbreviation
+(quote
"'"
(symbol)) @symbol
diff --git a/queries/vhs/highlights.scm b/queries/vhs/highlights.scm
new file mode 100644
index 00000000..67fa3cf8
--- /dev/null
+++ b/queries/vhs/highlights.scm
@@ -0,0 +1,38 @@
+[
+ "Output"
+ "Backspace"
+ "Down"
+ "Enter"
+ "Escape"
+ "Left"
+ "Right"
+ "Space"
+ "Tab"
+ "Up"
+ "Set"
+ "Type"
+ "Sleep"
+ "Hide"
+ "Show" ] @keyword
+
+[ "Shell"
+ "FontFamily"
+ "FontSize"
+ "Framerate"
+ "PlaybackSpeed"
+ "Height"
+ "LetterSpacing"
+ "TypingSpeed"
+ "LineHeight"
+ "Padding"
+ "Theme"
+ "LoopOffset"
+ "Width" ] @type
+
+[ "@" ] @operator
+(control) @function.macro
+(float) @float
+(integer) @number
+(comment) @comment @spell
+[(path) (string) (json)] @string
+(time) @symbol
diff --git a/scripts/ci-install-macos-latest.sh b/scripts/ci-install-macos-latest.sh
index 79b957cb..9899f17e 100644
--- a/scripts/ci-install-macos-latest.sh
+++ b/scripts/ci-install-macos-latest.sh
@@ -1,5 +1,6 @@
curl -L https://github.com/neovim/neovim/releases/download/${NVIM_TAG}/nvim-macos.tar.gz | tar -xz
sudo ln -s $(pwd)/nvim-macos/bin/nvim /usr/local/bin
+rm -rf $(pwd)/nvim-macos/lib/nvim/parser
mkdir -p ~/.local/share/nvim/site/pack/nvim-treesitter/start
ln -s $(pwd) ~/.local/share/nvim/site/pack/nvim-treesitter/start
diff --git a/scripts/ci-install-ubuntu-latest.sh b/scripts/ci-install-ubuntu-latest.sh
index ecfc164f..e65c670d 100644
--- a/scripts/ci-install-ubuntu-latest.sh
+++ b/scripts/ci-install-ubuntu-latest.sh
@@ -1,10 +1,9 @@
wget -O - https://github.com/tree-sitter/tree-sitter/releases/download/${TREE_SITTER_CLI_TAG}/tree-sitter-linux-x64.gz | gunzip -c > tree-sitter
sudo cp ./tree-sitter /usr/bin/tree-sitter
sudo chmod uog+rwx /usr/bin/tree-sitter
-wget https://github.com/neovim/neovim/releases/download/${NVIM_TAG}/nvim.appimage
-chmod u+x nvim.appimage
+wget https://github.com/neovim/neovim/releases/download/${NVIM_TAG}/nvim-linux64.tar.gz
+tar -zxf nvim-linux64.tar.gz
+sudo ln -s $(pwd)/nvim-linux64/bin/nvim /usr/local/bin
+rm -rf $(pwd)/nvim-linux64/lib/nvim/parser
mkdir -p ~/.local/share/nvim/site/pack/nvim-treesitter/start
ln -s $(pwd) ~/.local/share/nvim/site/pack/nvim-treesitter/start
-sudo cp ./nvim.appimage /usr/bin/nvim
-sudo chmod uog+rwx /usr/bin/nvim
-