Vim plugin python

From wikinotes

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.py

yourplugin.vim


vim-interface to your python plugin

let 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