feat(treesitter): allow capture text to be transformed

Co-authored-by: Lewis Russell <lewis6991@gmail.com>
This commit is contained in:
figsoda 2022-07-21 12:08:37 +01:00
parent 5c4b503d3c
commit bb8845340b
4 changed files with 28 additions and 2 deletions

View File

@ -151,6 +151,9 @@ The following new APIs or features were added.
• |:highlight| now supports an additional attribute "altfont".
• Treesitter captures can now be transformed by directives. This will allow
more complicated dynamic language injections.
==============================================================================
CHANGED FEATURES *news-changes*

View File

@ -354,6 +354,14 @@ local function get_range_from_metadata(node, id, metadata)
return { node:range() }
end
---@private
local function get_node_text(node, id, metadata, source)
if metadata[id] and metadata[id].text then
return metadata[id].text
end
return query.get_node_text(node, source)
end
--- Gets language injection points by language.
---
--- This is where most of the injection processing occurs.
@ -408,7 +416,7 @@ function LanguageTree:_get_injections()
-- Lang should override any other language tag
if name == 'language' and not lang then
lang = query.get_node_text(node, self._source) --[[@as string]]
lang = get_node_text(node, id, metadata, self._source) --[[@as string]]
elseif name == 'combined' then
combined = true
elseif name == 'content' and #ranges == 0 then

View File

@ -452,6 +452,21 @@ local directive_handlers = {
metadata[capture_id].range = range
end
end,
-- Transform the content of the node
-- Example: (#gsub! @_node ".*%.(.*)" "%1")
['gsub!'] = function(match, _, bufnr, pred, metadata)
assert(#pred == 4)
local id = pred[2]
local node = match[id]
local text = M.get_node_text(node, bufnr, { metadata = metadata[id] }) or ''
if not metadata[id] then
metadata[id] = {}
end
metadata[id].text = text:gsub(pred[3], pred[4])
end,
}
--- Adds a new predicate to be used in queries

View File

@ -728,7 +728,7 @@ int x = INT_MAX;
return list
]]
eq({ 'offset!', 'set!' }, res_list)
eq({ 'gsub!', 'offset!', 'set!' }, res_list)
end)
end)
end)