Saturday, September 15

Opening files quickly in Vim

My Python development environment consists of a GVim window for editing code and a gnome-terminal for running the unit tests. This works out well, but leaves some integration to be desired. In particular, jumping to a test failure point is a little cumbersome. I used to do it this way: copy the filename from the traceback, switch to vim, then type :e, paste the filename with middle-click (now I know I can use * instead) and press Enter, then enter the line number and press G. That is barely acceptable; this particular wart has even contributed to pushing a ex-co-worker towards Emacs (the horror!).

I have written a small vimscript function to make the aforementioned use case slightly easier. Now to jump to a failure point, just triple-click the corresponding line in the traceback (that selects the whole line), switch to Vim and invoke the function, which scrapes the clipboard for a filename and line number and opens it in the active buffer.

Installation: paste the OpenFileFromClipboard function in your ~/.vimrc and bind it to a key by adding the following lines to your .vimrc:

nmap  :call OpenFileFromClipboard()
imap  :call OpenFileFromClipboard()

These commands bind the key F4 to our function. The first command handles normal mode, and the second handles insert mode (hence the to momentarily escape the insert mode). You can of course change the shortcut to whatever you like.

The function should handle following types of references from the clipboard:

  • /etc/passwd
  • John saved his work to ~john/doc.txt and left.
  • File "/home/gintas/devel/project/tests.py", line 123, in tests.py
  • /usr/include/stdio.h:333:extern int sprintf (char *__restrict __s,

I hope someone finds this useful.

3 comments:

Dennis K. said...

Awesome!

Dalius said...

You might find Max Ischenko solution as well valuable:

http://maxischenko.in.ua/blog/entries/109/nose-vim-integration/

Marius said...

I've got a similar one that tries to extract the class/method/function name from the clipboard and jump to a tag. In case you're interested, it's at
http://mg.pov.lt/py-test-helper.vim

Building ctags with --extra=+q helps when you have unit test names named TestSomeClass.test and jumping to a tag named 'test' doesn't work well. The downside to this is that tab-completion after :tag is cluttered with all the methods.

Now I don't actually remember why I decided to use tags rather than line numbers, which are simpler and more reliable... oh, right, my test runner prints a summary of failed test names at the end of the output, and it's convenient to use those instead of hunting for a file reference in the middle of a possibly long log.