?

Log in

No account? Create an account

Previous Entry | Next Entry

extending vim with python

I was reading about the EMACS mode for erlang and I was stuck by a terrible sense of text editor envy.

http://bc.tech.coop/blog/070528.html

Arrow alignment? Imenu support?

since the vim bindings for erlang are still in development I might actually have to consider learning elisp and becoming an emacs user... or not.

http://github.com/pangloss/vim-erlang/tree/master

I did a bit of looking around and realised that there is a reason why vim simultaneously claims to be a scriptable text editor and yet nobody ever seems to script for it: vimscript. Vimscript has to be the ugliest language I've ever seen.

http://www.ibm.com/developerworks/linux/library/l-vim-script-1/index.html

Fortunately, vim does not lock you into vimscript as the only supported scripting language: currently the latest vims that ship with most linux distros are compiled with the python interface bindings, and perl and othe languages are also supported.

http://www.builderau.com.au/program/python/soa/Extending-Vim-with-Python/0,2000064084,339283181,00.htm

Awesome! So I spent the weekend (well part of it. My dad and my sister in law also had birthdays on the weekend) learning how to script vim in python.

Ok. if you fire up vim and type
:python print "hi"

and get the response
Hi


then you have if_pyth compiled into your copy of vim.

if you're on mac osx then this is not the case.

you will have to get the latest mac dmg image of python to install the library framework python for mac (althoug I prefer python 2.6.2 and use it in this example)
http://python.org/download/

After that, you can get the vim sources from their subversion repository

http://www.vim.org/subversion.php

and edit the makefile to enable python support (the line to uncomment is clearly marked)

once you compile and run vim, it should now find the latest python on your system.

if you're on fedora core 11, remember to
sudo yum install python-setuptools-devel
so you can use easy_install to get python libraries from the Python Package Index


after you're all set up, fire up vim and save the following text as the file pydemo.vim

function! Align_Arrows()
python << EOF
#by Thuan-Jin Kee
#12/7/2009
#http://thekit.livejournal.com/1008360.html

import vim, re
import string 
cb = vim.current.buffer
cw = vim.current.window

arrows = re.compile(r'->')

maximum = 0;


print "removing whitespace"

vim.command("%s/\s*->/ ->/g")

print "finding maximum indent"

for i in cb:
	try:
		j = arrows.finditer(i).next()
		if (maximum < j.start()):
			maximum = j.start()
	except StopIteration:
		#do nothing
		pass



print "indenting lines"

for i in range(0,len(cb)):
	try:
		j = arrows.finditer(cb[i]).next()
		offset =  maximum - j.start() 
# http://docs.python.org/library/string.html
		replacement =  "{0:{1}}->".format(" ",offset+1) 
		cb[i] = arrows.sub(replacement,cb[i],1) 

	except StopIteration:
		#do nothing
		pass


EOF
endfunction


function! PVer()
python << EOF
import sys
print sys.version
print sys.path
EOF
endfunction




write the file to disk and exit vim.

Now if you put pydemo.vim into a directory with some erlang files such as this one called lof.erl

-module(lof).
-export([
	multiply/1,
	double/0,	
	for/3,
	function_list/2,
	run_list/2
]).

%% lof.erl
%% by Thuan-Jin Kee
%% little exercise to work on lists of functions

multiply(F)	->	(fun(X)	->	F*X end).

double()		-> 	multiply(2).

for(Max,Max,F) 	-> [F(Max)];
for(Min,Max,F)	-> [F(Min)|for(Min+1,Max,F)].

function_list(Min,Max)	->	for(Min,Max,fun(F)->(fun(X)-> F*X end)end).

run_list(X,[H])	->[H(X)];
run_list(X,[H|T])	->[H(X)|run_list(X,T)].




and then you hit esc to put vim into command mode and type
:source pydemo.vim


hit enter and then type

:call Align_Arrows()


you should see the text end up looking something like this

-module(lof).
-export([
	multiply/1,
	double/0,	
	for/3,
	function_list/2,
	run_list/2
]).

multiply(F)             ->	(fun(X) ->	F*X end).

double()                -> 	multiply(2).

for(Max,Max,F)          -> [F(Max)];
for(Min,Max,F)          -> [F(Min)|for(Min+1,Max,F)].

function_list(Min,Max)  ->	for(Min,Max,fun(F) ->(fun(X) -> F*X end)end).

run_list(X,[H])         ->[H(X)];
run_list(X,[H|T])       ->[H(X)|run_list(X,T)].




more help is obtained by typing

:help if_pyth


when vim is in command mode.

Comments

( 5 comments — Leave a comment )
vassilissa
Jul. 14th, 2009 03:22 am (UTC)
:python print "hi"

Cool, it worked. I don't speak python yet, but it's on my to-do list, and vi is my editor.

BTW, look what I found: XMMS for vim!
thekit
Jul. 14th, 2009 03:26 am (UTC)
Awesome! be a great way to control the juke box from the keyboard and throw away the mouse.

EMACS would have just implemented a music player in elisp or something.

oh btw. If you want to have a script function accessible from everywhere, everytime you start vim, you can put it (or a command to source it) in your ~/.vimrc

ETA: Whoops. Just realised you'd already know about the .vimrc

Edited at 2009-07-14 03:28 am (UTC)
thekit
Jul. 14th, 2009 03:35 am (UTC)
Also, you might want to compile vim with if_ruby support, since that way you can work on your project and script your editor in the same language.

http://www.vim.org/scripts/script.php?script_id=2030

Edited at 2009-07-14 03:38 am (UTC)
ext_79255
Jul. 16th, 2009 01:59 am (UTC)
Script works for me ...
on Ubuntu 9.04 (Jaunty) with vim-gtk (gvim) and python installed.

Now if actually understood any Erlang ...
thekit
Jul. 29th, 2009 07:39 am (UTC)
Re: Script works for me ...
Great to hear!

If you'd like to get into erlang, I'd recommend Joe Armstrong's book from pragmatic bookshelf.
( 5 comments — Leave a comment )

Latest Month

August 2015
S M T W T F S
      1
2345678
9101112131415
16171819202122
23242526272829
3031     
Powered by LiveJournal.com
Designed by Naoto Kishi