Skip to content

Commit

Permalink
fix: use selection_range for navigation (#132)
Browse files Browse the repository at this point in the history
  • Loading branch information
stevearc committed Aug 9, 2022
1 parent 061981e commit 0a8c2c5
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 27 deletions.
8 changes: 5 additions & 3 deletions lua/aerial/navigation.lua
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ M.select = function(opts)
opts.index = opts.index or 1
end

local item = data[0]:item(opts.index)
local item = data:get_or_create(0):item(opts.index)
if not item then
error(string.format("Symbol %s is outside the bounds", opts.index))
return
Expand All @@ -206,7 +206,9 @@ M.select = function(opts)
end
local bufnr, _ = util.get_buffers()
vim.api.nvim_win_set_buf(winid, bufnr)
vim.api.nvim_win_set_cursor(winid, { item.lnum, item.col })
local lnum = item.selection_range and item.selection_range.lnum or item.lnum
local col = item.selection_range and item.selection_range.col or item.col
vim.api.nvim_win_set_cursor(winid, { lnum, col })
local cmd = config.post_jump_cmd
if cmd and cmd ~= "" then
vim.fn.win_execute(winid, cmd, true)
Expand All @@ -221,7 +223,7 @@ M.select = function(opts)
window.update_position(winid)
end
if config.highlight_on_jump then
util.flash_highlight(bufnr, item.lnum, config.highlight_on_jump)
util.flash_highlight(bufnr, lnum, config.highlight_on_jump)
end
end

Expand Down
60 changes: 36 additions & 24 deletions lua/aerial/window.lua
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,28 @@ M.get_position_in_win = function(bufnr, winid)
return M.get_symbol_position(bufdata, lnum, col)
end

---Returns -1 if item is before position, 0 if equal, 1 if after
---@param range aerial.Range
---@param lnum integer
---@param col integer
---@return integer
---@return boolean True when position is fully inside the range
local function compare(range, lnum, col)
if range.lnum > lnum then
return 1, false
elseif range.lnum == lnum then
if range.col > col then
return 1, false
elseif range.col == col then
return 0, true
else
return -1, range.end_lnum > lnum or (range.end_lnum == lnum and range.end_col >= col)
end
else
return -1, range.end_lnum > lnum or (range.end_lnum == lnum and range.end_col >= col)
end
end

---@class aerial.CursorPosition
---@field lnum integer
---@field closest_symbol aerial.Symbol
Expand All @@ -298,21 +320,23 @@ M.get_symbol_position = function(bufdata, lnum, col)
local selected = 0
local relative = "above"
local prev = nil
local exact_symbol
local symbol = bufdata:visit(function(item)
if item.lnum > lnum then
return prev or item
elseif item.lnum == lnum then
if item.col > col then
return prev or item
elseif item.col == col then
selected = selected + 1
relative = "exact"
return item
else
relative = "below"
local cmp, inside = compare(item, lnum, col)
if inside then
exact_symbol = item
if item.selection_range then
cmp = compare(item.selection_range, lnum, col)
end
else
end
if cmp < 0 then
relative = "below"
elseif cmp == 0 then
selected = selected + 1
relative = "exact"
return item
else
return prev or item
end
prev = item
selected = selected + 1
Expand All @@ -321,18 +345,6 @@ M.get_symbol_position = function(bufdata, lnum, col)
if symbol == nil then
symbol = prev
end
local exact_symbol = symbol
while
exact_symbol
and (
exact_symbol.lnum > lnum
or exact_symbol.end_lnum < lnum
or (exact_symbol.lnum == lnum and exact_symbol.col > col)
or (exact_symbol.end_lnum == lnum and exact_symbol.end_col < col)
)
do
exact_symbol = exact_symbol.parent
end
return {
lnum = math.max(1, selected),
closest_symbol = symbol,
Expand Down
39 changes: 39 additions & 0 deletions tests/window_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,43 @@ describe("config", function()
ret
)
end)
it("uses selection_range to detect position", function()
local var1 = {
kind = "Variable",
name = "var1",
level = 1,
lnum = 8,
end_lnum = 11,
col = 0,
end_col = 3,
selection_range = {
lnum = 9,
col = 0,
end_lnum = 9,
end_col = 12,
},
}
local var2 = {
kind = "Variable",
name = "var2",
level = 1,
lnum = 8,
end_lnum = 11,
col = 0,
end_col = 3,
selection_range = {
lnum = 10,
col = 0,
end_lnum = 10,
end_col = 12,
},
}
local bufdata = data.create()
bufdata.items = { var1, var2 }
local ret = window.get_symbol_position(bufdata, 10, 6)
assert.are.same(
{ lnum = 2, closest_symbol = var2, exact_symbol = var2, relative = "below" },
ret
)
end)
end)

0 comments on commit 0a8c2c5

Please sign in to comment.