From 05dcda8f9b0583505327692570a2cfd0225124dc Mon Sep 17 00:00:00 2001 From: Riley Bruins Date: Sun, 14 Jul 2024 08:10:19 -0700 Subject: fix(treesitter): recognize aliased parsers in omnifunc, query linter **Problem:** A query file for something like `html_tags` will not be given html node completion **Solution:** Check for parser aliases before offering completions Co-authored-by: Lewis Russell --- runtime/lua/vim/treesitter/_query_linter.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'runtime/lua/vim/treesitter/_query_linter.lua') diff --git a/runtime/lua/vim/treesitter/_query_linter.lua b/runtime/lua/vim/treesitter/_query_linter.lua index 12b4cbc7b9..6b8c3a17f2 100644 --- a/runtime/lua/vim/treesitter/_query_linter.lua +++ b/runtime/lua/vim/treesitter/_query_linter.lua @@ -40,7 +40,8 @@ end local function guess_query_lang(buf) local filename = api.nvim_buf_get_name(buf) if filename ~= '' then - return vim.F.npcall(vim.fn.fnamemodify, filename, ':p:h:t') + local resolved_filename = vim.F.npcall(vim.fn.fnamemodify, filename, ':p:h:t') + return resolved_filename and vim.treesitter.language.get_lang(resolved_filename) or nil end end -- cgit From f8e1ebd6f62662129fdb54574b305189e4a0b7af Mon Sep 17 00:00:00 2001 From: Riley Bruins Date: Mon, 26 Aug 2024 20:40:37 -0700 Subject: fix(treesitter): escape things like `"` in omnifunc results --- runtime/lua/vim/treesitter/_query_linter.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'runtime/lua/vim/treesitter/_query_linter.lua') diff --git a/runtime/lua/vim/treesitter/_query_linter.lua b/runtime/lua/vim/treesitter/_query_linter.lua index 6b8c3a17f2..8654b89c9b 100644 --- a/runtime/lua/vim/treesitter/_query_linter.lua +++ b/runtime/lua/vim/treesitter/_query_linter.lua @@ -241,7 +241,7 @@ function M.omnifunc(findstart, base) end end for _, s in pairs(parser_info.symbols) do - local text = s[2] and s[1] or '"' .. s[1]:gsub([[\]], [[\\]]) .. '"' ---@type string + local text = s[2] and s[1] or string.format('%q', s[1]):gsub('\n', 'n') ---@type string if text:find(base, 1, true) then table.insert(items, text) end -- cgit From 6913c5e1d975a11262d08b3339d50b579e6b6bb8 Mon Sep 17 00:00:00 2001 From: Gregory Anders <8965202+gpanders@users.noreply.github.com> Date: Sun, 1 Sep 2024 13:01:53 -0500 Subject: feat(treesitter)!: default to correct behavior for quantified captures (#30193) For context, see https://github.com/neovim/neovim/pull/24738. Before that PR, Nvim did not correctly handle captures with quantifiers. That PR made the correct behavior opt-in to minimize breaking changes, with the intention that the correct behavior would eventually become the default. Users can still opt-in to the old (incorrect) behavior for now, but this option will eventually be removed completely. BREAKING CHANGE: Any plugin which uses `Query:iter_matches()` must update their call sites to expect an array of nodes in the `match` table, rather than a single node. --- runtime/lua/vim/treesitter/_query_linter.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'runtime/lua/vim/treesitter/_query_linter.lua') diff --git a/runtime/lua/vim/treesitter/_query_linter.lua b/runtime/lua/vim/treesitter/_query_linter.lua index 8654b89c9b..ea1ae5416a 100644 --- a/runtime/lua/vim/treesitter/_query_linter.lua +++ b/runtime/lua/vim/treesitter/_query_linter.lua @@ -176,7 +176,7 @@ function M.lint(buf, opts) parser:parse() parser:for_each_tree(function(tree, ltree) if ltree:lang() == 'query' then - for _, match, _ in query:iter_matches(tree:root(), buf, 0, -1, { all = true }) do + for _, match, _ in query:iter_matches(tree:root(), buf, 0, -1) do local lang_context = { lang = lang, parser_info = parser_info, -- cgit From b9b408a56c7e607972beaa7214719ff1494e384c Mon Sep 17 00:00:00 2001 From: Riley Bruins Date: Fri, 13 Sep 2024 05:09:11 -0700 Subject: feat(treesitter): start moving get_parser to return nil #30313 **Problem:** `vim.treesitter.get_parser` will throw an error if no parser can be found. - This means the caller is responsible for wrapping it in a `pcall`, which is easy to forget - It also makes it slightly harder to potentially memoize `get_parser` in the future - It's a bit unintuitive since many other `get_*` style functions conventionally return `nil` if no object is found (e.g. `get_node`, `get_lang`, `query.get`, etc.) **Solution:** Return `nil` if no parser can be found or created - This requires a function signature change, and some new assertions in places where the parser will always (or should always) be found. - This commit starts by making this change internally, since it is breaking. Eventually it will be rolled out to the public API. --- runtime/lua/vim/treesitter/_query_linter.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'runtime/lua/vim/treesitter/_query_linter.lua') diff --git a/runtime/lua/vim/treesitter/_query_linter.lua b/runtime/lua/vim/treesitter/_query_linter.lua index ea1ae5416a..30acef559e 100644 --- a/runtime/lua/vim/treesitter/_query_linter.lua +++ b/runtime/lua/vim/treesitter/_query_linter.lua @@ -172,7 +172,7 @@ function M.lint(buf, opts) --- @type (table|nil) local parser_info = vim.F.npcall(vim.treesitter.language.inspect, lang) - local parser = vim.treesitter.get_parser(buf) + local parser = assert(vim.treesitter._get_parser(buf), 'query parser not found.') parser:parse() parser:for_each_tree(function(tree, ltree) if ltree:lang() == 'query' then -- cgit From 052e048db676ef3e68efc497c02902e3d43e6255 Mon Sep 17 00:00:00 2001 From: Riley Bruins Date: Thu, 19 Sep 2024 13:34:35 -0700 Subject: fix(treesitter): lint top-level anonymous nodes **Problem:** Top-level anonymous nodes are not being checked by the query linter **Solution:** Check them by adding them to the top-level query This commit also moves a table construction out of the match iterator so it is run less frequently. --- runtime/lua/vim/treesitter/_query_linter.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'runtime/lua/vim/treesitter/_query_linter.lua') diff --git a/runtime/lua/vim/treesitter/_query_linter.lua b/runtime/lua/vim/treesitter/_query_linter.lua index 30acef559e..417b8bafbb 100644 --- a/runtime/lua/vim/treesitter/_query_linter.lua +++ b/runtime/lua/vim/treesitter/_query_linter.lua @@ -65,7 +65,7 @@ local function normalize_opts(buf, opts) end local lint_query = [[;; query - (program [(named_node) (list) (grouping)] @toplevel) + (program [(named_node) (anonymous_node) (list) (grouping)] @toplevel) (named_node name: _ @node.named) (anonymous_node @@ -171,17 +171,17 @@ function M.lint(buf, opts) --- @type (table|nil) local parser_info = vim.F.npcall(vim.treesitter.language.inspect, lang) + local lang_context = { + lang = lang, + parser_info = parser_info, + is_first_lang = i == 1, + } local parser = assert(vim.treesitter._get_parser(buf), 'query parser not found.') parser:parse() parser:for_each_tree(function(tree, ltree) if ltree:lang() == 'query' then for _, match, _ in query:iter_matches(tree:root(), buf, 0, -1) do - local lang_context = { - lang = lang, - parser_info = parser_info, - is_first_lang = i == 1, - } lint_match(buf, match, query, lang_context, diagnostics) end end -- cgit From 0f067cd34d09b38f9aaf2e1732d825e89b573077 Mon Sep 17 00:00:00 2001 From: Riley Bruins Date: Sat, 14 Sep 2024 12:57:33 -0700 Subject: fix(treesitter): suppress get_parser warnings via opts.error --- runtime/lua/vim/treesitter/_query_linter.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'runtime/lua/vim/treesitter/_query_linter.lua') diff --git a/runtime/lua/vim/treesitter/_query_linter.lua b/runtime/lua/vim/treesitter/_query_linter.lua index 417b8bafbb..632d045293 100644 --- a/runtime/lua/vim/treesitter/_query_linter.lua +++ b/runtime/lua/vim/treesitter/_query_linter.lua @@ -177,7 +177,7 @@ function M.lint(buf, opts) is_first_lang = i == 1, } - local parser = assert(vim.treesitter._get_parser(buf), 'query parser not found.') + local parser = assert(vim.treesitter.get_parser(buf, nil, { error = false })) parser:parse() parser:for_each_tree(function(tree, ltree) if ltree:lang() == 'query' then -- cgit From 041d98fe8d892a81ed659c32be5360d4f80e7d18 Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Sat, 14 Sep 2024 13:27:44 +0200 Subject: feat(treesitter)!: add default fallback to `ft_to_lang` lookups Problem: Language names are only registered for filetype<->language lookups when parsers are actually loaded; this means users cannot rely on `vim.treesitter.language.get_lang()` or `get_filetypes()` to return the correct value when language and filetype coincide and always need to add explicit fallbacks. Solution: Always return the language name as valid filetype in `get_filetypes()`, and default to the filetype in `get_lang()`. Document this behavior. --- runtime/lua/vim/treesitter/_query_linter.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'runtime/lua/vim/treesitter/_query_linter.lua') diff --git a/runtime/lua/vim/treesitter/_query_linter.lua b/runtime/lua/vim/treesitter/_query_linter.lua index 632d045293..c5e4b86e1e 100644 --- a/runtime/lua/vim/treesitter/_query_linter.lua +++ b/runtime/lua/vim/treesitter/_query_linter.lua @@ -41,7 +41,7 @@ local function guess_query_lang(buf) local filename = api.nvim_buf_get_name(buf) if filename ~= '' then local resolved_filename = vim.F.npcall(vim.fn.fnamemodify, filename, ':p:h:t') - return resolved_filename and vim.treesitter.language.get_lang(resolved_filename) or nil + return resolved_filename and vim.treesitter.language.get_lang(resolved_filename) end end -- cgit