auto-session
auto-session copied to clipboard
[FEATURE] Handle interaction with lazy.nvim
Describe the bug
lazy.nvim
opens a floating window to install new plugins before initializing plugins. When auto-session
is loaded and it attempts to automatically restore the session, it overrides lazy.nvim
's UI with the session's open buffer, rather than opening everything in the background.
To Reproduce Steps to reproduce the behavior:
- Use
lazy.nvim
as the plugin manager. - Add any new plugin to your config, but do not install it yet.
- Restart neovim in any folder with a session saved.
- The
lazy.nvim
UI should open, displaying it installing the new plugin, before it is overridden with the last active buffer.
Expected behavior The UI shouldn't be overridden, and the buffer should be opened in the base window rather than the floating window.
Screenshots
Baseline (please complete the following information):
- Result of
set sessionoptions?
:sessionoptions=blank,buffers,curdir,folds,help,tabpages,winsize,terminal
- OS. e.g
uname -a
: Arch Linux - Neovim version
nvim --version
: v0.9.0
Additional context: It's possible this also happens if any floating window is open when an auto-restore happens, though it is a pretty niche edge case - there aren't many cases where a window would be open before a session is auto-restored. This is just the case I ran into.
Met the same problem on macOS, looking forward to resolve this.
Auto Session supports hooks to deal with things like this. I don't use lazy.nvim
myself so I unfortunately wouldn't know how to solve this particular issue you're having.
I think the best way to resolve this would be to have a hook that disables auto-load if a floating window is currently detected. Problem is, I'm not sure if the current hooks are robust enough.
Can the pre-restore hook cancel the restore process, and can it only be run on an auto-restore? The current hooks seem to run on any restore, which would affect a bit too much.
Right, you're correct. The current code does not support tweaking session loading to this level yet.
Hullo @rmagatti, have you had a go at using auto-session with Lazy, yet?
I've just moved to Lazy and I can't figure out how I'm supposed to stop this pain-in-the-ass Lazy popup from causing autosession to explode my window layout violently all over the place.
The only work together when Lazy hasn't got any updating to do and doesn't display the popup in the first place!
Given that auto-session is one of my favourite plugins by far, and the state of the art now seems to be Lazy (Packer is not even being updated), I'd really hope we can have the two plugins interacting smoothly.
Have you tried making a separate Neovim config running on Lazy and just making sure it all works alright? Go for it! I'm looking at it too, I'm just trying to figure out the best way like everybody else is.
I haven't had the time to switch to Lazy in my own config yet; meanwhile, adding more granular control through hooks around session loading would be a good addition. I'll try to get to it eventually but would, of course, welcome a PR if anyone would be interested in working on this in the meantime 👍
I've been playing around with Lazy's User Events, here. But to no avail...
A possible workaround that worked for me was to defer loading auto-session
until the Lazy view has been closed with autocmds.
- Make
auto-session
lazy
{
"rmagatti/auto-session",
-- add this to make auto-session lazy
-- also make sure you don't `require('auto-session')` anywhere
lazy = true
}
and add autocmds:
local autocmd = vim.api.nvim_create_autocmd
local lazy_did_show_install_view = false
local function auto_session_restore()
-- important! without vim.schedule other necessary plugins might not load (eg treesitter) after restoring the session
vim.schedule(function()
require("auto-session").AutoRestoreSession()
end)
end
autocmd("User", {
pattern = "VeryLazy",
callback = function()
local lazy_view = require("lazy.view")
if lazy_view.visible() then
-- if lazy view is visible do nothing with auto-session
lazy_did_show_install_view = true
else
-- otherwise load (by require'ing) and restore session
auto_session_restore()
end
end,
})
autocmd("WinClosed", {
pattern = "*",
callback = function(ev)
local lazy_view = require("lazy.view")
-- if lazy view is currently visible and was shown at startup
if lazy_view.visible() and lazy_did_show_install_view then
-- if the window to be closed is actually the lazy view window
if ev.match == tostring(lazy_view.view.win) then
lazy_did_show_install_view = false
auto_session_restore()
end
end
end,
})
I tried the above workaround, but, in the second autocmd, after the Lazy install window closed, lazy_view.visible()
was never true
and lazy_view.view.win
was nil
. As a consequence, the session would never restore after the Lazy window closed. Totally possible I did something wrong on my end.
I have started migrating my config to lazy.nvim, I still haven't come across the issue here but I'll keep this thread up to date with any findings
@mmirus Maybe it depends how the Lazy window is closed? I usually do :q
which triggers WinClose
. Also WinClose
according to docs is triggered before actually closing the window, so visible()
should be true
.
@zamotany that's a good guess. I think I was just pressing q
, which could work differently. I'll re-add the code to my config later and report back on if using :q
works. Thanks!
@zamotany confirmed, using :q
with your snippet works correctly, while just pressing q
does not. TY for the workaround and the help!
For anyone who wants to dig into that more, I think this is what runs when you press q
in the Lazy window. Personally, I'm fine with just exiting using :q
or my mapping for it instead of the q
lazy mapping.
It does seem to be the case that certain highlights are slightly wrong after closing the Lazy startup window vs when you start neovim without that window (e.g., the highlight for filenames in the diffview.nvim tree).
Also, for anyone who is wondering where to put the snippet, a nicely-contained way is to just pop it into the init
function in the Lazy spec for auto-session:
{
"rmagatti/auto-session",
lazy = true,
init = function()
-- ⭐ put @zamotany's snippet here
end,
}
I've been doing something similar with another plugin, but it should work the same with auto-session
. Try this, it works closing with q
and :q
{
"rmagatti/auto-session",
lazy = true,
init = function()
local function restore()
if vim.fn.argc(-1) > 0 then
return
end
vim.schedule(function()
require("auto-session").AutoRestoreSession()
end)
end
local lazy_view_win = nil
vim.api.nvim_create_autocmd("User", {
pattern = "VeryLazy",
callback = function()
local lazy_view = require("lazy.view")
if lazy_view.visible() then
lazy_view_win = lazy_view.view.win
else
restore()
end
end,
})
vim.api.nvim_create_autocmd("WinClosed", {
callback = function(event)
if not lazy_view_win or event.match ~= tostring(lazy_view_win) then
return
end
restore()
end,
})
end,
}
@delatorrejuanchi solution worked for me. However, I had to change pattern
to pattern = {"VeryLazy", "AlphaReady"}
but now I am not getting line numbers even though we are using vim.schedule()
.
@delatorrejuanchi's solution is spot on. I typically refrain from adding explicit support for other plugins to auto-session as it can escalate quickly, but since lazy has become the de facto standard for package management in Neovim, I'm open to integrating a tweaked version of this code into auto-session. Lately, I've been tight on time so I can't promise when I'll get around to it, but I definitely will eventually. In the meantime, if anyone finds some free time before I do, I am more than willing to review a PR for this!