3

I'm currently using the session saving to restore the state when the app (MacVim) is closed.

nnoremap <leader>q :mksession! ~/.vim/Session.vim<CR>:wqa<CR>
nnoremap <leader>www :mksession! ~/.vim/Session.vim<CR>:qa!<CR>

function! RestoreSession()
   if argc() == 0 "vim called without arguments
        execute (has("gui_running") ? "" : "silent!") 'source ~/.vim/Session.vim'
   end
endfunction
autocmd VimEnter * call RestoreSession()

However, this only works for a single GUI window. When I trigger the shortcut, it closes the current window. After all the windows are closed in the same way and then I open the app again, only the last closed GUI window is restored.

Is there any way to close all the GUI windows simultaneously and restore all of them on the next launch?

  • Are you talking about multiple GUI windows, each opened with a separate invocation of vim? Or one GUI window containing multiple vim windows (e.g. if you use :split)? – B Layer Mar 16 '18 at 10:00
  • @BLayer The former. – Blaszard Mar 16 '18 at 10:01
  • Those are each separate sessions. :mksession only works on one session at a time. – B Layer Mar 16 '18 at 10:04
  • @BLayer So is there no way to achieve it? Seems that the default vim only focuses on the single session, so if it is ever possible, it must be supported by each GVim..., right? – Blaszard Mar 16 '18 at 10:11
  • Sorry don't quite understand. What is "the default vim"? – B Layer Mar 16 '18 at 10:33
4

As I mentioned in my comments a session is associated with a single invocation of Vim so you can't do exactly what you're hoping to do. But I also mentioned something might be possible using shell scripts and Vim's "clientserver" functionality. I decided to chase that down...primarily for my own edification but since it works I figured I'd share it. (Your version of Vim must be compiled with +clientserver. Look at the output of :version.)

These are rudimentary scripts. My goal is just to demonstrate the concept rather than build production-grade stuff.

save_vim_sessions.sh

#!/bin/bash  

# For each instance of Vim save the session in a common directory,
# save the files, and then quit Vim. You can run this from one of
# the Vim instances if you like, perhaps using a key mapping.

SESSDIR=/tmp/vimsess
if [[ -d $SESSDIR ]]; then
    rm "$SESSDIR"/* 2> /dev/null
else
    mkdir -p "$SESSDIR"
    chmod 0777 "$SESSDIR"
fi

for server in $(vim --serverlist); do
    vim --servername "$server" \
        --remote-send ':<c-u>mksession! $TMP/vimsess/%:t<cr>' \
        --remote-send ':wqa<cr>'
done

For the most part the --remote-send parameters are self explanatory with the possible exception of <c-u> and %:t. <c-u> sends Ctrl-U which clears the Vim command line in case some text was already present. % represents the file path/name loaded in the current buffer. :t is a modifier that strips off the path and leaves just the name. For example, if you're editing /foo/bar.txt the session will be saved in /tmp/vimsess/bar.txt. It's a quick and dirty way to choose a relatively unique name for the session file. (Remember this isn't production-grade.)

launch_vim_sessions.sh

#!/bin/bash  

# Launch a vim session for each file in the common directory. 
# The end result is to exactly restore everything closed by 
# the other script.

SESSDIR=/tmp/vimsess
if [[ ! -d $SESSDIR ]]; then
    echo "Directory $SESSDIR not found"
    exit 1
fi

for sess in "$SESSDIR"/*; do
    vim -S "$sess" &
done

This assumes that $TMP in Vim has value /tmp. Update that and the directory in SESSDIR as needed to match your own preferences and/or system.

I'm using command vim here but that could just as well be gvim...I tested it with GUI windows as opposed to terminal Vim (the question is about GUI vim).

That's it.

  • Thanks but what does <c-u> and %:t do? I still find that it is not working and struggling... – Blaszard Mar 20 '18 at 8:02
  • @Blaszard Ever get this working? I wrote this for a lark mostly but I now use it all the time...works great. – B Layer Jul 9 '18 at 22:27
  • Unfortunately, at the time of the last comment (in March), no. And these days I use neovim, and don't use MacVim that much. – Blaszard Jul 9 '18 at 23:33
  • @Blaszard It should work with any version of vim/neovim that was compiled with +clientserver. I use it on linux and with gvim on windows. Anyways, was just curious...ironic that I ended up using it not you. – B Layer Jul 9 '18 at 23:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.