Vim and LaTeX :: Inverse PDF/DVI Searches with MacVIM (i.e., Vim.app on OS X)

UPDATE: This script is now a part of the Skim wiki.

BACKGROUND: The origins of this post are a Phase Portrait post, PDFSync inverse searches on Vim for OS X.

WINDOWS USERS: See "Performing inverse searches" from the VIM-LaTeX quick start guide.

I have posted information about this in a number of places [1, 2, 3, 4, 5]. I plan to add something at MacResearch sometime soon too. The package PDFSync allows users to do "backward searches" or "inverse searches" from PDF viewers like iTeXMac, TeXniscope, Skim, and others. That is, if you generate a PDF with LaTeX (or Plain TeX or ConTeXt), you will be able to click on text in the PDF and have an editor open up and position the cursor at the TeX source code that generated that text. That can be very nice.

There is a related feature for DVI files, but there are very few good DVI viewers out there (TeXniscope comes close), so I just focus on PDFSync).

I use Vim with VIM-LaTeX to do my document preparation. I would like to also be able to use PDFSync. However, while inverse searching is supported in Windows, it is not easily done in OS X.

I found a thread describing how to do inverse searching with AppleScript that issues raw commands to Vim. I decided to take that AppleScript, package it into a bash script, and fix it so that it had no problem handling files with spaces or symlinked files or multiple files with the same base name. The result is this script:

#!/bin/bash

filename="$1"
lineNum="$2"

[ "${filename:0:1}" == "/" ] || filename="${PWD}/$filename"  

exec osascript \
 -e "set ESC to ASCII character of 27" \
 -e "tell application \"Vim\" to activate" \
 -e "tell application \"System Events\"" \
   -e "tell process \"Vim\"" \
   -e "keystroke ESC & \":set hidden\" & return " \
   -e "keystroke \":if bufexists('$filename')\" & return " \
   -e "keystroke \":exe \\\":buffer \\\" . bufnr('$filename')\"  & return " \
   -e "keystroke \":else \" & return " \
   -e "keystroke \":    edit ${filename// /\\\\ }\" & return " \
   -e "keystroke \":endif\" & return " \
   -e "keystroke \":$lineNum\" & return " \
   -e "keystroke \"zO\" " \
   -e "end tell" \
 -e "end tell"
Copy that script in a place (preferably in your PATH) like
/usr/local/bin/gvim-pdfsync
and chmod it 0755. That is, do
chmod
 0755 /usr/local/bin/gvim-pdfsync
Then you can use the script like
gvim-pdfsync "%file" %line
where %file is the name of the file to be opened and %line is the line to place the cursor on. So, for Skim, you would put in your LaTeX (or Sync) preferences under "PDFSync" support:
Preset: Custom
Command: gvim-pdfsync
Arguments: "%file" %line
I hope that's useful to someone.