From 5e49ef0af3cb8dba658e5d0dc6a807f8edebf590 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Tue, 11 Jun 2024 12:05:18 +0100 Subject: refactor(lua): improve type annotations --- runtime/lua/vim/treesitter/_fold.lua | 1 - 1 file changed, 1 deletion(-) (limited to 'runtime/lua/vim/treesitter/_fold.lua') diff --git a/runtime/lua/vim/treesitter/_fold.lua b/runtime/lua/vim/treesitter/_fold.lua index eecf1ad6b1..04a3c62cf1 100644 --- a/runtime/lua/vim/treesitter/_fold.lua +++ b/runtime/lua/vim/treesitter/_fold.lua @@ -383,7 +383,6 @@ local function on_bytes(bufnr, foldinfo, start_row, start_col, old_row, old_col, end end ----@package ---@param lnum integer|nil ---@return string function M.foldexpr(lnum) -- cgit From 0e3e1e6b6d8370f1fcc9887d5cb931b131450a1c Mon Sep 17 00:00:00 2001 From: Jaehwang Jung Date: Thu, 20 Jun 2024 22:37:09 +0900 Subject: fix(treesitter): don't open fold when o/O adds a line below #28709 Problem: `o`-ing on a folded line opens the fold, because the new line gets the fold level from the above line (level '='), which extends the fold to the new line. `O` has a similar problem when run on the line below a fold. Solution: Use -1 for the added line to get the lower level from the above/below line. --- runtime/lua/vim/treesitter/_fold.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'runtime/lua/vim/treesitter/_fold.lua') diff --git a/runtime/lua/vim/treesitter/_fold.lua b/runtime/lua/vim/treesitter/_fold.lua index 04a3c62cf1..b8f1ef1282 100644 --- a/runtime/lua/vim/treesitter/_fold.lua +++ b/runtime/lua/vim/treesitter/_fold.lua @@ -87,7 +87,7 @@ end ---@param srow integer ---@param erow integer 0-indexed, exclusive function FoldInfo:add_range(srow, erow) - list_insert(self.levels, srow + 1, erow, '=') + list_insert(self.levels, srow + 1, erow, -1) list_insert(self.levels0, srow + 1, erow, -1) end -- cgit From c57a85e0eda067ea28ca5853358947332aceecfd Mon Sep 17 00:00:00 2001 From: Riley Bruins Date: Fri, 14 Jun 2024 17:54:10 -0700 Subject: perf(treesitter): remove unnecessary foldexpr loop Instead of looping over all captured nodes, just take the end range from the last node in the list. This uses the fact that nodes returned by iter_matches are ordered by their range (earlier to later). --- runtime/lua/vim/treesitter/_fold.lua | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'runtime/lua/vim/treesitter/_fold.lua') diff --git a/runtime/lua/vim/treesitter/_fold.lua b/runtime/lua/vim/treesitter/_fold.lua index b8f1ef1282..194e09babc 100644 --- a/runtime/lua/vim/treesitter/_fold.lua +++ b/runtime/lua/vim/treesitter/_fold.lua @@ -139,16 +139,12 @@ local function compute_folds_levels(bufnr, info, srow, erow, parse_injections) local range = ts.get_range(nodes[1], bufnr, metadata[id]) local start, _, stop, stop_col = Range.unpack4(range) - for i = 2, #nodes, 1 do - local node_range = ts.get_range(nodes[i], bufnr, metadata[id]) - local node_start, _, node_stop, node_stop_col = Range.unpack4(node_range) - if node_start < start then - start = node_start - end - if node_stop > stop then - stop = node_stop - stop_col = node_stop_col - end + if #nodes > 1 then + -- assumes nodes are ordered by range + local end_range = ts.get_range(nodes[#nodes], bufnr, metadata[id]) + local _, _, end_stop, end_stop_col = Range.unpack4(end_range) + stop = end_stop + stop_col = end_stop_col end if stop_col == 0 then -- cgit From 8474f529780ba20f9179ad1b60167ee9e53f8374 Mon Sep 17 00:00:00 2001 From: Jaehwang Jung Date: Sat, 6 Jul 2024 15:34:05 +0900 Subject: fix(treesitter.foldexpr): robustness against ctrl-c Problem: Exiting the insert mode with ctrl-c does not trigger InsertLeave autocmd. This may lead to nil error in treesitter foldexpr. Solution: Check nil. Folds still can be stale after exiting the insert mode with ctrl-c, but it will be eventually updated correctly. An alternative solution would be to ensure that exiting the insert mode always triggers do_foldupdate. This can be done either by "fixing" ctrl-c or with on_key callback that checks ctrl-c (nvim-cmp does this). --- runtime/lua/vim/treesitter/_fold.lua | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'runtime/lua/vim/treesitter/_fold.lua') diff --git a/runtime/lua/vim/treesitter/_fold.lua b/runtime/lua/vim/treesitter/_fold.lua index 194e09babc..27590eff5d 100644 --- a/runtime/lua/vim/treesitter/_fold.lua +++ b/runtime/lua/vim/treesitter/_fold.lua @@ -264,6 +264,15 @@ end ---@package function FoldInfo:do_foldupdate(bufnr) + -- InsertLeave is not executed when is used for exiting the insert mode, leaving + -- do_foldupdate untouched. If another execution of foldupdate consumes foldupdate_range, the + -- InsertLeave do_foldupdate gets nil foldupdate_range. In that case, skip the update. This is + -- correct because the update that consumed the range must have incorporated the range that + -- InsertLeave meant to update. + if not self.foldupdate_range then + return + end + local srow, erow = self.foldupdate_range[1], self.foldupdate_range[2] self.foldupdate_range = nil for _, win in ipairs(vim.fn.win_findbuf(bufnr)) do -- 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/_fold.lua | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'runtime/lua/vim/treesitter/_fold.lua') diff --git a/runtime/lua/vim/treesitter/_fold.lua b/runtime/lua/vim/treesitter/_fold.lua index 27590eff5d..7375beaf9d 100644 --- a/runtime/lua/vim/treesitter/_fold.lua +++ b/runtime/lua/vim/treesitter/_fold.lua @@ -131,9 +131,7 @@ local function compute_folds_levels(bufnr, info, srow, erow, parse_injections) -- Collect folds starting from srow - 1, because we should first subtract the folds that end at -- srow - 1 from the level of srow - 1 to get accurate level of srow. - for _, match, metadata in - query:iter_matches(tree:root(), bufnr, math.max(srow - 1, 0), erow, { all = true }) - do + for _, match, metadata in query:iter_matches(tree:root(), bufnr, math.max(srow - 1, 0), erow) do for id, nodes in pairs(match) do if query.captures[id] == 'fold' then local range = ts.get_range(nodes[1], bufnr, metadata[id]) -- 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/_fold.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'runtime/lua/vim/treesitter/_fold.lua') diff --git a/runtime/lua/vim/treesitter/_fold.lua b/runtime/lua/vim/treesitter/_fold.lua index 7375beaf9d..49792c3891 100644 --- a/runtime/lua/vim/treesitter/_fold.lua +++ b/runtime/lua/vim/treesitter/_fold.lua @@ -114,7 +114,7 @@ local function compute_folds_levels(bufnr, info, srow, erow, parse_injections) srow = srow or 0 erow = erow or api.nvim_buf_line_count(bufnr) - local parser = ts.get_parser(bufnr) + local parser = assert(ts._get_parser(bufnr)) parser:parse(parse_injections and { srow, erow } or nil) @@ -392,7 +392,7 @@ function M.foldexpr(lnum) lnum = lnum or vim.v.lnum local bufnr = api.nvim_get_current_buf() - local parser = vim.F.npcall(ts.get_parser, bufnr) + local parser = ts._get_parser(bufnr) if not parser then return '0' 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/_fold.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'runtime/lua/vim/treesitter/_fold.lua') diff --git a/runtime/lua/vim/treesitter/_fold.lua b/runtime/lua/vim/treesitter/_fold.lua index 49792c3891..7237d2e7d4 100644 --- a/runtime/lua/vim/treesitter/_fold.lua +++ b/runtime/lua/vim/treesitter/_fold.lua @@ -114,7 +114,7 @@ local function compute_folds_levels(bufnr, info, srow, erow, parse_injections) srow = srow or 0 erow = erow or api.nvim_buf_line_count(bufnr) - local parser = assert(ts._get_parser(bufnr)) + local parser = assert(ts.get_parser(bufnr, nil, { error = false })) parser:parse(parse_injections and { srow, erow } or nil) @@ -392,7 +392,7 @@ function M.foldexpr(lnum) lnum = lnum or vim.v.lnum local bufnr = api.nvim_get_current_buf() - local parser = ts._get_parser(bufnr) + local parser = ts.get_parser(bufnr, nil, { error = false }) if not parser then return '0' end -- cgit