aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/lua/vim')
-rw-r--r--runtime/lua/vim/_meta/vimfn.lua14
-rw-r--r--runtime/lua/vim/lsp.lua2
-rw-r--r--runtime/lua/vim/treesitter/_fold.lua7
-rw-r--r--runtime/lua/vim/treesitter/_meta.lua7
-rw-r--r--runtime/lua/vim/treesitter/_range.lua9
-rw-r--r--runtime/lua/vim/treesitter/dev.lua2
-rw-r--r--runtime/lua/vim/treesitter/highlighter.lua24
-rw-r--r--runtime/lua/vim/treesitter/languagetree.lua238
-rw-r--r--runtime/lua/vim/treesitter/query.lua28
9 files changed, 213 insertions, 118 deletions
diff --git a/runtime/lua/vim/_meta/vimfn.lua b/runtime/lua/vim/_meta/vimfn.lua
index 14aae99971..d5d9229ffb 100644
--- a/runtime/lua/vim/_meta/vimfn.lua
+++ b/runtime/lua/vim/_meta/vimfn.lua
@@ -3309,6 +3309,9 @@ function vim.fn.getpos(expr) end
--- text description of the error
--- type type of the error, 'E', '1', etc.
--- valid |TRUE|: recognized error message
+--- user_data
+--- custom data associated with the item, can be
+--- any type.
---
--- When there is no error list or it's empty, an empty list is
--- returned. Quickfix list entries with a non-existing buffer
@@ -7595,6 +7598,9 @@ function vim.fn.setpos(expr, list) end
--- text description of the error
--- type single-character error type, 'E', 'W', etc.
--- valid recognized error message
+--- user_data
+--- custom data associated with the item, can be
+--- any type.
---
--- The "col", "vcol", "nr", "type" and "text" entries are
--- optional. Either "lnum" or "pattern" entry can be used to
@@ -9733,8 +9739,9 @@ function vim.fn.type(expr) end
--- @return string
function vim.fn.undofile(name) end
---- Return the current state of the undo tree in a dictionary with
---- the following items:
+--- Return the current state of the undo tree for the current
+--- buffer, or for a specific buffer if {buf} is given. The
+--- result is a dictionary with the following items:
--- "seq_last" The highest undo sequence number used.
--- "seq_cur" The sequence number of the current position in
--- the undo tree. This differs from "seq_last"
@@ -9775,8 +9782,9 @@ function vim.fn.undofile(name) end
--- blocks. Each item may again have an "alt"
--- item.
---
+--- @param buf? any
--- @return any
-function vim.fn.undotree() end
+function vim.fn.undotree(buf) end
--- Remove second and succeeding copies of repeated adjacent
--- {list} items in-place. Returns {list}. If you want a list
diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua
index 0c4290d067..2a16bafbfc 100644
--- a/runtime/lua/vim/lsp.lua
+++ b/runtime/lua/vim/lsp.lua
@@ -2262,7 +2262,7 @@ end
local function adjust_start_col(lnum, line, items, encoding)
local min_start_char = nil
for _, item in pairs(items) do
- if item.filterText == nil and item.textEdit and item.textEdit.range.start.line == lnum - 1 then
+ if item.textEdit and item.textEdit.range.start.line == lnum - 1 then
if min_start_char and min_start_char ~= item.textEdit.range.start.character then
return nil
end
diff --git a/runtime/lua/vim/treesitter/_fold.lua b/runtime/lua/vim/treesitter/_fold.lua
index a02d0a584d..912a6e8a9f 100644
--- a/runtime/lua/vim/treesitter/_fold.lua
+++ b/runtime/lua/vim/treesitter/_fold.lua
@@ -147,11 +147,14 @@ local function normalise_erow(bufnr, erow)
return math.min(erow or max_erow, max_erow)
end
+-- TODO(lewis6991): Setup a decor provider so injections folds can be parsed
+-- as the window is redrawn
---@param bufnr integer
---@param info TS.FoldInfo
---@param srow integer?
---@param erow integer?
-local function get_folds_levels(bufnr, info, srow, erow)
+---@param parse_injections? boolean
+local function get_folds_levels(bufnr, info, srow, erow, parse_injections)
srow = srow or 0
erow = normalise_erow(bufnr, erow)
@@ -162,7 +165,7 @@ local function get_folds_levels(bufnr, info, srow, erow)
local parser = ts.get_parser(bufnr)
- parser:parse()
+ parser:parse(parse_injections and { srow, erow } or nil)
parser:for_each_tree(function(tree, ltree)
local query = ts.query.get(ltree:lang(), 'folds')
diff --git a/runtime/lua/vim/treesitter/_meta.lua b/runtime/lua/vim/treesitter/_meta.lua
index 36b1a9bbf8..d8babc9402 100644
--- a/runtime/lua/vim/treesitter/_meta.lua
+++ b/runtime/lua/vim/treesitter/_meta.lua
@@ -1,6 +1,6 @@
---@meta
----@class TSNode
+---@class TSNode: userdata
---@field id fun(self: TSNode): integer
---@field tree fun(self: TSNode): TSTree
---@field range fun(self: TSNode, include_bytes: false?): integer, integer, integer, integer
@@ -51,7 +51,7 @@ function TSNode:_rawquery(query, captures, start, end_, opts) end
---@field parse fun(self: TSParser, tree: TSTree?, source: integer|string, include_bytes: boolean?): TSTree, integer[]
---@field reset fun(self: TSParser)
---@field included_ranges fun(self: TSParser, include_bytes: boolean?): integer[]
----@field set_included_ranges fun(self: TSParser, ranges: Range6[])
+---@field set_included_ranges fun(self: TSParser, ranges: (Range6|TSNode)[])
---@field set_timeout fun(self: TSParser, timeout: integer)
---@field timeout fun(self: TSParser): integer
---@field _set_logger fun(self: TSParser, lex: boolean, parse: boolean, cb: TSLoggerCallback)
@@ -61,7 +61,8 @@ function TSNode:_rawquery(query, captures, start, end_, opts) end
---@field root fun(self: TSTree): TSNode
---@field edit fun(self: TSTree, _: integer, _: integer, _: integer, _: integer, _: integer, _: integer, _: integer, _: integer, _:integer)
---@field copy fun(self: TSTree): TSTree
----@field included_ranges fun(self: TSTree, include_bytes: boolean?): integer[]
+---@field included_ranges fun(self: TSTree, include_bytes: true): Range6[]
+---@field included_ranges fun(self: TSTree, include_bytes: false): Range4[]
---@return integer
vim._ts_get_language_version = function() end
diff --git a/runtime/lua/vim/treesitter/_range.lua b/runtime/lua/vim/treesitter/_range.lua
index 35081c6400..8d727c3c52 100644
--- a/runtime/lua/vim/treesitter/_range.lua
+++ b/runtime/lua/vim/treesitter/_range.lua
@@ -2,6 +2,10 @@ local api = vim.api
local M = {}
+---@class Range2
+---@field [1] integer start row
+---@field [2] integer end row
+
---@class Range4
---@field [1] integer start row
---@field [2] integer start column
@@ -16,7 +20,7 @@ local M = {}
---@field [5] integer end column
---@field [6] integer end bytes
----@alias Range Range4|Range6
+---@alias Range Range2|Range4|Range6
---@private
---@param a_row integer
@@ -111,6 +115,9 @@ end
---@param r Range
---@return integer, integer, integer, integer
function M.unpack4(r)
+ if #r == 2 then
+ return r[1], 0, r[2], 0
+ end
local off_1 = #r == 6 and 1 or 0
return r[1], r[2], r[3 + off_1], r[4 + off_1]
end
diff --git a/runtime/lua/vim/treesitter/dev.lua b/runtime/lua/vim/treesitter/dev.lua
index e94e8f08dc..f7625eb94b 100644
--- a/runtime/lua/vim/treesitter/dev.lua
+++ b/runtime/lua/vim/treesitter/dev.lua
@@ -99,7 +99,7 @@ function TSTreeView:new(bufnr, lang)
-- For each child tree (injected language), find the root of the tree and locate the node within
-- the primary tree that contains that root. Add a mapping from the node in the primary tree to
-- the root in the child tree to the {injections} table.
- local root = parser:parse()[1]:root()
+ local root = parser:parse(true)[1]:root()
local injections = {} ---@type table<integer,table>
parser:for_each_child(function(child, lang_)
child:for_each_tree(function(tree)
diff --git a/runtime/lua/vim/treesitter/highlighter.lua b/runtime/lua/vim/treesitter/highlighter.lua
index f8ec5b175d..56b075b723 100644
--- a/runtime/lua/vim/treesitter/highlighter.lua
+++ b/runtime/lua/vim/treesitter/highlighter.lua
@@ -1,5 +1,6 @@
local api = vim.api
local query = vim.treesitter.query
+local Range = require('vim.treesitter._range')
---@alias TSHlIter fun(): integer, TSNode, TSMetadata
@@ -14,6 +15,7 @@ local query = vim.treesitter.query
---@field _highlight_states table<TSTree,TSHighlightState>
---@field _queries table<string,TSHighlighterQuery>
---@field tree LanguageTree
+---@field redraw_count integer
local TSHighlighter = rawget(vim.treesitter, 'TSHighlighter') or {}
TSHighlighter.__index = TSHighlighter
@@ -139,6 +141,7 @@ function TSHighlighter.new(tree, opts)
return self
end
+--- @nodoc
--- Removes all internal references to the highlighter
function TSHighlighter:destroy()
if TSHighlighter.active[self.bufnr] then
@@ -186,7 +189,7 @@ function TSHighlighter:on_detach()
end
---@package
----@param changes Range6[][]
+---@param changes Range6[]
function TSHighlighter:on_changedtree(changes)
for _, ch in ipairs(changes) do
api.nvim__buf_redraw_range(self.bufnr, ch[1], ch[4] + 1)
@@ -245,7 +248,7 @@ local function on_line_impl(self, buf, line, is_spell_nav)
end
local range = vim.treesitter.get_range(node, buf, metadata[capture])
- local start_row, start_col, _, end_row, end_col, _ = unpack(range)
+ local start_row, start_col, end_row, end_col = Range.unpack4(range)
local hl = highlighter_query.hl_cache[capture]
local capture_name = highlighter_query:query().captures[capture]
@@ -310,31 +313,22 @@ function TSHighlighter._on_spell_nav(_, _, buf, srow, _, erow, _)
end
---@private
----@param buf integer
-function TSHighlighter._on_buf(_, buf)
- local self = TSHighlighter.active[buf]
- if self then
- self.tree:parse()
- end
-end
-
----@private
---@param _win integer
---@param buf integer
----@param _topline integer
-function TSHighlighter._on_win(_, _win, buf, _topline)
+---@param topline integer
+---@param botline integer
+function TSHighlighter._on_win(_, _win, buf, topline, botline)
local self = TSHighlighter.active[buf]
if not self then
return false
end
-
+ self.tree:parse({ topline, botline })
self:reset_highlight_state()
self.redraw_count = self.redraw_count + 1
return true
end
api.nvim_set_decoration_provider(ns, {
- on_buf = TSHighlighter._on_buf,
on_win = TSHighlighter._on_win,
on_line = TSHighlighter._on_line,
_on_spell_nav = TSHighlighter._on_spell_nav,
diff --git a/runtime/lua/vim/treesitter/languagetree.lua b/runtime/lua/vim/treesitter/languagetree.lua
index 4b2628609a..b4c9027794 100644
--- a/runtime/lua/vim/treesitter/languagetree.lua
+++ b/runtime/lua/vim/treesitter/languagetree.lua
@@ -18,7 +18,7 @@
--- Whenever you need to access the current syntax tree, parse the buffer:
---
--- <pre>lua
---- local tree = parser:parse()
+--- local tree = parser:parse({ start_row, end_row })
--- </pre>
---
--- This returns a table of immutable |treesitter-tree| objects representing the current state of
@@ -74,6 +74,7 @@ local TSCallbackNames = {
---@field package _callbacks_rec table<TSCallbackName,function[]> Callback handlers (recursive)
---@field private _children table<string,LanguageTree> Injected languages
---@field private _injection_query Query Queries defining injected languages
+---@field private _injections_processed boolean
---@field private _opts table Options
---@field private _parser TSParser Parser for language
---@field private _has_regions boolean
@@ -115,7 +116,9 @@ function LanguageTree.new(source, lang, opts)
end
local injections = opts.injections or {}
- local self = setmetatable({
+
+ --- @type LanguageTree
+ local self = {
_source = source,
_lang = lang,
_children = {},
@@ -123,14 +126,19 @@ function LanguageTree.new(source, lang, opts)
_opts = opts,
_injection_query = injections[lang] and query.parse(lang, injections[lang])
or query.get(lang, 'injections'),
+ _has_regions = false,
+ _injections_processed = false,
_valid = false,
_parser = vim._create_ts_parser(lang),
_callbacks = {},
_callbacks_rec = {},
- }, LanguageTree)
+ }
+
+ setmetatable(self, LanguageTree)
if vim.g.__ts_debug and type(vim.g.__ts_debug) == 'number' then
self:_set_logger()
+ self:_log('START')
end
for _, name in pairs(TSCallbackNames) do
@@ -141,12 +149,14 @@ function LanguageTree.new(source, lang, opts)
return self
end
+--- @private
function LanguageTree:_set_logger()
local source = self:source()
source = type(source) == 'string' and 'text' or tostring(source)
local lang = self:lang()
+ vim.fn.mkdir(vim.fn.stdpath('log'), 'p')
local logfilename = vim.fs.joinpath(vim.fn.stdpath('log'), 'treesitter.log')
local logfile, openerr = io.open(logfilename, 'a+')
@@ -171,7 +181,7 @@ end
---Measure execution time of a function
---@generic R1, R2, R3
---@param f fun(): R1, R2, R2
----@return integer, R1, R2, R3
+---@return number, R1, R2, R3
local function tcall(f, ...)
local start = vim.uv.hrtime()
---@diagnostic disable-next-line
@@ -199,7 +209,8 @@ function LanguageTree:_log(...)
local info = debug.getinfo(2, 'nl')
local nregions = #self:included_regions()
- local prefix = string.format('%s:%d: (#regions=%d) ', info.name, info.currentline, nregions)
+ local prefix =
+ string.format('%s:%d: (#regions=%d) ', info.name or '???', info.currentline or 0, nregions)
local msg = { prefix }
for _, x in ipairs(args) do
@@ -219,7 +230,7 @@ function LanguageTree:invalidate(reload)
-- buffer was reloaded, reparse all trees
if reload then
- for _, t in ipairs(self._trees) do
+ for _, t in pairs(self._trees) do
self:_do_callback('changedtree', t:included_ranges(true), t)
end
self._trees = {}
@@ -250,14 +261,18 @@ function LanguageTree:is_valid(exclude_children)
local valid = self._valid
if type(valid) == 'table' then
- for _, v in ipairs(valid) do
- if not v then
+ for i = 1, #self:included_regions() do
+ if not valid[i] then
return false
end
end
end
if not exclude_children then
+ if not self._injections_processed then
+ return false
+ end
+
for _, child in pairs(self._children) do
if not child:is_valid(exclude_children) then
return false
@@ -265,9 +280,12 @@ function LanguageTree:is_valid(exclude_children)
end
end
- assert(type(valid) == 'boolean')
+ if type(valid) == 'boolean' then
+ return valid
+ end
- return valid
+ self._valid = true
+ return true
end
--- Returns a map of language to child tree.
@@ -280,47 +298,72 @@ function LanguageTree:source()
return self._source
end
---- Parses all defined regions using a treesitter parser
---- for the language this tree represents.
---- This will run the injection query for this language to
---- determine if any child languages should be created.
----
----@return TSTree[]
-function LanguageTree:parse()
- if self:is_valid() then
- self:_log('valid')
- return self._trees
+--- @param region Range6[]
+--- @param range? boolean|Range
+--- @return boolean
+local function intercepts_region(region, range)
+ if #region == 0 then
+ return true
end
- local changes = {}
+ if range == nil then
+ return false
+ end
- -- Collect some stats
- local regions_parsed = 0
+ if type(range) == 'boolean' then
+ return range
+ end
+
+ for _, r in ipairs(region) do
+ if Range.intercepts(r, range) then
+ return true
+ end
+ end
+
+ return false
+end
+
+--- @private
+--- @param range boolean|Range?
+--- @return integer[] changes
+--- @return integer no_regions_parsed
+--- @return number total_parse_time
+function LanguageTree:_parse_regions(range)
+ local changes = {}
+ local no_regions_parsed = 0
local total_parse_time = 0
- --- At least 1 region is invalid
- if not self:is_valid(true) then
- -- If there are no ranges, set to an empty list
- -- so the included ranges in the parser are cleared.
- for i, ranges in ipairs(self:included_regions()) do
- if not self._valid or not self._valid[i] then
- self._parser:set_included_ranges(ranges)
- local parse_time, tree, tree_changes =
- tcall(self._parser.parse, self._parser, self._trees[i], self._source, true)
-
- -- Pass ranges if this is an initial parse
- local cb_changes = self._trees[i] and tree_changes or tree:included_ranges(true)
-
- self:_do_callback('changedtree', cb_changes, tree)
- self._trees[i] = tree
- vim.list_extend(changes, tree_changes)
-
- total_parse_time = total_parse_time + parse_time
- regions_parsed = regions_parsed + 1
- end
+ if type(self._valid) ~= 'table' then
+ self._valid = {}
+ end
+
+ -- If there are no ranges, set to an empty list
+ -- so the included ranges in the parser are cleared.
+ for i, ranges in pairs(self:included_regions()) do
+ if not self._valid[i] and intercepts_region(ranges, range) then
+ self._parser:set_included_ranges(ranges)
+ local parse_time, tree, tree_changes =
+ tcall(self._parser.parse, self._parser, self._trees[i], self._source, true)
+
+ -- Pass ranges if this is an initial parse
+ local cb_changes = self._trees[i] and tree_changes or tree:included_ranges(true)
+
+ self:_do_callback('changedtree', cb_changes, tree)
+ self._trees[i] = tree
+ vim.list_extend(changes, tree_changes)
+
+ total_parse_time = total_parse_time + parse_time
+ no_regions_parsed = no_regions_parsed + 1
+ self._valid[i] = true
end
end
+ return changes, no_regions_parsed, total_parse_time
+end
+
+--- @private
+--- @return number
+function LanguageTree:_add_injections()
local seen_langs = {} ---@type table<string,boolean>
local query_time, injections_by_lang = tcall(self._get_injections, self)
@@ -348,19 +391,60 @@ function LanguageTree:parse()
end
end
+ return query_time
+end
+
+--- Recursively parse all regions in the language tree using |treesitter-parsers|
+--- for the corresponding languages and run injection queries on the parsed trees
+--- to determine whether child trees should be created and parsed.
+---
+--- Any region with empty range (`{}`, typically only the root tree) is always parsed;
+--- otherwise (typically injections) only if it intersects {range} (or if {range} is `true`).
+---
+--- @param range boolean|Range|nil: Parse this range in the parser's source.
+--- Set to `true` to run a complete parse of the source (Note: Can be slow!)
+--- Set to `false|nil` to only parse regions with empty ranges (typically
+--- only the root tree without injections).
+--- @return TSTree[]
+function LanguageTree:parse(range)
+ if self:is_valid() then
+ self:_log('valid')
+ return self._trees
+ end
+
+ local changes --- @type Range6?
+
+ -- Collect some stats
+ local no_regions_parsed = 0
+ local query_time = 0
+ local total_parse_time = 0
+
+ --- At least 1 region is invalid
+ if not self:is_valid(true) then
+ changes, no_regions_parsed, total_parse_time = self:_parse_regions(range)
+ -- Need to run injections when we parsed something
+ if no_regions_parsed > 0 then
+ self._injections_processed = false
+ end
+ end
+
+ if not self._injections_processed and range ~= false and range ~= nil then
+ query_time = self:_add_injections()
+ self._injections_processed = true
+ end
+
self:_log({
- changes = changes,
- regions_parsed = regions_parsed,
+ changes = changes and #changes > 0 and changes or nil,
+ regions_parsed = no_regions_parsed,
parse_time = total_parse_time,
query_time = query_time,
+ range = range,
})
self:for_each_child(function(child)
- child:parse()
+ child:parse(range)
end)
- self._valid = true
-
return self._trees
end
@@ -384,7 +468,7 @@ end
---
---@param fn fun(tree: TSTree, ltree: LanguageTree)
function LanguageTree:for_each_tree(fn)
- for _, tree in ipairs(self._trees) do
+ for _, tree in pairs(self._trees) do
fn(tree, self)
end
@@ -466,18 +550,17 @@ function LanguageTree:_iter_regions(fn)
return
end
- if type(self._valid) ~= 'table' then
+ local was_valid = type(self._valid) ~= 'table'
+
+ if was_valid then
+ self:_log('was valid', self._valid)
self._valid = {}
end
local all_valid = true
for i, region in ipairs(self:included_regions()) do
- if self._valid[i] == nil then
- self._valid[i] = true
- end
-
- if self._valid[i] then
+ if was_valid or self._valid[i] then
self._valid[i] = fn(i, region)
if not self._valid[i] then
self:_log(function()
@@ -521,6 +604,8 @@ function LanguageTree:set_included_regions(new_regions)
for i, range in ipairs(region) do
if type(range) == 'table' and #range == 4 then
region[i] = Range.add_bytes(self._source, range)
+ elseif type(range) == 'userdata' then
+ region[i] = { range:range(true) }
end
end
end
@@ -542,7 +627,7 @@ function LanguageTree:set_included_regions(new_regions)
end
---Gets the set of included regions
----@return integer[][]
+---@return Range6[][]
function LanguageTree:included_regions()
if self._regions then
return self._regions
@@ -581,7 +666,7 @@ local function get_node_ranges(node, source, metadata, include_children)
-- We are excluding children so we need to mask out their ranges
for i = 0, child_count - 1 do
- local child = node:named_child(i)
+ local child = assert(node:named_child(i))
local c_srow, c_scol, c_sbyte, c_erow, c_ecol, c_ebyte = child:range(true)
if c_srow > srow or c_scol > scol then
ranges[#ranges + 1] = { srow, scol, sbyte, c_srow, c_scol, c_sbyte }
@@ -635,6 +720,29 @@ local function add_injection(t, tree_index, pattern, lang, combined, ranges)
table.insert(t[tree_index][lang][pattern].regions, ranges)
end
+-- TODO(clason): replace by refactored `ts.has_parser` API (without registering)
+---@param lang string parser name
+---@return boolean # true if parser for {lang} exists on rtp
+local has_parser = function(lang)
+ return vim._ts_has_language(lang)
+ or #vim.api.nvim_get_runtime_file('parser/' .. lang .. '.*', false) > 0
+end
+
+--- Return parser name for language (if exists) or filetype (if registered and exists)
+---
+---@param alias string language or filetype name
+---@return string? # resolved parser name
+local function resolve_lang(alias)
+ if has_parser(alias) then
+ return alias
+ end
+
+ local lang = vim.treesitter.language.get_lang(alias)
+ if lang and has_parser(lang) then
+ return lang
+ end
+end
+
---@private
--- Extract injections according to:
--- https://tree-sitter.github.io/tree-sitter/syntax-highlighting#language-injection
@@ -649,10 +757,10 @@ function LanguageTree:_get_injection(match, metadata)
for id, node in pairs(match) do
local name = self._injection_query.captures[id]
-
-- Lang should override any other language tag
if name == 'injection.language' then
- lang = vim.treesitter.get_node_text(node, self._source, { metadata = metadata[id] })
+ local text = vim.treesitter.get_node_text(node, self._source, { metadata = metadata[id] })
+ lang = resolve_lang(text) or resolve_lang(text:lower())
elseif name == 'injection.content' then
ranges = get_node_ranges(node, self._source, metadata[id], include_children)
end
@@ -726,8 +834,8 @@ end
---
--- TODO: Allow for an offset predicate to tailor the injection range
--- instead of using the entire nodes range.
----@private
----@return table<string, Range6[][]>
+--- @private
+--- @return table<string, Range6[][]>
function LanguageTree:_get_injections()
if not self._injection_query then
return {}
@@ -736,7 +844,7 @@ function LanguageTree:_get_injections()
---@type table<integer,TSInjection>
local injections = {}
- for tree_index, tree in ipairs(self._trees) do
+ for index, tree in pairs(self._trees) do
local root_node = tree:root()
local start_line, _, end_line, _ = root_node:range()
@@ -748,7 +856,7 @@ function LanguageTree:_get_injections()
-- TODO(lewis6991): remove after 0.9 (#20434)
lang, combined, ranges = self:_get_injection_deprecated(match, metadata)
end
- add_injection(injections, tree_index, pattern, lang, combined, ranges)
+ add_injection(injections, index, pattern, lang, combined, ranges)
end
end
@@ -771,7 +879,7 @@ function LanguageTree:_get_injections()
end, entry.regions)
table.insert(result[lang], regions)
else
- for _, ranges in ipairs(entry.regions) do
+ for _, ranges in pairs(entry.regions) do
table.insert(result[lang], ranges)
end
end
@@ -805,7 +913,7 @@ function LanguageTree:_edit(
end_row_new,
end_col_new
)
- for _, tree in ipairs(self._trees) do
+ for _, tree in pairs(self._trees) do
tree:edit(
start_byte,
end_byte_old,
diff --git a/runtime/lua/vim/treesitter/query.lua b/runtime/lua/vim/treesitter/query.lua
index 3b7e74c0cf..3093657313 100644
--- a/runtime/lua/vim/treesitter/query.lua
+++ b/runtime/lua/vim/treesitter/query.lua
@@ -435,6 +435,7 @@ predicate_handlers['vim-match?'] = predicate_handlers['match?']
---@class TSMetadata
---@field range? Range
+---@field conceal? string
---@field [integer] TSMetadata
---@field [string] integer|string
@@ -541,33 +542,6 @@ local directive_handlers = {
metadata.range = { start_row, start_col, end_row, end_col }
end
end,
- -- Set injection language from node text, interpreted first as language and then as filetype
- -- Example: (#inject-language! @_lang)
- ['inject-language!'] = function(match, _, bufnr, pred, metadata)
- local id = pred[2]
- local node = match[id]
- if not node then
- return
- end
-
- -- TODO(clason): replace by refactored `ts.has_parser` API
- local has_parser = function(lang)
- return vim._ts_has_language(lang)
- or #vim.api.nvim_get_runtime_file('parser/' .. lang .. '.*', false) > 0
- end
-
- local alias = vim.treesitter.get_node_text(node, bufnr, { metadata = metadata[id] })
- if not alias then
- return
- elseif has_parser(alias) then
- metadata['injection.language'] = alias
- else
- local lang = vim.treesitter.language.get_lang(alias)
- if lang and has_parser(lang) then
- metadata['injection.language'] = lang
- end
- end
- end,
}
--- Adds a new predicate to be used in queries