From 733b2e12b86a34c00aa07e0491762f88582792a5 Mon Sep 17 00:00:00 2001 From: Quentin Rasmont Date: Tue, 26 Apr 2022 22:42:48 +0200 Subject: feat(treesitter): add opts.concat to query.get_text_node As part of the upstream of utility functions from nvim-treesitter, this option when set to false allows to return a table (downstream behavior). Effectively making the switch from the downstream to the upstream function much easier. --- runtime/lua/vim/treesitter/query.lua | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'runtime/lua/vim/treesitter/query.lua') diff --git a/runtime/lua/vim/treesitter/query.lua b/runtime/lua/vim/treesitter/query.lua index 103e85abfd..697e2e7691 100644 --- a/runtime/lua/vim/treesitter/query.lua +++ b/runtime/lua/vim/treesitter/query.lua @@ -181,9 +181,14 @@ end --- Gets the text corresponding to a given node --- ----@param node the node ----@param source The buffer or string from which the node is extracted -function M.get_node_text(node, source) +---@param node table The node +---@param source table The buffer or string from which the node is extracted +---@param opts table Optional parameters. +--- - concat: (boolean default true) Concatenate result in a string +function M.get_node_text(node, source, opts) + opts = opts or {} + local concat = vim.F.if_nil(opts.concat, true) + local start_row, start_col, start_byte = node:start() local end_row, end_col, end_byte = node:end_() @@ -210,7 +215,7 @@ function M.get_node_text(node, source) end end - return table.concat(lines, '\n') + return concat and table.concat(lines, '\n') or lines elseif type(source) == 'string' then return source:sub(start_byte + 1, end_byte) end -- cgit From fd1595514b747d8b083f78007579d869ccfbe89c Mon Sep 17 00:00:00 2001 From: Thomas Vigouroux Date: Wed, 7 Sep 2022 08:39:56 +0200 Subject: Use weak tables in tree-sitter code (#17117) feat(treesitter): use weak tables when possible Also add the defaulttable function to create a table whose values are created when a key is missing. --- runtime/lua/vim/treesitter/query.lua | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'runtime/lua/vim/treesitter/query.lua') diff --git a/runtime/lua/vim/treesitter/query.lua b/runtime/lua/vim/treesitter/query.lua index 697e2e7691..78042a74bf 100644 --- a/runtime/lua/vim/treesitter/query.lua +++ b/runtime/lua/vim/treesitter/query.lua @@ -140,12 +140,9 @@ function M.get_query(lang, query_name) end end -local query_cache = setmetatable({}, { - __index = function(tbl, key) - rawset(tbl, key, {}) - return rawget(tbl, key) - end, -}) +local query_cache = vim.defaulttable(function() + return setmetatable({}, { __mode = 'v' }) +end) --- Parse {query} as a string. (If the query is in a file, the caller --- should read the contents into a string before calling). -- cgit From 0405594399741babd6d935d581eac2584b289f92 Mon Sep 17 00:00:00 2001 From: Thomas Vigouroux Date: Thu, 8 Sep 2022 09:47:36 +0200 Subject: feat(treesitter)!: do not merge queries by default (#20105) Problem: Treesitter queries for a given language in runtime were merged together, leading to errors if they targeted different parser versions (e.g., bundled viml queries and those shipped by nvim-treesitter). Solution: Runtime queries now work as follows: * The last query in the rtp without `; extends` in the header will be used as the base query * All queries (without a specific order) with `; extends` are concatenated with the base query BREAKING CHANGE: queries need to be updated if they are meant to extend other queries --- runtime/lua/vim/treesitter/query.lua | 37 ++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) (limited to 'runtime/lua/vim/treesitter/query.lua') diff --git a/runtime/lua/vim/treesitter/query.lua b/runtime/lua/vim/treesitter/query.lua index 78042a74bf..be5b24fd95 100644 --- a/runtime/lua/vim/treesitter/query.lua +++ b/runtime/lua/vim/treesitter/query.lua @@ -47,6 +47,9 @@ function M.get_query_files(lang, query_name, is_included) return {} end + local base_query = nil + local extensions = {} + local base_langs = {} -- Now get the base languages by looking at the first line of every file @@ -55,13 +58,26 @@ function M.get_query_files(lang, query_name, is_included) -- -- {language} ::= {lang} | ({lang}) local MODELINE_FORMAT = '^;+%s*inherits%s*:?%s*([a-z_,()]+)%s*$' + local EXTENDS_FORMAT = '^;+%s*extends%s*$' - for _, file in ipairs(lang_files) do - local modeline = safe_read(file, '*l') + for _, filename in ipairs(lang_files) do + local file, err = io.open(filename, 'r') + if not file then + error(err) + end - if modeline then - local langlist = modeline:match(MODELINE_FORMAT) + local extension = false + + for modeline in + function() + return file:read('*l') + end + do + if not vim.startswith(modeline, ';') then + break + end + local langlist = modeline:match(MODELINE_FORMAT) if langlist then for _, incllang in ipairs(vim.split(langlist, ',', true)) do local is_optional = incllang:match('%(.*%)') @@ -74,16 +90,25 @@ function M.get_query_files(lang, query_name, is_included) table.insert(base_langs, incllang) end end + elseif modeline:match(EXTENDS_FORMAT) then + extension = true end end + + if extension then + table.insert(extensions, filename) + else + base_query = filename + end + io.close(file) end - local query_files = {} + local query_files = { base_query } for _, base_lang in ipairs(base_langs) do local base_files = M.get_query_files(base_lang, query_name, true) vim.list_extend(query_files, base_files) end - vim.list_extend(query_files, lang_files) + vim.list_extend(query_files, extensions) return query_files end -- cgit From 893b659e88c61a8c3ce5b140ab475cd67e0ca6bc Mon Sep 17 00:00:00 2001 From: bfredl Date: Thu, 8 Sep 2022 11:17:29 +0200 Subject: fix(treesitter): use the right loading order for base queries (#20117) Use the first, not last, query for a language on runtimepath. Typically, this implies that a user query will override a site plugin query, which will override a bundled runtime query. --- runtime/lua/vim/treesitter/query.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'runtime/lua/vim/treesitter/query.lua') diff --git a/runtime/lua/vim/treesitter/query.lua b/runtime/lua/vim/treesitter/query.lua index be5b24fd95..2f6227af8e 100644 --- a/runtime/lua/vim/treesitter/query.lua +++ b/runtime/lua/vim/treesitter/query.lua @@ -97,7 +97,7 @@ function M.get_query_files(lang, query_name, is_included) if extension then table.insert(extensions, filename) - else + elseif base_query == nil then base_query = filename end io.close(file) -- cgit From 1939518ebab72878f2a8ca0cb85c09f7e70d1093 Mon Sep 17 00:00:00 2001 From: Thomas Vigouroux Date: Sat, 10 Sep 2022 11:26:23 +0200 Subject: fix(treesitter): prevent endless loop on self-inheritence Fixes #20139 --- runtime/lua/vim/treesitter/query.lua | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'runtime/lua/vim/treesitter/query.lua') diff --git a/runtime/lua/vim/treesitter/query.lua b/runtime/lua/vim/treesitter/query.lua index 2f6227af8e..90ed2a357c 100644 --- a/runtime/lua/vim/treesitter/query.lua +++ b/runtime/lua/vim/treesitter/query.lua @@ -34,6 +34,18 @@ local function safe_read(filename, read_quantifier) return content end +---@private +--- Adds @p ilang to @p base_langs, only if @p ilang is different than @lang +--- +---@return boolean true it lang == ilang +local function add_included_lang(base_langs, lang, ilang) + if lang == ilang then + return true + end + table.insert(base_langs, ilang) + return false +end + --- Gets the list of files used to make up a query --- ---@param lang The language @@ -84,10 +96,14 @@ function M.get_query_files(lang, query_name, is_included) if is_optional then if not is_included then - table.insert(base_langs, incllang:sub(2, #incllang - 1)) + if add_included_lang(base_langs, lang, incllang:sub(2, #incllang - 1)) then + extension = true + end end else - table.insert(base_langs, incllang) + if add_included_lang(base_langs, lang, incllang) then + extension = true + end end end elseif modeline:match(EXTENDS_FORMAT) then -- cgit