Vim plugin python
Vim plugins can also be written in python, if your vim has been compiled with a builtin python interpreter.
NOTE:
if your code is compatible with both python2/3, use `pyx` and `pyxeval`
documentation
official vim python docs http://vimdoc.sourceforge.net/htmldoc/if_pyth.html
Example
Project Structure
yourplugin/ plugin/ yourplugin.vim yourplugin.pyyourplugin.vim
vim-interface to your python pluginlet s:scriptroot=expand('<sfile>:p:h') " get path to current script if !has(python) echo "vim must be compiled with python" finish else execute 'pyfile '. s:scriptroot .'/yourplugin.py' endif function! HelloWorld() py hello_world() endfunc command! HelloWorld call HelloWorld()yourplugin.py
def hello_world(): print('hello world')Usage
In order to run, simply open a new vim instance, and:
:so testfile.vim :HelloWorld() " should print hello world
vim module
I'm only going to cover some of my most-used info here
:help python-vim " official documentation" you can experiment with the vim module " as you might expect to from the :ex commandline :py import vim :py print( vim.current.line )
import vim vim.current.buffer.name ## current filename vim.current.buffer ## current buffer vim.current.window ## current window vim.current.line ## current line vim.command( 'NERDtree' )
plugin libraries
If you are writing a plugin that involves a lot of python code, you'll likely want to create an importable python package (so that your code can be distributed across a handful of python modules.
Unfortunately,
__file__
is not accessible to python while the module is being read using:pyfile
.This is my solution:
"""" plugin/yourmodule.vim let s:scriptroot=expand('<sfile>:p:h') " <---- Provide the script-local variable s:scriptroot if !has('python') finish echo "Your version of vim does not support python" else execute 'pyfile ' . s:scriptroot . '/init_syspath.py' " <--- s:scriptroot acessible while reading file execute 'py import ptaskmgr.vim_plugin' py import logging py logging.basicConfig( lv=20 ) endif#### plugin/init_syspath.py filedir = vim.eval('s:scriptroot') # <--- access s:scriptroot if filedir not in sys.path: sys.path.append( filedir )
tips/tricks
Working within python within vim means working without pdb/ipdb. This takes a lot of getting used to. Furthermore, the last print statement is often hidden behind the
Press Enter to Continue
prompt.Here are some tips for dealing with some of the ackward bits of vim.
print('your message') print('---') ## hidden behind press enter import time;time.sleep(10) ## make sure message stays visible (if running in vim au command)A much cleaner solution to this, is to simply redirect all of the output from vim to a file. (and maybe run
tail -f
on it). That way you will have a complete record of everything that has been printed:redir! > vimout.log " redirect STDOUT to vimout.log :redir END " end redirecting STDOUT