nvr is a tool that helps controlling nvim processes.
It does two things:
- adds back the
--remote
family of options (seeman vim
) - helps controlling the current nvim from within
:terminal
To target a specific nvim process, use either the --servername
option or set
the environment variable $NVIM_LISTEN_ADDRESS
.
If the targeted address does not exist, nvr starts a new process on its own by
running "nvim". You can change the command by setting $NVR_CMD
.
Since $NVIM_LISTEN_ADDRESS
is implicitely set by each nvim process, you can
call nvr from within Neovim (:terminal
) without specifying --servername
.
NOTE: This tool relies on the Unix forking model, and thus Windows is not supported.
Imagine Neovim is set as your default editor: EDITOR=nvim
.
Now run git commit
. In a regular shell, a new nvim process starts. In a
terminal buffer (:terminal
), a new nvim process starts as well. Now you have
one nvim nested within another. You don't want that. Put this in your vimrc:
if has('nvim')
let $VISUAL = 'nvr -cc split --remote-wait'
endif
That way, you get a new window for entering the commit message instead of a nested nvim process.
Alternatively, you can make git always using nvr. In a regular shell, nvr will create a new nvim process. In a terminal buffer, nvr will open a new buffer.
$ git config --global core.editor 'nvr --remote-wait-silent'
See INSTALLATION.md
Start a nvim process (which acts as a server) in one shell:
$ NVIM_LISTEN_ADDRESS=/tmp/nvimsocket nvim
And do this in another shell:
$ # Spares us from using --servername all the time:
$ export NVIM_LISTEN_ADDRESS=/tmp/nvimsocket
$ # This is optional, since nvr assumes /tmp/nvimsocket by default.
$ # Open two files:
$ nvr --remote file1 file2
$ # Send keys to the current buffer:
$ nvr --remote-send 'iabc<esc>'
$ # Enter insert mode, insert 'abc', and go back to normal mode again.
$ # Evaluate any VimL expression, e.g. get all listed buffers:
$ nvr --remote-expr "join(sort(map(filter(range(bufnr('$')), 'buflisted(v:val)'), 'bufname(v:val)')), "\""\n"\"")"
.config/git/config
vim/vimrc
zsh/.zprofile
See nvr -h
for all options.
(Click on the GIFs to watch them full-size.)
Using nvr from within :terminal
:
How to open directories?
:e /tmp
opens a directory view via netrw. Netrw works by hooking into certain
events, BufEnter
in this case (see :au FileExplorer
for all of them).
Unfortunately Neovim's API doesn't trigger any autocmds on its own, so simply
nvr /tmp
won't work. Meanwhile you can work around it like this:
$ nvr /tmp -c 'doautocmd BufEnter'
Reading from stdin?
Yes! E.g. echo "foo\nbar" | nvr -o -
and cat file | nvr --remote -
work just
as you would expect them to work.
Exit code?
If you use a recent enough Neovim, nvr will use the same exit code as the linked nvim.
E.g. nvr --remote-wait <file>
and then :cquit
in the linked nvim will make
nvr return with 1.
Talking to nvr from Neovim?
Imagine nvr --remote-wait file
. The buffer that represents "file" in Neovim
now has a local variable b:nvr
. It's a list of channels for each connected nvr
process.
If we wanted to create a command that disconnects all nvr processes with exit code 1:
command! Cquit
\ if exists('b:nvr')
\| for chanid in b:nvr
\| silent! call rpcnotify(chanid, 'Exit', 1)
\| endfor
\| endif