diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2024-05-24 19:18:11 +0000 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2024-05-24 19:18:11 +0000 |
commit | ff7ed8f586589d620a806c3758fac4a47a8e7e15 (patch) | |
tree | 729bbcb92231538fa61dab6c3d890b025484b7f5 /runtime/lua/vim/treesitter/languagetree.lua | |
parent | 376914f419eb08fdf4c1a63a77e1f035898a0f10 (diff) | |
parent | 28c04948a1c887a1cc0cb64de79fa32631700466 (diff) | |
download | rneovim-ff7ed8f586589d620a806c3758fac4a47a8e7e15.tar.gz rneovim-ff7ed8f586589d620a806c3758fac4a47a8e7e15.tar.bz2 rneovim-ff7ed8f586589d620a806c3758fac4a47a8e7e15.zip |
Merge remote-tracking branch 'upstream/master' into mix_20240309
Diffstat (limited to 'runtime/lua/vim/treesitter/languagetree.lua')
-rw-r--r-- | runtime/lua/vim/treesitter/languagetree.lua | 98 |
1 files changed, 47 insertions, 51 deletions
diff --git a/runtime/lua/vim/treesitter/languagetree.lua b/runtime/lua/vim/treesitter/languagetree.lua index 62714d3f1b..b0812123b9 100644 --- a/runtime/lua/vim/treesitter/languagetree.lua +++ b/runtime/lua/vim/treesitter/languagetree.lua @@ -81,7 +81,7 @@ local TSCallbackNames = { ---List of regions this tree should manage and parse. If nil then regions are ---taken from _trees. This is mostly a short-lived cache for included_regions() ---@field private _lang string Language name ----@field private _parent_lang? string Parent language name +---@field private _parent? vim.treesitter.LanguageTree Parent LanguageTree ---@field private _source (integer|string) Buffer or string to parse ---@field private _trees table<integer, TSTree> Reference to parsed tree (one for each language). ---Each key is the index of region, which is synced with _regions and _valid. @@ -106,9 +106,8 @@ LanguageTree.__index = LanguageTree ---@param source (integer|string) Buffer or text string to parse ---@param lang string Root language of this tree ---@param opts vim.treesitter.LanguageTree.new.Opts? ----@param parent_lang? string Parent language name of this tree ---@return vim.treesitter.LanguageTree parser object -function LanguageTree.new(source, lang, opts, parent_lang) +function LanguageTree.new(source, lang, opts) language.add(lang) opts = opts or {} @@ -122,7 +121,6 @@ function LanguageTree.new(source, lang, opts, parent_lang) local self = { _source = source, _lang = lang, - _parent_lang = parent_lang, _children = {}, _trees = {}, _opts = opts, @@ -158,8 +156,10 @@ function LanguageTree:_set_logger() local lang = self:lang() - vim.fn.mkdir(vim.fn.stdpath('log'), 'p') - local logfilename = vim.fs.joinpath(vim.fn.stdpath('log'), 'treesitter.log') + local logdir = vim.fn.stdpath('log') --[[@as string]] + + vim.fn.mkdir(logdir, 'p') + local logfilename = vim.fs.joinpath(logdir, 'treesitter.log') local logfile, openerr = io.open(logfilename, 'a+') @@ -225,7 +225,10 @@ function LanguageTree:_log(...) self._logger('nvim', table.concat(msg, ' ')) end ---- Invalidates this parser and all its children +--- Invalidates this parser and its children. +--- +--- Should only be called when the tracked state of the LanguageTree is not valid against the parse +--- tree in treesitter. Doesn't clear filesystem cache. Called often, so needs to be fast. ---@param reload boolean|nil function LanguageTree:invalidate(reload) self._valid = false @@ -460,24 +463,6 @@ function LanguageTree:parse(range) return self._trees end ----@deprecated Misleading name. Use `LanguageTree:children()` (non-recursive) instead, ---- add recursion yourself if needed. ---- Invokes the callback for each |LanguageTree| and its children recursively ---- ----@param fn fun(tree: vim.treesitter.LanguageTree, lang: string) ----@param include_self boolean|nil Whether to include the invoking tree in the results -function LanguageTree:for_each_child(fn, include_self) - vim.deprecate('LanguageTree:for_each_child()', 'LanguageTree:children()', '0.11') - if include_self then - fn(self, self._lang) - end - - for _, child in pairs(self._children) do - --- @diagnostic disable-next-line:deprecated - child:for_each_child(fn, true) - end -end - --- Invokes the callback for each |LanguageTree| recursively. --- --- Note: This includes the invoking tree's child trees as well. @@ -505,19 +490,25 @@ function LanguageTree:add_child(lang) self:remove_child(lang) end - local child = LanguageTree.new(self._source, lang, self._opts, self:lang()) + local child = LanguageTree.new(self._source, lang, self._opts) -- Inherit recursive callbacks for nm, cb in pairs(self._callbacks_rec) do vim.list_extend(child._callbacks_rec[nm], cb) end + child._parent = self self._children[lang] = child self:_do_callback('child_added', self._children[lang]) return self._children[lang] end +--- @package +function LanguageTree:parent() + return self._parent +end + --- Removes a child language from this |LanguageTree|. --- ---@private @@ -752,7 +743,6 @@ local has_parser = vim.func._memoize(1, function(lang) end) --- Return parser name for language (if exists) or filetype (if registered and exists). ---- Also attempts with the input lower-cased. --- ---@param alias string language or filetype name ---@return string? # resolved parser name @@ -766,19 +756,10 @@ local function resolve_lang(alias) return alias end - if has_parser(alias:lower()) then - return alias:lower() - end - local lang = vim.treesitter.language.get_lang(alias) if lang and has_parser(lang) then return lang end - - lang = vim.treesitter.language.get_lang(alias:lower()) - if lang and has_parser(lang) then - return lang - end end ---@private @@ -792,7 +773,7 @@ function LanguageTree:_get_injection(match, metadata) local combined = metadata['injection.combined'] ~= nil local injection_lang = metadata['injection.language'] --[[@as string?]] local lang = metadata['injection.self'] ~= nil and self:lang() - or metadata['injection.parent'] ~= nil and self._parent_lang + or metadata['injection.parent'] ~= nil and self._parent:lang() or (injection_lang and resolve_lang(injection_lang)) local include_children = metadata['injection.include-children'] ~= nil @@ -802,7 +783,11 @@ function LanguageTree:_get_injection(match, metadata) -- Lang should override any other language tag if name == 'injection.language' then local text = vim.treesitter.get_node_text(node, self._source, { metadata = metadata[id] }) - lang = resolve_lang(text) + lang = resolve_lang(text:lower()) -- language names are always lower case + elseif name == 'injection.filename' then + local text = vim.treesitter.get_node_text(node, self._source, { metadata = metadata[id] }) + local ft = vim.filetype.match({ filename = text }) + lang = ft and resolve_lang(ft) elseif name == 'injection.content' then ranges = get_node_ranges(node, self._source, metadata[id], include_children) end @@ -1054,20 +1039,19 @@ function LanguageTree:_on_detach(...) end end ---- Registers callbacks for the |LanguageTree|. ----@param cbs table An |nvim_buf_attach()|-like table argument with the following handlers: ---- - `on_bytes` : see |nvim_buf_attach()|, but this will be called _after_ the parsers callback. +--- Registers callbacks for the [LanguageTree]. +---@param cbs table<TSCallbackNameOn,function> An [nvim_buf_attach()]-like table argument with the following handlers: +--- - `on_bytes` : see [nvim_buf_attach()], but this will be called _after_ the parsers callback. --- - `on_changedtree` : a callback that will be called every time the tree has syntactical changes. --- It will be passed two arguments: a table of the ranges (as node ranges) that --- changed and the changed tree. --- - `on_child_added` : emitted when a child is added to the tree. --- - `on_child_removed` : emitted when a child is removed from the tree. ---- - `on_detach` : emitted when the buffer is detached, see |nvim_buf_detach_event|. +--- - `on_detach` : emitted when the buffer is detached, see [nvim_buf_detach_event]. --- Takes one argument, the number of the buffer. --- @param recursive? boolean Apply callbacks recursively for all children. Any new children will --- also inherit the callbacks. function LanguageTree:register_cbs(cbs, recursive) - ---@cast cbs table<TSCallbackNameOn,function> if not cbs then return end @@ -1091,7 +1075,14 @@ end ---@param range Range ---@return boolean local function tree_contains(tree, range) - return Range.contains({ tree:root():range() }, range) + local tree_ranges = tree:included_ranges(false) + + return Range.contains({ + tree_ranges[1][1], + tree_ranges[1][2], + tree_ranges[#tree_ranges][3], + tree_ranges[#tree_ranges][4], + }, range) end --- Determines whether {range} is contained in the |LanguageTree|. @@ -1108,12 +1099,18 @@ function LanguageTree:contains(range) return false end +--- @class vim.treesitter.LanguageTree.tree_for_range.Opts +--- @inlinedoc +--- +--- Ignore injected languages +--- (default: `true`) +--- @field ignore_injections? boolean + --- Gets the tree that contains {range}. --- ---@param range Range4 `{ start_line, start_col, end_line, end_col }` ----@param opts table|nil Optional keyword arguments: ---- - ignore_injections boolean Ignore injected languages (default true) ----@return TSTree|nil +---@param opts? vim.treesitter.LanguageTree.tree_for_range.Opts +---@return TSTree? function LanguageTree:tree_for_range(range, opts) opts = opts or {} local ignore = vim.F.if_nil(opts.ignore_injections, true) @@ -1139,9 +1136,8 @@ end --- Gets the smallest named node that contains {range}. --- ---@param range Range4 `{ start_line, start_col, end_line, end_col }` ----@param opts table|nil Optional keyword arguments: ---- - ignore_injections boolean Ignore injected languages (default true) ----@return TSNode | nil Found node +---@param opts? vim.treesitter.LanguageTree.tree_for_range.Opts +---@return TSNode? function LanguageTree:named_node_for_range(range, opts) local tree = self:tree_for_range(range, opts) if tree then @@ -1152,7 +1148,7 @@ end --- Gets the appropriate language that contains {range}. --- ---@param range Range4 `{ start_line, start_col, end_line, end_col }` ----@return vim.treesitter.LanguageTree Managing {range} +---@return vim.treesitter.LanguageTree tree Managing {range} function LanguageTree:language_for_range(range) for _, child in pairs(self._children) do if child:contains(range) then |