aboutsummaryrefslogtreecommitdiffstats
path: root/lua
diff options
context:
space:
mode:
authorSantos Gallegos <stsewd@protonmail.com>2020-09-05 19:06:09 -0500
committerThomas Vigouroux <tomvig38@gmail.com>2020-09-07 18:24:55 +0200
commit9c456edb3ad24be92a54b42545df8f0d0ee4c71b (patch)
treeeb49ea2ff33a236758f14328683e326702720dff /lua
parentFold: respect max_fold_level from 'foldnestmax' (diff)
downloadnvim-treesitter-9c456edb3ad24be92a54b42545df8f0d0ee4c71b.tar
nvim-treesitter-9c456edb3ad24be92a54b42545df8f0d0ee4c71b.tar.gz
nvim-treesitter-9c456edb3ad24be92a54b42545df8f0d0ee4c71b.tar.bz2
nvim-treesitter-9c456edb3ad24be92a54b42545df8f0d0ee4c71b.tar.lz
nvim-treesitter-9c456edb3ad24be92a54b42545df8f0d0ee4c71b.tar.xz
nvim-treesitter-9c456edb3ad24be92a54b42545df8f0d0ee4c71b.tar.zst
nvim-treesitter-9c456edb3ad24be92a54b42545df8f0d0ee4c71b.zip
Incremental selection: fix skipping some nodes
The range from ts nodes are a little different than neovim's nodes. They start at 0 and the end is exclusive. For example, a nvim range (1, 3, 2, 4) is the equivalent to the ts range (0, 2, 1, 4). Since we may hit parent nodes that have the same range as its child, we skip those till we find one that actually changes the selection (since this is the relevant part for the user). Fixes https://github.com/nvim-treesitter/nvim-treesitter/issues/232
Diffstat (limited to 'lua')
-rw-r--r--lua/nvim-treesitter/incremental_selection.lua53
1 files changed, 28 insertions, 25 deletions
diff --git a/lua/nvim-treesitter/incremental_selection.lua b/lua/nvim-treesitter/incremental_selection.lua
index d716584fe..e40cc13cc 100644
--- a/lua/nvim-treesitter/incremental_selection.lua
+++ b/lua/nvim-treesitter/incremental_selection.lua
@@ -16,25 +16,16 @@ function M.init_selection()
ts_utils.update_selection(buf, node)
end
--- moves 0-based node position by one character
-local function inclusive_pos_to_exclusive(row, col)
- local line = vim.fn.getline(row + 1)
-
- -- move by one character changes row?
- if #line == col + 1 then
- return row + 1, 0
- else
- return row, col + 1
- end
-end
-
+--- Get a ts compatible range of the current visual selection.
+--
+-- The range of ts nodes start with 0 and the ending range is exclusive.
local function visual_selection_range()
local _, csrow, cscol, _ = unpack(vim.fn.getpos("'<"))
local _, cerow, cecol, _ = unpack(vim.fn.getpos("'>"))
- if csrow < cerow or (csrow == cerow and cscol <= cecol) then
- return csrow-1, cscol-1, inclusive_pos_to_exclusive(cerow-1, cecol-1)
+ if csrow < cerow or (csrow == cerow and cscol <= cecol) then
+ return csrow - 1, cscol - 1, cerow - 1, cecol
else
- return cerow-1, cecol-1, inclusive_pos_to_exclusive(csrow-1, cscol-1)
+ return cerow - 1, cecol - 1, csrow - 1, cscol
end
end
@@ -49,9 +40,9 @@ local function select_incremental(get_parent)
local buf = api.nvim_get_current_buf()
local nodes = selections[buf]
- -- initialize incremental selection with current selection
+ local csrow, cscol, cerow, cecol = visual_selection_range()
+ -- Initialize incremental selection with current selection
if not nodes or #nodes == 0 or not range_matches(nodes[#nodes]) then
- local csrow, cscol, cerow, cecol = visual_selection_range()
local root = parsers.get_parser().tree:root()
local node = root:named_descendant_for_range(csrow, cscol, cerow, cecol)
ts_utils.update_selection(buf, node)
@@ -63,15 +54,27 @@ local function select_incremental(get_parent)
return
end
- local node = get_parent(nodes[#nodes])
- if not node then return end
-
- table.insert(selections[buf], node)
- if node ~= nodes[#nodes] then
- table.insert(nodes, node)
+ -- Find a node that changes the current selection.
+ local node = nodes[#nodes]
+ while true do
+ node = get_parent(node)
+ if not node then return end
+ local srow, scol, erow, ecol = node:range()
+ local same_range = (
+ srow == csrow
+ and scol == cscol
+ and erow == cerow
+ and ecol == cecol
+ )
+ if not same_range then
+ table.insert(selections[buf], node)
+ if node ~= nodes[#nodes] then
+ table.insert(nodes, node)
+ end
+ ts_utils.update_selection(buf, node)
+ return
+ end
end
-
- ts_utils.update_selection(buf, node)
end
end