3

I don't usually navigate my filesystem from Vim, but instead use a file manager and sometimes even the good, old interactive shell (command line).

Issuing vim file from the command line or from a terminal based file manager (MC, Vifm, Ranger, ...) totally defeats their purpose of navigation, since Vim takes over the terminal, blocking the shell or file manager. Of course, even this is impossible for GUI file managers since they don't run in a terminal.

A general solution is to use xterm -e vim file & to open each desired file in its own terminal, but after some time I end up with various open terminals, each with a file, and cycling through them with AltTab becomes cumbersome.

Is there a way to open every new file from my navigation utility (whatever it is) in a new buffer/tab of a same existing Vim instance?

1 Answer 1

6

First make sure vim --version | grep clientserver returns +clientserver. If it returns - instead of +, an easy way to enable that capability is to install Gvim, even though we won't use it. In Debian and Ubuntu, sudo apt install vim-athena installs it. An alternative for experienced users who definetly want to skip Gvim is to build Vim from sources with flags --with-x=yes --disable-gui.

Now that you have +clientserver, create the file vimserver with contents:

#!/bin/sh
serv=${S:-xtvim}
if vim --serverlist | grep -qxiF "$serv"; then
    vim --servername "$serv" --remote-tab "$@"
else
    xterm -e vim -p --servername "$serv" "$@" &
fi

Don't forget to put vimserver in a directory in your $PATH and to make it executable with chmod +x vimserver. If you use other terminal, find in its manpage what is the appropriate flag to execute the command in a new terminal window1.

Test it on some files (multiple files can be passed in the arguments):

vimserver file1 file2
vimserver file3 file4 file5
S=xyz vimserver file6

Each file opens in a new tab of a same Vim instance named "XTVIM", except for file6, which goes to a different instance, "XYZ". If you want new files to be in a new buffer, just change --remote-tab to --remote and remove the -p flag.

Explaining vimserver

The server name, assigned to the serv variable, defaults to "xtvim", but as seen above a different one can be specified with the environment variable S.

Grep looks for the exact value of serv in the server list (but case-insensitively since Vim forces its server names to uppercase). If it is found, that server loads the file, otherwise, a new terminal is launched and the server with it.

Requesting focus

The terminal is not focused when a file is opened in an already existing server; Setting an instance name for the window and adding a Xdotool line solves that:

#!/bin/sh
serv=${S:-xtvim}
if vim --serverlist | grep -qxiF "$serv"; then
    xdotool search --classname "^$serv$" windowactivate
    vim --servername "$serv" --remote-tab "$@"
else
    xterm -name "$serv" -e vim -p --servername "$serv" "$@" &
fi

Because of the -name option, Xdotool can locate the Vim window and request focus to it. Some terminals lack that option but have --role, which Xdotool can also use for search since version 3.20210804.2.

File managers

Vifm

Edit ~/.config/vifm/vifmrc:

filextype <text/*> vimserver %f

Multiple files can be opened at the same via visual mode or tagging.

Midnight Commander

Edit the extension file ~/.config/mc/mc.ext:

type/text
 Open=vimserver %s

Tagging multiple files is also possible in MC.

GUI file-managers

For many of them, the procedure is right clicking a text file, Open with... > Custom command line / Use a custom command. In the command text field, enter vimserver and, if any, mark a checkbox or press the button that sets it as default.

Gvim

If you are OK with Gvim2, do not bother with vimserver. Just use gvim --remote-tab-silent.

1: Gnome-terminal, Xfce4-terminal and Terminator use the -x flag, not -e.
2: Goldilocks comments about the Gvim usage in What are practical uses of the client-server mode?.

1
  • gvim --remote <filename> opens a file in a buffer in an existing gvim instance.
    – NeilG
    Nov 17, 2021 at 7:09

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.