Is there a way to let gVim only run a single instance, so that when a new file is opened with it it's automatically opened in a new tab in the currently running instance?
I know you can do that by passing --remote-tab-silent
but I want to configure gvim so that this becomes the default behavior. i.e. I want to type gvim filename
and make it act as if I passed the --remote-tab-silent
option to it.
gVim 7.2
Edit
I'm on windows (vista)
If you are using the bash shell (on Linux/OS X/using Cygwin) is to add you ~/.bashrc
file:
gvim () { command gvim --remote-silent "$@" || command gvim "$@"; }
On Windows I think you could have a gvim.bat
batch-script to achieve the same..
gvim.exe -p --remote-tab-silent %1 %*
If gvim.exe isn't in your path
Run > Search "Environment"
Edit PATH var for current user or system.
It depends on your operating system and shell. Using linux you can always set up an alias like:
alias gvim='gvim --remote-tab-silent'
in your .bashrc
(if you use bash as your login shell).
On windows see the Vim wiki for solution: http://vim.wikia.com/wiki/Launch_files_in_new_tabs_under_Windows .
I've found the --remote-tab-silent
option in an alias to work for the most part except when I've wanted to pass options to gvim (e.g. gvim --serverlist
) - in which case gvim treats the option as a literal filename which is no good as firstly that's not what you wanted and secondly you have to clean up the buffers from your now tainted vim session.
It's not practical to use another alias or resolve vim
/gvim
differently for some cases such as the following.
gvim
gvim /path/to/files
gvim --serverlist
gvim -p /path/to/file1 /path/to/file2
gvim -t tag filename
My solution is the following wrapper script around gvim
(~/.bin/gvim
) as Tom Veiner suggests but this will only use an existing server if none of the arguments are gvim
options - otherwise, a new server is created.
#!/usr/bin/perl
use v5.10;
sub gvim { exec { '/usr/bin/gvim' } '/usr/bin/gvim', @_; }
if (scalar @ARGV) {
unshift @ARGV, '--remote-tab-silent' unless /^--?/ ~~ @ARGV;
gvim @ARGV
}
else {
chomp(my $serverlist = `gvim --serverlist`);
if (length $serverlist) {
gvim '--remote-send', '<Esc>:tabnew<CR>'
} else { gvim }
}
alias tvim="gvim --servername `gvim --serverlist | head -1` --remote-tab"
This make vim open a new file in new tab on same instance of vim. Source: http://eustaquiorangel.com/posts/477
Portable Wrapper Script:
I got a little tired of working around this in cygwin + windows so I finally did something about it. I started with the wrapper script defined above but I wound up making it a lot more robust and multi-env capable for *nix and Win.
#!/bin/bash
#bash wrapper for windows/cygwin gvim
#####################################################################
## Cygwin/*nix and Windows gvim wrapper script, alias friendly, path friendly
## Author: Matt Gregory (skyleach (AT) geemale (dot) com)
## Version: 1.5
## Date: Thu Jun 12 10:02:54 2014
## Known Bugs:
## Changes:
## Thu Jun 12 10:04:08 2014 : Initital posting to StackOverflow
#####################################################################
[[ -z ${WINVIM} ]] && WINVIM=true
[[ -z ${VIMRUN} ]] && export VIMRUN='' #scoping
if [[ ${WINVIM} = false ]]; then
[[ ! ${VIMRUN} ]] && VIMRUN='/bin/gvim'
ANS=$("${VIMRUN}" --serverlist | grep GVIM)
else
[[ ! "${VIMRUN}" ]] && VIMRUN='/cygdrive/c/Program Files/vim/vim74/gvim'
ANS=$(ps -Wsl | grep "${VIMRUN}" | sed -e "s/\s\+\([0-9]\+\).*/\1/g")
fi
[[ ! -z ${VIM} && ${WINVIM} = true ]] && export VIM=$(cygpath -wal "${VIM}")
RT="--remote-tab"
[[ $ANS ]] || unset RT
if [ ! -z ${DEBUG} ]; then
echo "WINVIM: ${WINVIM}"
echo "VIMRUN: ${VIMRUN}"
echo "ANS: ${ANS}"
echo "VIM: ${VIM}"
fi
#process arguments or stdin
if [ ${#} -ne 0 ]; then
[[ ! -z ${DEBUG} ]] && echo "Got arguments [${#}]:'${@}'"
for OFILE in "${@}"; do # if [ -f "${OFILE}" ] || [ -d "${OFILE}" ]; then
[[ -h ${OFILE} ]] && OFILE="$(readlink -f "${OFILE}")"
[[ ${WINVIM} == true ]] && OFILE=$(cygpath -wal "${OFILE}")
echo "\"${VIMRUN}\" --servername GVIM $RT \"${OFILE}\""
"${VIMRUN}" --servername GVIM $RT "${OFILE}" &
if [[ -z ${RT} ]] || [[ ! "${RT}" ]]; then
RT="--remote-tab"
sleep 5 #give gvim time to start up, running too fast messes things up
else
sleep .3 #shorter sleep for tabs
fi
#fi
done
else
while read OFILE; do
[[ -h ${OFILE} ]] && OFILE="$(readlink -f "${OFILE}")"
[[ ${WINVIM} == true ]] && OFILE=$(cygpath -wal "${OFILE}")
echo "\"${VIMRUN}\" --servername GVIM $RT \"${OFILE}\""
"${VIMRUN}" --servername GVIM $RT "${OFILE}" &
if [[ -z ${RT} ]] || [[ ! "${RT}" ]]; then
RT="--remote-tab"
sleep 3 #give gvim time to start up, running too fast messes things up
else
sleep .3 #shorter sleep for tabs
fi
done
fi
# vim: set filetype=sh:
How to use it effectively:
- Install the above code into a script file on yor path somewhere
- Add a WINVIM environment variable to windows or your ~/.bashrc file in order to set the default script behavior. true/use windows. false/use x11
alias some command to cygwin and/or windows gvim like so:
echo "alias gwrap='WINVIM=false ~/src/localscripts/wgwrap'" >> ~/.bashrc echo "alias wgvim='wgwrap'" >> ~/.bashrc
NOTE: If the hard-coded paths to gvim are incorrect for your system you can edit the script directly, the alias(s) and/or add the environment variables WINVIM and/or VIMRUN. You can set them in the alias as I do above for gwrap or you can add them to your .bashrc or Windows system environment.
I often find that I want to go to a specific place in a file. The only way I found to do this was:
gvim --remote-send '^[:tabnew +$lineno $filename ^M'
where ^[
is esc (typed ctrl-v esc) and ^M
is enter (ctrl-v enter).
Hope this helps. If anyone understands how to use --remote-expr, give me a shout.
I'm using TotalCommander for file browsing. It lets you press "F4" to edit the file. So in the "Editor for F4" option window, you just need to do the following:
C:\Program Files (x86)\Vim\vim73\gvim.exe --remote-tab-silent
Works on my win7 64bit machine.
The solutions above don't launch the gvim server on first execution, so I use:
ANS=`pgrep -fx "$VIM"`
# Launch server if needed
if [[ ! $ANS ]]; then
$VIM
fi
# Now open the file
if [[ $1 ]]; then
$VIM --remote-tab "$@"
fi
modified from https://stackoverflow.com/a/15335004/214686
NOT For WINDOWS
I use MacVim (snapshot 73).
Add this to your .bash_profile.
It won't generate "NO NAME" and error message.
vi() {
if [[ `mvim --serverlist` == 'VIM' ]]; then
command mvim --remote-tab-silent "$@"
else
command mvim "$@"
fi
}
Using MacVim, I discovered the default servername was simply VIM. Sticking with that theme, I threw the following function in my bashrc and it works like a charm:
mvim() { ~/bin/mvim --servername VIM --remote-tab-wait-silent $* & }
gvimt () { [ $# -ne 0 ] && command gvim --remote-silent-tab $@ || command gvim $@; }
I'm actually using
gvim () {
if [ "$#" -gt 0 ]
then
gvim --remote-tab-silent "$@" &
else
gvim "$@" &
fi
}
It kills errors and only used the flag when there is a parameter
来源:https://stackoverflow.com/questions/936501/let-gvim-always-run-a-single-instance