aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/treesitter.lua
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/lua/vim/treesitter.lua')
-rw-r--r--runtime/lua/vim/treesitter.lua164
1 files changed, 51 insertions, 113 deletions
diff --git a/runtime/lua/vim/treesitter.lua b/runtime/lua/vim/treesitter.lua
index e7a66c00b2..a09619f369 100644
--- a/runtime/lua/vim/treesitter.lua
+++ b/runtime/lua/vim/treesitter.lua
@@ -1,44 +1,21 @@
local api = vim.api
-local LanguageTree = require('vim.treesitter.languagetree')
-local Range = require('vim.treesitter._range')
----@type table<integer,LanguageTree>
+---@type table<integer,vim.treesitter.LanguageTree>
local parsers = setmetatable({}, { __mode = 'v' })
----@class TreesitterModule
----@field highlighter TSHighlighter
----@field query TSQueryModule
----@field language TSLanguageModule
-local M = setmetatable({}, {
- __index = function(t, k)
- ---@diagnostic disable:no-unknown
- if k == 'highlighter' then
- t[k] = require('vim.treesitter.highlighter')
- return t[k]
- elseif k == 'language' then
- t[k] = require('vim.treesitter.language')
- return t[k]
- elseif k == 'query' then
- t[k] = require('vim.treesitter.query')
- return t[k]
- end
-
- local query = require('vim.treesitter.query')
- if query[k] then
- vim.deprecate('vim.treesitter.' .. k .. '()', 'vim.treesitter.query.' .. k .. '()', '0.10')
- t[k] = query[k]
- return t[k]
- end
-
- local language = require('vim.treesitter.language')
- if language[k] then
- vim.deprecate('vim.treesitter.' .. k .. '()', 'vim.treesitter.language.' .. k .. '()', '0.10')
- t[k] = language[k]
- return t[k]
- end
- end,
+local M = vim._defer_require('vim.treesitter', {
+ _fold = ..., --- @module 'vim.treesitter._fold'
+ _query_linter = ..., --- @module 'vim.treesitter._query_linter'
+ _range = ..., --- @module 'vim.treesitter._range'
+ dev = ..., --- @module 'vim.treesitter.dev'
+ highlighter = ..., --- @module 'vim.treesitter.highlighter'
+ language = ..., --- @module 'vim.treesitter.language'
+ languagetree = ..., --- @module 'vim.treesitter.languagetree'
+ query = ..., --- @module 'vim.treesitter.query'
})
+local LanguageTree = M.languagetree
+
--- @nodoc
M.language_version = vim._ts_get_language_version()
@@ -53,7 +30,7 @@ M.minimum_language_version = vim._ts_get_minimum_language_version()
---@param lang string Language of the parser
---@param opts (table|nil) Options to pass to the created language tree
---
----@return LanguageTree object to use for parsing
+---@return vim.treesitter.LanguageTree object to use for parsing
function M._create_parser(bufnr, lang, opts)
if bufnr == 0 then
bufnr = vim.api.nvim_get_current_buf()
@@ -100,10 +77,10 @@ end
--- If needed, this will create the parser.
---
---@param bufnr (integer|nil) Buffer the parser should be tied to (default: current buffer)
----@param lang (string|nil) Filetype of this parser (default: buffer filetype)
+---@param lang (string|nil) Language of this parser (default: from buffer filetype)
---@param opts (table|nil) Options to pass to the created language tree
---
----@return LanguageTree object to use for parsing
+---@return vim.treesitter.LanguageTree object to use for parsing
function M.get_parser(bufnr, lang, opts)
opts = opts or {}
@@ -142,7 +119,7 @@ end
---@param lang string Language of this string
---@param opts (table|nil) Options to pass to the created language tree
---
----@return LanguageTree object to use for parsing
+---@return vim.treesitter.LanguageTree object to use for parsing
function M.get_string_parser(str, lang, opts)
vim.validate({
str = { str, 'string' },
@@ -195,12 +172,12 @@ end
---to get the range with directives applied.
---@param node TSNode
---@param source integer|string|nil Buffer or string from which the {node} is extracted
----@param metadata TSMetadata|nil
+---@param metadata vim.treesitter.query.TSMetadata|nil
---@return Range6
function M.get_range(node, source, metadata)
if metadata and metadata.range then
assert(source)
- return Range.add_bytes(source, metadata.range)
+ return M._range.add_bytes(source, metadata.range)
end
return { node:range(true) }
end
@@ -209,7 +186,7 @@ end
---@param range Range
---@returns string
local function buf_range_get_text(buf, range)
- local start_row, start_col, end_row, end_col = Range.unpack4(range)
+ local start_row, start_col, end_row, end_col = M._range.unpack4(range)
if end_col == 0 then
if start_row == end_row then
start_col = -1
@@ -237,7 +214,7 @@ function M.get_node_text(node, source, opts)
if metadata.text then
return metadata.text
elseif type(source) == 'number' then
- local range = vim.treesitter.get_range(node, source, metadata)
+ local range = M.get_range(node, source, metadata)
return buf_range_get_text(source, range)
end
@@ -266,9 +243,9 @@ function M.node_contains(node, range)
vim.validate({
-- allow a table so nodes can be mocked
node = { node, { 'userdata', 'table' } },
- range = { range, Range.validate, 'integer list with 4 or 6 elements' },
+ range = { range, M._range.validate, 'integer list with 4 or 6 elements' },
})
- return Range.contains({ node:range() }, range)
+ return M._range.contains({ node:range() }, range)
end
--- Returns a list of highlight captures at the given position
@@ -317,6 +294,7 @@ function M.get_captures_at_pos(bufnr, row, col)
for capture, node, metadata in iter do
if M.is_in_node_range(node, row, col) then
+ ---@diagnostic disable-next-line: invisible
local c = q._query.captures[capture] -- name of the capture in the query
if c ~= nil then
table.insert(matches, { capture = c, metadata = metadata, lang = tree:lang() })
@@ -348,6 +326,23 @@ function M.get_captures_at_cursor(winnr)
return captures
end
+--- Optional keyword arguments:
+--- @class vim.treesitter.get_node.Opts
+--- @inlinedoc
+---
+--- Buffer number (nil or 0 for current buffer)
+--- @field bufnr integer?
+---
+--- 0-indexed (row, col) tuple. Defaults to cursor position in the
+--- current window. Required if {bufnr} is not the current buffer
+--- @field pos { [1]: integer, [2]: integer }?
+---
+--- Parser language. (default: from buffer filetype)
+--- @field lang string?
+---
+--- Ignore injected languages (default true)
+--- @field ignore_injections boolean?
+
--- Returns the smallest named node at the given position
---
--- NOTE: Calling this on an unparsed tree can yield an invalid node.
@@ -358,11 +353,7 @@ end
--- vim.treesitter.get_parser(bufnr):parse(range)
--- ```
---
----@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)
+---@param opts vim.treesitter.get_node.Opts?
---
---@return TSNode | nil Node at the given position
function M.get_node(opts)
@@ -374,7 +365,7 @@ function M.get_node(opts)
bufnr = api.nvim_get_current_buf()
end
- local row, col
+ local row, col --- @type integer, integer
if opts.pos then
assert(#opts.pos == 2, 'Position must be a (row, col) tuple')
row, col = opts.pos[1], opts.pos[2]
@@ -392,34 +383,6 @@ function M.get_node(opts)
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
----@param opts table Optional keyword arguments:
---- - lang string|nil Parser language
---- - ignore_injections boolean Ignore injected languages (default true)
----
----@return TSNode | nil Node at the given position
----@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 = api.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
@@ -428,26 +391,12 @@ function M.get_node_at_pos(bufnr, row, col, opts)
return root_lang_tree:named_node_for_range(ts_range, opts)
end
---- Returns the smallest named node under the cursor
----
----@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 = api.nvim_win_get_buf(winnr)
-
- return M.get_node({ bufnr = bufnr, ignore_injections = false }):type()
-end
-
--- Starts treesitter highlighting for a buffer
---
--- Can be used in an ftplugin or FileType autocommand.
---
--- Note: By default, disables regex syntax highlighting, which may be required for some plugins.
---- In this case, add ``vim.bo.syntax = 'on'`` after the call to `start`.
+--- In this case, add `vim.bo.syntax = 'on'` after the call to `start`.
---
--- Example:
---
@@ -461,7 +410,7 @@ end
--- ```
---
---@param bufnr (integer|nil) Buffer to be highlighted (default: current buffer)
----@param lang (string|nil) Language of the parser (default: buffer filetype)
+---@param lang (string|nil) Language of the parser (default: from buffer filetype)
function M.start(bufnr, lang)
bufnr = bufnr or api.nvim_get_current_buf()
local parser = M.get_parser(bufnr, lang)
@@ -483,13 +432,14 @@ end
---
--- While in the window, press "a" to toggle display of anonymous nodes, "I" to toggle the
--- display of the source language of each node, "o" to toggle the query editor, and press
---- <Enter> to jump to the node under the cursor in the source buffer.
+--- [<Enter>] to jump to the node under the cursor in the source buffer. Folding also works
+--- (try |zo|, |zc|, etc.).
---
---- Can also be shown with `:InspectTree`. *:InspectTree*
+--- Can also be shown with `:InspectTree`. [:InspectTree]()
---
---@param opts table|nil Optional options table with the following possible keys:
---- - lang (string|nil): The language of the source buffer. If omitted, the
---- filetype of the source buffer is used.
+--- - lang (string|nil): The language of the source buffer. If omitted, detect
+--- from the filetype of the source buffer.
--- - bufnr (integer|nil): Buffer to draw the tree into. If omitted, a new
--- buffer is created.
--- - winid (integer|nil): Window id to display the tree buffer in. If omitted,
@@ -501,7 +451,7 @@ end
--- argument and should return a string.
function M.inspect_tree(opts)
---@diagnostic disable-next-line: invisible
- require('vim.treesitter.dev').inspect_tree(opts)
+ M.dev.inspect_tree(opts)
end
--- Returns the fold level for {lnum} in the current buffer. Can be set directly to 'foldexpr':
@@ -513,19 +463,7 @@ end
---@param lnum integer|nil Line number to calculate fold level for
---@return string
function M.foldexpr(lnum)
- return require('vim.treesitter._fold').foldexpr(lnum)
-end
-
---- Returns the highlighted content of the first line of the fold or falls back to |foldtext()|
---- if no treesitter parser is found. Can be set directly to 'foldtext':
----
---- ```lua
---- vim.wo.foldtext = 'v:lua.vim.treesitter.foldtext()'
---- ```
----
----@return { [1]: string, [2]: string[] }[] | string
-function M.foldtext()
- return require('vim.treesitter._fold').foldtext()
+ return M._fold.foldexpr(lnum)
end
return M