diff options
author | Gregory Anders <8965202+gpanders@users.noreply.github.com> | 2023-02-22 08:01:08 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-02-22 08:01:08 -0700 |
commit | 675826da63e879efa97c0998fea192ed5c79d56e (patch) | |
tree | e21ae122150af334db50b43477f48a2f7811cbac | |
parent | 2281669470436a57f3bae746db05bb7b9ee4c171 (diff) | |
download | rneovim-675826da63e879efa97c0998fea192ed5c79d56e.tar.gz rneovim-675826da63e879efa97c0998fea192ed5c79d56e.tar.bz2 rneovim-675826da63e879efa97c0998fea192ed5c79d56e.zip |
refactor(treesitter): Add vim.treesitter.get_node() (#22360)
This function replaces both vim.treesitter.get_node_at_pos() and
vim.treesitter.get_node_at_cursor(). These two functions are similar
enough that they don't need separate interfaces. Even worse,
get_node_at_pos() returns a TSNode while get_node_at_cursor() returns a
string, so the two functions behave slightly differently.
vim.treesitter.get_node() combines these two into a more streamlined
interface. With no arguments, it returns the node under the cursor in
the current buffer. Optionally, it can accept a buffer number or a
position to get the node at a given position in a given buffer.
-rw-r--r-- | runtime/doc/deprecated.txt | 8 | ||||
-rw-r--r-- | runtime/doc/news.txt | 2 | ||||
-rw-r--r-- | runtime/doc/treesitter.txt | 29 | ||||
-rw-r--r-- | runtime/lua/vim/treesitter.lua | 57 |
4 files changed, 73 insertions, 23 deletions
diff --git a/runtime/doc/deprecated.txt b/runtime/doc/deprecated.txt index e7b0a710e8..42dfb53e77 100644 --- a/runtime/doc/deprecated.txt +++ b/runtime/doc/deprecated.txt @@ -119,6 +119,14 @@ LSP FUNCTIONS - *vim.lsp.buf.range_formatting()* Use |vim.lsp.formatexpr()| or |vim.lsp.buf.format()| instead. +TREESITTER FUNCTIONS +- *vim.treesitter.language.require_language()* Use |vim.treesitter.language.add()| + instead. +- *vim.treesitter.get_node_at_pos()* Use |vim.treesitter.get_node()| + instead. +- *vim.treesitter.get_node_at_cursor()* Use |vim.treesitter.get_node()| + and |TSNode:type()| instead. + LUA - *vim.register_keystroke_callback()* Use |vim.on_key()| instead. diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index 8b41f2d104..2a12a144e6 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -208,5 +208,7 @@ release. • `vim.treesitter.language.require_language()` has been deprecated in favour of |vim.treesitter.language.add()|. +• |vim.treesitter.get_node_at_pos()| and |vim.treesitter.get_node_at_cursor()| + are both deprecated in favor of |vim.treesitter.get_node()|. vim:tw=78:ts=8:sw=2:et:ft=help:norl: diff --git a/runtime/doc/treesitter.txt b/runtime/doc/treesitter.txt index e35e145301..16de49029e 100644 --- a/runtime/doc/treesitter.txt +++ b/runtime/doc/treesitter.txt @@ -508,30 +508,21 @@ get_captures_at_pos({bufnr}, {row}, {col}) table[] List of captures `{ capture = "capture name", metadata = { ... } }` -get_node_at_cursor({winnr}) *vim.treesitter.get_node_at_cursor()* - Returns the smallest named node under the cursor - - Parameters: ~ - • {winnr} (integer|nil) Window handle or 0 for current window (default) - - Return: ~ - (string) Name of node under the cursor - - *vim.treesitter.get_node_at_pos()* -get_node_at_pos({bufnr}, {row}, {col}, {opts}) +get_node({opts}) *vim.treesitter.get_node()* Returns the smallest named node at the given position Parameters: ~ - • {bufnr} (integer) Buffer number (0 for current buffer) - • {row} (integer) Position row - • {col} (integer) Position column - • {opts} (table) Optional keyword arguments: - • lang string|nil Parser language - • ignore_injections boolean Ignore injected languages - (default true) + • {opts} (table|nil) Optional keyword arguments: + • bufnr integer|nil Buffer number (nil or 0 for current + buffer) + • pos table|nil 0-indexed (row, col) tuple. Defaults to cursor + position in the current window. Required if {bufnr} is not + the current buffer + • ignore_injections boolean Ignore injected languages (default + true) Return: ~ - |TSNode||nil under the cursor + |TSNode| | nil Node at the given position get_node_range({node_or_range}) *vim.treesitter.get_node_range()* Returns the node's range or an unpacked range table diff --git a/runtime/lua/vim/treesitter.lua b/runtime/lua/vim/treesitter.lua index c524b20bc2..c1e5325519 100644 --- a/runtime/lua/vim/treesitter.lua +++ b/runtime/lua/vim/treesitter.lua @@ -288,6 +288,50 @@ end --- Returns the smallest named node at the given position --- +---@param opts table|nil Optional keyword arguments: +--- - bufnr integer|nil Buffer number (nil or 0 for current buffer) +--- - pos table|nil 0-indexed (row, col) tuple. Defaults to cursor position in the +--- current window. Required if {bufnr} is not the current buffer +--- - ignore_injections boolean Ignore injected languages (default true) +--- +---@return TSNode | nil Node at the given position +function M.get_node(opts) + opts = opts or {} + + local bufnr = opts.bufnr + + if not bufnr or bufnr == 0 then + bufnr = a.nvim_get_current_buf() + end + + local row, col + if opts.pos then + assert(#opts.pos == 2, 'Position must be a (row, col) tuple') + row, col = opts.pos[1], opts.pos[2] + else + assert( + bufnr == a.nvim_get_current_buf(), + 'Position must be explicitly provided when not using the current buffer' + ) + local pos = a.nvim_win_get_cursor(0) + -- Subtract one to account for 1-based row indexing in nvim_win_get_cursor + row, col = pos[1] - 1, pos[2] + end + + assert(row >= 0 and col >= 0, 'Invalid position: row and col must be non-negative') + + local ts_range = { row, col, row, col } + + local root_lang_tree = M.get_parser(bufnr) + if not root_lang_tree then + return + end + + return root_lang_tree:named_node_for_range(ts_range, opts) +end + +--- Returns the smallest named node at the given position +--- ---@param bufnr integer Buffer number (0 for current buffer) ---@param row integer Position row ---@param col integer Position column @@ -296,12 +340,16 @@ end --- - ignore_injections boolean Ignore injected languages (default true) --- ---@return TSNode|nil under the cursor +---@deprecated function M.get_node_at_pos(bufnr, row, col, opts) + vim.deprecate('vim.treesitter.get_node_at_pos()', 'vim.treesitter.get_node()', '0.10') if bufnr == 0 then bufnr = a.nvim_get_current_buf() end local ts_range = { row, col, row, col } + opts = opts or {} + local root_lang_tree = M.get_parser(bufnr, opts.lang) if not root_lang_tree then return @@ -315,12 +363,13 @@ end ---@param winnr (integer|nil) Window handle or 0 for current window (default) --- ---@return string Name of node under the cursor +---@deprecated function M.get_node_at_cursor(winnr) + vim.deprecate('vim.treesitter.get_node_at_cursor()', 'vim.treesitter.get_node():type()', '0.10') winnr = winnr or 0 local bufnr = a.nvim_win_get_buf(winnr) - local cursor = a.nvim_win_get_cursor(winnr) - return M.get_node_at_pos(bufnr, cursor[1] - 1, cursor[2], { ignore_injections = false }):type() + return M.get_node({ bufnr = bufnr, ignore_injections = false }):type() end --- Starts treesitter highlighting for a buffer @@ -493,8 +542,8 @@ function M.show_tree(opts) a.nvim_buf_clear_namespace(b, pg.ns, 0, -1) - local cursor = a.nvim_win_get_cursor(win) - local cursor_node = M.get_node_at_pos(buf, cursor[1] - 1, cursor[2], { + local cursor_node = M.get_node({ + bufnr = buf, lang = opts.lang, ignore_injections = false, }) |