maandag 21 mei 2007

python scripting in vim (2)

Hi,

Hopefully you all found my first tutorial helpfull,
this will be a second more advanced tutorial about scripting vim in python.
In this tutorial we will make a script to test if your python script doesn't contain syntax errors, we will use pyflakes for this

let' s get started with the module pyflakse,
you can find pyflakes on http://divmod.org/trac/wiki/DivmodPyflakes
install it on ubuntu: apt-get install pyflakes

We will use pyflakes because it is fast, if you're interested you can also look at pylint and pychecker.

first let's do some tests with pyflakes
open some python interpreter:


>>>file = "/path/to/file"
>>>code = open(file, 'r').read()
>>>tree = compiler.parse(code)
>>>w = pyflakes.Checker(tree)
>>>for warning in w.messages: print warning


if your file contains an error, it should be shown. If the code has a syntax or indentation error, the compiler fase will fail but we will handle that in the script.

Now lets write this in a vim script,
we will write this script in a seperate file,
this is because we can keep or .vimrc clean and because we only want to load this file when we are editing python scripts (see this blog)

the script we will write, will toggle a buffer to show the errors. If no errors are found the scirpt will just write a message.
We write 4 functions,
checkSyntax
doSyntaxCheck
closeBuffer
bufferOpen

checkSyntax is the main function that you have to call when you want to have a map to this script


#!/usr/bin/python

import vim
import pyflakes
import compiler

def checkSyntax():
"""This function checks if the output buffer is already open. If it is open,
we will close it (because we want to toggle). If it is not open, we will
create
the output buffer and do the real syntax check with (doSyntaxCheck)
"""
#first save the current buffer
current = vim.current.buffer
#check if the buffer is open
b = bufferOpen()
if not b:
vim.command("bel silent new output")
output = vim.current.buffer
doSyntaxCheck(current, output)

else:
closeBuffer(b)


def doSyntaxCheck(current, output):
"""This function will do the real syntax check, first we will create a string
that contains
the current buffer, we will then try to parse the code with compiler and then
run pyflakes on it.
All errors are printed in the output window, if no errors are found, a message
is printed and the buffer is closed again
"""
#convert the list of lines to a string
code = "\n".join(current)
try:
tree = compiler.parse(code)
except (SyntaxError, IndentationError), inst:
output[0:0] = [str(inst).strip()]
else:
w = pyflakes.Checker(tree)
w.messages.sort(lambda a,b: cmp(a.lineno, b.lineno))

if w.messages:
for warning in w.messages:
output[0:0] = [str(warning).strip()]

else:
closeBuffer(output)
print "code ok"


def bufferOpen():
"""This function checks all the buffers if a buffer with a name containing
output exists. If it exists we return that buffer, else we return None
"""
for b in vim.buffers:
if "output" in b.name:
return b

return None


def closeBuffer(buffer):
"""Completely delete buffer"""
cmd = "bwipeout! " + buffer.name

vim.command(cmd)


Stay tuned...
I hope you all liked this tutorial.
reactions are always welcome, and I'll do my best to publish a new tutorial soon!

5 opmerkingen:

Anoniem zei
Deze reactie is verwijderd door een blogbeheerder.
Anoniem zei

Your blog keeps getting better and better! Your older articles are not as good as newer ones you have a lot more creativity and originality now keep it up!

Anoniem zei
Deze reactie is verwijderd door een blogbeheerder.
Anoniem zei
Deze reactie is verwijderd door een blogbeheerder.
Anoniem zei
Deze reactie is verwijderd door een blogbeheerder.