Monday, November 2, 2009

On-the-fly code checking in VIM

Topic of this blogpost is on-the-fly source checking in the text editor VIM. The idea is simple - we want to see our coding mistakes as soon is possible and we do not want to check our code manualy all the time. While coding C, there is classic code-compile-run cycle which can be obviously done automaticaly (excluding the 'code' part). And this is when the project Codecheck comes on the scene.

Codecheck is a project developed by Birgi Tamersoy as a "Google Summer of Code" activity and supervised by Bram Moolenear (the author of the VIM editor). It is a set of scripts which are runned periodicaly (depending if the text was changed) while the user writes some code. There is no need to save the file or escaping from the insert mode. The checking is done in paralel to users typing or any changes.

It works like this - the user activates codecheck inside of vim (compiled with codecheck support) by typing ':ccadd <cmd> <file>'. The command to run should be something like 'gcc -Wall -pedantic -ansi' or 'g++' or in fact it can be any executable program. The file is the file which has to be checked - that is of course the edited file so we can use the '%' substitute, but because of some shortcomings in codecheck there must be FULL path to the file. And, once the code checking is activated, user will see errors and warnings from the given command (i.e. gcc) as highlighted lines in edited file, in real time, as he codes. For deactivating code checking, there is ':ccrem' command, or you can just close the file.

If you still cannot imagine what it does and what I am talking about, you can see codecheck in action on youtube.

Well, it seems interesting, right? So how can we try it? Because codecheck is in fact a patch for VIM, we have to patch and compile it. It is not difficult, but you should be familiar with compilation of software before trying this out.

First step - creating temporary directory where we will do all the work.

mkdir /tmp/codecheck


Second step - we will fetch codecheck project from google code subversion repository. You need to have a subversion client to fetch the sources. If you haven't, you can of course go to the codecheck website and download it using some browser.

cd /tmp/codecheck
svn checkout http://codecheck.googlecode.com/svn/trunk/ codecheck-svn


Third step - now we fetch VIM source code. I used 'ftp.cz.vim.org' (czech mirror) but you can change it to some closer mirror. Then I downloaded checksum of the source code and verified correctness of the file using md5sum.

cd /tmp/codecheck
wget ftp://ftp.cz.vim.org/pub/vim/unix/vim-7.2.tar.bz2
wget --quiet ftp://ftp.cz.vim.org/pub/vim/unix/MD5SUMS
grep vim-7.2.tar.bz2 MD5SUMS > x
mv x MD5SUMS
md5sum -c MD5SUMS


Fourth step - now we will download and apply the patches for VIM. This step is not neccessary. If you want to, you can skip this step completely.

cd /tmp/codecheck
mkdir vim-patches
cd vim-patches/
for x in $(seq -w 0 267); do echo $x; \
wget --quiet ftp://ftp.cz.vim.org/pub/vim/patches/7.2/7.2.$x; done
wget --quiet ftp://ftp.cz.vim.org/pub/vim/patches/7.2/MD5SUMS
sed -i '/gz$/d' MD5SUMS
md5sum -c MD5SUMS
cd /tmp/codecheck
bzip2 -d vim-7.2.tar.bz2
tar xf vim-7.2.tar
cd vim72/
for x in $(seq -w 0 267); do echo $x; patch -p0 -f -i ../vim-patches/7.2.$x; done


Fifth step - this is the most important step here. We will patch our VIM source code with codecheck project so the VIM gains ability to code checking. The order of applying patches is important.

cd /tmp/codecheck/vim72/
patch -p0 -N < ../codecheck-svn/code_check_vim_source.patch001
patch -p0 -N < ../codecheck-svn/code_check_v0.1.patch
cp ../codecheck-svn/code_check.c src/


Sixth step - now we can compile our sources. After this step you should have a './src/vim' executable. If you do not, you either did something wrong or your system is not ready for compiling (maybe you are missing gcc, gnu make or something)

cd /tmp/codecheck/vim72
./configure && make


Now you can try out code checking using the compiled VIM from src directory by executing
/tmp/codecheck/vim72/src/vim
After that, create some C code and write it on the disk somewhere. Then use the VIM command ':ccadd gcc -Wall -pedantic -ansi /full/path/to/your/source.c'. Now you should see some highlighted lines (if you made mistakes in your code).


As you can see, using the codecheck is natural and comfortable.

And how does it work? Well, obviously it takes our command given by :ccadd and aplies it on the given filename, then catches the ouput (stdout and stderr), parses it and shows it as highlighted lines. As you can see, it leaves some trash as hidden files (.*). And how does it look? For purpose of seeing it working I created a bash script called 'delaycmd'. It goes like this:

#!/usr/bin/env bash
if [ -z "$1" ] || [ -z "$2" ]
then
echo "Usage: $0 <delay> <cmd> [<args>]"
exit 0
fi
delay=$1
cmd=$2
shift 2
args=$@
sleep "${delay}" && \
${cmd} $@


This script takes several arguments. The first argument is number, second is program name and the rest is arguments of the command. As you can see, it executes the given program name with given arguments after given time.

Example: delaycmd 3 ls
Output: Wait three seconds and list the directory

Now, we use our script in this maner - ':ccadd delaycmd 30 gcc -Wall -pedantic -ansi /full/path/to/our/source.c'. Then we look into processes list to see something like this:

xterm              -- terminal window
bash -- shell interpreter executed in terminal window
vim -- vim executed from the shell interpreter
sh -- forked shell within vim which is executing..
bash -- .. our bash script 'delaycmd'
sleep -- which is currently running command 'sleep'


So the codecheck executes new process and VIM itself is running further. There is one catch in that. The forked compilation process survive dead of the VIM process.

Conclusion

Codecheck is nice idea and it is well done. But it is unstable (a have seen it crash VIM instance several times) and has some flaws (the process survival). In future, it will not be included in VIM itself (IMHO), because it is trying to turn a text editor into an IDE which is obviously wrong way. And second (more serious) problem is that the project Codecheck has really slow development (seems forgotten and dead).

8 comments:

Anonymous said...

Poor C programmers...

I have these two lines in my .vimrc

map W :!clear; perl -wc %<CR>

I do have to save the file for this to work.

Anonymous said...

Why somebody would use VIM for 'software development' ? It seems like quite ridiculous idea to me. I am a C/Java developer and i am fully satisfied with high-level IDE`s like Eclipse,Visual Studio.

V jednoduchosti VIMu je krasa, ale co napojeni na dalsi 'systemy' - bugzilla,db resources, tasks, prepinani mezi tridami, debugging, podle me produktivita musi jit do kytek...

Anonymous said...

The ones who do not use Vim will never understand. Poor souls... I recently discovered netbeans has an awesome plugin called JVI... It gives you VIM key bindings on the IDE...

autor said...

Good for you ! So its all about key shortcuts ? :)

JPhenow said...

No one should need an IDE. I don't need to trudge through some sluggishly chunky IDE like the likes of Eclipse

autor said...

VIM is incredibly effective text editor, many extensions exits but thats all. 'Modern' IDE`s (Eclipse, Netbeans, Visual studio...) integrates a lot of features togetger (code auto-completion, autobuild, hot deploy, refactoring features, static code check, integration with SVN, bugzilla, DB, debugging etc...) and in the result people are more productive. VIM has not been created for 'business' so will be always step (a lot of steps ! ) behind with features and capabalities of modern IDE`s. Thats strong point, isnt it ?

Its not bad idea use VIM as a IDE for open-source project - for your own fun. But from position of project manager / tech lead i would fired everybody from my team who will thinks like 'maybe VIM is better than Eclipse'. There is a clear line between cruel sw business world and romantic open-source *nix world.

Share your thoughts with me if you want :)
Howg

Birgi Tamersoy said...

Hello Martin,

This is Birgi. First of all thank you very much for taking the time to write such a good and detailed howto.

I am also very sorry about the slow development, but just wanted to say that CodeCheck is not forgotten or dead :) (at least for me). Everytime I decide to spend some time on it, something about the school stops me doing so. I really hope I can improve CodeCheck, and your comments are very welcomed.

About the Vim vs IDE conversation, I personally can use a Vim + terminal combination more efficiently than any IDE. Of course, this is all about getting used to some specific development environment more than the others. However, Vim is like an addiction. Once you get used to it you just find yourself doing "Esc :w" on other IDEs, office programs and mail clients. That is why, Vim is the only thing I use for everything I do write now :) (thanks to Mutt & LaTeX).

Take care all,

Birgi

Alper said...

CodeCheck rules :)

Post a Comment