Flaky Goodness

Integrating terminal Vim with Finder [UPDATED 2015-02-10]

February 24, 2014

MacVim is a great choice for Vim on the Mac. It is a pre-built GUI wrapper with a lot of nice extras that smooth the infamous Vim learning curve. But the Vim experience is better in its native habitat1, the terminal, and like others, I grew to prefer text-mode Vim.

I hate losing Finder integration though. I want to be able to double-click on a text file and have it open in my editor, preferably reusing an existing Vim session if available. This is non-trivial to set up with terminal Vim. The approach I'll describe here is fiddly, hacky and a work in progress. But it does work.

XQuartz

Might as well get the hard part over with first. Check to see if you have Vim compiled with the necessary options:

vim --version

Do you see +clientserver, +X11, and +xterm_clipboard? I'm guessing you do not.

Here's the thing. If you want this procedure to work you're going to need to install and run XQuartz in the background, all the time. I have mine set to run at startup and I leave it running while I use my machine. I'd prefer not to need this because I don't use X11 for anything else, but it is fundamental to this configuration so I've learned to live with it.

Go ahead and install XQuartz now, because you'll need it on your system before re-compiling Vim.

UPDATE 2015-02-10: OS X 10.10 Yosemite

You'll need to link the X11 include and library directories to where the vim configure script can find them:

sudo ln -s /opt/X11/include /usr/include/X11 sudo ln -s /opt/X11/lib /usr/lib/X11

Compile Vim from source

You can't call yourself a programmer until you've compiled your own editor from source, right? Well, here we go.

Download the Vim source and configure. Here are the options I use:

make distclean
./configure --with-features=huge \
                --enable-rubyinterp \
                --enable-pythoninterp \
                --enable-luainterp \
                --enable-cscope \
                --enable-gui=gtk2 \
                --disable-darwin

You're disabling the available OS X integration (--disable-darwin) in favour of XTerm integration (--enable-gui=gtk2). That flag will be ignored by the configure script if you haven't installed XQuartz, so scroll through the configure output and confirm that your --enable-gui=gtk2 wasn't discarded.

Now:

make
sudo make install

And check that everything worked with:

vim --version

You should now see +clientserver, +X11 and +xterm_clipboard.

tmux

If you're this far down the text-mode rabbit hole you have probably already installed tmux. But if you haven't, download and install it from source.

iTerm2

Here's one you don't have to recompile. A long time ago I thought that the built in terminal on OS X was fine and that I didn't need a souped-up terminal, but I was wrong. Get iTerm2.

Now you want to set up an iTerm2 profile specifically for creating/connecting to a tmux session and a Vim server. Here's a screenshot of what I've done:

iTerm2 profile

iTerm2 profile for launching tmux and Vim

That full command-line is:

/bin/zsh -c "tmux attach -t TMUX || tmux new -s TMUX '/usr/local/bin/vim --servername VIM'" 

Substitute your shell of choice if you haven't got religion on oh-my-zsh yet.

We are not even close to finished yet.

AppleScript

Now you want a script to actually tell iTerm2 to start a new terminal session using this profile, or just activate an existing one if available. Open up AppleScript Editor and type the following.

tell application "iTerm"
    activate
    repeat with theTerminal in terminals
        repeat with theSession in sessions of theTerminal
            if (name of theSession contains "tmux") or (name of theSession contains "vim") then
                set current terminal to theTerminal
                select theSession
                return
            end if
        end repeat
    end repeat

    -- No tmux or vim session yet. Start one.

    set theTerminal to (make new terminal)
    tell theTerminal
        launch session "VimServer"
    end tell
end tell

I've saved mine into ~/bin/open-tmux-or-vim.scpt.

This script is actually pretty handy, and I've bound it to Ctrl-Option-Cmd-V (using a Quicksilver trigger, but you can use whatever you want).

Automator workflow

Now we're going to make an application (actually just an Automator workflow) that will accept the files we've selected or double-clicked in the Finder and hand them off to the running Vim server we started (or will start). Fire up Automator and create an application as follows:

Automator workflow

Automator workflow for opening from Finder

I know what you're thinking. Sleep 0.5? Really? This is number one on the To Do list for future improvement. But for now, I've hardcoded a delay so that Vim has a chance to set up a listening server to accept the --remote-tab-silent we're issuing. Without the delay the Vim server won't have launched yet.

I've saved mine into ~/bin/OpenWithVim.app.

Associate file extensions

Right-click on a .txt file in the finder and choose Open With... > Other.... Enable All Applications and navigate to where you saved OpenWithVim.app. Click Add..., now click Change All... and Continue.

Try double-clicking on this file, or any other .txt file. It should open in terminal Vim within a tmux session.

Bonus points

If you want to associate lots of extensions and (like me) want to do this on several Macs, the Open With... dance is too cumbersome. Duti is a great solution to this, and I've mapped a Vim command to edit and trigger my .duti.conf file so adding new associations is a breeze. The bundle ID for the automator action you just created, by the way, is com.apple.automator.OpenWithVim.

Conclusion

If you've read this far and come to the conclusion that you should probably just use MacVim, I don't blame you. But I'm loving this set up right now and expect it will only get better.


1. There are good reasons for this, and they won't sway you until you've experienced it yourself. Building your own Vim is convenient because you can enable all the features you want and you can stay up to date. But mostly, there is a gestalt that occurs when you're working with solely pure-keyboard, pure-text tools. The allure is so strong that I'm considering switching to text-mode, tmux-friendly mail, Twitter, and messaging clients.