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

From Vifm Wiki
Jump to navigation Jump to search
m (Xaizek moved page How to send all files to specific Vim instance to How to open files in specific Vim instance without leaving a redirect: Better wording in the title)
(Add shell integration. Also fix variable naming.)
Line 42: Line 42:
  
 
<source lang="vim">
 
<source lang="vim">
let $VIMARG='--servername work'
+
let $VIMARGS='--servername work'
 
</source>
 
</source>
  
 
==== Command to pick target ====
 
==== Command to pick target ====
  
Having to type something like <code>let $VIMARG='--servername project'</code>
+
Having to type something like <code>let $VIMARGS='--servername project'</code>
 
each time one wants to change target instance is not very good idea.  It's
 
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:
 
better to add a command which would set target.  Here it is:
Line 58: Line 58:
 
to be sent to <code>project1</code> instance and after
 
to be sent to <code>project1</code> instance and after
 
<code>:target project2</code> all files will be sent to <code>project2</code>.
 
<code>:target project2</code> all files will be sent to <code>project2</code>.
 +
 +
=== Integration with shell ===
 +
 +
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 <code>$VIMARGS</code> in two
 +
steps.
 +
 +
==== Shell configuration update ====
 +
 +
Obviously, one needs to add the variable to shell configuration file (e.g. to
 +
<code>~/.bashrc</code>), for example:
 +
 +
<source lang="bash">
 +
function g()
 +
{
 +
    gvim $VIMARGS --remote-tab-silent "$@"
 +
}
 +
</source>
 +
 +
No need for double quotes around <code>$VIMARGS</code> because we don't
 +
want to pass argument with empty value to Vim (it works as if it were
 +
<code>.</code> and starts browsing in current directory).
 +
 +
==== Communicating <code>$VIMARGS</code> to the shell ====
 +
 +
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 <code>:target</code> command could be updated in the
 +
following manner:
 +
 +
<source lang="vim">
 +
command! target : let $VIMARGS = '--servername "%a"'
 +
              \| execute "!tmux %%i set-environment VIMARGS '".$VIMARGS."'"
 +
</source>
 +
 +
Here we set <code>$VIMARGS</code> variable for all new panes/windows of
 +
the current tmux session.  Note <code>%%i</code>, percent sign must be
 +
duplicated to survive first command substitution, which turns it into
 +
<code>%i</code> macro in the second one.
  
 
[[Category:HOWTO]]
 
[[Category:HOWTO]]

Revision as of 14:52, 26 February 2015

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

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

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

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

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

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

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

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.