mirror of
https://github.com/nvim-treesitter/nvim-treesitter.git
synced 2026-07-01 19:17:02 -04:00
Add strip! directive for queries
The strip! directive is implemented in the tree-sitter tags crate in
the main tree-sitter repo
(de53b82e2c/tags/src/lib.rs (L167)).
It is used specifically for tag extraction to shrink the range of a node
(or better the text of a node).
For our textobjects queries the strip! directive might be use full since
it allows us to strip aways whitespaces and leading/trailing characters.
This commit is contained in:
parent
63c1853674
commit
77fc8cd9e7
1 changed files with 84 additions and 0 deletions
|
|
@ -1,5 +1,6 @@
|
|||
local api = vim.api
|
||||
local ts = vim.treesitter
|
||||
local utils = require 'nvim-treesitter.utils'
|
||||
|
||||
local M = {}
|
||||
|
||||
|
|
@ -71,6 +72,56 @@ function M.get_query(lang, query_name)
|
|||
end
|
||||
end
|
||||
|
||||
--This function is copied from Neovims treesitter.lua to enforece same behavior
|
||||
local magic_prefixes = {['\\v']=true, ['\\m']=true, ['\\M']=true, ['\\V']=true}
|
||||
local function check_magic(str)
|
||||
if string.len(str) < 2 or magic_prefixes[string.sub(str,1,2)] then
|
||||
return str
|
||||
end
|
||||
return '\\v'..str
|
||||
end
|
||||
|
||||
local function strip_beginning(lines, regex)
|
||||
local current_col = 0
|
||||
local current_line = 0
|
||||
local re = vim.regex(check_magic('^('..regex..')'))
|
||||
for linenr, line in ipairs(lines) do
|
||||
current_line = linenr
|
||||
local match_start, match_end = re:match_str(line)
|
||||
if match_start ~= 0 then
|
||||
break
|
||||
else
|
||||
current_col = match_end
|
||||
end
|
||||
if match_end ~= vim.str_byteindex(line, #line) then
|
||||
break
|
||||
end
|
||||
current_line = current_line + 1
|
||||
end
|
||||
return current_line - 1, current_col
|
||||
end
|
||||
|
||||
local function strip_end(lines, regex)
|
||||
local current_col = 0
|
||||
local line_diff = 0
|
||||
local re = vim.regex(check_magic('('..regex..')$'))
|
||||
for linenr=#lines, 1, -1 do
|
||||
local line = lines[linenr]
|
||||
line_diff = #lines - linenr
|
||||
local match_start, match_end = re:match_str(line)
|
||||
if match_end ~= vim.str_byteindex(line, #line) then
|
||||
break
|
||||
else
|
||||
current_col = match_start
|
||||
end
|
||||
if match_start ~= 0 then
|
||||
break
|
||||
end
|
||||
line_diff = line_diff + 1
|
||||
end
|
||||
return line_diff, current_col
|
||||
end
|
||||
|
||||
function M.iter_prepared_matches(query, qnode, bufnr, start_row, end_row)
|
||||
-- A function that splits a string on '.'
|
||||
local function split(string)
|
||||
|
|
@ -120,6 +171,39 @@ function M.iter_prepared_matches(query, qnode, bufnr, start_row, end_row)
|
|||
if pred[1] == "set!" and type(pred[2]) == "string" then
|
||||
insert_to_path(prepared_match, split(pred[2]), pred[3])
|
||||
end
|
||||
if pred[1] == "strip!" and #pred == 3 then
|
||||
local query_name = query.captures[pred[2]]
|
||||
local regex = pred[3]
|
||||
|
||||
local node = utils.get_at_path(prepared_match, query_name..'.node')
|
||||
local ts_utils = require 'nvim-treesitter.ts_utils'
|
||||
local node_lines = ts_utils.get_node_text(node, bufnr)
|
||||
local start_line, start_col, end_line, end_col = node:range()
|
||||
|
||||
local strip_line, strip_col = strip_beginning(node_lines, regex)
|
||||
start_line = start_line + strip_line
|
||||
if strip_line == 0 then
|
||||
start_col = start_col + strip_col
|
||||
else
|
||||
start_col =strip_col
|
||||
end
|
||||
local strip_line, strip_col = strip_end(node_lines, regex)
|
||||
end_line = end_line - strip_line
|
||||
if strip_line == 0 then
|
||||
end_col = end_col - strip_col
|
||||
else
|
||||
end_col = strip_col
|
||||
end
|
||||
|
||||
end_line = math.max(end_line, start_line)
|
||||
if end_line == start_line then
|
||||
end_col = math.max(end_col, start_col)
|
||||
end
|
||||
|
||||
insert_to_path(prepared_match,
|
||||
split(query_name..'.processed_range'),
|
||||
{start_line, start_col, end_line, end_col})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue