vimsingle-instance

Using single vim instance with --remote-silent


I've always been a console vim user, but lately I've tried to use gvim. I've made settings such that my console habits won't suffer, such as opening an urxvt terminal at the current directory with .

However having multiple gvims and terminals open with my netbook is horrible, quickly reducing my vim-space to a centimeter or two. At best, the window width is halved, making it impossible to vertically split screen (tiling wm).

I went around this problem by aliasing vim to gvim --remote-silent and it worked fine for a couple of days, but today I needed to use -c '' and realized that having any switches behind --remote-silent opens those switches as files. So doing gvim --remote-silent --foo bar opens two files, --foo and bar.

I put a new alias for alias vim=gvim, but I'm afraid this will make me a console vim user again, sooner than I thought I would.

So the question is, what would be the preferred way to keep using gvim, with minimal effort (setting up the system can be laborous) so that I can still keep using vim with its full power. The solution does not need to use remote vim, it should just minimize the gvim windows.


Solution

  • I'm late coming to this party, but I have a suggestion.

    First, I agree with @Herbert - there's usually very little reason to ever run more than one Vim instance (console or otherwise). The advantages of keeping things in one instance is just too great. But, I see the need to mix in -c; although I can't see the need to do it myself :D.

    The best way I can see to get this functionality is to use the --remote-send feature of vim instead of --remote-silent. This means a bit of shell scripting, however:

    #!/bin/bash
    
    function resolveFile
    {
        if [ -f "$1" ]; then
            echo $(readlink -f "$1")
        else
            echo "$1"
        fi
    }
    
    function gg
    {
        local opts=$(getopt -o c: --long command: -n "gg" -- "$@")
        if [ $? != 0 ]; then return 1; fi
        eval set -- "$opts"
        cmd=""
        while :
        do
            case "$1" in
                -c|--command)
                    cmd="$2"
                    shift 2
                    ;;
                --) shift
                    break
                    ;;
            esac
        done
    
        if [[ -n "$cmd" ]]; then
            if [[ -n "${1-}" ]]; then
                cmd=":e $(resolveFile $1)<cr>$cmd<cr>"
            else
                cmd="$cmd<cr>"
            fi
            shift 1
        fi
        files=""
        for f in $@
        do
            files="$files $(resolveFile $f)"
        done
        cmd="$cmd:args! $files<cr>"
        gvim --remote-send "$cmd"
    }
    

    I've only marginally tested that, but you should be able to do things like:

    gg -c G file1 file2 file3 file4
    

    That should edit file1 and move to the bottom of it. It should then also add file2, file3 and file4 to the args list so that you can perform commands such as :bnext. It should also revert to the same sort of functionality as --remote-silent when you don't supply a -c.

    I really think it's worth jumping through these hoops in order to properly integrate your command-line experience with a single Vim instance. Having everything in one place is just too sweet to give up.