Wednesday, July 11, 2007

PDFSync inverse searches on Vim for OS X

FINAL UPDATE: See the new post, "PDFSync Inverse Searches in MacVim," for the state of the art on this subject.
UPDATE 8: Skim 0.6 and up supports spell checking of a PDF. This is a strange feature of a PDF viewer since Skim does not allow you to edit the PDF text directly. However, it makes a lot of sense when inverse searches are supported. After doing Shift+Command+CLICK on the misspelled word, the TeX editor will open up near the line of TeX where the word is found.

UPDATE 7: caveat Vimmer! Inverse searches in Skim are called up with Shift+Command+CLICK. This is fine; however, if you hold Shift+Command too long, the AppleScript for calling up Vim is going to get confused. In other words, be sure to release the modifier keys as soon as possible after the "click."

UPDATE 6: I found information about doing both forward and backward searches with Vim and PDFView (see also: using gotoline.sh). From these, I've made hacks to the VIM-LaTeX scripts for PDFView and other viewers (like Skim and TeXniscope). I will describe these hacks in another post.

UPDATE 5: See Vim Tip #225 and the corresponding wiki entry for information about both backward and FORWARD searches in Vim. I also found a nice LaTeX tools script for Vim that has forward searching built in. I found these pages linked from a page on xdvi inverse searches.

UPDATE 4: Very trivial updates have been made in a 1.03 version of this script.

UPDATE 3: I have posted a 1.02 version of this script. The changes are fairly trivial, but you might be interested in checking it out.

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

UPDATE 1: I have mirrored this post at my web site.

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
After configuring Skim, BE SURE TO CLICK AWAY FROM THE TEXT BOXES before closing the configuration. For example, click on one of the other tabs. Otherwise, the dialog box may not record your changes to the last text box you changed.

I hope that's useful to someone.

3 comments:

Anonymous said...

Thanks for this script. Everything is fine, except for the Arguments box of the pdfsync. When I change the argument box from its default value, it doesn't hold it and evertime it is looking for a file named l, because the beginning of the default arguments entry looks like -l.

Do you have any idea why this is happening? I have got my mac just yesterday and I am quite a newbie to Mac OS.

Best,
Hooman

Theo said...

This isn't exactly a bug in Skim. It's just a funny thing about text boxes.

You need to be sure to click away from the text boxes after modifying them. For example, edit both text boxes and then click one of the other TABS before closing the dialog.

Otherwise, you'll close the dialog before Skim notes that you changed the text box.

That should fix things. Otherwise, you'd have to modify the preference file directly.

Adam said...

You should use 'key code 53' instead of 'keystroke ESC'. On my machine, at least, keystroke ESC deletes a character.

Also, bufexists('$file') should be bufexists(bufname('$file')) if the file is open in a different buffer and the current file has a different path.