Pages

Tuesday, March 30, 2010

Python in Vim Script

I realized that we could embed python script in vim script. Thus we can do something that vim script can't do but python can.

In windows vim package, vim only supports for python24. But my python version was python26 therefore I needed to recompile vim or if you're too lazy, you could download compiled gvim.exe and vim.exe for python support at http://www.gooli.org/blog/gvim-72-with-python-2526-support-windows-binaries/ and replace your original gvim.exe and vim.exe with them.

Usually in Linux, vim package is already compiled with python support. You can script python in vim script with no time.

To check python already work in vim, you can type command bellow, if you see the message it means python already works well.
:py print "python in vim"
or
:python print "python in vim"

There are 3 ways to include python code in vim script:
  • By using python command for example:
    python import sys
    python sys.argv=["foo", "bar"]
    python print "this's python script"

  • By using marker:
    python << PYSCRIPT
    #python code here sys.argv=["foo", "bar"]
    print "this's python script"
    PYSCRIPT

    In example above I use "PYSCRIPT" as python marker, but you can another tag word for you python script marker.
  • By including file:
    pyfile python-script.py
There are some commands vim provided to communicate between python and vim itself, but here I will explain only 2 of them briefly, those are "vim.command" and "vim.eval". Before using them you need to import vim module in python script. You can import it by adding below line in your python code:
import vim

vim.command is used to execute vim command in python script, for example when I want to turn off syntax color, I will add script below:
vim.command("syntax off")

vim.eval is used to get value of variables in vim script, for example :
let s:test_str = "Just test"
python << PYTHON_SCRIPT
import vim
str = vim.eval("s:test_str")
print str
PYTHON_SCRIPT


You can get more detail information about python in vim script in vim help
:help python

For further example I tried to create simple tags-setter and ctags-generator by reading it from a configuration file, here is the code.

/home/test/tag-cfg:
tag-file=/home/test/tags
src-dir=/home/test/src-code


/vim/test/tag-gen-set.vim:
let s:conf_file = "/home/test/tag-cfg"
pyfile vim_tags_gen_set.py
py gen_and_set_tags(vim.eval('s:proj_file'))


/vim/test/vim_tags_gen_set.py:
import vim

def dir_trim(str):
    if '/' != str[len(str) - 1]:
    str = str + '/'
    return str

def str_trim(str):
    if '\n' == str[len(str) - 1]:
    str = str[:-1]
    return str

def gen_and_set_tags(proj_file):
    # Open file
    f = open(proj_file, "r")

    # Get project file path
    f.seek(13)
    tmp_str = f.readline()
    tmp_str = str_trim(tmp_str)
    project_file = tmp_str

    # Get tag file path
    f.seek(9,1)
    tmp_str = f.readline()
    tmp_str = str_trim(tmp_str)
    tag_file = tmp_str

    # Get source dir
    f.seek(8,1)
    tmp_str = f.readline()
    tmp_str = str_trim(tmp_str)
    src_dir = tmp_str

    # Close file
    f.flush()
    f.close()

    # Set the commands
    cmd_gen_tags = "!ctags -R -f " + tag_file + " " + src_dir + "/*"
    cmd_set_tags = "set tags=" + tag_file

    print cmd_gen_tags
    print cmd_set_tags

    # Execute the commands
    vim.command(cmd_gen_tags)
    vim.command(cmd_set_tags)