feat(ts): add support for multiline nodes in get_node_text (#14999)

Based on https://github.com/neovim/neovim/pull/14445

This extends `vim.treesitter.query.get_node_text` to return the text
that spans a node's range even if start_row ~= end_row.
This commit is contained in:
Mathias Fußenegger
2021-12-12 12:05:39 +01:00
committed by GitHub
parent 3aff3d6349
commit 1f3c0593eb
2 changed files with 55 additions and 10 deletions

View File

@@ -164,8 +164,6 @@ function M.parse_query(lang, query)
return self
end
-- TODO(vigoux): support multiline nodes too
--- Gets the text corresponding to a given node
---
---@param node the node
@@ -175,11 +173,26 @@ function M.get_node_text(node, source)
local end_row, end_col, end_byte = node:end_()
if type(source) == "number" then
if start_row ~= end_row then
local lines
local eof_row = vim.api.nvim_buf_line_count(source)
if start_row >= eof_row then
return nil
end
local line = a.nvim_buf_get_lines(source, start_row, start_row+1, true)[1]
return string.sub(line, start_col+1, end_col)
if end_col == 0 then
lines = a.nvim_buf_get_lines(source, start_row, end_row, true)
end_col = #lines[#lines]
else
lines = a.nvim_buf_get_lines(source, start_row, end_row + 1, true)
end
lines[1] = string.sub(lines[1], start_col + 1)
local end_index = end_col
if #lines == 1 then
end_index = end_col - start_col
end
lines[#lines] = string.sub(lines[#lines], 1, end_index)
return table.concat(lines, "\n")
elseif type(source) == "string" then
return source:sub(start_byte+1, end_byte)
end
@@ -211,11 +224,6 @@ local predicate_handlers = {
["lua-match?"] = function(match, _, source, predicate)
local node = match[predicate[2]]
local regex = predicate[3]
local start_row, _, end_row, _ = node:range()
if start_row ~= end_row then
return false
end
return string.find(M.get_node_text(node, source), regex)
end,