VIM + Python

VIM, mint ideális Python IDE

Horák György (Repa)

dyuri kukac horak pont hu

Mi az a VIM?

  • Vi IMproved
  • 1991 - Bram Moolenaar
  • *nix rendszerekben mindenhol
  • ... de bárhol máshol is
  • ... és kb. mindenhez van "vimesítő" plugin
  • modális editor (normal, insert, visual, ...)
  • ~/.vimrc, ~/.vim/
Egyébként maga a vi már 1976 óta létezik.

Nem python specifikus dolgok

Modelines

  • set modelines=5
  • # vim: fileencoding=utf8:filetype=python:tw=79

A vim (ha a modelines változó értéke pozitív szám) megnézi a megnyitott file első és utolsó néhány sorát, hogy talál-e benne neki szóló sort, ami az adott filera vonatkozó konfigurációs beállításokat tartalmaz. Ez a modeline.

Bár a modlines változó alapesetben 5 szokott lenni, ezt néhany disztribúció megváltoztatja, ezért nem árt, ha mi magunk is beállítjuk a vimrcnkben.

Python fileok szerkesztésekor külon hasznos a modline használata, ugyanis ha ékezeteket (speciális karaktereket) használunk, kötelező megadnunk az általunk használt kódolást, és a python a vim modeline-t tudja értelmezni ilyen szempontból.

FTPlugins

  • autocmd FileType python <parancs>
  • ftplugin/filetype.vim
  • ftplugin/filetype_valami.vim
  • ftplugin/filetype/valami.vim

File Type Plugins

Automatikusan betöltődnek az adott filetípusnál (feltéve, hogy nincs kikapcsolva, :filetype plugin on).

VIM, mint Python editor

PEP-8

set expandtab
set textwidth=79
set tabstop=8
set softtabstop=4
set shiftwidth=4
Mehet ftpluginok közé, de akár egy modeline-ba is belefér.

Syntax highlighting, autoindent

syntax on
set autoindent
set number!
set list!
set commentstring=#%s
inoremap # X<C-H>#

A syntax hilite-ot, és az automata indentálást nem részletezném miért hasznosak, a number változó allítgatásával a sorszámozást kapcsolhatjuk ki/be, a list változóval pedig a whitespace karaktereket tehetjük "láthatóvá" - ezzel elkerülhetjuk a TAB/space problémákat. (Egyébként a retab parancs lecseréli space-ekre a tabokat, a beallításoknak megfelelő módon.)

Alapértelmezésben az egész soros commenteket valamiért kicsúsztatja a vim a sor elejére, és akkor oda az aktuális indentálás, ezt kerülhetjük el az utolsó paranccsal.

VIM, mint Python IDE

python.vim

  • http://www.vim.org/scripts/script.php?script_id=30
  • ]t, ]e - block elejére/végére ugrás
  • ]#, ]u - kijelölt szakasz ki/visszacommentelése
  • ]v - block kijelölése

Folding

  • Automatikus: http://www.vim.org/scripts/script.php?script_id=1494
  • Manuális:
    • set foldmethod=marker
    • set commentstring=#%s
    • zf, zo, zc

A script egyébként Nógrádi Dániel munkaja, aki neve alapján valszeg honfitársunk, köszi.

Kódkiegészítés

  • ^X^O
  • autocmd FileType python set omnifunc=pythoncomplete#Complete
  • set completeopt=menu,preview

Kódkiegészítés 2.

  • $ pysmell . -o PYSMELLTAGS[.valami]
  • source pysmell.vim
  • set omnifunc=pysmell#Complete

A pysmell-nek rajta kell lennie a pythonpath-on természetesen.

Legegyszerűbb ftpluginnel megoldani a dolgot.

A PYSMELLTAGS fileoknak a project rootban kell lenniük, hogy a pysmell megtalálja őket, illetve mindenképpen kell egy kiterjesztés nélküli is.

Kódkiegészítés screenshot

Taglist

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

exuberant ctags kell neki

Taglist screenshot

Syntax checking

set makeprg=python\ -c\ \"import\ py_compile,sys;\ sys.stderr=sys.stdout;\ py_compile.compile(r'%')\"
set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%m
  • :make
  • cn/cp

Sajna csak kézzel megy, nem automatikusan a háttérben, de a semminél jobb. A cp/cn parancsokkal ugorhatunk az előző/következő hibára, de a python úgyis megáll az elsőnél :)

Kód futtatása

  • map <buffer> <S-e> :w<CR>:!/usr/bin/env python %<CR>

SHIFT-e megnyomásakor lefuttatja az éppen szerkesztett kódot.

Debug

  • http://code.google.com/p/vimpdb/

VIM, kiegészítők pythonban

  • +python opcióval fordítva (vim --version)
  • import vim ...

Kódrészlet futtatása

python << EOL 
import vim
def EvaluateCurrentRange():
  eval(compile("\n".join(vim.current.range),'','exec'), globals())
EOL
map <F6> :py EvaluateCurrentRange()<CR>

Sajat debug

def SetBreakpoint():
    import re
    nLine = int( vim.eval( 'line(".")'))

    strLine = vim.current.line
    strWhite = re.search( '^(\s*)', strLine).group(1)

    vim.current.buffer.append(
       "%(space)sfrom ipdb import set_trace;set_trace() %(mark)s Breakpoint %(mark)s" %
         {'space':strWhite, 'mark': '#' * 30}, nLine - 1)

vim.command( 'map <f7> :py SetBreakpoint()<cr>')
Innen van: http://www.cmdln.org/wp-content/uploads/2008/10/python_ipdb.vim

Sajat debug 2.

def RemoveBreakpoints():
    import re

    nCurrentLine = int( vim.eval( 'line(".")'))

    nLines = []
    nLine = 1
    for strLine in vim.current.buffer:
        if strLine.lstrip()[:38] == 'from ipdb import set_trace;set_trace()':
            nLines.append( nLine)
            print nLine
        nLine += 1

    nLines.reverse()

    for nLine in nLines:
        vim.command( 'normal %dG' % nLine)
        vim.command( 'normal dd')
        if nLine < nCurrentLine:
            nCurrentLine -= 1

    vim.command( 'normal %dG' % nCurrentLine)

vim.command( 'map <s-f7> :py RemoveBreakpoints()<cr>')
Innen van: http://www.cmdln.org/wp-content/uploads/2008/10/python_ipdb.vim

További hasznos kiegészítők

  • screen irányítása - http://technotales.wordpress.com/2007/10/03/like-slime-for-vim/
  • tasklist - http://www.vim.org/scripts/script.php?script_id=2607
  • VCSCommand - http://www.vim.org/scripts/script.php?script_id=90
  • NERDTree - http://www.vim.org/scripts/script.php?script_id=1658
  • minibuf exporer - http://www.vim.org/scripts/script.php?script_id=159
  • snippetsEmu - http://www.vim.org/scripts/script.php?script_id=1318
  • http://www.vim.org/scripts/ ...

Kérdések

Köszönöm a figyelmet!