Skip to content
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

[FEATURE] Auto save manually named sessions #386

Closed
kqvanity opened this issue Oct 9, 2024 · 22 comments
Closed

[FEATURE] Auto save manually named sessions #386

kqvanity opened this issue Oct 9, 2024 · 22 comments
Assignees
Labels
enhancement New feature or request

Comments

@kqvanity
Copy link

kqvanity commented Oct 9, 2024

Is your feature request related to a problem? Please describe.

  • Manually named sessions don't get auto-saved
  • Executing SessionSave manually will save the content in a new session named after the CWD (with auto_create set or not)
  • If single directory/file support is set on, It'd override the current CWD-based session (thus named ones are better in that case)

Describe the solution you'd like
I'd favor support for named sessions for multiple reasons

  • short custom name
  • not tied to the CWD
  • Single-file support

Describe alternatives you've considered
I've tried setting up hooks to named of the current session when a session-save event is triggered, but it became recursive

Additional context
N/A

@kqvanity kqvanity added the enhancement New feature or request label Oct 9, 2024
@cameronr
Copy link
Collaborator

cameronr commented Oct 9, 2024

Thanks for filling the new issue!

Just to make sure we're on the same page, auto-session already supports named sessions, just call :SessionSave with an argument, e.g. :SessionSave mysession. That will save a session called mysession that isn't named for the cwd. However, manually named session aren't currently used when autosaving on exit (it alway saves to a session name derived from the cwd).

I don't think it would hard to add the ability for manually named sessions to be autosaved on exit (but there isn't currently a way to autoload them on start). That would look like this:

  1. start nvim, have some files open
  2. Save a session via :SessionSave mysession or restore a manually named session via :SessionSearch or :SessionRestore
  3. open/close files
  4. exit nvim
  5. auto-session saves to mysession (instead of session named for cwd)

Would that work for your workflow?

@kqvanity
Copy link
Author

kqvanity commented Oct 9, 2024

Thanks for filling the new issue!

I should be the one thanking you for taking the time to consider this feature.

Would that work for your workflow?

Exactly.

Ff named sessions would be be auto-updated, would that allow loading/reading single separate files e.g., shell profiles, separate singular config files, etc.?

@cameronr
Copy link
Collaborator

Ok, I think I have it working the way I described above.

If you want to test it, you can temporary change the top of your auto-session config to:

  -- 'rmagatti/auto-session',
  'cameronr/auto-session',

After changing the config, you'll have to open Lazy (or whatever plugin manager you use) and update the plugin to actually pull it down (and restart nvim just to be sure).

Ff named sessions would be be auto-updated, would that allow loading/reading single separate files e.g., shell profiles, separate singular config files, etc.?

I'm not quite sure what that means. You could have a manually named session for whatever file(s) you wanted to. The only issue is you'll have to manually load them since they're not named after the cwd. But once loaded, they should update when you exit (if you use my fork above).

I'm curious, though, why you'd want a session for a single file?

@kqvanity
Copy link
Author

I did test out yesterday, and noticed flakey behavior that i've been trying to reproduce.
namely, If I have multiple named sessions opened. it seems like the very first one is the only that get auto-updated. Removing ~/.local/share/nvim/auto_session/session_control.json solves the issue temporarily however.

not quite sure what that means.

I'm curious, though, why you'd want a session for a single file?

The ideal workflow for me would be having a mix of CWD and named sessions for entire projects/dir that I explicitly SessionSave. It'd be a huge convenience to also be able to auto restore/load let's say, shell profiles when directly opening them e.g., nvim .zshrc

@cameronr
Copy link
Collaborator

Hmm, session_control.json is only used for the alternate session feature (in :SessionSearch you can swap to session before the current session with <C-s>; it's not used for anything else so I'd be surprised if it was involved somehow. If you have multiple nvim sessions running all loaded from the same session, the last one that exits will write it's state to the session file and that will be what's loaded the next time nvim is started.

When you say you have "multiple named sessions opened", do you mean in multiple instances of nvim or something else?

I really want to make sure I understand your use case. When you run nvim .zshrc what session are you hoping to have it load? Are there other files you want it to open at the same time?

Is it possible for you to describe your desired setup with actual examples, maybe with this template:

Session #n

  • cwd: where nvim is started
  • nvim cmd: how nvim is launched with any arguments
  • session name: how you want session named
  • autorestore desired: do you want it to autorestore
  • open files:
  • change cwd: do you change directories inside nvim
  • how do you think about this session conceptually / what do you do in the session
  • any other interesting details about how you use the session, what you want it to do, etc

For example:

Session 1:

  • cwd: ~/dotfiles
  • nvim cmd: nvim
  • session name: automatically named for cwd
  • autorestore desired: yes
  • open files: tmux.conf, .wezterm.lua
  • change cwd: no
  • used for editing my dotfiles, i want it to autoload and autosave on exit. i usually have it open all the time

Session 2:

  • cwd: ~/dotfiles
  • nvim cmd: nvim .zshrc
  • session name: manually named 'dot-project'
  • autorestore desired: ideally yes, but ok if not
  • open files: .zshrc
  • change cwd: no
  • used to to make quick changes to my .zshrc.

@kqvanity
Copy link
Author

When you say you have "multiple named sessions opened", do you mean in multiple instances of nvim or something else?

Having multiple nvim instances, yes. $ nvim ... $ nvim.
That's my stock config. If you can't reproduce this flakey behavior, then it's probably on my end (even though I've tried so many times to figure out what's wrong`

    {
      -- 'rmagatti/auto-session',
      'cameronr/auto-session',
      lazy = false,

      ---enables autocomplete for opts
      ---@module "auto-session"
      ---@type AutoSession.Config
      opts = {
          enabled = true, -- Enables/disables auto creating, saving and restoring
          root_dir = vim.fn.stdpath "data" .. "/sessions/", -- Root dir where sessions will be stored
          auto_save = true, -- Enables/disables auto saving session on exit
          auto_restore = false, -- Enables/disables auto restoring session on start
          auto_create = false, -- Enables/disables auto creating new session files. Can take a function that should return true/false if a new session file should be created or not
          suppressed_dirs = nil, -- Suppress session restore/create in certain directories
          -- suppressed_dirs = { '~/', '~/Projects', '~/Downloads', '/' },
          allowed_dirs = nil, -- Allow session restore/create in certain directories
          auto_restore_last_session = false, -- On startup, loads the last saved session if session for cwd does not exist
          use_git_branch = false, -- Include git branch name in session name
          lazy_support = true, -- Automatically detect if Lazy.nvim is being used and wait until Lazy is done to make sure session is restored correctly. Does nothing if Lazy isn't being used. Can be disabled if a problem is suspected or for debugging
          bypass_save_filetypes = { 'alpha', 'dashboard' }, -- -- List of file types to bypass auto save when the only buffer open is one of the file types listed, useful to ignore dashboards (or whatever dashboard you use)
          close_unsupported_windows = true, -- Close windows that aren't backed by normal file before autosaving a session
          args_allow_single_directory = true, -- Follow normal sesion save/load logic if launched with a single directory as the only argument
          args_allow_files_auto_save = false, -- Allow saving a session even when launched with a file argument (or multiple files/dirs). It does not load any existing session first. While you can just set this to true, you probably want to set it to a function that decides when to save a session when launched with file args. See documentation for more detail
          continue_restore_on_error = false, -- Keep loading the session even if there's an error
          cwd_change_handling = true, -- Follow cwd changes, saving a session before change and restoring after
          log_level = "info", -- Sets the log level of the plugin (debug, info, warn, error).

          session_lens = {
            load_on_setup = true, -- Initialize on startup (requires Telescope)
            theme_conf = { -- Pass through for Telescope theme options
              -- layout_config = { -- As one example, can change width/height of picker
              --   width = 0.8,    -- percent of window
              --   height = 0.5,
              -- },
            },
            previewer = false, -- File preview for session picker

            mappings = {
              -- Mode can be a string or a table, e.g. {"i", "n"} for both insert and normal mode
              delete_session = { "i", "<C-D>" },
              alternate_session = { "i", "<C-S>" },
              copy_session = { "i", "<C-Y>" },
            },

            session_control = {
              control_dir = vim.fn.stdpath "data" .. "/auto_session/", -- Auto session control dir, for control files, like alternating between two sessions with session-lens
              control_filename = "session_control.json", -- File name of the session control file
            },

          },
        }
        -- log_level = 'debug',
    },

Is it possible for you to describe your desired setup with actual examples, maybe with this template:

Session 1

  • navigate to any directory
  • open nvim
  • invoke SessionSearch
  • look for named sessions
  • continue working where I left off
  • exit nvim qa
  • back to step $1

Session 2

  • Another tmux/shell tab
  • navigating around the file system
  • want to open a single config file
  • nvim .config
  • navigate to line 10 - char 20
  • make small change
  • never manually interact with auto_session whatsoever
  • auto_session will however automatically save my current state in that single file
  • close nvim
  • open nvim back up again to continue working on the file
  • auto_session auto restore my state

Mind you that individual files would be loaded automatically without even having designated session names for them in session_search for example

@cameronr
Copy link
Collaborator

Thanks for the detailed response! I'll break my response into sections:

  1. Config

While it's not necessary, you don't have to include the default values in your config so you could trim your config to:

          auto_restore = false, -- Enables/disables auto restoring session on start
          auto_create = false, -- Enables/disables auto creating new session files. Can take a function that should return true/false if a new session file should be created or not
          bypass_save_filetypes = { 'alpha', 'dashboard' }, -- -- List of file types to bypass auto save when the only buffer open is one of the file types listed, useful to ignore dashboards (or whatever dashboard you use)
          continue_restore_on_error = false, -- Keep loading the session even if there's an error
          cwd_change_handling = true, -- Follow cwd changes, saving a session before change and restoring after
          log_level = "info", -- Sets the log level of the plugin (debug, info, warn, error).

Also, I'm curious why you have continue_restore_on_error set to false? Outside of some edge cases, that should really be set to true. Have you had any session load errors?

  1. Flakiness: can you explain more what flaky behavior you're seeing? Is it sessions not restoring correctly? Or is it something else that's not working? The more detail you can provide the easier it will be for me to understand / potentially reproduce the issue.

  2. Session 1 behavior: With my fork, that should now work. If it's not working for you, please let me know.

  3. For single files, what state are you trying to restore? If it's remembering the cursor position (line/column), you can use this autocmd (it doesn't even need a session, just uses marks, can go anywhere in your nvim config, doesn't have to go in your auto-session config):

-- from: https://www.reddit.com/r/neovim/comments/1abd2cq/what_are_your_favorite_tricks_using_neovim/
vim.api.nvim_create_autocmd('BufReadPost', {
  desc = 'Open file at the last position it was edited earlier',
  command = 'silent! normal! g`"zv',
})

Beyond remembering your cursor position, is there other data you're trying to restore with single file sessions?

@kqvanity
Copy link
Author

While it's not necessary, you don't have to include the default values in your config so you could trim your config to:

I usually copy-paste the default config explicitly, just in case I ever wanted to fiddle with it later on.

Have you had any session load errors?

I've just keep toggling different options on/off thinking it could be the reason why this odd behavior.

Session 1 behavior:

unfortunately It's still not working for me. I've tried to lazy load auto-session as the singly plugin, and still to no avail. I've tried a minimal session with only two tabs, and still without much like. I know that's now quite informative, but i really don't know what's wrong

For single files

Thank you. It works just fine. I initially thought that was the responsibility of the session manager

@cameronr
Copy link
Collaborator

Ok, I think we're making progress. So I think the only issue now is that named sessions aren't saving your changes on exit? Is that right?

Can you describe in as much detail as possible what's not working? You don't have to worry about why it's not working (that's my job :) ), I just need to know what you're doing and what you're seeing that doesn't look right.

You described your workflow as:

Session 1
navigate to any directory
open nvim
invoke SessionSearch
look for named sessions
continue working where I left off
exit nvim qa
back to step $1

Is the problem that when go back to "step $1", the session you restored from SessionSearch doesn't have the changes you previously made? Again, the more detail the better. Specifically what are you seeing that is wrong (e.g. is a file you were expecting to be open not open or is a buffer you were expected to be closed not closed or is it something else that is wrong)?

@kqvanity
Copy link
Author

Is the problem that when go back to "step $1", the session you restored from SessionSearch doesn't have the changes you previously made?

Exactly. I have to update it manually for it take effect using SessionSave session_name. However, other times, it does work. Maybe early on when removing ~/.local/share/nvim/auto_session/session_control.json and ~/.local/share/nvim/sessions/*.

  • I usually open multiple neovim instances
  • each instance restore a separate named session
  • do the changes e.g., open tabs, multiple buffers, scroll around etc
  • :qa
  • go to step 1
  • try to restore any session
  • The last changes i've made aren't saved. The last ones preserved are those manually saved with SessionSave

@cameronr
Copy link
Collaborator

cameronr commented Oct 13, 2024

Thank you, that's very helpful. That sounds like it might not actually be using my fork as that's how the code worked before my changes and that work flow is working for me in my fork. Can you do the following:

  1. run :Lazy sync
  2. in the Lazy window that pops up, find auto-session in the list and hit enter when your cursor is on it to expand it.
  3. Post a screenshot of what it says to this issue. For example, this is what it shows for me:

Screenshot 2024-10-13 at 11 34 01

@kqvanity
Copy link
Author

The same commit

Screenshot_20241013-221053_733x182

@cameronr
Copy link
Collaborator

Ok, great, so we can rule that out. Next step is to turn on some logging. Can you do the following:

  1. Add log_level = 'debug', to your auto-session config
  2. restart nvim
  3. restore a manually named session (one where it doesn't usually save your session on exit)
  4. instead of exiting, run this: :=require('auto-session').AutoSaveSession() (i.e. press : and then paste in everything, starting with the = and press enter). That will simulate what happens when you exit but still let us see the logs
  5. Post the contents of the debug log. You can find it either at :messages (if you don't use nvim-notify) or :Notifications (if you do use it or noice)

@kqvanity
Copy link
Author

messages output

auto-session DEBUG: Config at start of setup {
  args_allow_files_auto_save = false,
  args_allow_single_directory = true,
  auto_create = false,
  auto_restore = false,
  auto_restore_last_session = false,
  auto_save = true,
  bypass_save_filetypes = { "alpha", "dashboard" },
  close_unsupported_windows = true,
  continue_restore_on_error = false,
  cwd_change_handling = true,
  enabled = true,
  lazy_support = true,
  log_level = "debug",
  root_dir = "/home/keinvanity/.local/share/nvim/sessions/",
  session_lens = {
    load_on_setup = true,
    mappings = {
      alternate_session = { "i", "<C-S>" },
      copy_session = { "i", "<C-Y>" },
      delete_session = { "i", "<C-D>" }
    },
    previewer = false,
    session_control = {
      control_dir = "/home/keinvanity/.local/share/nvim/auto_session/",
      control_filename = "session_control.json"
    },
    theme_conf = {}
  },
  use_git_branch = false
}
auto-session WARN: vim.o.sessionoptions is missing localoptions. 
Use `:checkhealth autosession` for more info.
auto-session DEBUG: Root dir set to: /home/keinvanity/.local/share/nvim/sessions/
auto-session DEBUG: Loading session lens
auto-session DEBUG: Lazy is loaded, but not visible, will try to restore session
auto-session DEBUG: enabled_for_command_line_argv, launch_argv: {}
auto-session DEBUG: No arguments, saving/restoring enabled
auto-session DEBUG: No session restored, call no_restore hooks
false

@cameronr
Copy link
Collaborator

Thanks for that logging but I need the logging after you have restored a session and run the auto save function i mentioned in my previous message. please do the following:

  1. restore a manually named session (one where it doesn't usually save your session on exit)
  2. instead of exiting, run this: :=require('auto-session').AutoSaveSession() (i.e. press : and then paste in everything, starting with the = and press enter). That will simulate what happens when you exit but still let us see the logs
  3. Post the contents of the debug log. You can find it either at :messages (if you don't use nvim-notify) or :Notifications (if you do use it or noice)

@kqvanity
Copy link
Author

I did exactly that the last time, but now it's returning more output. After running Notifications I assume

08:18:35 PM msg_show auto-session DEBUG: Config at start of setup {
  args_allow_files_auto_save = false,
  args_allow_single_directory = true,
  auto_create = false,
  auto_restore = false,
  auto_restore_last_session = false,
  auto_save = true,
  bypass_save_filetypes = { "alpha", "dashboard" },
  close_unsupported_windows = true,
  continue_restore_on_error = false,
  cwd_change_handling = true,
  enabled = true,
  lazy_support = true,
  log_level = "debug",
  root_dir = "/home/keinvanity/.local/share/nvim/sessions/",
  session_lens = {
    load_on_setup = true,
    mappings = {
      alternate_session = { "i", "<C-S>" },
      copy_session = { "i", "<C-Y>" },
      delete_session = { "i", "<C-D>" }
    },
    previewer = false,
    session_control = {
      control_dir = "/home/keinvanity/.local/share/nvim/auto_session/",
      control_filename = "session_control.json"
    },
    theme_conf = {}
  },
  use_git_branch = false
}
auto-session WARN: vim.o.sessionoptions is missing localoptions. 
Use `:checkhealth autosession` for more info.
auto-session DEBUG: Root dir set to: /home/keinvanity/.local/share/nvim/sessions/
auto-session DEBUG: Loading session lens
auto-session DEBUG: Lazy is loaded, but not visible, will try to restore session
auto-session DEBUG: enabled_for_command_line_argv, launch_argv: {}
auto-session DEBUG: No arguments, saving/restoring enabled
auto-session DEBUG: No session restored, call no_restore hooks
08:19:02 PM msg_show.echo   Notifications 2024-10-14T20:18:48 MessagesINFO 2024-10-14T20:18:38 NotifyDEBUG auto-session DEBUG: get_session_file_name no session_name, using cwd: /home/keinvanity
2024-10-14T20:18:38 NotifyDEBUG auto-session DEBUG: Autosaving before restoring {
  cwd = "/home/keinvanity",
  session_name = "dis2"
}
2024-10-14T20:18:38 NotifyDEBUG auto-session DEBUG: enabled_for_command_line_argv, launch_argv: {}
2024-10-14T20:18:38 NotifyDEBUG auto-session DEBUG: No arguments, saving/restoring enabled
2024-10-14T20:18:38 NotifyDEBUG auto-session DEBUG: find_matching_directory {
  dirToFind = "/home/keinvanity",
  dirsToCheck = {}
}
2024-10-14T20:18:38 NotifyDEBUG auto-session DEBUG: suppress_session didn't find a match, returning false
2024-10-14T20:18:38 NotifyDEBUG auto-session DEBUG: bypass_save_by_filetype: false
2024-10-14T20:18:38 NotifyDEBUG auto-session DEBUG: auto_save_conditions_met: returning true
2024-10-14T20:18:38 NotifyDEBUG auto-session DEBUG: get_session_file_name no session_name, using cwd: /home/keinvanity
2024-10-14T20:18:38 NotifyDEBUG auto-session DEBUG: Create not enabled and no existing session, not creating session
2024-10-14T20:18:38 NotifyDEBUG auto-session DEBUG: RestoreSessionFromDir start { "/home/keinvanity/.local/share/nvim/sessions/", "dis2" }
2024-10-14T20:18:38 NotifyDEBUG auto-session DEBUG: RestoreSessionFromDir validated session_dir:  /home/keinvanity/.local/share/nvim/sessions/
2024-10-14T20:18:38 NotifyDEBUG auto-session DEBUG: RestoreSessionFromDir escaped session name: dis2.vim
2024-10-14T20:18:38 NotifyDEBUG auto-session DEBUG: get_session_file_name no session_name, using cwd: /home/keinvanity
2024-10-14T20:18:38 NotifyDEBUG auto-session DEBUG: Session is manually named
2024-10-14T20:18:38 NotifyDEBUG auto-session DEBUG: RestoreSessionFile restoring session from: /home/keinvanity/.local/share/nvim/sessions/dis2.vim
2024-10-14T20:18:38 NotifyDEBUG auto-session DEBUG: DirChangedPre
2024-10-14T20:18:38 NotifyDEBUG auto-session DEBUG: {
  ["changed window"] = "false",
  cwd = "/home/keinvanity",
  scope = "global",
  target = "~"
}
2024-10-14T20:18:38 NotifyDEBUG auto-session DEBUG: DirChangedPre: restore_in_progress/vim.g.SessionLoad is true, ignoring this event
2024-10-14T20:18:38 NotifyDEBUG auto-session DEBUG: DirChanged
2024-10-14T20:18:38 NotifyDEBUG auto-session DEBUG:   cwd: /home/keinvanity
2024-10-14T20:18:38 NotifyDEBUG auto-session DEBUG:   changed window: false
2024-10-14T20:18:38 NotifyDEBUG auto-session DEBUG:   scope: global
2024-10-14T20:18:38 NotifyDEBUG auto-session DEBUG: DirChangedPre: restore_in_progress/vim.g.SessionLoad is true, ignoring this event
2024-10-14T20:18:38 NotifyDEBUG auto-session DEBUG: Restored session: dis2
2024-10-14T20:18:38 NotifyINFO Restored session: dis2
2024-10-14T20:18:38 NotifyDEBUG auto-session DEBUG: Loaded session control data:  {
  alternate = "/home/keinvanity/.local/share/nvim/sessions/navi.vim",
  current = "/home/keinvanity/.local/share/nvim/sessions/dis2.vim"
}
2024-10-14T20:18:38 NotifyDEBUG auto-session DEBUG: Not writing to session control file, current is same as session_file_name: /home/keinvanity/.local/share/nvim/sessions/dis2.vim
2024-10-14T20:18:43 MessagesINFO false
2024-10-14T20:18:43 NotifyDEBUG auto-session DEBUG: launch_argv is nil, saving/restoring enabled
2024-10-14T20:18:43 NotifyDEBUG auto-session DEBUG: find_matching_directory {
  dirToFind = "/home/keinvanity",
  dirsToCheck = {}
}
2024-10-14T20:18:43 NotifyDEBUG auto-session DEBUG: suppress_session didn't find a match, returning false
2024-10-14T20:18:43 NotifyDEBUG auto-session DEBUG: bypass_save_by_filetype: false
2024-10-14T20:18:43 NotifyDEBUG auto-session DEBUG: auto_save_conditions_met: returning true
2024-10-14T20:18:43 NotifyDEBUG auto-session DEBUG: get_session_file_name no session_name, using cwd: /home/keinvanity
2024-10-14T20:18:43 NotifyDEBUG auto-session DEBUG: Create not enabled and no existing session, not creating session

@cameronr
Copy link
Collaborator

cameronr commented Oct 14, 2024

Ahh, I see the bug now. When auto-create = false, I'm not checking the right session name: it's using one named for the cwd not the manually saved name so it's blocking creation of the session. Thanks for all of the help digging into this!

cameronr added a commit to cameronr/auto-session that referenced this issue Oct 14, 2024
When auto-saving, if the session has been manually named use that
session name instead of the cwd session name. Fixes manually named
session not auto-saving on exit.
@cameronr
Copy link
Collaborator

cameronr commented Oct 14, 2024

Ok, just committed a fix. Can you try the updating my fork of auto-session and see if it's working for you now?

@kqvanity
Copy link
Author

Thank you so much for the time and your detailed guidance!
I just updated it and it works just fine!

Please just notify me when this PR would get merged to revert back to the original repo. Thanks!

@cameronr
Copy link
Collaborator

Glad it's working now! I'll reopen the issue and it'll get closed when the code is merged in.

@cameronr cameronr reopened this Oct 15, 2024
@rmagatti
Copy link
Owner

Great back and forth here btw! Thanks for making auto-session better! 🙏

cameronr added a commit that referenced this issue Oct 18, 2024
feat: autosave manually named sessions,  #386, #389
@cameronr
Copy link
Collaborator

@kqvanity changes are merged in now. You can switch back to the main fork

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants