mirror of
https://github.com/nvim-treesitter/nvim-treesitter.git
synced 2026-07-14 01:10:02 -04:00
chore(textobject): use query.find_best_match to find next/previous textobject
This commit is contained in:
parent
e629efafd8
commit
f6681c230f
2 changed files with 60 additions and 40 deletions
|
|
@ -212,6 +212,36 @@ function M.get_capture_matches(bufnr, capture_string, query_group)
|
||||||
return matches
|
return matches
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function M.find_best_match(bufnr, capture_string, query_group, filter_predicate, scoring_function)
|
||||||
|
if not string.sub(capture_string, 1,2) == '@' then
|
||||||
|
api.nvim_err_writeln('capture_string must start with "@"')
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
--remove leading "@"
|
||||||
|
capture_string = string.sub(capture_string, 2)
|
||||||
|
|
||||||
|
local best
|
||||||
|
local best_score
|
||||||
|
|
||||||
|
for maybe_match in M.iter_group_results(bufnr, query_group) do
|
||||||
|
local match = utils.get_at_path(maybe_match, capture_string)
|
||||||
|
|
||||||
|
if match and filter_predicate(match) then
|
||||||
|
local current_score = scoring_function(match)
|
||||||
|
if not best then
|
||||||
|
best = match
|
||||||
|
best_score = current_score
|
||||||
|
end
|
||||||
|
if current_score > best_score then
|
||||||
|
best = match
|
||||||
|
best_score = current_score
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return best
|
||||||
|
end
|
||||||
|
|
||||||
-- Iterates matches from a query file.
|
-- Iterates matches from a query file.
|
||||||
-- @param bufnr the buffer
|
-- @param bufnr the buffer
|
||||||
-- @param query_group the query file to use
|
-- @param query_group the query file to use
|
||||||
|
|
|
||||||
|
|
@ -145,56 +145,46 @@ end
|
||||||
|
|
||||||
function M.next_textobject(node, query_string, same_parent, bufnr)
|
function M.next_textobject(node, query_string, same_parent, bufnr)
|
||||||
local node = node or ts_utils.get_node_at_cursor()
|
local node = node or ts_utils.get_node_at_cursor()
|
||||||
|
if not node then return end
|
||||||
|
local _, _, node_end = node:end_()
|
||||||
local bufnr = bufnr or api.nvim_get_current_buf()
|
local bufnr = bufnr or api.nvim_get_current_buf()
|
||||||
|
|
||||||
local matches = queries.get_capture_matches(bufnr, query_string, 'textobjects')
|
local next_node = queries.find_best_match(bufnr,
|
||||||
local _, _ , node_end = node:end_()
|
query_string,
|
||||||
local next_node
|
'textobjects',
|
||||||
local next_node_start
|
function(match)
|
||||||
|
if not same_parent or node:parent() == match.node:parent() then
|
||||||
for _, m in pairs(matches) do
|
local _, _, start = match.node:start()
|
||||||
local _, _, other_end = m.node:start()
|
return start > node_end
|
||||||
if other_end > node_end then
|
end
|
||||||
if not same_parent or node:parent() == m.node:parent() then
|
end,
|
||||||
if not next_node then
|
function(match)
|
||||||
next_node = m
|
local _, _, node_start = match.node:start()
|
||||||
_, _, next_node_start = next_node.node:start()
|
return -node_start
|
||||||
end
|
end)
|
||||||
if other_end < next_node_start then
|
|
||||||
next_node = m
|
|
||||||
_, _, next_node_start = next_node.node:start()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return next_node and next_node.node
|
return next_node and next_node.node
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.previous_textobject(node, query_string, same_parent, bufnr)
|
function M.previous_textobject(node, query_string, same_parent, bufnr)
|
||||||
local node = node or ts_utils.get_node_at_cursor()
|
local node = node or ts_utils.get_node_at_cursor()
|
||||||
|
if not node then return end
|
||||||
|
local _, _, node_start = node:start()
|
||||||
local bufnr = bufnr or api.nvim_get_current_buf()
|
local bufnr = bufnr or api.nvim_get_current_buf()
|
||||||
|
|
||||||
local matches = queries.get_capture_matches(bufnr, query_string, 'textobjects')
|
local previous_node = queries.find_best_match(bufnr,
|
||||||
local _, _ , node_start = node:start()
|
query_string,
|
||||||
local previous_node
|
'textobjects',
|
||||||
local previous_node_end
|
function(match)
|
||||||
|
if not same_parent or node:parent() == match.node:parent() then
|
||||||
for _, m in pairs(matches) do
|
local _, _, end_ = match.node:end_()
|
||||||
local _, _, other_end = m.node:end_()
|
return end_ < node_start
|
||||||
if other_end < node_start then
|
end
|
||||||
if not same_parent or node:parent() == m.node:parent() then
|
end,
|
||||||
if not previous_node then
|
function(match)
|
||||||
previous_node = m
|
local _, _, node_end = match.node:end_()
|
||||||
_, _, previous_node_end = previous_node.node:end_()
|
return node_end
|
||||||
end
|
end)
|
||||||
if other_end > previous_node_end then
|
|
||||||
previous_node = m
|
|
||||||
_, _, previous_node_end = previous_node.node:end_()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return previous_node and previous_node.node
|
return previous_node and previous_node.node
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue