mirror of
https://github.com/nvim-treesitter/nvim-treesitter.git
synced 2026-07-11 16:00:02 -04:00
Textobjects: Allow nested textobjects on goto_adjacent
This commit is contained in:
parent
f6681c230f
commit
be2cfc1bca
1 changed files with 37 additions and 25 deletions
|
|
@ -84,15 +84,17 @@ local function swap_textobject(query_string, direction)
|
||||||
local bufnr, textobject_range, node = textobject_at_point(query_string)
|
local bufnr, textobject_range, node = textobject_at_point(query_string)
|
||||||
local step = direction > 0 and 1 or -1
|
local step = direction > 0 and 1 or -1
|
||||||
if not node then return end
|
if not node then return end
|
||||||
|
local overlapping_range_ok = false
|
||||||
|
local same_parent = true
|
||||||
for _ = 1, math.abs(direction), step do
|
for _ = 1, math.abs(direction), step do
|
||||||
if direction > 0 then
|
if direction > 0 then
|
||||||
ts_utils.swap_nodes(textobject_range,
|
ts_utils.swap_nodes(textobject_range,
|
||||||
M.next_textobject(node, query_string, true, bufnr),
|
M.next_textobject(node, query_string, same_parent, overlapping_range_ok, bufnr),
|
||||||
bufnr,
|
bufnr,
|
||||||
"yes, set cursor!")
|
"yes, set cursor!")
|
||||||
else
|
else
|
||||||
ts_utils.swap_nodes(textobject_range,
|
ts_utils.swap_nodes(textobject_range,
|
||||||
M.previous_textobject(node, query_string, true, bufnr),
|
M.previous_textobject(node, query_string, same_parent, overlapping_range_ok, bufnr),
|
||||||
bufnr,
|
bufnr,
|
||||||
"yes, set cursor!")
|
"yes, set cursor!")
|
||||||
end
|
end
|
||||||
|
|
@ -107,13 +109,13 @@ function M.swap_previous(query_string)
|
||||||
swap_textobject(query_string, -1)
|
swap_textobject(query_string, -1)
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.goto_adjacent(query_string, forward, start, same_parent)
|
function M.goto_adjacent(query_string, forward, start, same_parent, overlapping_range_ok)
|
||||||
local bufnr, _, node = textobject_at_point(query_string)
|
local bufnr, _, node = textobject_at_point(query_string)
|
||||||
local adjacent_textobject
|
local adjacent_textobject
|
||||||
if forward then
|
if forward then
|
||||||
adjacent_textobject = M.next_textobject(node, query_string, same_parent, bufnr)
|
adjacent_textobject = M.next_textobject(node, query_string, same_parent, overlapping_range_ok, bufnr)
|
||||||
else
|
else
|
||||||
adjacent_textobject = M.previous_textobject(node, query_string, same_parent, bufnr)
|
adjacent_textobject = M.previous_textobject(node, query_string, same_parent, overlapping_range_ok, bufnr)
|
||||||
end
|
end
|
||||||
|
|
||||||
if adjacent_textobject then
|
if adjacent_textobject then
|
||||||
|
|
@ -129,33 +131,35 @@ function M.goto_adjacent(query_string, forward, start, same_parent)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- luacheck: push ignore 631
|
-- luacheck: push ignore 631
|
||||||
M.goto_next_start = function(query_string) M.goto_adjacent(query_string, 'forward', 'start', false) end
|
M.goto_next_start = function(query_string) M.goto_adjacent(query_string, 'forward', 'start', not 'same_parent', 'overlap ok') end
|
||||||
M.goto_next_end = function(query_string) M.goto_adjacent(query_string, 'forward', false, false) end
|
M.goto_next_end = function(query_string) M.goto_adjacent(query_string, 'forward', not 'start', not 'same_parent', 'overlap ok') end
|
||||||
M.goto_previous_start = function(query_string) M.goto_adjacent(query_string, false, 'start', false) end
|
M.goto_previous_start = function(query_string) M.goto_adjacent(query_string, not 'forward', 'start', not 'same_parent', 'overlap ok') end
|
||||||
M.goto_previous_end = function(query_string) M.goto_adjacent(query_string, false, false, false) end
|
M.goto_previous_end = function(query_string) M.goto_adjacent(query_string, not 'forward', not 'start', not 'same_parent', 'overlap ok') end
|
||||||
-- luacheck: pop
|
-- luacheck: pop
|
||||||
|
|
||||||
function M.goto_next_end(query_string)
|
function M.next_textobject(node, query_string, same_parent, overlapping_range_ok, bufnr)
|
||||||
local bufnr, _, node = textobject_at_point(query_string)
|
|
||||||
if not node then return end
|
|
||||||
local next_textobject = M.next_textobject(node, query_string, false, bufnr)
|
|
||||||
local next_textobject_range = next_textobject:range()
|
|
||||||
api.nvim_win_set_cursor(api.nvim_get_current_win(), { next_textobject_range[3] + 1, next_textobject_range[4] + 1 })
|
|
||||||
end
|
|
||||||
|
|
||||||
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()
|
||||||
|
if not node then return end
|
||||||
|
|
||||||
|
local _, _, node_end = node:end_()
|
||||||
|
local search_start, _
|
||||||
|
if overlapping_range_ok then
|
||||||
|
_, _, search_start = node:start()
|
||||||
|
search_start = search_start - 1
|
||||||
|
else
|
||||||
|
_, _, search_start = node:end_()
|
||||||
|
end
|
||||||
|
|
||||||
local next_node = queries.find_best_match(bufnr,
|
local next_node = queries.find_best_match(bufnr,
|
||||||
query_string,
|
query_string,
|
||||||
'textobjects',
|
'textobjects',
|
||||||
function(match)
|
function(match)
|
||||||
|
if match.node == node then return end
|
||||||
if not same_parent or node:parent() == match.node:parent() then
|
if not same_parent or node:parent() == match.node:parent() then
|
||||||
local _, _, start = match.node:start()
|
local _, _, start = match.node:start()
|
||||||
return start > node_end
|
local _, _, end_ = match.node:end_()
|
||||||
|
return start > search_start and end_ > node_end
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
function(match)
|
function(match)
|
||||||
|
|
@ -166,19 +170,27 @@ function M.next_textobject(node, query_string, same_parent, bufnr)
|
||||||
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, overlapping_range_ok, 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()
|
||||||
|
if not node then return end
|
||||||
|
|
||||||
|
local _, _, node_start = node:start()
|
||||||
|
local search_end, _
|
||||||
|
if overlapping_range_ok then
|
||||||
|
_, _, search_end = node:end_()
|
||||||
|
search_end = search_end + 1
|
||||||
|
else
|
||||||
|
_, _, search_end = node:start()
|
||||||
|
end
|
||||||
local previous_node = queries.find_best_match(bufnr,
|
local previous_node = queries.find_best_match(bufnr,
|
||||||
query_string,
|
query_string,
|
||||||
'textobjects',
|
'textobjects',
|
||||||
function(match)
|
function(match)
|
||||||
if not same_parent or node:parent() == match.node:parent() then
|
if not same_parent or node:parent() == match.node:parent() then
|
||||||
local _, _, end_ = match.node:end_()
|
local _, _, end_ = match.node:end_()
|
||||||
return end_ < node_start
|
local _, _, start = match.node:start()
|
||||||
|
return end_ < search_end and start < node_start
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
function(match)
|
function(match)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue