echasnovski / mini.nvim

Library of 40+ independent Lua modules improving overall Neovim (version 0.8 and higher) experience with minimal effort
MIT License
4.45k stars 171 forks source link

[mini.sessions] Session management based on git branches #987

Closed GuillaumeLagrange closed 1 week ago

GuillaumeLagrange commented 1 week ago

Contributing guidelines

Module(s)

mini.sessions, maybe mini.git

Description

VSCode has a neat feature described in this screenshot

image

What it does is automatically save and restore editors (~buffers + windows in nvim world) depending on your source control branch.
There is also a setting for a default behavior, i.e when a new branch is opened.

Would such a feature belong to mini.sessions ? I know other plugins manage this kind of stuff, but I really like mini.sessions

Even if it does not, I think a snippet on how to do this could be handy in the documentation, what do you think ?

I could try and build one, but I was wondering if anyone new of a way to react to branch change events ? I would rather avoid polling a git status command every few seconds to detect that we just changed session.

Key points of the UX I would love

echasnovski commented 1 week ago

Thanks for such detailed suggestion!

I consider overall design and feature set of 'mini.sessions' complete. So I am afraid this type of functionality won't be part of 'mini.sessions'.

The 'mini.git' module could help, but it works for every buffer separately (gets data from that buffer's repository, and not necessarily from current working directory). And as sessions are allowed to contain buffers from several repositories, it is not clear when it should prompt the session update.

Closing as not planned.


My best suggestion would indeed be to make a best effort of automating this:

GuillaumeLagrange commented 6 days ago

I settled with a small autocommand on focus gain, since I generally have a terminal external to nvim where I perform any git operation.

Sharing the solution I came up with in case anyone wants the same behavior as me i.e

Init Mini.sessions with the following options

    require('mini.sessions').setup({
      file = '',
    })

Then


local function get_session_name()
  local name = string.gsub(vim.fn.getcwd(), '/', '_')
  local branch = vim.trim(vim.fn.system('git branch --show-current'))
  if vim.v.shell_error == 0 and branch ~= '' then
    return name .. '_' .. branch
  else
    return name
  end
end

if vim.fn.argc(-1) == 0 then
  vim.api.nvim_create_autocmd({ 'VimEnter', 'FocusGained' }, {
    nested = true,
    callback = function()
      local session_name = get_session_name()

      -- Save session for current branch
      if vim.v.this_session ~= '' then
        MiniSessions.write()
      end

      if MiniSessions.detected[session_name] and string.find(vim.v.this_session, session_name, 1, true) == nil then
        MiniSessions.read(session_name)
      else
        -- If we are opening a new branch, create a session for the new branch with current state
        MiniSessions.write(get_session_name())
      end
    end,
  })

  vim.api.nvim_create_autocmd('VimLeavePre', {
    callback = function()
      if vim.v.this_session == '' then
        return
      end

      MiniSessions.write(get_session_name())
    end,
  })
end

It is extremely opinionated (and will not work on Windows because I handle session paths in a very dirty way), but hopefully it could give some ideas to some people

Cheers !

echasnovski commented 6 days ago

Thanks for the follow up!

This looks relatively straightforward and easy to understand. Nice job!

The fact that it synchronously executes system command is not ideal, but I guess it is not a huge deal as it is executed on rather rare events.