2
0
mirror of https://github.com/mhinz/neovim-remote synced 2024-11-11 13:10:34 +00:00
neovim-remote/README.md
2017-09-29 17:09:08 +02:00

4.4 KiB

neovim-remote

Build status Wheel? PyPI version Supported Python versions License

Intro

nvr is a tool that helps controlling nvim processes.

It does two things:

  1. adds back the --remote family of options (see man vim)
  2. 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.

Use case

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'

Installation

See INSTALLATION.md

Usage

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.

Demos

(Click on the GIFs to watch them full-size.)

Using nvr from another shell: Demo 1

Using nvr from within :terminal: Demo 2

FAQ

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