From c4eb0b64bd4923a72fe737837cfe234c80fb539c Mon Sep 17 00:00:00 2001 From: Guilherme Soares <48023091+guilhas07@users.noreply.github.com> Date: Mon, 27 May 2024 13:20:03 +0200 Subject: fix(treesitter): find buffer in multiple windows #28922 Problem: 1. When interacting with multiple :InspectTree and the source buffer windows there is a high chance of errors due to the window ids not being updated and validated. 2. Not all InspectTree windows were closed when the source buffer was closed. Solution: 1. Update InspectTree window id on `CursorMoved` event and validate source buffer window id before trying to navigate to it. 2. Close all InspectTree windows --- runtime/lua/vim/treesitter/dev.lua | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'runtime/lua/vim/treesitter/dev.lua') diff --git a/runtime/lua/vim/treesitter/dev.lua b/runtime/lua/vim/treesitter/dev.lua index 5c91f101c0..ca8cf85eda 100644 --- a/runtime/lua/vim/treesitter/dev.lua +++ b/runtime/lua/vim/treesitter/dev.lua @@ -325,7 +325,10 @@ function M.inspect_tree(opts) opts = opts or {} + -- source buffer local buf = api.nvim_get_current_buf() + + -- window id for source buffer local win = api.nvim_get_current_win() local treeview = assert(TSTreeView:new(buf, opts.lang)) @@ -334,12 +337,14 @@ function M.inspect_tree(opts) close_win(vim.b[buf].dev_inspect) end + -- window id for tree buffer local w = opts.winid if not w then vim.cmd(opts.command or '60vnew') w = api.nvim_get_current_win() end + -- tree buffer local b = opts.bufnr if b then api.nvim_win_set_buf(w, b) @@ -375,6 +380,12 @@ function M.inspect_tree(opts) callback = function() local row = api.nvim_win_get_cursor(w)[1] local lnum, col = treeview:get(row).node:start() + + -- update source window if original was closed + if not api.nvim_win_is_valid(win) then + win = vim.fn.win_findbuf(buf)[1] + end + api.nvim_set_current_win(win) api.nvim_win_set_cursor(win, { lnum + 1, col }) end, @@ -432,6 +443,7 @@ function M.inspect_tree(opts) return true end + w = api.nvim_get_current_win() api.nvim_buf_clear_namespace(buf, treeview.ns, 0, -1) local row = api.nvim_win_get_cursor(w)[1] local lnum, col, end_lnum, end_col = treeview:get(row).node:range() @@ -441,6 +453,11 @@ function M.inspect_tree(opts) hl_group = 'Visual', }) + -- update source window if original was closed + if not api.nvim_win_is_valid(win) then + win = vim.fn.win_findbuf(buf)[1] + end + local topline, botline = vim.fn.line('w0', win), vim.fn.line('w$', win) -- Move the cursor if highlighted range is completely out of view @@ -506,7 +523,10 @@ function M.inspect_tree(opts) buffer = buf, once = true, callback = function() - close_win(w) + -- close all tree windows + for _, window in pairs(vim.fn.win_findbuf(b)) do + close_win(window) + end end, }) end -- cgit From 8cbb1f20e557461c8417583a7f69d53aaaef920b Mon Sep 17 00:00:00 2001 From: Ilia Choly Date: Tue, 4 Jun 2024 09:06:02 -0400 Subject: refactor(lua): use tuple syntax everywhere #29111 --- runtime/lua/vim/treesitter/dev.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'runtime/lua/vim/treesitter/dev.lua') diff --git a/runtime/lua/vim/treesitter/dev.lua b/runtime/lua/vim/treesitter/dev.lua index ca8cf85eda..56608bbf14 100644 --- a/runtime/lua/vim/treesitter/dev.lua +++ b/runtime/lua/vim/treesitter/dev.lua @@ -174,7 +174,7 @@ end --- @param source_buf integer --- @param inspect_buf integer --- @param inspect_win integer ---- @param pos? { [1]: integer, [2]: integer } +--- @param pos? [integer, integer] local function set_inspector_cursor(treeview, lang, source_buf, inspect_buf, inspect_win, pos) api.nvim_buf_clear_namespace(inspect_buf, treeview.ns, 0, -1) -- cgit From 9217e0d671b790d39192181cb894cfec012f06a6 Mon Sep 17 00:00:00 2001 From: Riley Bruins Date: Thu, 4 Jul 2024 10:09:19 -0700 Subject: fix(treesitter): display fields for anonymous nodes in :InspectTree --- runtime/lua/vim/treesitter/dev.lua | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'runtime/lua/vim/treesitter/dev.lua') diff --git a/runtime/lua/vim/treesitter/dev.lua b/runtime/lua/vim/treesitter/dev.lua index 56608bbf14..bd0ef5a011 100644 --- a/runtime/lua/vim/treesitter/dev.lua +++ b/runtime/lua/vim/treesitter/dev.lua @@ -220,14 +220,13 @@ function TSTreeView:draw(bufnr) local text ---@type string if item.node:named() then - if item.field then - text = string.format('%s: (%s', item.field, item.node:type()) - else - text = string.format('(%s', item.node:type()) - end + text = string.format('(%s', item.node:type()) else text = string.format('%q', item.node:type()):gsub('\n', 'n') end + if item.field then + text = string.format('%s: %s', item.field, text) + end local next = self:get(i + 1) if not next or next.depth <= item.depth then -- cgit From 94d42a3e7239a4035ee4429cbd71d5b0162b8289 Mon Sep 17 00:00:00 2001 From: Riley Bruins Date: Sun, 28 Jul 2024 13:42:18 -0700 Subject: fix(treesitter): highlight anonymous nodes in inspect_tree **Problem:** With anonymous nodes toggled in the inspect tree, only named nodes will be highlighted when moving the cursor in the source code buffer. **Solution:** Retrieve the anonymous node at the cursor (when toggled on in the inspect tree) and highlight them when appropriate, for better clarity/specificity. --- runtime/lua/vim/treesitter/dev.lua | 1 + 1 file changed, 1 insertion(+) (limited to 'runtime/lua/vim/treesitter/dev.lua') diff --git a/runtime/lua/vim/treesitter/dev.lua b/runtime/lua/vim/treesitter/dev.lua index bd0ef5a011..e89aea2b85 100644 --- a/runtime/lua/vim/treesitter/dev.lua +++ b/runtime/lua/vim/treesitter/dev.lua @@ -183,6 +183,7 @@ local function set_inspector_cursor(treeview, lang, source_buf, inspect_buf, ins lang = lang, pos = pos, ignore_injections = false, + include_anonymous = treeview.opts.anon, }) if not cursor_node then return -- 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/dev.lua | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'runtime/lua/vim/treesitter/dev.lua') diff --git a/runtime/lua/vim/treesitter/dev.lua b/runtime/lua/vim/treesitter/dev.lua index e89aea2b85..606d5b27b9 100644 --- a/runtime/lua/vim/treesitter/dev.lua +++ b/runtime/lua/vim/treesitter/dev.lua @@ -76,10 +76,9 @@ end --- ---@package function TSTreeView:new(bufnr, lang) - local ok, parser = pcall(vim.treesitter.get_parser, bufnr or 0, lang) - if not ok then - local err = parser --[[ @as string ]] - return nil, 'No parser available for the given buffer:\n' .. err + local parser = vim.treesitter._get_parser(bufnr or 0, lang) + if not parser then + return nil, 'No parser available for the given buffer.' end -- For each child tree (injected language), find the root of the tree and locate the node within @@ -539,7 +538,7 @@ local edit_ns = api.nvim_create_namespace('treesitter/dev-edit') local function update_editor_highlights(query_win, base_win, lang) local base_buf = api.nvim_win_get_buf(base_win) local query_buf = api.nvim_win_get_buf(query_win) - local parser = vim.treesitter.get_parser(base_buf, lang) + local parser = assert(vim.treesitter._get_parser(base_buf, lang)) api.nvim_buf_clear_namespace(base_buf, edit_ns, 0, -1) local query_content = table.concat(api.nvim_buf_get_lines(query_buf, 0, -1, false), '\n') @@ -596,8 +595,8 @@ function M.edit_query(lang) end vim.cmd(cmd) - local ok, parser = pcall(vim.treesitter.get_parser, buf, lang) - if not ok then + local parser = vim.treesitter._get_parser(buf, lang) + if not parser then return nil, 'No parser available for the given buffer' end lang = parser:lang() -- cgit From b63cd8cbaec1518b6580bf6e07e75a72c8779253 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Fri, 27 Sep 2024 03:27:00 -0700 Subject: fix(treesitter): EditQuery shows swapfile ATTENTION #30536 Problem: EditQuery shows swapfile ATTENTION, but this buffer is not intended for preservation (and the dialog breaks the UX). Solution: Set 'noswapfile' on the buffer before renaming it. --- runtime/lua/vim/treesitter/dev.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'runtime/lua/vim/treesitter/dev.lua') diff --git a/runtime/lua/vim/treesitter/dev.lua b/runtime/lua/vim/treesitter/dev.lua index 606d5b27b9..2a6e166ef1 100644 --- a/runtime/lua/vim/treesitter/dev.lua +++ b/runtime/lua/vim/treesitter/dev.lua @@ -153,7 +153,7 @@ end ---@param w integer ---@param b integer -local function set_dev_properties(w, b) +local function set_dev_options(w, b) vim.wo[w].scrolloff = 5 vim.wo[w].wrap = false vim.wo[w].foldmethod = 'expr' @@ -164,6 +164,7 @@ local function set_dev_properties(w, b) vim.bo[b].buftype = 'nofile' vim.bo[b].bufhidden = 'wipe' vim.bo[b].filetype = 'query' + vim.bo[b].swapfile = false end --- Updates the cursor position in the inspector to match the node under the cursor. @@ -354,7 +355,7 @@ function M.inspect_tree(opts) vim.b[buf].dev_inspect = w vim.b[b].dev_base = win -- base window handle vim.b[b].disable_query_linter = true - set_dev_properties(w, b) + set_dev_options(w, b) local title --- @type string? local opts_title = opts.title @@ -606,7 +607,7 @@ function M.edit_query(lang) vim.b[buf].dev_edit = query_win vim.bo[query_buf].omnifunc = 'v:lua.vim.treesitter.query.omnifunc' - set_dev_properties(query_win, query_buf) + set_dev_options(query_win, query_buf) -- Note that omnifunc guesses the language based on the containing folder, -- so we add the parser's language to the buffer's name so that omnifunc -- 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/dev.lua | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'runtime/lua/vim/treesitter/dev.lua') diff --git a/runtime/lua/vim/treesitter/dev.lua b/runtime/lua/vim/treesitter/dev.lua index 2a6e166ef1..dbf0e73250 100644 --- a/runtime/lua/vim/treesitter/dev.lua +++ b/runtime/lua/vim/treesitter/dev.lua @@ -76,9 +76,14 @@ end --- ---@package function TSTreeView:new(bufnr, lang) - local parser = vim.treesitter._get_parser(bufnr or 0, lang) + local parser = vim.treesitter.get_parser(bufnr or 0, lang, { error = false }) if not parser then - return nil, 'No parser available for the given buffer.' + return nil, + string.format( + 'Failed to create TSTreeView for buffer %s: no parser for lang "%s"', + bufnr, + lang + ) end -- For each child tree (injected language), find the root of the tree and locate the node within @@ -539,7 +544,7 @@ local edit_ns = api.nvim_create_namespace('treesitter/dev-edit') local function update_editor_highlights(query_win, base_win, lang) local base_buf = api.nvim_win_get_buf(base_win) local query_buf = api.nvim_win_get_buf(query_win) - local parser = assert(vim.treesitter._get_parser(base_buf, lang)) + local parser = assert(vim.treesitter.get_parser(base_buf, lang, { error = false })) api.nvim_buf_clear_namespace(base_buf, edit_ns, 0, -1) local query_content = table.concat(api.nvim_buf_get_lines(query_buf, 0, -1, false), '\n') @@ -596,9 +601,10 @@ function M.edit_query(lang) end vim.cmd(cmd) - local parser = vim.treesitter._get_parser(buf, lang) + local parser = vim.treesitter.get_parser(buf, lang, { error = false }) if not parser then - return nil, 'No parser available for the given buffer' + return nil, + string.format('Failed to show query editor for buffer %s: no parser for lang "%s"', buf, lang) end lang = parser:lang() -- cgit From 4349bdbd0bd0096b4f4bea0feda0961e3b03f3cc Mon Sep 17 00:00:00 2001 From: Riley Bruins Date: Fri, 27 Sep 2024 18:08:05 -0700 Subject: fix(treesitter): specify success status in edit_query return value --- runtime/lua/vim/treesitter/dev.lua | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'runtime/lua/vim/treesitter/dev.lua') diff --git a/runtime/lua/vim/treesitter/dev.lua b/runtime/lua/vim/treesitter/dev.lua index dbf0e73250..6a2f7ae936 100644 --- a/runtime/lua/vim/treesitter/dev.lua +++ b/runtime/lua/vim/treesitter/dev.lua @@ -579,6 +579,8 @@ end --- @private --- @param lang? string language to open the query editor for. +--- @return boolean? `true` on success, `nil` on failure +--- @return string? error message, if applicable function M.edit_query(lang) local buf = api.nvim_get_current_buf() local win = api.nvim_get_current_win() @@ -678,6 +680,8 @@ function M.edit_query(lang) }) vim.cmd('normal! G') vim.cmd.startinsert() + + return true end return M -- cgit From 5331f87f6145f705c73c5c23f365cecb9fbc5067 Mon Sep 17 00:00:00 2001 From: Jongwook Choi Date: Tue, 1 Oct 2024 12:07:30 -0400 Subject: fix(treesitter): indent size for inspect_tree #28727 Problem: For :InspectTree, indent size (`&shiftwidth`) for the tree viewer may be incorrect. This is because the tree viewer buffer with the filetype `query` does not explicitly configures the tab size, which can mismatch with the default indent size (2) assumed by TSTreeView's implementation. Solution: Set shiftwidth to be the same as TSTreeViewOpts specifies, which defaults to 2. --- runtime/lua/vim/treesitter/dev.lua | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'runtime/lua/vim/treesitter/dev.lua') diff --git a/runtime/lua/vim/treesitter/dev.lua b/runtime/lua/vim/treesitter/dev.lua index 6a2f7ae936..90c3720b80 100644 --- a/runtime/lua/vim/treesitter/dev.lua +++ b/runtime/lua/vim/treesitter/dev.lua @@ -158,7 +158,8 @@ end ---@param w integer ---@param b integer -local function set_dev_options(w, b) +---@param opts nil|{ indent?: integer } +local function set_dev_options(w, b, opts) vim.wo[w].scrolloff = 5 vim.wo[w].wrap = false vim.wo[w].foldmethod = 'expr' @@ -170,6 +171,11 @@ local function set_dev_options(w, b) vim.bo[b].bufhidden = 'wipe' vim.bo[b].filetype = 'query' vim.bo[b].swapfile = false + + opts = opts or {} + if opts.indent then + vim.bo[b].shiftwidth = opts.indent + end end --- Updates the cursor position in the inspector to match the node under the cursor. @@ -360,7 +366,7 @@ function M.inspect_tree(opts) vim.b[buf].dev_inspect = w vim.b[b].dev_base = win -- base window handle vim.b[b].disable_query_linter = true - set_dev_options(w, b) + set_dev_options(w, b, { indent = treeview.opts.indent }) local title --- @type string? local opts_title = opts.title -- cgit