Skip to content

Commit

Permalink
feat: highlight_closest config option (#52)
Browse files Browse the repository at this point in the history
  • Loading branch information
stevearc committed Feb 3, 2022
1 parent 0cb2711 commit 5ba5985
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 38 deletions.
5 changes: 4 additions & 1 deletion lua/aerial/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ local default_options = {
},

-- Enum: split_width, full_width, last, none
-- Determines line highlighting mode when multiple splits are visible
-- Determines line highlighting mode when multiple splits are visible.
-- split_width Each open window will have its cursor location marked in the
-- aerial buffer. Each line will only be partially highlighted
-- to indicate which window is at that location.
Expand All @@ -52,6 +52,9 @@ local default_options = {
-- none Do not show the cursor locations in the aerial window.
highlight_mode = "split_width",

-- Highlight the closest symbol if the cursor is not exactly on one.
highlight_closest = true,

-- When jumping to a symbol, highlight the line for this many ms.
-- Set to false to disable
highlight_on_jump = 300,
Expand Down
2 changes: 1 addition & 1 deletion lua/aerial/data.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ local BufData = {
local new = {
items = {},
positions = {},
last_position = 1,
last_win = -1,
collapsed = {},
}
setmetatable(new, { __index = t })
Expand Down
31 changes: 14 additions & 17 deletions lua/aerial/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -118,28 +118,19 @@ M.get_location = function(exact)
if not pos then
return {}
end
local item = bufdata:item(pos.lnum)
local cur = vim.api.nvim_win_get_cursor(0)
local item
if exact then
item = pos.exact_symbol
else
item = pos.closest_symbol
end
local ret = {}
while item do
if exact then
if not item.end_lnum or not item.end_col then
-- end_lnum/end_col isn't supported by all backends yet
elseif
item.lnum > cur[1]
or item.end_lnum < cur[1]
or (item.lnum == cur[1] and item.col > cur[2])
or (item.end_lnum == cur[1] and item.end_col < cur[2])
then
goto continue
end
end
table.insert(ret, 1, {
kind = item.kind,
icon = config.get_icon(item.kind),
name = item.name,
})
::continue::
item = item.parent
end
return ret
Expand Down Expand Up @@ -204,14 +195,20 @@ M.tree_cmd = function(action, opts)
fold = true,
})
local index
local item
if opts.index then
index = opts.index
elseif util.is_aerial_buffer() then
index = vim.api.nvim_win_get_cursor(0)[1]
else
index = window.get_position_in_win().lnum
local pos = window.get_position_in_win()
index = pos.lnum
item = pos.closest_symbol
end
if item == nil then
item = data[0]:item(index)
end
local lnum = data[0]:item(index).lnum
local lnum = item.lnum
local did_update, new_cursor_pos = tree.edit_tree_node(data[0], action, index, opts)
if did_update then
if config.link_tree_to_folds and opts.fold then
Expand Down
2 changes: 1 addition & 1 deletion lua/aerial/navigation.lua
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ M.select = function(opts)
opts.index = vim.api.nvim_win_get_cursor(0)[1]
else
local bufdata = data[0]
opts.index = bufdata.positions[winid]
opts.index = bufdata.positions[winid].lnum
end
opts.index = opts.index or 1
end
Expand Down
18 changes: 8 additions & 10 deletions lua/aerial/render.lua
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,10 @@ M.update_highlights = function(buf)
local hl_width = math.floor(util.get_width(aer_bufnr) / #winids)

if hl_mode == "last" then
local row = bufdata.last_position
vim.api.nvim_buf_add_highlight(aer_bufnr, ns, "AerialLine", row - 1, 0, -1)
local pos = bufdata.positions[bufdata.last_win]
if pos and (config.highlight_closest or pos.exact_symbol) then
vim.api.nvim_buf_add_highlight(aer_bufnr, ns, "AerialLine", pos.lnum - 1, 0, -1)
end
return
end

Expand All @@ -144,14 +146,10 @@ M.update_highlights = function(buf)
if i == #winids then
end_hl = -1
end
vim.api.nvim_buf_add_highlight(
aer_bufnr,
ns,
"AerialLine",
bufdata.positions[winid].lnum - 1,
start_hl,
end_hl
)
local pos = bufdata.positions[winid]
if config.highlight_closest or pos.exact_symbol then
vim.api.nvim_buf_add_highlight(aer_bufnr, ns, "AerialLine", pos.lnum - 1, start_hl, end_hl)
end
if hl_mode ~= "full_width" then
start_hl = end_hl
end_hl = end_hl + hl_width
Expand Down
41 changes: 33 additions & 8 deletions lua/aerial/window.lua
Original file line number Diff line number Diff line change
Expand Up @@ -209,36 +209,61 @@ M.get_position_in_win = function(bufnr, winid)
local bufdata = data[bufnr]
local selected = 0
local relative = "above"
bufdata:visit(function(item)
local prev = nil
local symbol = bufdata:visit(function(item)
if item.lnum > lnum then
return true
return prev or item
elseif item.lnum == lnum then
if item.col > col then
return true
return prev or item
elseif item.col == col then
selected = selected + 1
relative = "exact"
return true
return item
else
relative = "below"
end
else
relative = "below"
end
prev = item
selected = selected + 1
end)
-- Check if we're on the last symbol
if symbol == nil then
symbol = prev
end
local exact_symbol = symbol
while
exact_symbol
-- TODO: end_lnum/end_col isn't supported by all backends yet
and exact_symbol.end_lnum
and exact_symbol.end_col
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,
exact_symbol = exact_symbol,
relative = relative,
}
end

-- Updates all cursor positions for a given source buffer
M.update_all_positions = function(bufnr, last_focused_win)
local source_buffer = util.get_buffers(bufnr)
local all_source_wins = util.get_fixed_wins(source_buffer)
M.update_position(all_source_wins, last_focused_win)
end

-- Update the cursor position for one or more windows
-- winids can be nil, a winid, or a list of winids
M.update_position = function(winids, last_focused_win)
if not config.highlight_mode or config.highlight_mode == "none" then
Expand Down Expand Up @@ -267,7 +292,7 @@ M.update_position = function(winids, last_focused_win)
if pos ~= nil then
bufdata.positions[target_win] = pos
if last_focused_win and (last_focused_win == true or last_focused_win == target_win) then
bufdata.last_position = pos.lnum
bufdata.last_win = target_win
end
end
end
Expand All @@ -276,14 +301,14 @@ M.update_position = function(winids, last_focused_win)
if last_focused_win then
local aer_winid = util.buf_first_win_in_tabpage(aer_bufnr)
if aer_winid then
local last_position = bufdata.last_position
local last_position = bufdata.positions[bufdata.last_win]
local lines = api.nvim_buf_line_count(aer_bufnr)

-- When aerial window is global, the items can change and cursor will move
-- before the symbols are published, which causes the line number to be
-- invalid.
if lines >= last_position then
api.nvim_win_set_cursor(aer_winid, { bufdata.last_position, 0 })
if last_position and lines >= last_position.lnum then
api.nvim_win_set_cursor(aer_winid, { last_position.lnum, 0 })
end
end
end
Expand Down

0 comments on commit 5ba5985

Please sign in to comment.