Difference between revisions of "How to open files in specific Vim instance"

From Vifm Wiki
Jump to navigation Jump to search
(Add shell integration. Also fix variable naming.)
(<source> -> <syntaxhighlight>)
 
Line 11: Line 11:
 
Say you have a mapping to open file in Vim which looks like this:
 
Say you have a mapping to open file in Vim which looks like this:
  
<source lang="vim">
+
<syntaxhighlight lang="vim">
 
nnoremap o :!gvim --remote-tab-silent %f &<cr>
 
nnoremap o :!gvim --remote-tab-silent %f &<cr>
</source>
+
</syntaxhighlight>
  
 
Same should be applicable to <code>'vicmd'</code>/<code>'vixcmd'</code> options.
 
Same should be applicable to <code>'vicmd'</code>/<code>'vixcmd'</code> options.
Line 25: Line 25:
 
Vim invocation command:
 
Vim invocation command:
  
<source lang="vim">
+
<syntaxhighlight lang="vim">
 
nnoremap o :!gvim $VIMARGS --remote-tab-silent %f &<cr>
 
nnoremap o :!gvim $VIMARGS --remote-tab-silent %f &<cr>
</source>
+
</syntaxhighlight>
  
 
Here <code>$VIMARGS</code> can include anything and we want to put
 
Here <code>$VIMARGS</code> can include anything and we want to put
Line 41: Line 41:
 
Setting environment variable looks like this:
 
Setting environment variable looks like this:
  
<source lang="vim">
+
<syntaxhighlight lang="vim">
 
let $VIMARGS='--servername work'
 
let $VIMARGS='--servername work'
</source>
+
</syntaxhighlight>
  
 
==== Command to pick target ====
 
==== Command to pick target ====
Line 51: Line 51:
 
better to add a command which would set target.  Here it is:
 
better to add a command which would set target.  Here it is:
  
<source lang="vim">
+
<syntaxhighlight lang="vim">
 
command! target :let $VIMARGS = '--servername "%a"'
 
command! target :let $VIMARGS = '--servername "%a"'
</source>
+
</syntaxhighlight>
  
 
That's it, now simply running <code>:target project1</code> will cause all files
 
That's it, now simply running <code>:target project1</code> will cause all files
Line 72: Line 72:
 
<code>~/.bashrc</code>), for example:
 
<code>~/.bashrc</code>), for example:
  
<source lang="bash">
+
<syntaxhighlight lang="bash">
 
function g()
 
function g()
 
{
 
{
 
     gvim $VIMARGS --remote-tab-silent "$@"
 
     gvim $VIMARGS --remote-tab-silent "$@"
 
}
 
}
</source>
+
</syntaxhighlight>
  
 
No need for double quotes around <code>$VIMARGS</code> because we don't
 
No need for double quotes around <code>$VIMARGS</code> because we don't
Line 91: Line 91:
 
following manner:
 
following manner:
  
<source lang="vim">
+
<syntaxhighlight lang="vim">
 
command! target : let $VIMARGS = '--servername "%a"'
 
command! target : let $VIMARGS = '--servername "%a"'
 
               \| execute "!tmux %%i set-environment VIMARGS '".$VIMARGS."'"
 
               \| execute "!tmux %%i set-environment VIMARGS '".$VIMARGS."'"
</source>
+
</syntaxhighlight>
  
 
Here we set <code>$VIMARGS</code> variable for all new panes/windows of
 
Here we set <code>$VIMARGS</code> variable for all new panes/windows of

Latest revision as of 16:16, 8 March 2021

There are some usage scenarios in which one might want to open all/some files in specific Vim instance. This can be done via Vim client-server facilities which include means to send file for opening in specific instance. Vim must be compiled with +clientserver feature.

Here only single example is described, one can think of something better/different (binding to process id, terminal multiplexer session, etc.).

How files are opened[edit]

Say you have a mapping to open file in Vim which looks like this:

nnoremap o :!gvim --remote-tab-silent %f &<cr>

Same should be applicable to 'vicmd'/'vixcmd' options. Here you see mapping, because it is handy to have different ways to open files (in the same terminal, separate terminal multiplexer window/split, gVim instance).

Amending Vim run command[edit]

To bind the command we need to pass --servername option to Vim. Let's use environment variable $VIMARGS for this and put it into Vim invocation command:

nnoremap o :!gvim $VIMARGS --remote-tab-silent %f &<cr>

Here $VIMARGS can include anything and we want to put --servername argument there.

Picking target instance[edit]

By default $VIMARGS is empty, so first found server is used by remote commands (just as usual). Setting $VIMARGS to --servername name makes all consecutive file opens to use Vim with that server name (if there is none yet, it will be created).

Setting environment variable looks like this:

let $VIMARGS='--servername work'

Command to pick target[edit]

Having to type something like let $VIMARGS='--servername project' each time one wants to change target instance is not very good idea. It's better to add a command which would set target. Here it is:

command! target :let $VIMARGS = '--servername "%a"'

That's it, now simply running :target project1 will cause all files to be sent to project1 instance and after :target project2 all files will be sent to project2.

Integration with shell[edit]

There are many ways to open files without using Vifm, but quite popular one is probably opening files from shell. In this case, one might want to have the same functionality there. Lets assume there is an alias or a function that opens a file in gVim and teach it to make use of $VIMARGS in two steps.

Shell configuration update[edit]

Obviously, one needs to add the variable to shell configuration file (e.g. to ~/.bashrc), for example:

function g()
{
    gvim $VIMARGS --remote-tab-silent "$@"
}

No need for double quotes around $VIMARGS because we don't want to pass argument with empty value to Vim (it works as if it were . and starts browsing in current directory).

Communicating $VIMARGS to the shell[edit]

If terminal multiplexer is not used, nothing special needs to be done because environment variables set in Vifm are visible in all child processes.

In case tmux is used, our :target command could be updated in the following manner:

command! target : let $VIMARGS = '--servername "%a"'
               \| execute "!tmux %%i set-environment VIMARGS '".$VIMARGS."'"

Here we set $VIMARGS variable for all new panes/windows of the current tmux session. Note %%i, percent sign must be duplicated to survive first command substitution, which turns it into %i macro in the second one.