aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lua/nvim-treesitter/locals.lua2
-rw-r--r--lua/nvim-treesitter/textobjects.lua27
-rw-r--r--lua/nvim-treesitter/ts_utils.lua7
-rw-r--r--queries/cpp/textobjects.scm9
4 files changed, 39 insertions, 6 deletions
diff --git a/lua/nvim-treesitter/locals.lua b/lua/nvim-treesitter/locals.lua
index 93bcd90fd..c092a0739 100644
--- a/lua/nvim-treesitter/locals.lua
+++ b/lua/nvim-treesitter/locals.lua
@@ -126,7 +126,7 @@ function M.get_capture_matches(bufnr, capture_string, query_kind)
local matches = {}
for _, match in pairs(M.get_locals(bufnr, query_kind)) do
- local insert = utils.get_at_path(match, capture_string..'.node')
+ local insert = utils.get_at_path(match, capture_string)
if insert then
table.insert(matches, insert)
diff --git a/lua/nvim-treesitter/textobjects.lua b/lua/nvim-treesitter/textobjects.lua
index 4d8bb7cd1..51acca165 100644
--- a/lua/nvim-treesitter/textobjects.lua
+++ b/lua/nvim-treesitter/textobjects.lua
@@ -31,7 +31,7 @@ function M.select_textobject(query_string)
for m in queries.iter_prepared_matches(query, root, bufnr, start_row, end_row) do
for _, n in pairs(m) do
if n.node then
- table.insert(matches, n.node)
+ table.insert(matches, n)
end
end
end
@@ -39,19 +39,38 @@ function M.select_textobject(query_string)
local match_length
local smallest_range
+ local earliest_start
for _, m in pairs(matches) do
- if ts_utils.is_in_node_range(m, row, col) then
- local length = ts_utils.node_length(m)
+ if ts_utils.is_in_node_range(m.node, row, col) then
+ local length = ts_utils.node_length(m.node)
if not match_length or length < match_length then
smallest_range = m
match_length = length
end
+ -- for nodes with same length take the one with earliest start
+ if match_length and length == smallest_range then
+ local start = m.start
+ if start then
+ local _, _, start_byte = m.start.node:start()
+ if not earliest_start or start_byte < earliest_start then
+ smallest_range = m
+ match_length = length
+ earliest_start = start_byte
+ end
+ end
+ end
end
end
if smallest_range then
- ts_utils.update_selection(bufnr, smallest_range)
+ if smallest_range.start then
+ local start_range = {smallest_range.start.node:range()}
+ local node_range = {smallest_range.node:range()}
+ ts_utils.update_selection(bufnr, {start_range[1], start_range[2], node_range[3], node_range[4]})
+ else
+ ts_utils.update_selection(bufnr, smallest_range.node)
+ end
end
end
diff --git a/lua/nvim-treesitter/ts_utils.lua b/lua/nvim-treesitter/ts_utils.lua
index f9c3de104..ebeb12354 100644
--- a/lua/nvim-treesitter/ts_utils.lua
+++ b/lua/nvim-treesitter/ts_utils.lua
@@ -325,7 +325,12 @@ end
-- Set visual selection to node
function M.update_selection(buf, node)
- local start_row, start_col, end_row, end_col = node:range()
+ local start_row, start_col, end_row, end_col
+ if type(node) == 'table' then
+ start_row, start_col, end_row, end_col = unpack(node)
+ else
+ start_row, start_col, end_row, end_col = node:range()
+ end
if end_row == vim.fn.line('$') then
end_col = #vim.fn.getline('$')
diff --git a/queries/cpp/textobjects.scm b/queries/cpp/textobjects.scm
index 2a808047a..ed26fcf31 100644
--- a/queries/cpp/textobjects.scm
+++ b/queries/cpp/textobjects.scm
@@ -4,3 +4,12 @@
(for_range_loop
(_)? @loop.inner) @loop.outer
+
+(template_declaration
+ (function_definition) @function.outer) @function.outer.start
+
+(template_declaration
+ (struct_specifier) @class.outer) @class.outer.start
+
+(template_declaration
+ (class_specifier) @class.outer) @class.outer.start