• programming in python • a course for the curious •

Vim & Python

There are a few plugins for writing Python code in Vim. Just recently I started to use jedi-vim. It implements omnicompletion for Python using the jedi module. Both jedi-vim and jedi are authored by David Halter. There are a few things you can configure and they are well documented on the github jedi-vim page. The plugin works for me very smoothly, its nicely designed and has some cool features. I really like the jedi#goto() function which by default is bound to <Leader>g. When you are on a variable, class or function name and you hit <Leader>g it takes you straight to the definition of that object. I've implemented such a function for vim scripts (ftpdev plugin) and it helps a lot working with code. Jedi-vim allows to change the default key bindings, which is also nice since I got used to hitting gd to go to a local declaration. Let me note that it is really well done: it can take you to different modules where the object was defined. If you import an object from a module this might require two steps: first will take you to the import statement and next will go to that module, if you imported whole module it will take you directly to the object definition. The only restriction are the built-in modules which are implemented in C rather than Python, but you will not go around this anyway.

Jedi-vim can also find related names (with <Leader>n) in the current project and populate the quick fix list with the results. Related names are the ones which correspond to the same object. Let say that you import a function from a module in two different places (files): then jedi will find that these two names are related. Then you can easily jump between different position where the name occurs.

Another nice feature is the renaming function. It renames all the related names. I haven't played much with this but it sounds promising: especially if you change your mind with the object name at some point. You can first use the <Leader>n to review where the changes will be made. It seems that if you change the name of an object with the 'as' keyword (from ... import ... as ...) the name just after import, which is the original name of the object is not added to the related names, but I guess this can be fixed ...

Another nice feature to have is folding. There are a few plugin which can fold python code and I found SimplyFold the best solution. It really does the job well. The only problem is that is might be slow on big python files. For me it was not working on my previous laptop (which was a bit slow any way) with 2000 lines of code but with a new fast computer it works just fine. If it is too slow for you, you can always use the trick: ":set fdm=indent". It will fold probably more that you would like to, but it should be fast enough.

I also use the following helper motion commands:

  1. fun! Python_jump(pat, flag, count)
  2. normal! m`
  3. for x in range(a:count)
  4. call search(a:pat, a:flag)
  5. endfor
  6. endfun
  7. nnoremap <silent> <buffer> ]] :<C-U>call Python_jump('^\s*\zs\(def\\|class\)\>', 'W', v:count1)<cr>
  8. nnoremap <silent> <buffer> [[ :<C-U>call Python_jump('^\s*\zs\(def\\|class\)\>', 'bW', v:count1)<cr>
  9. nnoremap <silent> <buffer> ]} :<C-U>call Python_jump('^\(def\\|class\)\>', 'W', v:count1)<cr>
  10. nnoremap <silent> <buffer> [{ :<C-U>call Python_jump('^\(def\\|class\)\>', 'bW', v:count1)<cr>

There is yet one more plugin which is useful. PyInteractive can turn vim command line into Python REPL, which state is persistent (i.e. all objects are left intact when you switch it on and off). It is nice to test code snippets, but also you can run buffers. It has completion so it much nicer that typing :py print(...) all the time.

Contact us.
Created using , and
we are not associated with Python Software Foundation
© Copyright 2012, 2013 Accorda Institute.