jeudi 26 mars 2015

Dompter VIM en trois temps 2/3

Temps 2 : Grok your VIM

Après avoir été convaincu de changer votre éditeur pour Vim et avoir pris connaissance de quelques commandes de bases, place à la phase suivante : la configuration.

vim_love

On n'écrit pas que du code dans notre travail. On s'exprime aussi par écrit, dans un langage plus humain, pour échanger avec d'autres collaborateurs qui ne sont pas tout le temps du même métier; on n'est pas dispensé de la maîtrise de l'orthographe. Voyons ce que le correcteur d'orthographe de VIM propose pour le spell checking.

Pour l'activation/désactivation …
:set spell
:set nospell

 … et pour les commandes d'utilisation
 z= voir les suggestions sur le mot mal orthographié
]s se mettre sur le prochain mot mal orthographié
[s se mettre sur le précédent mot mal orthographié
zg ajouter le mot au dictionnaire
zug annuler l'ajout du mot au dictionnaire

Le spell checking parait ici contre-intuitif. Pour chacune des commandes, on a au minimum deux caractères à taper, y compris parfois un caractère spécial (“]”,”[“ ou “=”). Utiliser Vim de cette manière peut être très vite déroutant. Les premiers signes de frustration font leur apparition, comme cet utilisateur qui se plaint sur Stackoverflow d'être plus productif avec ses précédents éditeurs qu'avec VIM qu'on lui a pourtant présenté comme étant l'éditeur du développeur...
I've heard a lot about Vim, both pros and cons. It really seems you should be (as a developer) faster with Vim than with any other editor. I'm using Vim to do some basic stuff and I'm at best 10 times less productive with Vim.
… Et la réponse qui a suivi résume l'idée de cet article :
Your problem with Vim is that you don't grok vi.
http://stackoverflow.com/questions/1218390/what-is-your-most-productive-shortcut-with-vim

Sans une configuration minimale l'éditeur reste très peu pratique. Pour découvrir la vraie puissance de VIM il faut l'adapter à ses habitudes. Le travail commence dans le fichier de config ~/.vimrc qui joue le même rôle que ~/.gitconfig pour Git ou ~/.bashrc pour Linux. On peut trouver des fichiers .vimrc sur github mais il vaut mieux en prendre un qui soit basique et l'enrichir au fur et à mesure. Cela doit refléter une habitude qui n'est pas universelle. On trouvera principalement dans le fichier des configs de bases, des mappings et des macros (fonctions).

Configuration de base

Dans la partie configuration on met les options par défaut, celles dont on a besoin le plus souvent. Les options rarement utilisées pourront être activées manuellement.

Exemple : Puis qu'il est plus pratique de se repérer à partir de la position courante que des numéros de lignes, on choisira par défaut l'affichage des numéros de lignes en mode relatif.
set relativeNumber


Si au cour d'une session on veut passer à l'affichage en mode absolu on exécute les deux commandes (en mode command-line):
:set norelativenumber
:set nu

 On va essayer de voir d'autres options que l'on peut avoir besoin de spécifier dans le fichier de config.

Faire une recherche intelligente
set ignorecase
set smartcase
Avec cette configuration si le mot recherché est en minuscule la casse n'est pas prise en compte. Par contre si une des lettres du mot est en majuscule on a la recherche en case-sensitive.

Ne pas rendre VIM compatible avec Vi. Si on active la compatibilité on perd les fonctionnalités de VIM qui n'existent pas dans VI. 
set nocompatible

Mettre en évidence la position du curseur avec une ligne horizontale.
set cursorline

Afficher la commande sur la barre d'état.
set showcmd

Mettre en évidence les parenthèses qui correspondent.
set showmatch

Activer la recherche incrémentale. La recherche s'effectue au fur et à mesure qu'on fait la saisie.
set incsearch

Masquer les buffers quand ils ne sont plus utilisés.
set hidden

Définir la couleur de fond.
set background=dark

Choisir l'encoding pour l'affichage et l'encoding pour les fichiers.
set encoding=utf8
set fileencoding=utf-8

Prendre le dictionnaire français pour le spell checking.
set spell spelllang=fr_fr

Mettre 4 espaces pour l'indentation. On utilise soit la tabulation (tabstop) soit ">>" (shiftwidth).
set tabstop=4
set shiftwidth=4

80, le nombre maximal de caractères par ligne.
set textwidth=80

Ne pas couper un mot pour aller à la ligne.
set linebreak

Par défaut leader est mappé en "\". Il est remappé en "," pour une utilisation plus simple.
let mapleader = “,”


Du Mapping pour aller plus vite !

Pour faire un petit parallèle risqué avec le développement : quand on a un block de codes qui revient à différents endroits d'un projet on pense automatique à le simplifier par une structure plus compacte. C'est presque la même chose avec le mapping, on cherche à simplifier pour aller encore plus vite. On y a recours généralement quand on doit exécuter une combinaison de commandes fréquemment utilisée ou invoquer une fonction. On peut appliquer le mapping à un mode spécifique, modal mapping (imap, nmap et vmap), ou à tous les modes, general mapping (map).

Une des contraintes quand on crée un mapping est d'avoir des collisions. Certains raccourcis peuvent être déjà définis par l'OS, l'éditeur même, un plugin de l'éditeur ou une macro. On n'en crée pas délibérément. Quelques astuces sont mises à notre disposition pour limiter les risques de collisions et aussi pour avoir des raccourcis plus intuitifs :
  • Utiliser les touches dont on ne se sert presque jamais F2, F3, ...
  • Combiner les touches avec les keys modifier Ctrl, Alt, Shift,
  • Préfixer avec leader : c'est une touche qu'on choisit pour préfixer les mappings. Par défaut c'est “\” mais dans la pratique on utilise très souvent “,” ou “-”. Il doit donc être remappé dans le .vimrc.

Le mode Insert est très pauvre. On doit le quitter à chaque fois qu'on doit faire une action un peu compliquée. Pour supprimer une ligne par exemple il faut en général faire :

<esc> pour aller au mode normal 
dd suppression de la ligne 
i pour revenir en mode insert

Pour mettre un mot en majuscule depuis le mode il faut au minium faire <esc>viwgUi .


Ces actions sont très courantes quand on fait de l'édition. Comme le développeur a horreur de la répétition, VIM nous facilite la tâche avec le mapping qui nous permet de muscler notre éditeur.
En ajoutant ces lignes dans notre config on pourra réaliser des actions sans quitter le mode Insert. Ctrl-D pour supprimer une ligne, Ctrl-U pour mettre en majuscule un mot ou Ctrl-Y pour dupliquer une ligne.

imap <C-D> <esc> ddi 
imap <C-U> <esc> viwgUi 
imap <C-Y> <esc> yypi

j et k pour une Navigation entre lignes virtuelles
nmap j gj nmap k gk
Recursive mappings
Par défaut le mapping sur VIM est récursif. Si on ajoute ce map

map j gg
map Q j
Q est mappé en j , j mappé en gg, donc Q mappé en gg. On parle de recursive mapping
noremap W j
Si on ne veut pas de mapping recursif on utilise le mot clé noremap. Ici W devient juste j et pas gg. 
Pour se mettre à l'abri des mauvaises surprises il est préférable d'utiliser par défaut un mapping non récursif.

Ctrl-S pour sauvegarder depuis les modes Normal ou Insert …
noremap <C-S> :w<CR>
inoremap <C-S><C-O> :w<CR>

 … on peut aussi passer <leader>w
noremap <leader>w :w<CR>
inoremap <leader>w <C-O>:w<CR>

jj, Enter ou Shift-Enter pour un Echappe plus intuitif
inoremap jj <esc> inoremap <CR> <esc>
inoremap <S-CR> <esc>

Arrow keys désactivé
Certains proposent de désactiver les touches fléchées, avec la valeur Nop, pour se forcer à utiliser les touches hjkl pour la navigation. D'autres proposent d'en faire un autre usage.
noremap <Up> <Nop>
noremap <Down> <Nop>
noremap <Left> <Nop>
noremap <Right> <Nop>

Alt-J et Alt-K pour déplacer la ligne courante en mode normal
nmap <M-J> mz:m+<CR>'z
nmap <M-K> mz:m-2<CR>'z

Alt-J et Alt-K pour déplacer un block de lignes en mode Visual
vmap <M-J> :m'>+<CR>'<my'>mzgv'yo'z
vmap <M-K> :m'<-2'><CR>my'<mzgv'yo'z
Leader The leader is a kind of “namespace” to keep those customizations separate and prevent them from shadowing default commands. (Steve Losh)
<leader>i pour les aller retour entre les modes Normal et Insert
nnoremap <leader>i i inoremap <leader>i <es>

Spell checking (http://amix.dk/vim/vimrc.html)
<leader>ss pour activer/désactiver le spell checking …
nnoremap ss :setlocal spell!

et les commandes ,sn ,sp ,sa ,sz pour l'utilisation
nnoremap <leader>sn ]s
nnoremap <leader>sp [s
nnoremap <leader>sa zg
nnoremap <leader>sz z=

Edition de .vimrc avec<leader>ev et<leader>sv
Il est très fréquent de vouloir faire des modifications sur .vimrc, et de voir les effets dans l'immédiat, alors qu'on est en pleine édition. Voici un mapping simple qui facilite l'écriture et le chargement des modifications.
nnoremap <leader>ev :vsplit $MYVIMRC
nnoremap <leader>sv :source $MYVIMRC

$MYVIMRC une variable qui correspond au fichier .vimrc
:vsplit pour ouvrir .vimrc dans un nouvel onglet vertical
:source pour charger la dernière configuration

Basculer de relative à absolute
On peut avoir besoin de basculer entre le relative et l'absolute dans l'affichage des numéros de lignes. Avec ce mapping la commande est<leader>n  

function! NumberToggle()      
  if(&relativenumber == 1)        
     set norelativenumber      
     set number        
     highlight LineNr ctermfg=yellow     
  else        
    set nonumber        
    set relativenumber        
    highlight LineNr 
    ctermfg=green     
  endif   
endfunc   

nnoremap<leader>n :call NumberToggle()<CR>

http://jeffkreeftmeijer.com/2012/relative-line-numbers-in-vim-for-super-fast-movement/

 Bonus abbréviation
iabbrev @@ yakhya.dabo@arolla.fr
iabbrev cc AROLLA – Mastering Software Development


On ferme la deuxième partie de la série sur l’abréviation. Elle nous permet d'insérer rapidement les champs qu'on utilise couramment dans le texte, prénom, nom, adresse e-mail, signature, site web, … Avec la config ci-dessus, on peut se limiter à taper @@ pour l'e-mail ou cc pour copyright.

Conclusion

C'est dans dans la partie configuration qu'on découvre la vraie puissance de VIM. Le mapping doit être le premier réflexe pour rendre plus simples des actions complexes et pour éviter des répétitions comme les aller-retour entre le mode normal et les autres modes. N'hésitez pas à vous inspirer d'exemples sur le net pour enrichir votre configuration.
On est bien tenté de dire qu'avec VIM on peut tout faire.