VI - BFO

Transcription

VI - BFO
VI : un éditeur pour la VIe !
[email protected]
1
Présentation de vi
vi existe maintenant depuis la fin des années 70. Il y a de fortes chances qu’il existe encore dans 60 ans
lorsque vous prendrez votre retraite. Comme le vélo est l’outil du cycliste et le piano l’outil du pianiste,
l’éditeur de textes est l’outil de base de l’informaticien, car son travail est de modifier des fichiers. Il y a
deux éditeurs de texte professionnels en ce bas monde : vi et emacs.
Il est possible de modifier un fichier avec un éditeur quelconque, tout comme il est possible de faire le Tour
de France avec un vélo hollandais, ou de jouer Au clair de la lune avec un orgue Bontempi a 20 touches.
Mais pour prendre l’exemple du pianiste, un orgue Bontempi reste un jouet totalement inutilisable pour
interpréter une fugue de Bach.
vi et emacs sont des Bösendorfer : des pianos à queue de concert faisant 3m de long et pesant
presque 600 Kg (cf. http ://tinyurl.com/c7t47), dont il est possible de sortir des choses merveilleuses
et étonnantes pour peu que l’on sache en jouer, c’est-à-dire à condition d’avoir fait du piano pendant de
nombreuses années. C’est beaucoup plus lourd et plus encombrant qu’un Bontempi, mais ce n’est pas
comparable, bien que tous les deux soient capables de jouer Au clair de la lune. Un bon ouvrier a de bons
outils. Bien qu’il soit beaucoup plus facile de jouer du Bontempi (avec accompagnement automatique et
boı̂te à rythmes avec valse, tango, rock et samba) je n’ai encore jamais vu de pianiste donner un concert
avec un Bontempi . . . il doit bien y avoir une raison, non ?
vi existe sur toutes les plateformes (Unix, Windows, MacOs, VAX/VMS, Amiga,. . .), et fonctionne sur
tous les types de fichiers1 , même les plus récents (xml, html, java, C#, . . .) car il y a de nouvelles versions
qui sortent périodiquement. C’est l’outil du pro, adapté à la meilleure interface homme-ordinateur existant
à présent (et la même que le piano) : le clavier (et pas la souris, le mulot, ou le cochon-d’inde, qui servent
à démocratiser l’utilisation des ordinateurs et à permettre à votre grand-mère de surfer sur internet).
Car j’avais oublié de préciser une évidence : l’interface naturelle pour communiquer avec un ordinateur,
c’est le clavier, pour la bonne raison qu’on a pratiquement tous 10 doigts, et que ça va donc 10 fois plus
vite de les utiliser que d’utiliser une souris pour cliquer sur quelque-chose. Pour terminer la comparaison
avec le piano : imaginez-vous qu’il soit possible de jouer autre chose qu’Au clair de la lune, en cliquant
sur les touches d’un piano virtuel avec une souris ? ? ?
Et bien en informatique, c’est pareil : la souris est bien trop lente pour faire quoi que ce soit avec. C’est
un périphérique génial pour les débutants, car ça rend l’informatique conviviale et utilisable par tous.
Mais dès qu’on veut gagner en rapidité et en efficacité, la souris est totalement inutilisable.
Un seul exemple ? Supposez que vous vouliez dupliquer une ligne. Avec une souris, il faut 1) sélectionner
la ligne, 2) cliquer sur Edition → copier, 3) positionner le curseur au début de la ligne suivante, 4)
cliquer sur Edition → coller. C’est intuitif pour les débutants, mais ça fera bien rire n’importe quel
utilisateur de vi qui fera ça en 2 touches : Yp. (Y met la ligne en mémoire (commande yank), et p pose
le contenu de la mémoire après le curseur (commande put)).
Vous démarrez en informatique. Investissez et apprenez à vous servir du bon outil : vos doigts et un
éditeur performant et adapté à l’écriture de programmes de tous formats : vi ou emacs.
En ce qui concerne vi, la version principale actuelle est VIM (pour VI IMproved) (chercher vim sur google),
maintenue par Bram Moolenaar. vi est supporté par toute la communauté des informaticiens qui, à la
manière des logiciels libres, lui ajoutent périodiquement (et gratuitement !) des raffinements. vi n’est donc
pas un “vieil” éditeur. C’est un éditeur gratuit, multi-fichiers, multi-fenêtres, optimisé pour un usage au
clavier et qui a bénéficié de 30 ans de raffinements les plus divers et variés. C’est une Ferrari, qu’il faut
apprendre à conduire (et qui surprendra ceux qui viennent de passer le permis).
1 sauf
l’hexadécimal, pour lequel il y a des éditeurs spécifiques.
1
2
Principe de fonctionnement
Avant tout, il y a bien entendu un manuel écrit par Bram Moolenaar (taper :help manual) mais il est
un peu long, d’où ce document de 14 pages résumant ce que j’utilise personnellement. vi fonctionne sous
deux modes : le mode commande (où les touches que l’on tape sont des commandes) et le mode insertion
(où les touches que l’on tape se retrouvent dans le fichier édité). Ce fonctionnement est très puissant,
car il permet de disposer d’énormément de commandes (autant de commandes qu’il y a de touches sur
le clavier) sans devoir utiliser la souris. Le prix à payer pour cet agrément et ce confort d’utilisation est
que, comme il n’y a pas de menus déroulants, il faut apprendre à s’en servir.
Lorsqu’on ne modifie pas le contenu du fichier, toujours revenir en mode commande avec la touche esc
(escape). Il faut considérer le mode insertion comme exceptionnel.
Méfiance : si, par inadvertance, vous passez en majuscules, les effets seront surprenants car les commandes
effectuées seront bien évidemment différentes. . . : dans ce cas, tapez vite esc pour revenir en mode
commande (au cas où vous seriez passé en mode insertion), repassez en mode minuscule et tapez des
uuuuu... (undo) jusqu’à récupérer l’effet des commandes en majuscules. Si vous avez été trop loin dans
les undo, le redo se fait avec des CTRL-R.
3
Configuration et fichiers de configuration
Avant tout, autant commencer par un vi bien configuré. Il y a tout plein d’options (cf. :help options)
qu’on peut modifier avec la commande set, mais avant de rentrer dans la modification d’options, je vous
propose un fichier de configuration de base. Le fichier .vimrc est un des fichiers de configuration de
vim (tapez :scriptnames pour lister tous les fichiers chargés). Il contient une collection de commandes
qu’on pourrait taper au clavier à chaque fois qu’on rentre sous vi. Il faut le mettre dans votre répertoire
personnel ($HOME) pour que vi puisse le retrouver. Voici le contenu de celui que je vous propose :
set nocompatible
" utiliser les améliorations de VIM sur vi
syntax enable
" permettre le coloriage syntaxique en gardant vos couleurs perso
set undolevels=1000
" mémoriser 1000 "undo"
set ignorecase
" ignorer minuscules/majuscules dans les recherches
set smartcase
" faire ça de manière intelligente...
set incsearch
" trouve tous les termes cherchés dans le fichier
set hlsearch
" surligne les termes trouvés
set wrapmargin=7
" insère automatiquement un CR 7 caractères avant la fin de ligne
set autoindent
" récupère l’indentation de la ligne précédente
set smartindent
" modifie l’indentation suivant le contenu du texte (prog. C/C++/...)
set expandtab
" perso, je n’aime pas les tab, donc je les remplace par des espaces
set tabstop=2
" je dis qu’un tab vaut 2 espaces
set nosmarttab
" ne jamais insérer de tab à mon insu
set shiftwidth=2
" valeur de l’indentation standard : 2 caractères (va moins loin à droite)
set wildignore=*.bak,~*,*.o,*.info,*.swp,*.obj,*.class,*.aux,*.toc,*.log,*.dvi,*.pdf,*.ps,*.exe
" ne pas proposer les extensions inintéressantes
set viminfo=’20,%,h,
" paramètres pour vi : mémoriser les marques dans 20 fichiers
" se souvenir des buffers avec noms de fichier
set ruler
" afficher les numéros de ligne et de colonne où se trouve le curseur
set showcmd
" affiche la commande courante à gauche des No de ligne et de colonne
set nojoinspaces
" ne pas insérer 2 espaces après "." lors d’un J
set textwidth=73
" casser la ligne pour ne pas dépasser 73 caractères
set columns=80
" nombre de colonnes d’une fen^
etre vim par défaut
set splitbelow
" lorsqu’une nouvelle fen^
etre est insérée, la mettre dessous
set tildeop
" permet à la commande ~ d’^
etre utilisée comme opérateur
filetype plugin on
" demande à vi de charger un plugin spécifique au type de fichier
autocmd BufNewFile,BufRead *.html source $HOME/confightml
2
Pour connaı̂tre la signification de chacune de ces options, vous pouvez taper :help smartcase par
exemple ( :q pour sortir de l’aide).
Sur la dernière ligne, il y a un exemple montrant l’utilisation d’une “autocommande,” demandant à
vi de lire le ficher “source” confightml si l’extension du fichier édité est .html. Voici mon fichier de
configuration confightml :
imap
imap
imap
imap
imap
imap
imap
imap
imap
imap
^Và
^V^
a
^Vç
^Vè
^Vé
^V^
e
^V^
ı
^V^
o
^Vù
^V^
ı
à
â
ç
è
é
ê
î
ô
ù
û
La commande imap permet de changer la valeur d’une touche. Ainsi, lorsqu’un fichier html est chargé
dans vi, à chaque fois que j’insère le caractère “à”, vi le remplace par &agrave ;.
Mais bon, maintenant que la configuration est faite, on peut commencer à essayer de se servir de vi.
4
4.1
Commandes de base
Déplacement simple dans le texte
Lorsque vous êtes en mode commande ( ESC ) les déplacements se font de préférence avec les touches
h (←) j (↓) k (↑) l (→). Toujours dans l’esprit d’améliorer l’efficacité, l’utilisation des touches h j k l
est beaucoup plus rapide que les flèches, car on n’a pas besoin de déplacer sa main du clavier pour les
utiliser. Comme tous les informaticiens (les vrais, ceux qui ont de la corne au bout des doigts à force de
taper sur un clavier ;-) finissent par les connaı̂tre d’instinct, beaucoup de logiciels les utilisent comme par
exemple less, beaucoup de programmes de jeux, mais aussi gmail de Google (k pour passer au message
au dessus, j pour passer au message en dessous,) et les exemples sont légion. Si vous implémentez un
programme où il y a des déplacements, n’oubliez-pas d’autoriser les déplacements avec h j k l. Cela
aidera votre programme à être standard et vous vous ferez plein de petits copains informaticiens.
Pour information, page up se fait avec CTRL-B (backward) et page down se fait avec CTRL-F (forward). Ca
vaut la peine de le mentionner car more utilise ces raccourcis (avec les versions modernes de more, il est
possible de remonter ou de descendre d’une page, mais toujours pas d’une ligne).
4.2
Commandes de base d’insertion, de suppression et de remplacement
Comme vous le verrez, les commandes de vi viennent souvent par deux (minuscule et majuscule) :
i a Passage en mode insertion avant le curseur (i pour insert) ou après le curseur (a pour append).
I A Passage en mode insertion en début de ligne (I) ou en fin de ligne (A).
o O Création d’une ligne blanche en dessous (o) ou au dessus du curseur (O).
x X Suppression d’un caractère sous le curseur (x) ou précédant le curseur (X).
r R Remplace 1 caractère (r) ou passe en mode remplacement (R).
s S substitue 1 caractère (s) ou une ligne complète (S). s est plus intéressant à substituer en conjonction
avec un nombre : 10s permet de substituer 10 caractères.
3
D dd supprime la fin d’une ligne (d) ou la ligne entière (dd).
J Join. Permet de “rejoindre” des lignes coupées par un CR. Notez que la réunion des deux lignes est
faite de manière “intelligente.”
Pratiquement toutes les commandes vi peuvent être précédées d’un nombre.
Essayez de taper : 10icoucou ESC pour voir ce que ça donne, ou 3dd (puis u pour récupérer).
4.3
Registre courant, Undo et Redo
u défait une action. vi peut mémoriser un très grand nombre de changements (configurable dans
.vimrc).
CTRL-R la refait.
U remet la ligne courante dans son état d’origine (quelque soit le nombre de modifs sur la ligne tant
qu’on n’a pas changé de ligne).
Y met la ligne entière dans le registre courant.
p P commande put. Toute suppression (commandes d c s x) met le texte supprimé dans un registre
courant (tout comme Y). p insère le contenu du registre courant après le curseur, P avant.
4.4
Écriture, lecture, édition et sortie de vi
La sauvegarde et la sortie passent par le mode de commande en ligne.
:f permet de connaı̂tre le nom du fichier courant.
:w écrit les dernières modifications effectuées dans le fichier courant. :w ! force l’écriture.
:w titi écrit le contenu fichier courant dans titi.
:e titi édite le fichier titi. :e ! force l’édition, et :e# édite le fichier précédemment ouvert.
:r toto (et insère) le contenu de toto en dessous du curseur.
:q permet de quitter. vi refuse de quitter si vous n’avez pas sauvé votre travail. :q ! force la sortie.
:wq ZZ :x Ces 3 commandes permettent de sauvegarder et quitter.
4.5
Récupération lors d’un problème
Lorsque vous éditez un fichier sous vi, un fichier temporaire est ouvert, dans lequel vi entre toutes les
modifications que vous effectuez. Sous Unix, vi reste en sticky ce qui lui permet d’éviter de se faire éjecter
en zone de swap. Le noyau connaı̂t vi, et lors d’un problème, il y a fermeture automatique des fichiers
temporaires de modification, ce qui permet de ne jamais rien perdre (ou presque).
Si pour une raison quelconque, il y a un problème en cours d’édition (coupure d’alimentation, plantage,
kill ...), toutes les modifications depuis la dernières ouverture sont donc (à quelques caractères près)
présentes dans le fichier temporaire de sauvegarde. Après l’incident, si vous cherchez à éditer à nouveau
le fichier, vi peut reconstituer ce qui s’était passé jusqu’à la survenue du problème. Plusieurs options
sont alors disponibles :
Ouvrir en lecture seule le fichier précédemment sauvegardé.
Éditer quand même le fichier précédemment sauvegardé (en perdant les modifications faites depuis la
dernière sauvegarde).
Récupérer les dernières modifications. Le fichier sera alors pratiquement identique à celui en cours
d’édition au moment du problème, à quelques caractères près. Si les 2 derniers caractères étaient
d} (suppression de paragraphe), bien sûr, le paragraphe risque d’être toujours présent.
4
Quitter
Supprimer le fichier de modifications
Si vous choisissez Récupérer (l’option conseillée), vous vous retrouverez donc dans l’état où vous étiez
quelques caractères avant l’incident. Si vous continuez à éditer le fichier, et si vous sauvegardez, cela
n’effacera pas le fichier de modifications sauvegardé précédemment. Ceci signifie que lors de la prochaine
ouverture du même fichier, vi vous reproposera les mêmes options, à cause de l’ancien fichier de modifications présent sur le système. Cette seconde fois, si vous choisissez Récupérer, vous allez perdre les
modifications faites précédemment.
En cas d’interruption d’une édition sous vi, la bonne procédure à suivre est donc la suivante, lorsque le
système revient à lui :
1. Rouvrir le fichier avec vi.
2. Récupérer les modifications.
3. Sauvegardez et quitter (ZZ).
4. Rouvrir le fichier avec vi.
5. Cette fois-ci, choisissez de Supprimer le fichier de modifications.
Le fichier de modifications n’existant plus, vi ne vous embêtera plus avec.
4.6
Recherche simple
/toto va jusqu’à l’occurrence de la chaı̂ne toto (recherche toto) vers le bas. Ensuite, n cherche l’occurrence suivante, et N la précédente.
?toto pareil que /toto, mais vers le haut. n et N fonctionnent aussi, mais à l’envers.
* raccourci allant à la prochaine occurrence du mot sur lequel se trouve le curseur. NN permet de remonter
sur l’occurrence précédente.
4.7
Recherche/remplacement simple
Pour cette commande (qui n’est pas simple), autant commencer avec du par-cœur, avant d’en voir toutes
les possibilités.
:g/toto/s//titi/gp va remplacer toutes les occurrences de toto par titi. Le :g sert à dire qu’il s’agit
d’un remplacement global (sur toutes les lignes du fichier). Le /toto/ dit que l’on chercher toto. Le
s est la commande substitute, que l’on appliquera au motif déjà cherché // et que l’on remplacera
par titi. Le dernier / sert à délimiter la chaı̂ne à remplacer. Enfin, le g suivant dit qu’on veut que
le remplacement soit effectué sur toutes les occurrences de toto dans la ligne, et p va afficher toutes
les modifications effectuées.
La plupart des éditeurs standards s’arrêtent là au point de vue possibilités d’édition. Vous l’aurez compris,
c’est là que commence vi (et probablement emacs).
Les pages qui suivent décrivent les commandes que j’utilise quotidiennement et naturellement après 20
ans de pratique de cet éditeur, et qui font que je ne peux plus me passer de vi. Elles ne doivent constituer
qu’environ 10% de la totalité des commandes de vi. Chaque année, je découvre de nouvelles choses que
j’apprends à utiliser et à apprécier. Peut-être arriverai-je à utiliser 20% des commandes d’ici la retraite.
Attention : choisissez maintenant entre vi et emacs. L’expérience montre que ceux qui démarrent avec
vi ne peuvent plus passer à emacs (c’est mon cas) et inversement. Les plus bêtes pensent que leur éditeur
est le meilleur, et crachent sur l’autre. En fait, les deux ont leurs avantages et leurs inconvénients, et sont
probablement équivalents en puissance. Une différence de taille, cependant : emacs est beaucoup plus
gros que vi.
5
5
5.1
Commandes un peu plus avancées
Commande reine de vi (et méritant une section à part entière) : .
. refait la dernière commande exécutée.
3. la refait trois fois. Génial, non ? A ma connaissance, une telle commande n’existe que dans vi.
Exercice : Créez un fichier Syracuse.c contenant les lignes :
public class Syracuse{ // Conjecture de Syracuse
public static void main (String[] args){
int i=15;
while (i!=1){
if (i%2==0) i=i/2;
else i=3*i+1;
System.out.println(i);
}
}
}
Comme vous avez pu le voir, vi est un éditeur de programmeur (indentation automatique, coloration
automatique, . . .), et ça marche avec n’importe quel type de fichier (et sa syntaxe propre, comme
HTML et tous les autres langages).
Maintenant, mettez-vous sur la ligne if (i%2==0) i=i/2;. Tapez 2Y, puis 7P. Maintenant, si le
but est de supprimer les else jusqu’à la fin, il suffit d’aller sur le premier else suivant avec la
commande /else, puis de supprimer le mot avec dw (delete word). Ensuite, n vous emmènera sur
le else suivant, et . répètera la dernière commande effectuée (suppression du mot), . . .pour arriver
à :
public class Syracuse{ // Conjecture de Syracuse
public static void main (String[] args){
int i=15;
while (i!=1){
if (i%2==0) i=i/2;
i=3*i+1;
if (i%2==0) i=i/2;
i=3*i+1;
...
if (i%2==0) i=i/2;
i=3*i+1;
System.out.println(i);
}
}
}
La succession de n et . sert donc de recherche/remplacement interactif sous vi. (Il aurait été possible
de tout remplacer d’un coup avec :g/else/s/// (on verra cette commande plus tard).
5.2
Commandes de déplacement avancées
Beaucoup de commandes de vi s’utilisent en conjonction avec une commande de déplacement. Il est
donc très utile de les connaı̂tre, pour aller plus vite. Il y a plein d’autres commandes de déplacement que
celles ci-dessous (cf. :help motion puis double clic sur |motion.txt|) mais je ne vous mets que celles
que j’utilise habituellement.
w b Déplacement d’un mot vers la droite (w pour word) ou d’un mot vers la gauche (b pour back).
f F{lettre} ; , Occurrence suivante (f) ou précédente (F) de la lettre {lettre} sur une ligne. ; (pointvirgule) répète la dernière recherche f ou F, et , (virgule) répète la dernière recherche f ou F dans
le sens opposé.
6
0 ˆ $ Début, premier caractère non blanc et dernier caractère de la ligne.
% Très pratique pour la programmation : si l’on est positionné sur une parenthèse, accolade, crochet, %
trouve la parenthèse, accolade, crochet correspondant.
[n]| Amène le curseur sur la nième colonne de la ligne.
[n]G ou :[n] va à la ligne n.
G tout seul va en fin de fichier (:0 pour aller en début de fichier).
( ) { } ) va jusqu’au bout de la phrase courante, ( jusqu’au début de la phrase. } va jusqu’à la fin du
pararaphe courant, { jusqu’au début. Permet de travailler à la vitesse de l’éclair sur des zones de
texte : d3} supprime automatiquement trois paragraphes (séparés par des lignes vides). Essayez de
faire aussi vite à la souris ou avec tout autre moyen...
m ma permet de poser la marque a à l’endroit du curseur. L’ensemble des lettres [a-z] et [A-Z] peuvent
être utilisées comme marques, avec la subtilité que les marques majuscules mémorisent le nom du
fichier. Comme vi est un éditeur multi-fichiers (on peut éditer plusieurs fichiers à la fois), on peut
sauter d’un fichier à un autre si on a utilisé une marque majuscule.
’ ‘ ’ permet de retourner à une ligne portant une marque (’a pour retourner à la marque a). ‘ permet
de retourner à une marque au caractère près. Ainsi, ‘A permettra de retourner à la marque A dans
un fichier éventuellement différent du fichier en cours d’édition. Il est intéressant de noter que même
sans laisser de marque, il est possible de revenir à la position d’origine après un déplacement en
utilisant ’’ ou ‘‘ (avant tout déplacement, vi laisse une marque éphémère par défaut).
Exercice : Sur le fichier ci-dessus, on veut incrémenter les 2 en 3, 4, 5, . . . sur toutes les lignes
if (i%2==0) i=i/2;
Se positionner sur la deuxième ligne contenant if (i%2==0) i=i/2;, puis taper f2 puis r3 puis ;.
pour changer aussi le deuxième 2.
Ensuite, taper /if pour aller sur la prochaine ligne contenant un if, ;r4 ;. pour changer le if (i%2==0) i=i/2;
en if (i%4==0) i=i/4;. Ensuite, on continue avec n;r5;. jusqu’à obtenir :
public class Syracuse{ // Conjecture de Syracuse
public static void main (String[] args){
int i=15;
while (i!=1){
if (i%2==0) i=i/2;
i=3*i+1;
if (i%3==0) i=i/3;
i=3*i+1;
...
if (i%9==0) i=i/9;
i=3*i+1;
System.out.println(i);
}
}
}
5.3
Commandes plus évoluées de substitution, remplacement, destruction,
mémorisation, mise en page
On a déjà vu les commandes de base i, a, o, x, r, s. Il existe des commandes plus évoluées permettant d’aller bien plus vite :
ddepl supprime sur un déplacement. dw supprime un mot. 3dw effectue trois suppressions de mots, ce
qui est équivalent à d3w qui supprime sur un déplacement de trois mots. 3d) supprime directement
trois phrases et 3d} supprime trois paragraphes. dfr supprime vers la droite jusqu’au caractère r de
7
la ligne courante. dFr supprime vers la gauche jusqu’au caractère r. d ; supprime jusqu’au prochain
caractère r, et d, jusqu’au précédent (suivant le sens du déplacement original. d/toto supprime
depuis le curseur jusqu’au mot toto dans le texte. d‘a supprime jusqu’à la marque a. dG supprime
jusqu’à la fin du texte. Essayez de refaire ces commandes avec n’importe quel autre éditeur de
textes, et appréciez le gain de temps. . .
D dd D est un raccourci pour effacer le restant de la ligne. dd est un raccourci pour effacer la ligne
courante (3dd effacera trois lignes).
c pour change. cw changera sur un déplacement d’un mot, c’est à dire que cette commande permettra
de changer un mot. Très rapide et très utile. 3cw changera trois mots. Les déplacements décrits
ci-dessus pour d s’appliquent bien entendu à c.
y Cette commande signifie yank. Suivi d’une commande de déplacement, le texte parcouru lors du
déplacement est déplacé dans le registre courant. y} mémorise donc un paragraphe entier.
˜ Met le caractère sous le curseur en majuscules (ou minuscule) suivant la casse. Sous Windows, il faut
faire ESC pour voir le changement se faire. Si le mode tildeop est activé ( :set tildeop), on
peut adjoindre une commande de déplacement. ~ ) change la casse jusqu’à la fin d’une phrase.
gu gU gu met tout en minuscule sur la longueur du déplacement. gU met tout en majuscules sur la
longueur du déplacement. gU) met toute une phrase en majuscules. gU} met tout un paragraphe
en majuscules, et gUG met tout jusqu’à la fin du fichier en majuscules.
= Très intéressant pour la programmation en C : = indente un texte en C sur la longueur d’un
déplacement. Si l’on se met sur la première ligne ( :0) alors =G indentera tout le fichier correctement à la mode C. C’est très utile pour voir les fautes de parenthèsage. Pour réindenter une
fonction seulement, se mettre sur l’accolade de début de la fonction, puis taper =%.
gq Pratiquement pareil que = mais en mode texte. Effectuer gq} permet de reformatter un paragraphe
(faire terminer les lignes au bon endroit).
> < Deux commandes très utiles pour l’indentation. > augmente l’indentation sur la longueur d’un
déplacement, et < diminue l’indentation. Le plus pratique est d’utiliser > et < avec la commande
de sélection visuelle v.
zf zo zd zc Repli. zf suivi d’un mouvement permet de “replier” des lignes (fold). Pour s’en souvenir, le
z symbolise un repli. L’intérêt est qu’un fichier avec des replis est beaucoup plus lisible qu’un fichier
sans replis, et qu’un paragraphe (ou une fonction) repliée se manipule comme une seule ligne (facile
à déplacer). Un repli s’ouvre à l’aide de zo (open), se ferme à l’aide de zc (close) et se détruit avec
zd. Après zd, le contenu du pli n’est pas détruit. C’est le pli qui l’est. Lorsqu’elle est appliquée sur
l’accolade ouvrante du début d’une fonction, zf% replie la fonction entière.
zE zM zR zE Supprime tous les plis du fichier, zM ferme tous les plis, zR ouvre tous les plis.
5.4
Recherche de texte et recherche/remplacement
Recherche Comme évoqué plus haut, la commande permettant de faire une recherche est /. Ainsi,
/toto cherchera toutes les occurrences de toto. Si l’option ignorecase a été mise à on, la recherche
trouvera les occurrences de toto quelle que soit la casse des lettres. Si l’option smartcase a été mise
à on, alors, la recherche sans restriction de casse ne concerne que les lettres écrites en minuscules.
Ainsi, /tOto ne trouvera que les occurrences de tOto.
Pour simplifier les recherches, vi n’utilise pas les expressions rationnelles étendues par défaut (mode
nomagic). Pour les utiliser, il faut donc activer ce mode ( :set magic) et ensuite, on peut utiliser
vi comme sed ou tout autre outil unix utilisant les expressions rationnelles (tapez :help pattern
pour voir les chaı̂nes qu’on peut rechercher sous vi).
Si vous utilisez l’option de surlignage des recherches (hlsearch) et que le surlignage vous embête,
vous pouvez temporairement le supprimer en tapant :noh (abréviation de :nohlsearch).
8
Substitution La commande de substitution complète est :
:[range]s[ubstitute]/{pattern}/{string}/[&][c][e][g][p][r][i][I] [count] Après les :
servant à passer en mode ligne, vous pouvez donner une zone où la substitution s’effectuera. 5,10
effectuera les substitutions sur les lignes 5 à 10, 1,. depuis le début du fichier jusqu’à la ligne
courante. s est la commande de substitution, qui va remplacer {pattern} par {string}.
Les expressions régulières ne sont pas utilisées pour la recherche du pattern si vous n’avez pas
tapé :se magic.
Ensuite, les options les plus intéressantes sont les suivantes :
c demande confirmation à chaque substitution.
g remplace toutes les occurrences sur une ligne (par défaut, seule la première occurrence est remplacée).
p affiche (print) les substitutions effectuées pour contrôle.
Si l’option magic est sélectionnée, on peut tout faire (ou presque). Par exemple, votre binôme vous
passe un fichier écrit en LATEX contenant par erreur dans les 20 pages du texte des {\em x+},
{\em x-}, {\em y+}, {\em y-} alors qu’il aurait fallu écrire $x+$, $x-$, $y+$, $y-$.
Et bien d’un seul coup d’un seul, :g/{\\em \([xy].\)}/s//$\1$/gp va correctement faire toutes
les modifs dans le fichier !
Mais comme s affiche le nombre de substitutions effectuées, on peut l’utiliser pour compter :
:g/le/s//&/g
compte le nombre d’occurrences de la chaı̂ne le dans un texte.
:g/\<le\>/s//&/g
compte le nombre d’occurrences du mot le dans un texte.
:100,200s/\i\+/&/g
compte le nombre de mots entre entre la ligne 100 et 200
\i représente un caractère d’identificateur (faire :help \i pour découvrir plus de caractères spéciaux).
5.5
Couleurs
Il est bien entendu possible de modifier les couleurs d’affichage des différents éléments syntaxiques (à
mettre dans le .vimrc pour chargement automatique). Pour exemple, voici mes couleurs perso :
highlight
highlight
highlight
highlight
highlight
6
6.1
Normal guibg=#D2E4A6
Normal guifg=Black
Constant guifg=#BC7032
PreProc guifg=#7C2BB5
Comment guifg=#4D1ED2
Commandes avancées
Registres
vi contient un certain nombre de registres mémoire, qui sont bien utiles pour stocker temporairement
des mots ou des lignes de texte. La commande " permet d’accéder aux registres. Par exemple, "ay} va
mettre un paragraphe dans le registre a. "ap va coller le paragraphe sauvegarder dans le registre a sous
le curseur. Il y a plusieurs types de registres :
Registres a à z et A à Z Ce sont 52 mémoires permettant d’enregistrer des zones de texte. "cY
mémorise la ligne courante dans le registre c. "cp (ou "cP) permet d’en récupérer le contenu.
Registres 0 à 9 Ils contiennent les dernières lignes supprimées. A chaque nouvelle suppression, le
contenu est décalé d’un cran. "3p va faire réapparaı̂tre l’avant avant avant dernière suppression
de lignes.
9
Registre ” Il s’agit du registre courant, dans lequel vont automatiquement se mettre toutes les suppressions, même si un registre avait été spécifié. Ex : "xdw supprime un mot et le met dans le registre
x (cf. ci-dessus), mais il est aussi mis dans ". Pour le récupérer, "xp va fonctionner, mais aussi ""p
et donc aussi p, car p va se servir dans le registre courant qui est le registre ".
Registre . A l’inverse de ", . contient le dernier texte inséré. Essayez avec ".p.
Registres % # : % contient le nom du fichier courant. # contient le nom du dernier fichier édité
avec la commande e ( :e titi, par exemple) et : contient la dernière commande ligne exécutée
(commande commençant par :).
Registre * ou + Ils contiennent un texte copié ou coupé dans une autre application. De même, si l’on
met du texte dedans ("*y} par exemple), ce texte est disponible pour d’autres applications.
C’est un trou noir. Tout ce qu’on met dedans disparaı̂t, et il ne contient rien. (Ex : " y}
Registre
devrait mettre un paragraphe dans . Si l’on fait " p plus loin, on ne retrouve rien.
Registre / Contient la dernière chaı̂ne recherchée.
Pour finir, il est possible de voir le contenu de tous les registres à l’aide de la commande :display. (La
commande peut se raccourcir en :dis).
6.2
Registres de commande
Les registres précédents étaient capables de stocker du texte. Mais il est aussi possible de mémoriser des
commandes dans des registres 0 à 9 et a à Z :
q{0-9a-zA-Z"} Enregistre les caractères tapés par la suite dans le registre {0-9a-z}. L’utilisation de
majuscules ajoutera les caractères au contenu du registre minuscule existant.
q Arrête l’enregistrement.
@{0-9a-z"} Exécute le contenu du registre {0-9a-z”}.
@@ répète l’exécution du dernier registre.
Deux commandes à priori peu intéressantes le deviennent tout d’un coup beaucoup plus : il s’agit des
commandes CTRL-A et CTRL-X qui incrémentent et décrémentent la prochaine valeur sur la ligne (essayez).
Noter que si vous êtes sous windaube et que CTRL-A a été remappé sur la sélection de tout le texte, il
est toujours possible de mapper une autre touche dessus, en tapant, par exemple :
:map <F2> ^V^A
Ainsi, si dans un fichier, on tape exactement :
mot[1]=1;
puis, si l’on se positionne sur le m de mot et que l’on tape exactement qaYp CTRL-A l CTRL-A q on a
créé une autre ligne tout en incrémentant l’index et la valeur de mot !
Pour recommencer, il faudra faire @a ou @@ (répétition de la dernière exécution). Pour augmenter de 10
lignes, il suffit de faire 20@a. La renumérotation est automatique !
6.3
Sélection visuelle
Les commandes de vi s’exécutent souvent avec un déplacement (par exemple >} pour indenter tout un
paragraphe). Mais plutôt que de leur associer un déplacement, on peut les exécuter sur une zone de texte
sélectionnée.
v débute une sélection visuelle au caractère près.
V débute une sélection visuelle ligne par ligne.
10
Une fois que la zone est débutée, on l’étend avec une commande de déplacement (h, j, k, l) mais aussi
}, 3}, ), G, 4w ou autre.
Une fois la zone délimitée, utiliser une commande dessus (d, y, c, =, <, >,
u pour mettre en majuscules et minuscules.
, ...) mais aussi U et
Beaucoup plus fort :
CTRL-v débute une sélection visuelle verticale ! Utiliser CTRL-Q si CTRL-V est remappé sur “coller”.
Sur la liste que l’on vient de créer :
mot[1]=1;
mot[2]=2;
mot[3]=3;
mot[4]=4;
mot[5]=5;
mot[6]=6;
mot[7]=7;
mot[8]=8;
mot[9]=9;
mot[10]=10;
mot[11]=11;
mot[12]=12;
mot[13]=13;
indentons les lignes d’un cran. Sélectionnez l’ensemble des lignes en vous mettant sur la première ligne,
puis en tapant V}
Ensuite, supposons que l’on veuille dédoubler la colonne pour obtenir
mot[1]=1;
mot[2]=2;
mot[3]=3;
mot[4]=4;
mot[5]=5;
mot[6]=6;
mot[7]=7;
mot[8]=8;
mot[9]=9;
mot[10]=10;
mot[11]=11;
mot[12]=12;
mot[13]=13;
mot[1]=1;
mot[2]=2;
mot[3]=3;
mot[4]=4;
mot[5]=5;
mot[6]=6;
mot[7]=7;
mot[8]=8;
mot[9]=9;
mot[10]=10;
mot[11]=11;
mot[12]=12;
mot[13]=13;
Rien de plus facile : il suffit de se mettre sur la première ligne avant mot, et de faire une sélection verticale
en faisant CTRL-v}$
Une fois que tout le bloc est sélectionné, il suffit de le mémoriser et de le dupliquer avec yP
Si je veux changer tous les mot de la deuxième colonne en pot, mettez-vous sur le premier mot de la
deuxième colonne puis tapez CTRL-vjjjjjj... jusqu’à sélectionner tous les mmmmm, puis tapez rp et
voilà ! Vous avez des petits pots partout !
Si vous voulez changer les mot de la première colonne en pomot, allez sur le premier pot de la deuxième
colonne, tapez CTRL-vjjjjjj... jusqu’à sélectionner tous les p puis tapez l pour sélectionner des po et
mémorisez en tapant y. Ensuite, placez-vous sur le premier m du mot de la première colonne et tapez p.
Vous avez des pomot à la place des mot.
Jouez un peu avec CTRL-v puis d et p pour voir comment ça fonctionne.
11
7
Multifenêtrage
Comme il a été évoqué plus haut, vi est un éditeur multifenêtres.
CTRL-w s CTRL-W signifie qu’on va faire une commande de multi-fenêtrage (Window) et la commande
est s pour split, qui signifie séparer en deux. Du coup, votre fichier apparaı̂t maintenant sur deux
sous-fenêtres. Vous pouvez consulter et éditer deux endroits de votre fichier simultanément (très
utile pour faire des comparaisons, . . .
Pour éditer un autre fichier dans une sous-fenêtre, il suffit d’ouvrir un fichier avec :e toto
Pour supprimer une fenêtre, il suffit de quitter l’édition dans cette fenêtre avec :q
CTRL-w h j k l sert à se déplacer d’une fenêtre vers l’autre. CTRL-w j va permettre de passer vers la
fenêtre du bas. Mais à quoi peuvent bien servir CTRL-w h et CTRL-w l ? ? ?
CTRL-w v sert à créer une nouvelle fenêtre verticale (vers laquelle on ira avec CTRL-w l).
Si vous voulez maintenir 80 caractères dans votre fenêtre courante, mettre l’option :set winwidth=80
(que l’on peut abrégér en :se wiw=80).
CTRL-w x sert à échanger (xchange) deux fenêtres.
CTRL-w n crée une fenêtre vide.
CTRL-w r effectue une rotation des fenêtres (à essayer avec plusieurs fenêtres horizontales ou verticales).
CTRL-w + Agrandit la fenêtre courante (au détriment d’une autre). 10CTRL-w + agrandit la fenêtre
courante de 10 lignes.
CTRL-w - Réduit la fenêtre courante (à l’avantage d’une autre). 10CTRL-w - réduit la fenêtre courante
de 10 lignes.
CTRL-w < et > Réduit et augmente la largeur de la fenêtre courante.
CTRL-w = Donne une taille à peu près égale à toutes les fenêtres.
:se scrollbind est une commande marrante qui permet de lier toutes les fenêtres dans lesquelles elle a
été tapée. Si vous tapez :se scrollbind dans deux fenêtres différentes, si vous montez dans une fenêtre,
l’autre montera aussi. Très très utile pour les comparaisons.
Pour libérer une fenêtre de cette contrainte, utilisez :se noscrollbind.
Encore plus utile pour comparer deux fichiers : si l’on édite toto, :diffsplit titi ouvrira une seconde
fenêtre présentant titi et surlignant les différences entre les deux fichiers. Lorsque l’on est dans un fichier,
dp permet de copier la version dans laquelle on se trouve dans l’autre fichier (diffput), et do permet de
récupérer la différence depuis l’autre fichier (diffobtain).
7.1
Maquereaux et abréviations
Il existe plusieurs types de macro-commandes suivant le mode dans lequel on se trouve :
:nmap x y Macrodéfinition fonctionnant en mode normal (le mode commande, bien sûr).
:vmap x y Macro fonctionnant en mode de sélection visuelle (dans lequel on entre avec v ou V).
:omap x y Macrodéfinition fonctionnant en mode d’attente d’opérateur (de déplacement, par exemple).
:imap x y Macrodéfinition fonctionnant en mode insertion.
:cmap x y Macrodéfinition fonctionnant en mode commande-ligne ( : en bas de page).
:lmap x y Macrodéfinition spécifique à un langage.
12
À noter que ces commandes seules ( :imap par exemple) permettent d’obtenir la liste des macrodéfinitions
définies.
Toutes ces macros viennent avec leurs copines :nunmap, :vunmap, :ounmap, ... qui suppriment une
macro, et il existe aussi les anciennes commandes map et unmap qui sont plus générales (cf. :help map).
Comme exemple d’utilisation, si vous tapez un texte html, vous savez que les accents (é è ê à . . .) sont
reconnus par les brouteurs français, mais pas forcément par les autres. Le moyen d’écrire une page html
lisible par tous les brouteurs est d’utiliser &eacute ; pour “é”, &egrave ; pour è, . . ..
La solution habituellement utilisée consiste à faire une recherche remplacement, mais c’est bien long car
en français, il y a un paquet de signes diacritiques (à â é è ê ı̂ ô ù û ç) et on en oublie toujours un ou
deux.
Avec les macrodéfinitions, rien de plus simple. Il suffit de redéfinir “é” en &eacute ; avec la commande :imap (pour le mode insertion seulement).
Essayez et tapez :
:imap ! é &eacute
puis passez en mode insertion, et tapez “é”.
Une fois que vous avez tapé toutes les macros spécifiques à un texte en html, il serait dommage de perdre
tout ce beau travail. Si vous prévoyez de réutiliser vos macros assez souvent, vous pouvez les écrire dans
un fichier de votre choix (fichiermacros par exemple). La commande source fichiermacros permettra
à vi de relire les commandes comme si elles avaient été tapées après un :.
Plus simple : vous pouvez tout tester dans le fichier courant, puis taper :mk fichiermacroshtml. Cette
commande écrira l’ensemble de la configuration courante de vi dans fichiermacroshtml (qu’il suffira
de relire plus tard avec un :source fichiermacroshtml.
Il est alors possible de demander à vi de charger automatiquement un fichier contenant des macros (ou
autres commandes ligne) en mettant dans le .vimrc une “autocommande” autocmd du style :
autocmd BufNewFile,BufRead *.html source $HOME/fichiermacroshtml
Cette commande demandera à vi d’effectuer la commande source $HOME/fichiermacroshtml lors de
la création (BufNewFile) ou du chargement (BufRead) d’un nouveau fichier dont le nom correspond à
*.html.
Au fait, j’avais oublié de dire que vi incluait aussi un langage de programmation complet (avec fonctions,
gestion des exceptions, . . .). Ainsi, si dans les 20 premières lignes, un fichier html contient la ligne Derniere
modification : <date heure>, vi pourra automatiquement insére la date et l’heure de modification
en tapant :
:autocmd BufWritePre,FileWritePre *.html
ks|call DernMod()|’s
:fun DernMod()
: if line("$") > 20
:
let l = 20
: else
:
let l = line("$")
: endif
: exe "1," . l . "g/Derniere modification : /s/Derniere modification : .*/Derniere modification : " .
: \ strftime("%d %b %Y")
:endfun
Et tant qu’on y est, il est aussi possible de faire appel à d’autres autocommandes dans une autocommande
(et ce, de manière récursive).
En ce qui concerne le langage de programmation inclus dans vi, voici un petit exemple. Ouvrez un fichier
appelé dec2hex par exemple, et tapez les lignes suivantes :
13
" La fonction Dec2Hex() renvoie la valeur hexadécial d’un nombre décimal
func Dec2Hex(nr)
let n = a:nr
let r = ""
while n
let r = ’0123456789ABCDEF’[n % 16] . r
let n = n / 16
endwhile
return r
endfunc
Ensuite, ouvrez si dans vi, vous tapez :source dec2hex vous pourrez convertir des nombres décimaux
en hexadécimal. Par exemple, la commande :echo Dec2Hex(233) affichera alors E9 :-)
Pour plus d’informations sur le langage de programmation inclus dans vi, tapez :help eval.
Pour terminer sur cette section, il faut savoir qu’il existe aussi la possibilité de définir des macro-définitions
“orientées texte” que sont les abréviations. Par exemple, si vous devez souvent taper bonjour, on pourra
utiliser :
:ab bo bonjour
7.2
Commandes plus exotiques (c’est possible ?)
Completion automatique vi sait compléter automatiquement des mots ou même des lignes. Si vous
utilisez des noms de variable longs (conseillé pour ne pas s’embrouiller), vous pouvez utiliser la
complétion en tapant le début du mot, puis CTRL-P. Si vous êtes sûrs de ne pas utiliser la touche
TAB dans vos fichiers (ce qui est mon cas) vous pouvez la “remapper” avec la ligne :
:imap <TAB> ^P pour avoir une complétion automatique fonctionnant comme sous LINUX. Si
vous appuyez plusieurs fois sur CTRL-P, vous verrez les différents mots précédents s’afficher. Pour
compléter sur un mot suivant, taper CTRL-N (P pour Previous, N pour Next).
Le ^P s’obtient en tapant d’abord CTRL-v puis CTRL-p, car sous vi, CTRL-v sert à rentrer des
caractères de contrôle.
Mais attention, car après, plus de tabulation. . ., sauf à taper ^V<TAB>
Voulez-vous récupérer une ligne précédente commençant de manière identique ? Alors, commencer
à taper la ligne, puis tapez CTRL-X CTRL-L. CTRL-X CTRL-N complètera avec une ligne suivante.
Enfin, si vous voulez compléter un nom de fichier dans votre répertoire, commencez à taper le nom
du fichier puis CTRL-X CTRL-F (très utile en programmation).
Cryptage du contenu d’un fichier :X demande la clé à utiliser et passe en mode crypté. Après avoir
sauvé le fichier, il faudra redonner la clé pour décrypter.
Gestion des étapes d’une compilation vi est un éditeur écrit par des informaticiens pour des informaticiens, alors bien évidemment, il sait gérer les compilations, sous n’importe quel langage. La
commande :make nomfich lancera la compilation (après avoir sauvé le fichier courant) en utilisant
le contenu de makeprg comme commande de make (valeur make par défaut).
:cope ouvrira la fenêtre d’erreurs de compilation, puis :cn permet de passer à l’erreur suivante,
et :cp à l’erreur précédente. :cla va sur la dernière erreur, et :cfir sur la première erreur. Lorsque
vous tapez :cn, vi surligne l’erreur dans le fichier d’erreurs, et vous emmène directement sur la
ligne incriminée. Il ne vous reste plus qu’à corrige, puis relancer :make nomfich (ou :m↑).
Pour éviter d’avoir à taper le nom du fichier courant après :make, il suffit de remplacer le contenu
de la variable makeprg et de mettre par exemple :set makeprg=make\ %<
ou plus simple encore, remapper une touche de fonction :map <F2> :make %<CR><CR>
Des environnements sont déjà programmés pour des compilateurs spécifiques. Pour compiler du
LATEX par exemple, il suffit d’écrire :compiler tex pour que la commande make nomfich démarre
une latexification du fichier nomfich.tex.
14