Let gVim always run a single instance

拈花ヽ惹草 提交于 2019-11-28 16:21:19
dbr

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 .

shalomb

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.

alsuren

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.

Stefan van der Walt

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!