Session Management in Vim
If you ask me about the most underrated feature in Vim, my answer would be ‘Session Management’ straightaway! Just like any other “modern” editors, Vim does support sessions.
What is a Session
Before I go in-depth, let me explain what exactly is a Session in Vim. Simply
:help session): A Session keeps the Views for all windows, plus the global settings.
An example of session could be: If I have opened a project and worked for an hour, and then closed it. My Vim session would be one hour long.
Sessions in Vim are not persistent by default. One has to make it persistent. Most people do not know about it because they probably have never felt the need for it.
I was one of those people who didn’t feel the need for storing sessions, until recently. And I am not ashamed of it. It just happens… mostly because, we don’t need it yet.
Importance of Session
To answer the question ‘How a persistent Session is Useful’, let’s find out what we lack without it.
- Time. Yes! Imagine, you are working on a project, and for some reason, you closed Vim. So when you open it again, you gotta recreate those perfectly sized windows, open files of reconfigure options etc.
- Context. It’s not easy to remember which file you were editing, the last time you have worked on a project.
Now, what if I say that you could boot into Vim without losing any of the previous windows, tabs etc? not even the cursor location. That would be great, is not it?
That’s where persistent session comes into action. It enables Vim to load the last session, much like what we see in editors like Visual Studio Code.
There are multiple techniques one may use to handle Sessions. I will, however, talk about the one I use.
First, I let Vim look for any existing session files. If one exists for the
current session, Vim would update it automatically when I close Vim. The Reason
I don’t let Vim save Sessions for which no session file exists, because that
makes me counter-productive. For example, I needed to edit a config file, say,
.vimrc from my
$HOME directory. Had I enabled auto-create session file, a
new session file for
$HOME directory will be created, which I obviously don’t
want. That session does not make any sense.
So, if a session file is not created automatically, how do I create it then?
Well, it’s really simple. I defined a command for creating new Sessions, called
SessCreate using Vim Language.
Now, I can simply call this command from inside Vim whenever I need it.
Let me show you how I did it.
fu! SessionCreate() if !isdirectory(expand("~/.vim/sessions")) execute "call mkdir(expand('~/.vim/sessions', 'p'))" endif execute 'mksession ~/.vim/sessions/' . split(getcwd(), '/')[-1] . '.vim' endfunction command SessCreate call SessionCreate()
if !isdirectory(expand("~/.vim/sessions")) execute "call mkdir(expand('~/.vim/sessions', 'p'))" endif
Check if a directory
$HOME/.vim.sessions exist. If not, create it with
execute "call mkdir(expand('~/.vim/sessions', 'p'))". This is the directory
where sessions are stored. An alternate location for storing session is the
project directory itself. But that is not something I want to use, as not
everyone uses Vim. So, this would be an added bloat for them.
call in Vim Script is uses to call a function.
mkdir() is used to create a
p is a flag that can be passed to
mkdir() so that it creates
parent directories as and when necessary. Lastly,
expand() is used to expand
any Shell expandables. Here, it converts
execute 'mksession ~/.vim/sessions/' . split(getcwd(), '/')[-1] . '.vim'
mksession is a built-in command for creating session from current Vim state.
It saves the created session in
~/.vim/sessions/DIR_NAME.vim. Here, the
DIR_NAME is the working directory where Vim is opened. So, session for
~/Projects/github/awesome-vim would be saved into
Saving a Session in Existing Session File
Now, it’s time for some automation. Check out the following code snippet:
fu! SessionSave() if filewritable(expand('~/.vim/sessions/' . split(getcwd(), '/')[-1] . '.vim')) execute 'mksession! ~/.vim/sessions/' . split(getcwd(), '/')[-1] . '.vim' endif endfunction
This function checks whether the existing session file is writable. And save
latest session if true. That’s it. The exclamation mark(
!) is for overwriting
Restoring a Session
Finally, when I open Vim again, I want saved buffer(if any) to be restored. Following function is responsible for this:
fu! SessionRestore() let l:session_file = '~/.vim/sessions/' . split(getcwd(), '/')[-1] . '.vim' if filereadable(expand(session_file)) echo session_file execute 'source ~/.vim/sessions/' . split(getcwd(), '/')[-1] . '.vim' if bufexists(1) for l in range(1, bufnr('$')) if bufwinnr(l) == -1 exec 'sbuffer ' . l endif endfor endif endif endfunction
Let me explain what it does exactly.
let l:session_file = '~/.vim/sessions/' . split(getcwd(), '/')[-1] . '.vim' if filereadable(expand(session_file)) echo session_file execute 'source ~/.vim/sessions/' . split(getcwd(), '/')[-1] . '.vim' endif
First, check if the file is readable. There’s no point in sourcing it if Vim can’t access it. Then simply source it to Vim. That’s it.
if bufexists(1) for l in range(1, bufnr('$')) if bufwinnr(l) == -1 exec 'sbuffer ' . l endif endfor endif
bufexists() function checks if any
bufnr() returns all
available buffers. …and so on. Read more about them using
So, that’s it. Persistent Sessions makes our life dramatically easier when using Vim (or NeoVim, GVim whatever flavour you use).
P.S.: I am a new Vim user. I am open to suggesstions. Feel free to suggest anything that would make use Vim in a more productive way!!