Skip to content

fix(renderer): clean out edge cases of cursor.position.restore #1355

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Feb 18, 2024
34 changes: 17 additions & 17 deletions lua/neo-tree/ui/renderer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -522,8 +522,10 @@ M.focus_node = function(state, id, do_not_focus_window, relative_movement, botto
end
local success, err = pcall(vim.api.nvim_win_set_cursor, state.winid, { linenr, col })

-- now ensure that the window is scrolled correctly
if success then
-- forget about cursor position as it is overwritten
M.position.clear(state)
-- now ensure that the window is scrolled correctly
local execute_win_command = function(cmd)
if vim.api.nvim_get_current_win() == state.winid then
vim.cmd(cmd)
Expand Down Expand Up @@ -667,6 +669,16 @@ M.position = {
state.position.node_id = node_id
state.position.is.restorable = true
end,
clear = function (state)
log.debug("Forget about cursor position.")
-- Clear saved position, so that we can save another position later.
state.position.topline = nil
state.position.lnum = nil
-- After focusing a node, we clear it so that subsequent renderer.position.restore don't
-- focus on it anymore
state.position.node_id = nil
state.position.is.restorable = false
end,
restore = function(state)
if state.position.is.restorable then
if state.position.topline and state.position.lnum then
Expand All @@ -675,21 +687,15 @@ M.position = {
vim.api.nvim_win_call(state.winid, function()
vim.fn.winrestview({ topline = state.position.topline, lnum = state.position.lnum })
end)
-- Clear saved position, so that we can save another position later.
state.position.topline = nil
state.position.lnum = nil
end
if state.position.node_id then
log.debug("Focusing on node_id: " .. state.position.node_id)
M.focus_node(state, state.position.node_id, true)
-- After focusing a node, we clear it so that subsequent renderer.position.restore don't
-- focus on it anymore
state.position.node_id = nil
end
else
log.debug("Position is not restorable")
end
state.position.is.restorable = false
M.position.clear(state)
end,
is = { restorable = true },
}
Expand All @@ -699,7 +705,7 @@ M.position = {
M.redraw = function(state)
if state.tree and M.tree_is_visible(state) then
log.trace("Redrawing tree", state.name, state.id)
-- every now and then this will fail because the window was closed in
-- every now and then this will fail because the window was closed in
-- betweeen the start of an async refresh and the redraw call.
-- This is not a problem, so we just ignore the error.
local success = pcall(render_tree, state)
Expand Down Expand Up @@ -938,7 +944,7 @@ local get_buffer = function(bufname, state)
vim.api.nvim_buf_set_option(bufnr, "filetype", "neo-tree")
vim.api.nvim_buf_set_option(bufnr, "modifiable", false)
vim.api.nvim_buf_set_option(bufnr, "undolevels", -1)
autocmd.buf.define(bufnr, "WinLeave", function()
autocmd.buf.define(bufnr, "BufDelete", function()
M.position.save(state)
end)
end
Expand Down Expand Up @@ -1045,15 +1051,9 @@ M.acquire_window = function(state)
vim.api.nvim_buf_set_name(state.bufnr, bufname)
vim.api.nvim_set_current_win(state.winid)
-- Used to track the position of the cursor within the tree as it gains and loses focus
--
-- Note `WinEnter` is often too early to restore the cursor position so we do not set
-- that up here, and instead trigger those events manually after drawing the tree (not
-- to mention that it would be too late to register `WinEnter` here for the first
-- iteration of that event on the tree window)
win:on({ "WinLeave" }, function()
win:on({ "BufDelete" }, function()
M.position.save(state)
end)

win:on({ "BufDelete" }, function()
win:unmount()
end, { once = true })
Expand Down