Vim Tips Wiki
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
Tip 733 Printable Monobook Previous Next

created 2004 · complexity basic · author Rene Aguirre · version 5.7

I just discovered Vim, I really liked 'split' capability, I'm so used to edit Python source code on SciTe editor, I really missed the default CTRL-1 to check the syntax and F5 to run the script...

So, this is my suggestion, add these lines to your vimrc file:

autocmd BufRead *.py set makeprg=python\ -c\ \"import\ py_compile,sys;\ sys.stderr=sys.stdout;\ py_compile.compile(r'%')\"
autocmd BufRead *.py set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%m
autocmd BufRead *.py nmap <F5> :!python %<CR>

Make sure that python is in your path, now when you open any python file just type ":make" to get the syntax errors, use ":cnext", to move to next error, check the help on make (":help make") for more info on how to navigate errors.

As you are checking now, <F5> is mapped to execute the current script. Also I suggest you to use add the following lines to vimrc:

autocmd BufRead *.py set tabstop=4
autocmd BufRead *.py set nowrap
autocmd BufRead *.py set go+=b

That will make to use a 4 spaces for you tabstop (only visually), it avoids wrapping your code and will add a bottom scrollbar. Now I like vim a litle bit more.


How about having the line:

nmap <buffer> <F5> :w<Esc>mwG:r!python %<CR>`.

in the file $VIM/vimfiles/ftplugin/python.vim?

(I have the preceding line with 'python' replaced by 'perl' in the file $VIM/vimfiles/ftplugin/perl.vim )

(The adjective <buffer> in the map of <F5> restricts the map to the buffer. The map of <F5> as given in the tip is "permanent" in the sense that after opening a *.py file, the map remains for other non-*.py files.

Also, putting the map in a ftplugin-file means that it is available even when the python file-type is detected by means other than the .py extension -- means such as the command ':set ft=python' or the shebang.)

The counterpart of python's sys.stderr=sys.stdout in perl is the following line placed toward the beginning of the perl file:

BEGIN {(*STDERR = *STDOUT) || die;}

The preceding is needed so that the 'r' in the map of <F5> can capture stuff in stderr.

Here's a script that automatically checks the syntax while saving and refuses to save files with syntax errors. Mildly hacky but it seems to work just fine.

" Define the current compiler
if exists("compiler")
let compiler = "python"

" Set python as the make program and
setlocal makeprg=python
setlocal errorformat=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%m

" When writing Python file check the syntax
au! BufWriteCmd *.py call CheckPythonSyntax()

function CheckPythonSyntax()
  " Write the current buffer to a temporary file, check the syntax and
  " if no syntax errors are found, write the file
  let curfile = bufname("%")
  let tmpfile = tempname()
  silent execute "write! ".tmpfile
  let output = system("python -c \"__import__('py_compile').compile(r'".tmpfile."')\" 2>&1")
  if output != ''
    " Make sure the output specifies the correct filename
    let output = substitute(output, fnameescape(tmpfile), fnameescape(curfile), "g")
    echo output
  " Delete the temporary file when done
  call delete(tmpfile)