From b480d25155d69d53fb4aaaacdfdfef410ea8ddc9 Mon Sep 17 00:00:00 2001 From: Stephan Seitz Date: Wed, 15 Jul 2020 19:32:41 +0200 Subject: feat(textobjects): Add `start` to include preceding things like documentation --- lua/nvim-treesitter/locals.lua | 2 +- lua/nvim-treesitter/textobjects.lua | 27 +++++++++++++++++++++++---- lua/nvim-treesitter/ts_utils.lua | 7 ++++++- 3 files changed, 30 insertions(+), 6 deletions(-) (limited to 'lua') 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('$') -- cgit v1.2.3-70-g09d2