feat: Optionally not auto-update cursors position

This also fixes a typo from an old commit (did not catch the bug because
all this time I was testing with the same window!), and put
auto_update_events into outline_items since it makes more sense, and is
closer to highlight_hovered_item and (the new) auto_follow_cursor.

Added code_buf to state since it appears to be used quite often now.
This commit is contained in:
hedy
2023-11-18 11:14:18 +08:00
parent 82ab53a167
commit d65696a9cf
2 changed files with 42 additions and 29 deletions

View File

@@ -18,7 +18,16 @@ M.defaults = {
outline_items = { outline_items = {
show_symbol_details = true, show_symbol_details = true,
show_symbol_lineno = false, show_symbol_lineno = false,
-- The two below are both for auto_update_events.follow
highlight_hovered_item = true, highlight_hovered_item = true,
-- On open, always followed. This is for auto_update_events.follow, whether
-- to auto update cursor position to reflect code location. If false, can
-- manually trigger with follow_cursor (API, command, keymap action).
auto_follow_cursor = true,
auto_update_events = {
follow = { 'CursorMoved' },
items = { 'InsertLeave', 'WinEnter', 'BufEnter', 'BufWinEnter', 'TabEnter', 'BufWritePost' },
},
}, },
outline_window = { outline_window = {
position = 'right', position = 'right',
@@ -37,10 +46,6 @@ M.defaults = {
winhl = 'OutlineDetails:Comment,OutlineLineno:LineNr', winhl = 'OutlineDetails:Comment,OutlineLineno:LineNr',
jump_highlight_duration = 400, jump_highlight_duration = 400,
center_on_jump = true, center_on_jump = true,
auto_update_events = {
cursor = { 'CursorMoved' },
items = { 'InsertLeave', 'WinEnter', 'BufEnter', 'BufWinEnter', 'TabEnter', 'BufWritePost' },
},
}, },
preview_window = { preview_window = {
auto_preview = false, auto_preview = false,

View File

@@ -10,8 +10,8 @@ local writer = require('outline.writer')
local M = {} local M = {}
local function setup_global_autocmd() local function setup_global_autocmd()
if utils.table_has_content(cfg.o.outline_window.auto_update_events.items) then if utils.table_has_content(cfg.o.outline_items.auto_update_events.items) then
vim.api.nvim_create_autocmd(cfg.o.outline_window.auto_update_events.items, { vim.api.nvim_create_autocmd(cfg.o.outline_items.auto_update_events.items, {
pattern = '*', pattern = '*',
callback = M._refresh, callback = M._refresh,
}) })
@@ -32,6 +32,7 @@ M.state = {
---@type outline.FlatSymbolNode[] ---@type outline.FlatSymbolNode[]
flattened_outline_items = {}, flattened_outline_items = {},
code_win = 0, code_win = 0,
code_buf = 0,
autocmds = {}, autocmds = {},
-- In case unhide_cursor was called before hide_cursor for _some_ reason, -- In case unhide_cursor was called before hide_cursor for _some_ reason,
-- this can still be used as a fallback -- this can still be used as a fallback
@@ -43,6 +44,7 @@ local function wipe_state()
outline_items = {}, outline_items = {},
flattened_outline_items = {}, flattened_outline_items = {},
code_win = 0, code_win = 0,
code_buf = 0,
autocmds = {}, autocmds = {},
opts = {}, opts = {},
} }
@@ -71,24 +73,27 @@ local function __refresh()
end end
local curwin = vim.api.nvim_get_current_win() local curwin = vim.api.nvim_get_current_win()
local curbuf = vim.api.nvim_get_current_buf()
local newbuf = curbuf ~= M.state.code_buf
if M.state.codewin ~= curwin then if M.state.code_win ~= curwin then
if M.state.autocmds[M.state.codewin] then
vim.api.nvim_del_autocmd(M.state.autocmds[M.state.codewin])
end
M.state.codewin = curwin
end
if cfg.o.outline_items.highlight_hovered_item or cfg.o.symbol_folding.auto_unfold_hover then
if M.state.autocmds[M.state.code_win] then if M.state.autocmds[M.state.code_win] then
vim.api.nvim_del_autocmd(M.state.autocmds[M.state.code_win]) vim.api.nvim_del_autocmd(M.state.autocmds[M.state.code_win])
end end
if utils.str_or_nonempty_table(cfg.o.outline_window.auto_update_events.cursor) then end
M.state.autocmds[M.state.code_win] = M.state.code_win = curwin
vim.api.nvim_create_autocmd(cfg.o.outline_window.auto_update_events.cursor, { M.state.code_buf = curbuf
buffer = vim.api.nvim_win_get_buf(M.state.code_win),
if cfg.o.outline_items.highlight_hovered_item or cfg.o.symbol_folding.auto_unfold_hover then
if M.state.autocmds[curwin] then
vim.api.nvim_del_autocmd(M.state.autocmds[curwin])
end
if utils.str_or_nonempty_table(cfg.o.outline_items.auto_update_events.follow) then
M.state.autocmds[curwin] =
vim.api.nvim_create_autocmd(cfg.o.outline_items.auto_update_events.follow, {
buffer = curbuf,
callback = function() callback = function()
M._highlight_current_item(nil) M._highlight_current_item(nil, cfg.o.outline_items.auto_follow_cursor)
end, end,
}) })
end end
@@ -97,7 +102,8 @@ local function __refresh()
local items = parser.parse(response, vim.api.nvim_get_current_buf()) local items = parser.parse(response, vim.api.nvim_get_current_buf())
_merge_items(items) _merge_items(items)
_update_lines() local update_cursor = newbuf or cfg.o.outline_items.auto_follow_cursor
_update_lines(update_cursor)
end end
providers.request_symbols(refresh_handler) providers.request_symbols(refresh_handler)
@@ -296,7 +302,8 @@ function M._set_all_folded(folded, nodes)
end end
---@param winnr? integer Window number of code window ---@param winnr? integer Window number of code window
function M._highlight_current_item(winnr) ---@param update_cursor? boolean
function M._highlight_current_item(winnr, update_cursor)
local has_provider = M.has_provider() local has_provider = M.has_provider()
local has_outline_open = M.view:is_open() local has_outline_open = M.view:is_open()
local current_buffer_is_outline = M.view.bufnr == vim.api.nvim_get_current_buf() local current_buffer_is_outline = M.view.bufnr == vim.api.nvim_get_current_buf()
@@ -323,9 +330,9 @@ function M._highlight_current_item(winnr)
-- parents folded) -- parents folded)
-- In one go -- In one go
-- XXX: Could current win ~= M.state.codewin here? -- XXX: Could current win ~= M.state.code_win here?
_update_lines(true) _update_lines(update_cursor)
end end
local function setup_keymaps(bufnr) local function setup_keymaps(bufnr)
@@ -413,6 +420,7 @@ local function handler(response, opts)
end end
M.state.code_win = vim.api.nvim_get_current_win() M.state.code_win = vim.api.nvim_get_current_win()
M.state.code_buf = vim.api.nvim_get_current_buf()
M.state.opened_first_outline = true M.state.opened_first_outline = true
if opts and opts.on_symbols then if opts and opts.on_symbols then
@@ -429,12 +437,12 @@ local function handler(response, opts)
if M.state.autocmds[M.state.code_win] then if M.state.autocmds[M.state.code_win] then
vim.api.nvim_del_autocmd(M.state.autocmds[M.state.code_win]) vim.api.nvim_del_autocmd(M.state.autocmds[M.state.code_win])
end end
if utils.str_or_nonempty_table(cfg.o.outline_window.auto_update_events.cursor) then if utils.str_or_nonempty_table(cfg.o.outline_items.auto_update_events.follow) then
M.state.autocmds[M.state.code_win] = M.state.autocmds[M.state.code_win] =
vim.api.nvim_create_autocmd(cfg.o.outline_window.auto_update_events.cursor, { vim.api.nvim_create_autocmd(cfg.o.outline_items.auto_update_events.follow, {
buffer = vim.api.nvim_win_get_buf(M.state.code_win), buffer = M.state.code_buf,
callback = function() callback = function()
M._highlight_current_item(nil) M._highlight_current_item(nil, cfg.o.outline_items.auto_follow_cursor)
end, end,
}) })
end end
@@ -450,7 +458,7 @@ local function handler(response, opts)
setup_keymaps(M.view.bufnr) setup_keymaps(M.view.bufnr)
setup_buffer_autocmd() setup_buffer_autocmd()
local items = parser.parse(response, vim.api.nvim_win_get_buf(M.state.code_win)) local items = parser.parse(response, M.state.code_buf)
M.state.outline_items = items M.state.outline_items = items
local current local current
@@ -474,7 +482,7 @@ function M.follow_cursor(opts)
end end
if require('outline.preview').has_code_win() then if require('outline.preview').has_code_win() then
M._highlight_current_item(M.state.code_win) M._highlight_current_item(M.state.code_win, true)
else else
return false return false
end end