VIM come IDE di sviluppo in Python

Tue 07 February 2023

Ogni sviluppatore si trova prima o poi a dover capire quale possa essere il miglior IDE (Integrated Development Environment) per un particolare linguaggio di programmazione. La scelta non è mai ne banale ne scontata, tuttavia, utilizzando più di un linguaggio per lavorare, lo sviluppatore potrebbe trovarsi nella condizione di dover utilizzare diversi strumenti adatti uno per ogni differente linguaggio di programmazione.

Ogni IDE, infatti, ha le sue caratteristiche e quindi deve essere studiato dallo sviluppatore per poter sfruttare le potenzialità che offre. Questo studio può rappresentare un'attività frustrante, può portare via molto tempo e può scoraggiare lo sviluppatore dal configurare l'IDE portandolo a lavorare con strumenti altamente rudimentali.

Nel lavoro di tutti i giorni mi confronto con situazioni di questo tipo e per tale motivo ho deciso di non dover più scegliere quale IDE utilizzare ma di imparare qualcosa che con il tempo rimane costante e che mi permette di migliorare la mia abilità nell'utilizzo quotidiano; la mia scelta è infatti ricaduta su VIM.

VIM è un editor testuale onnipresente sui sistemi Unix e Linux. VIM è leggero, veloce, stabile ed altamente configurabile. Con VIM si ha un editor base se lo si vuole oppure un IDE perfettamente funzionante con qualsiasi linguaggio.

In questo articolo voglio approfondire la configurazione di VIM per lavorare come IDE nello sviluppo di applicazioni Python. La configurazione di VIM può spaventare all'inizio ma seguendo passo passo l'articolo riuscirete a far funzionare tutto come desiderato.

Installazione

La prima verifica da eseguire è quella di assicurarsi che, sul tuo pc, sia installato VIM. VIM è solitamente preinstallato su ambienti nix.

Per vedere se VIM è installato eseguire il comando:

vim --version

Se VIM è installato otterai un qualcosa del genere come risposta:

VIM - Vi IMproved 9.0 (2022 Jun 28, compiled Jan 12 2023 11:41:18)
Included patches: 1-1182
Compiled by Arch Linux
Huge version without GUI.  Features included (+) or not (-):
+acl               +file_in_path      +mouse_urxvt       -tag_any_white
+arabic            +find_in_path      +mouse_xterm       +tcl/dyn
+autocmd           +float             +multi_byte        +termguicolors
+autochdir         +folding           +multi_lang        +terminal
-autoservername    -footer            -mzscheme          +terminfo
-balloon_eval      +fork()            +netbeans_intg     +termresponse
+balloon_eval_term +gettext           +num64             +textobjects
-browse            -hangul_input      +packages          +textprop
++builtin_terms    +iconv             +path_extra        +timers
+byte_offset       +insert_expand     +perl/dyn          +title
+channel           +ipv6              +persistent_undo   -toolbar
+cindent           +job               +popupwin          +user_commands
-clientserver      +jumplist          +postscript        +vartabs
-clipboard         +keymap            +printer           +vertsplit
+cmdline_compl     +lambda            +profile           +vim9script
+cmdline_hist      +langmap           -python            +viminfo
+cmdline_info      +libcall           +python3/dyn       +virtualedit
+comments          +linebreak         +quickfix          +visual
+conceal           +lispindent        +reltime           +visualextra
+cryptv            +listcmds          +rightleft         +vreplace
+cscope            +localmap          +ruby/dyn          +wildignore
+cursorbind        +lua/dyn           +scrollbind        +wildmenu
+cursorshape       +menu              +signs             +windows
+dialog_con        +mksession         +smartindent       +writebackup
+diff              +modify_fname      -sodium            -X11
+digraphs          +mouse             -sound             -xfontset
-dnd               -mouseshape        +spell             -xim
-ebcdic            +mouse_dec         +startuptime       -xpm
+emacs_tags        +mouse_gpm         +statusline        -xsmp
+eval              -mouse_jsbterm     -sun_workshop      -xterm_clipboard
+ex_extra          +mouse_netterm     +syntax            -xterm_save
+extra_search      +mouse_sgr         +tag_binary        
-farsi             -mouse_sysmouse    -tag_old_static    
   system vimrc file: "/etc/vimrc"
     user vimrc file: "$HOME/.vimrc"
 2nd user vimrc file: "~/.vim/vimrc"
      user exrc file: "$HOME/.exrc"
       defaults file: "$VIMRUNTIME/defaults.vim"
  fall-back for $VIM: "/usr/share/vim"
Compilation: gcc -c -I. -Iproto -DHAVE_CONFIG_H -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -g -ffile-prefix-map=/build/vim/src=/usr/src/debug/vim -flto=auto -D_REENTRANT -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 
Linking: gcc -Wl,-E -Wl,-rpath,/usr/lib/perl5/5.36/core_perl/CORE -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -flto=auto -L/usr/local/lib -o vim -lm -ltinfo -lelf -lacl -lattr -lgpm -Wl,-E -Wl,-rpath,/usr/lib/perl5/5.36/core_perl/CORE -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -flto=auto -fstack-protector-strong -L/usr/local/lib -L/usr/lib/perl5/5.36/core_perl/CORE -lperl -lpthread -ldl -lm -lcrypt -lutil -lc -L/usr/lib -ltclstub8.6 -ldl -lz -lpthread -lm

La risposta ricevuta, in caso di installazione di VIM sul pc, mostra come VIM è stato compilato e quali sono le caratteristiche supportate.

Per seguire correttamente l'articolo, controlla che:

  1. VIM abbia una versione superiore a 7.3
  2. VIM supporti python: controllare che sia presente la dicitura +python

Se entrambe le caratteristiche sono soddisfatte, puoi proseguire la lettura dell'articolo, altrimenti reinstalla vim per soddisfare le caratteristiche indicate. L'installazione di VIM è fuori dallo scopo di questo articolo.

Configurazione VIM

VIM, nella sua configurazione base, offre molte caratteristiche agli sviluppatori. Tuttavia, per poter configurare VIM come un IDE moderno hai la necessità di un gestore dei plugin. Un gestore dei plugin lavora come tutti i gestori di pacchetti dei sistemi Unix/Linux e si occupa di installare i pacchetti e risolvere eventuali dipendenze sul nostro pc per poterli utilizzare.

Vundle

VIM ha molti gestori di plugin, ma nell'articolo gestirai i pacchetti con Vundle. Vundle è l'abbreviazione di Vim bundle; nel gergo VIM plugin e bundle sono sinonimi.

Per capire come inizializzare la configurazione di Vundle puoi fare riferimento alla documentazione ufficiale. La stessa è riportata nel presente paragrafo.

Per installare Vundle, eseguire il comando:

git clone https://github.com/gmarik/Vundle.vim.git ~/.vim/bundle/Vundle.vim

Il comando scarica Vundle all'interno della carella ~/.vim/Bundle. Da questo momento in poi puoi utilizzare Vundle configurando il file ~/.vimrc

Per aggiungere il file ~/.vimrc, se non già presente, eseguire:

touch ~/.vimrc

Per inizializzare Vundle inserire nel file ~/.vimrc le seguenti istruzioni:

set nocompatible              " obbligatorio
filetype off                  " obbligatorio

" imposta percorso Vundle di runtime e inizializza Vundle
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()

" abilita la gestione pacchetti con Vundle
Plugin 'gmarik/Vundle.vim'

" Tutti i plugin devono essere inseriti tra vundle#begin e vundle#end

call vundle#end()            " required
filetype plugin indent on    " required

Per poter installare i plugin abbiamo due possibilità. La prima prevede l'installazione dei plugin dall'interno di VIM. Per installare plugin dall'interno di VIM, apri l'editor digitando:

vim .

e successivamente esegui il comando:

:PluginInstall

Questo comando si occupa di installare i pacchetti per te, producendo un output del tipo:

Installazione pacchetti Vundle

La seconda possibilità prevede l'installazione dei plugin da riga di comando senza aprire VIM. Per installare in questa modalità eseguire:

vim +PluginInstall +qall

Configurazione IDE

Le possibilità di personalizzazione offerte da VIM sono tantissime, in questo articolo vedrai quelle più rilevanti che ti consentiranno di configurare VIM come editor per lo sviluppo in Python.

Conoscenza di base

Prima di addentrarci nelle configurazioni specifiche di VIM come Python IDE è importante ricordarti che, per sfruttare al meglio tutte le peculiarità di VIM, devi avere conoscenza ed un minimo di pratica con i comandi ed i concetti base dell'editor.

I concetti base da conoscere, che non sono affrontati in questo articolo ma in altri del blog, sono:

  • Comandi base per la scrittura, cancellazione, ripetizione
  • Gestione delle finestre e suddivisione del layout
  • Buffers

Questi concetti sono trasversali ed indipendenti dalla gestione di file Python; possono infatti essere utilizzati per editare qualsiasi tipo di file e rappresentano la vera forza di VIM.

Ora procediamo con le nozioni specifiche per la configurazione di VIM come Python IDE.

Chiusura ed apertura di blocchi di codice

VIM può essere configurato per consentire la chiusura e l'apertura di blocchi di codice, come classi e metodi, al fine di consentire lo scorrimento del codice più agevolmente da parte dello sviluppatore. Tale caratteristica è presente nei moderni IDE e non è presente per default su VIM ma possiamo configurarlo come segue.

Puoi abilitare la funzionalità inserendo nel ~/.vimrc le seguenti istruzioni:

" Abilitazione chiusura ed apertura codice
set foldmethod=indent
set foldlevel=99

Per poter aprire e chiudere blocchi di codice a questo punto puoi utilizzare il comando za. La scorciatoia za può risultare un pò scomoda; per poterla modificare, associando per esempio la pressione della barra spaziatrice, inserisci nel ~/.vimrc la seguente istruzione:

nnoremap <space> za

Da questo momento potrai aprire e chiudere il codice utilizzando la barra spaziatrice.

Alle volte può essere molto comodo vedere la docstrings per il blocco di codice che altrimenti sarebbe nascosto.

Per poter vedere la docstring quando si chiude il codice, installare il plugin SimpylFold

Plugin 'tmhedberg/SimpylFold'

ed inserire la seguente istruzione:

let g:SimpylFold_docstring_preview=1

Indentazione del codice

VIM non prevede indentazione del codice nella sua installazione base. Per indentare il codice Python su VIM possiamo impostare l'editor per seguire le regole dettate dalle linee guida PEP8 oppure possiamo affidarci all'indentazione automatica del codice.

Indentazione seguendo linee guida PEP8

Per poter configurare VIM a seguire le linee guida PEP8, aggiungi le seguenti configurazioni nel file ~/.vimrc:

au BufNewFile,BufRead *.py set tabstop=4
au BufNewFile,BufRead *.py set softtabstop=4
au BufNewFile,BufRead *.py set shiftwidth=4
au BufNewFile,BufRead *.py set textwidth=79
au BufNewFile,BufRead *.py set expandtab
au BufNewFile,BufRead *.py set autoindent
au BufNewFile,BufRead *.py set fileformat=unix

Le precedenti configurazioni consentono di dare gli standard quattro spazi quando si indenta utilizzando la tabulazione, non consentono di oltrepassare gli 80 caratteri in orizzontale (sulla stessa riga) nella scrittura del codice, salvano i file in formato unix senza avere problemi di conversione.

Indentazione automatica

Nella precedente configurazione è stata inserita la direttiva autoindent che consente di impostare l'autoindentazione. Tale direttiva funziona, ma ci sono dei casi, quale quello della segnatura della funzione multilinea dove tale direttiva non offre il risultato atteso.

Per ovviare a tali problemi può essere usato il plugin indentpython.vim aggiungendo la direttiva su ~/.vimrc:

Plugin 'vim-scripts/indentpython.vim'

Segnare spazi bianchi non necessari

All'interno del codice scritto potrebbero essere presenti degli spazi bianchi non necessari. Puoi configurare la segnalazione degli spazi bianchi inserendo nel ~/.vimrc le seguenti direttive:

highlight BadWhitespace ctermbg=red guibg=darkred
au BufRead,BufNewFile *.py,*.pyw,*.c,*.h match BadWhitespace /\s\+$/

La direttiva colora di rosso gli spazi bianchi per agevolare la cancellazione degi stessi.

Impostare UTF-8 come codifica di default

Quando lavori con Python3 è opportuno utilizzare la codifica UTF-8. Per forzare VIM a lavorare con la codifica UTF-8, inserire la seguente direttiva:

set encoding=utf-8

Autocompletamento

VIM consente di inserire l'autocompletamento del codice mediante l'uso di plugin. Il miglior plugin per l'autocompletamento del codice Python è YouCompleteMe.

Per poter installare il plugin, inserire all'interno della porzione di ~/.vimrc riferito a Vundle, la seguente direttiva:

Bundle 'Valloric/YouCompleteMe'

Il plugin automaticamente utilizza differenti autocompletamenti configurati per vari linguaggi. Per il codice Python utilizza Jedi e per farlo funzionare utilizza delle librerie in C, che devono essere necessariamente presenti sul pc ospitante la configurazione.

A seguito dell'installazione del Plugin potrai trovare la comparsa di un errore ad ogni apertura di VIM. Per ovviare a tale errore è necessario compilare il plugin accedendo alla cartella scaricata da Vundle. Per compilare il plugin eseguire i seguenti comandi:

cd ~/.vim/bundle/YouCompleteMe
python3 install.py --all

Il comando, dopo alcuni minuti, compila il plugin. Se l'operazione va a buon fine, non vedrai più il messaggio di errore altrimenti dovrai provvedere alla ricompilazione del plugin. Eventuali errori possono essere dovutio alla mancanza di qualche dipendenza; in questo caso fare riferimento alla documentazione ufficiale del plugin.

Una volta installato il plugin funziona correttamente; puoi tuttavia aggiungere alcune personalizzazioni. In primo luogo puoi impostare che la finestra degli autocompletamenti vada via una volta che la abbiamo utilizzata; per fare ciò, inserire la seguente direttiva:

let g:ycm_autoclose_preview_window_after_completion=1

Puoi anche impostare una scorciatoia per la definizione dell'avvio dell'autocompletamento, inserendo la seguente direttiva:

map <leader>g  :YcmCompleter GoToDefinitionElseDeclaration<CR>

dove leader rappresenta il tasto chiave da impostare sul ~/.vimrc con la seguente direttiva:

let mapleader = "," " set leader character for commands

La direttiva deve essere inserita in cima al file .vimrc ed una volta impostata può essere utilizzata all'interno dei comandi che lo definiscono.

Supporto al virtualenv

Python consiglia lo sviluppo utilizzando i virtualenv che non rappresentano un argomento per il presente articolo. Possiamo utilizzare il virtualenv del progetto sul quale stiamo lavorando, assicurando di aprire il nostro VIM da un terminale nel quale il virtualenv desiderato è attivo.

Per esempio, se hai un progetto sul path ~/src/mio_progetto dovrai:

cd ~/src/mio_progetto

# Attivare il virtualenv
source .env/bin/activate

# Aprire VIM
vim .

A questo punto VIM è aperto con il virtualenv abilitato e quindi, ad esempio, autocompleta le istruzioni utilizzando le librerie installate sul virtualenv.

Controllo sintattico del codice Python

Il controllo sintattico del codice Python può essere eseguito mediante l'utilizzo di due plugin: syntastic e vim-flake8.

Il plugin syntastic è la soluzione più completa per controllare sintatticamente il codice, poiché prevede il supporto per molti linguaggi e quindi è da preferire se si vuole uno strumento che vada bene non solo per il controllo sintattico di Python.

Per installare il plugin inserisci nel ~/.vimrc:

Plugin 'vim-syntastic/syntastic'

ed inserisci una prima configurazione base che utilizza Flake8 come controllore sintattico.

set statusline+=%#warningmsg#
set statusline+=%{SyntasticStatuslineFlag()}
set statusline+=%*

let g:syntastic_always_populate_loc_list = 1
let g:syntastic_auto_loc_list = 1
let g:syntastic_check_on_open = 1
let g:syntastic_check_on_wq = 0

let g:syntastic_python_checkers = ['flake8']

Da notare che come Python checker puoi inserire quello che preferisci (ad esempio: pylint). Per funzionare il controllore deve essere installato sull'ambiente di sviluppo.

Il plugin vim-flake8 puoi installarlo come segue:

Plugin 'nvie/vim-flake8'

e attivare il controllo del codice premendo il pulsante <F7>.

Evidenziazione della sintassi

Puoi evidenziare la sintassi Python nei file inserendo le seguenti direttive:

let python_highlight_all=1
syntax on

Colorazione dell'editor

VIM per default prende il colore del terminale sul quale è in esecuzione. Puoi tuttavia personalizzare i colori dell'editor inserendo delle direttive all'interno del file ~/.vimrc.

Supponiamo di voler installare la colorazione solarized quando si utilizza VIM in modalità GUI e Zenburn quando utilizziamo VIM sul terminale. In primo luogo installiamo i seguenti plugin, inserendo sul ~/.vimrc:

Plugin 'jnurmine/Zenburn'
Plugin 'altercation/vim-colors-solarized'

Successivamente per discriminare VIM su GUI e VIM su terminale puoi inserire le seguenti direttive:

if has('gui_running')
  set background=dark
  colorscheme solarized
else
  colorscheme zenburn
endif

Ovviamente puoi omettere la condizione inserendo solamente

colorscheme zenburn

qualora non contempli l'utilizzo di GUI per vim.

Infine, occorre sottolineare che alcuni temi prevedono versioni dark e light. In questo caso possiamo cambiare tra una modalità e l'altra impostando il pulsante di switch come segue:

call togglebg#map("<F5>")

nel precedente caso il tasto F5 modifica la modalità del tema.

Navigazione dei file

Per aggiungere una finestra che consente la navigazione dei file e delle cartelle mentre manteniamo aperto uno o più file, puoi utilizzare il plugin NERDTree. Per installare il plugin aggiungere al ~/.vimrc le seguenti direttive:

Plugin 'scrooloose/nerdtree'

NERDTree è un plugin molto potente e può essere configurato in molti modi. Per analizzare come configurare NERDTree fare riferimento alla documentazione ufficiale.

Una possibile personalizzazione di NERDTree prevede la possibilità di rimuovere alcuni file dalla visualizzazione. Se ad esempio vuoi nascondere i file .pyc aggiungi la seguente direttiva:

let NERDTreeIgnore=['\.pyc$', '\~$'] "ignore files in NERDTree

Ricerca file

Una funzionalità molto importante offerta dagli editor, oltre all'alberatura dei file e delle cartelle, è quella della ricerca dei file inserendo una stringa di testo. In VIM possiamo abilitare questa funzionalità installando il plugin ctrlp. Per installare il plugin inserire nel file ~/.vimrc:

Plugin 'kien/ctrlp.vim'

Una volta installato il plugin, digitando Ctrl + P abiliteremo la ricerca (appare una finestra in basso) inserendo la chiave di ricerca. Le ricerche possibili sono molto avanzate e saranno trattate in un articolo a parte.

Numerazione delle righe

Per numerare le rige su VIM inserire:

set nu

Integrazione GIT

Puoi integrare il versionamento con GIT utilizzando il plugin vim-fugitive inserendo:

Plugin 'tpope/vim-fugitive'

Powerline

Il progetto PowerLine offre una status bar che mostra il virtualenv, il branch git, il file sul quale stiamo lavorando e altro. Powerline è un progetto scritto in Python e supporta shell come zsh, bash, tmux, IPython. Per installare Powerline:

Plugin 'Lokaltog/powerline', {'rtp': 'powerline/bindings/vim/'}

Per default la powerline si attiva quando si hanno due finestre aperte su VIM. Per forzare la visualizzazione sempre aperta della powerline aggiungi al file ~/.vimrc:

set laststatus=2

Conclusioni

In questo articolo hai visto come configurare VIM come IDE per lo sviluppo Python. VIM offre tante altre possibili configurazioni rispetto a quelle presentate in questo articolo, tuttavia seguendo le istruzioni indicate riuscirai ad avere un supporto nelle tue attività di sviluppo.