0

Here's how I restart vim:

$ vim
:q
$ vim

Is there a way to restart vim so that there is no need to type the second vim in the shell?

  • 1
    If you just want to reload the configuration of .vimrc, you could just do :source $MYVIMRC. But, as for restarting from within vim... I can't think of anything. – klaus Sep 6 at 2:43
  • 1
    This seems to be a little bit of an XY problem. What do you want to accomplish? Are you looking to reset vim to all of it's defaults, or do you actually want the vim program to close and restart? (In which case, I don't think there will be any solution other than close it and restart) – DJMcMayhem Sep 6 at 5:19
  • 1
    @DJMcMayhem I am looking to reset all settings to default ones, reload all plugins, and reload vimrc. – Flux Sep 6 at 5:54
  • 5
    Hehe. Start vim from shell with vim || vim. If you :q then that's it. But if you :cquit then a new instance of vim will start up right after the first instance exits. ;) I wouldn't actually do this, of course, though it's true that you can have vim exit with an error code...i.e. non-zero...by using :cquit. – B Layer Sep 6 at 6:15
  • 2
    I don't understand. If you want to restart, you quit and start again. That's how it works for all applications. – Christian Brabandt Sep 6 at 7:37
3

To answer your title question is pretty simple, just add this to your shell aliases (note untested, there may be syntax issues, but I think it gets the point across):

vim() {
    while command vim $@; do
    done;
}

In other words, run vim in an infinite loop. If you quit with :q, The script will restart vim, and you can break out and really quit by using :cq.


But I think if I just leave you there, it'll be doing you a disservice. I believe what your real question is and what you really wanted to do is that you want to reload vim config from scratch without losing your editing session.

There are two things you need to do to make that happen:

  1. You'll want to save your editing session and reload them later; this will allow you to restore your open buffers and window/tab arrangements. Vim supports the basic mechanism for session saving here using :mksession, but this builtin functionality is a bit low level for daily use. If you need to do this regularly, you'd want to have a session manager to make this feature actually usable and mostly automatic, try either xolox/vim-session plugin or tpope/vim-obsession.

  2. You probably also want to set persistent undofile, this setting allows you to undo your edits throughout multiple editing session (i.e. over restarts)

  • 1
    I think you need a command inside the loop; : should work: 0x0.st/zJMq.txt – user938271 Sep 6 at 16:22
  • 1
    It works, but if you suspend Vim then send it to the foreground, then it stops working (i.e. after quitting Vim, it's not restarted anymore). At least that's what happens in bash 4.3.48. – user938271 Sep 6 at 16:29
3

Add this in your vimrc:

nno <space>R :<c-u>call <sid>vim_quit_and_restart()<cr>
fu! s:vim_quit_and_restart() abort
    if has('gui_running') | echo 'not available in GUI' | return | endif
    sil! update
    sil call system('kill -USR1 $(ps -p '.getpid().' -o ppid=)')
    qa!
endfu

And this in your bashrc:

trap __catch_signal_usr1 USR1
__catch_signal_usr1() { trap __catch_signal_usr1 USR1; vim; }

Pressing SPC R should make Vim restart.

Works on Vim 8.1.1967 and bash 4.3.48.


If your shell is zsh (version 5.7.1 sure; other versions probably), things get more complicated because of a pitfall. If you suspend Vim (C-z, :stop, :suspend), after restarting it one or several times, you may not be able to send it back to the foreground, because for some reason the Vim job gets lost (absent from the shell's job table).

It could be a bug in zsh, or a race condition, I don't know. There exists a workaround (restarting from a hook):

restarting_vim=
trap __catch_signal_usr1 USR1
__catch_signal_usr1() {
  trap __catch_signal_usr1 USR1
  restarting_vim=1
}
__restart_vim() {
  emulate -L zsh
  if [[ -n "${restarting_vim}" ]]; then
    restarting_vim=
    vim
  fi
}
precmd_functions=(__restart_vim)

but it suffers from another issue; you can't restart several times consecutively, unless you suspend and $ fg right back in between 2 restarts. Maybe this could be fixed with an additional workaround, making zsh automatically suspend and $ fg after every restart via another signal and trap, but it seems awkward.

As long as you never suspend Vim (install :nno <c-z> <nop> and :vno <c-z> <nop> to avoid any accident), the Vim mapping + zsh trap works fine (at least in my experience).

  • 1
    Problematic with gui – eyal karni Sep 16 at 7:34
1

I am on macOS with neovim. I will just provide my code:

if exists('g:GuiLoaded')
    nmap <leader>rv :!osascript -e 'tell application "Terminal" to do script "sh /users/eyalkarni/vimpy3/vimqt.sh"'<CR>
else
    nmap <leader>rv :!osascript -e 'tell application "Terminal" to do script "sh /users/eyalkarni/vimpy3/vimr.sh"'<CR>
endif

g:GuiLoaded signals neovim-qt. I assume it is VimR otherwise.

The bash file is:

killall nvim-qt || open -a nvim-qt || exit
  • You can check for and use @user938271 answer if on terminal – eyal karni Sep 19 at 21:29
  • That bash script is... non-sensical. The pipes should actually be &&s, because youre not chaining inputs and outputs. Each of those will actually run in their own subshell, too. – D. Ben Knoble Sep 20 at 2:04
  • I meant to do || because things are needed to be done in any case. Anyway, it doesn't matter. – eyal karni Sep 20 at 6:00
  • 2
    then use ; if you do not intend to AND/OR the commands. It certainly matters. – Christian Brabandt Sep 20 at 6:10

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.