Posted on :: Tags:

The Problem

There are many different session plugins in Neovim, but none that I have found to exactly what I want. When you are moving between multiple different branches of a Git repo, it would be nice to have sessions saved for that specific branch. That's what this does!

The Script

In your .zshrc, copy the following code:

function nv() {
  if [[ -z "$@" ]]; then
    CWD=${PWD:t}
    SESSION_PATH=$HOME/.local/share/nvim/sessions/${CWD}/
    SESSION_FILE="Session.vim"
    GIT_BRANCH=""
    if [[ -d ".git" ]]; then
        GIT_BRANCH=$(git branch --show-current)
        GIT_BRANCH=${GIT_BRANCH//\//-} # replace '/' with '-' in branch name for dir purposes
        mkdir -p ${SESSION_PATH} # make session path if not exists
        SESSION_FILE="${SESSION_PATH}Session-${GIT_BRANCH}.vim"
    fi
    if [[ -f "$SESSION_FILE" ]]; then
        nvim -S "$SESSION_FILE" -c "lua vim.g.savesession = true ; vim.g.sessionfile = \"${SESSION_FILE}\""
    else
        nvim -c "lua vim.g.savesession = true ; vim.g.sessionfile = \"${SESSION_FILE}\""
    fi
  else
    nvim "$@"
  fi
}

Well, what does this do?

If you run source ~/.zshrc, this will allow you to now run $ nv command instead of $ nvim. This is not the final step, but it's a start. What's happening is that we are now able to store sessions in directories that match your Git repository layouts. For instance, say that I have a repo called website, and two branches, test and main; What this allows for is your repo test has two subdirectories called test and main under /.local/share/nvim/sessions/. In these subdirs you will have a session file for each branch that will get loaded when you run $ nv. This script will run Neovim with those correct directory session files. Now for the Neovim portion.

The Code

In your Neovim config, you will need an autocommand to save the correct session file. This requires a Neovim version of 0.10 or greater. In a file that gets sourced or is in your init.lua, add the following command:

vim.api.nvim_create_autocmd("VimLeavePre", {
	pattern = "*",
	callback = function()
		if vim.g.savesession then
			if vim.g.sessionfile ~= "" then
			  vim.api.nvim_command(string.format("mks! %s", vim.g.sessionfile))
			end
		end
	end,
})

Here we say, on VimPreLeave (right before Neovim exits) we want to save the session. If the session file does not already exist, then make one! This comes from the ${SESSION_FILE} seen in the script above. Notice that in that else statement from the script we are also setting savesession to true, so this should just work.

If we run $ nvim we will get our normal setup with no sessions which can sometimes be convenient as well, so it's the best of both worlds.