# Vi

vi est un éditeur de texte plein écran écrit par Bill Joy en 1976 sur une des premières versions de la distribution Unix BSD.
Il est présent d'office sur la majorité des systèmes Unix actuels, souvent sous la forme d'un clone du logiciel vi originel.

## Les débuts
### Développement

vi a été programmé en 1976 et 1979 par Bill Joy, alors étudiant en second cycle à l'Université de Berkeley. Il avait d'abord tâché de perfectionner l'éditeur ligne d'Unix ed, qui en était à sa 6e version, et avait abouti à l'éditeur ligne ex. Chuck Haley et un autre étudiant, Mark Horton, apportèrent à vi le principe des « macros » , tout en portant le logiciel sur une multitude de plates-formes Unix. Dès la diffusion de  BSD 4.1 (1981), l'éditeur vi comportait ses principaux traits actuels.

### Origine du nom

Le nom vi provient de l'abréviation la plus courte possible (c'est-à-dire sans ambiguïté) de la commande visual de l'éditeur de texte ex, car cette commande fait passer l'éditeur ex du mode ligne par ligne au mode plein écran : ce n'est donc au départ qu’une interface visuelle (en anglais, Visual Interface) de l'éditeur ex (lui-même extension de l'éditeur en ligne ed). ex est toujours disponible dans vi en appuyant sur : en mode commande. En pratique, lors de l'invocation de vi ou ex, un unique programme est démarré : son comportement est décidé par le nom avec lequel on l'a appelé.
Le nom vi correspondant à la fois à des initiales et au nom de son fichier d'installation, il est usuellement prononcé en énonçant les deux lettres en anglais, c'est-à-dire [vi: aɪ], plutôt que comme un mot à part entière [vi].

## Principe de fonctionnement

vi est un éditeur modal, c'est-à-dire que la signification des boutons et des touches change selon le mode dans lequel il se trouve.
En mode insertion, le texte tapé est inséré dans le document. Appuyer sur la touche Echap depuis le mode insertion permet de passer dans le mode commande, dans lequel les touches correspondent à des déplacements du curseur ou à des fonctions d'édition. Par exemple, j descend le curseur d'une ligne, x efface le caractère sous le curseur (la position « sous le curseur » peut désigner la droite du curseur si ce dernier se place entre les caractères, au-dessus du caractère de soulignement ou sous le bloc rectangulaire, selon la manière dont le terminal représente le curseur).
Les touches tapées en mode commande ne sont pas insérées dans le texte, ce qui est une cause fréquente de confusion pour les utilisateurs débutants avec vi.
En mode commande, de nombreuses opérations peuvent être effectuées en série avec des séquences de touches simples, sans qu'il soit nécessaire de maintenir les touches Alt ou Ctrl enfoncées. Les opérations les plus élaborées sont composées d'opérations plus primaires. Par exemple, d3w efface trois mots (d pour delete (effacer) et w pour word (mot), c2fa change (change) le texte jusqu'à ce qu'il trouve (find) le second (2) a. Pour les utilisateurs expérimentés, cela permet de travailler très efficacement. Cela permet également à l'utilisateur de conserver en permanence ses mains sur le clavier.
Enfin, en tapant : en mode commande, on passe dans un mode « bas d'écran » où les commandes déjà disponibles sur l'éditeur ligne ed peuvent être activées.
Les premières versions de vi ne donnaient aucune indication sur le mode dans lequel elles se trouvaient. Il était fréquent que les utilisateurs tapent machinalement sur la touche Echap pour s'assurer que l'éditeur était bien dans le mode commande (vi émet un signal sonore s'il est déjà dans ce mode). Les versions plus modernes de vi indiquent le mode dans une barre d'état ou graphiquement (par exemple la forme ou la couleur du curseur). Des implémentations graphiques de vi (par exemple GVim) supportent aussi l'utilisation de la souris et des menus pour accéder aux fonctions d'édition.

## Évolution

vi est devenu de facto l'éditeur standard d'unix et il a été l'éditeur favori de nombreux hackers jusqu'à l'arrivée d'Emacs en 1984. Il est à noter qu'Emacs est bien plus qu'un simple éditeur de texte et est pourtant souvent mis en concurrence avec vi. À ce jour (2011), vi ou l'un de ses clones peut être trouvé dans presque toutes les installations d'Unix. La Single UNIX Specification (plus particulièrement l'« IEEE standard 1003.2, Part 2: Shell and utilities ») et POSIX inclut vi. Ainsi, tout système se conformant à cette spécification intègre vi.
Bien que son créateur, Bill Joy, ait lui-même déclaré en 1999 qu'il « avait été créé pour un monde désormais disparu », vi est encore largement utilisé par les utilisateurs des différentes variantes d'Unix. Il démarre plus vite que les versions lourdes de l'« éditeur » Emacs et utilise moins de mémoire. Conséquemment, même des fans d'Emacs l'utilisent comme éditeur pour le courrier électronique ou pour de petites éditions.
vi et Emacs sont les éternels belligérants de la guerre des éditeurs.

## Clones et dérivés

De nombreux éditeurs de texte basés sur vi existent. Les clones sont des mises en œuvre, libres ou non, de vi, c'est-à-dire qu'ils respectent théoriquement le jeu de commandes standard du vi de POSIX. Toutefois, la majorité de ces clones supportent également des fonctionnalités supplémentaires. Les dérivés sont des programmes, éditeurs de texte ou non, qui ont conservé le principe de fonctionnement de vi (en partie ou complètement) pour leur propre fonctionnement.
* vi est un portage vers les systèmes Unix modernes du vi classique de la BSD 3.7. Cette implémentation, qui s'appuie sur le code de ed, est libre au sens BSD depuis janvier 2002.
* nvi est une implémentation de l'éditeur de texte ex/vi distribuée dans la Fourth Berkeley Software Distribution (4BSD). Il s'agit de la version de vi qui est fournie avec toutes les distributions BSD open source. Elle possède de nombreuses améliorations par rapport au vi classique, notamment l'historique et l'édition des commandes, le complètement des noms de fichiers, l'édition de plusieurs tampons, le multi-fenêtrage (y compris l'édition d'un même tampon dans plusieurs fenêtres), etc. À part ces améliorations, son interface utilisateur est à peu de chose près identique à celle du vi classique. Cette implémentation est très compacte, rapide, et se fond très naturellement dans l'environnement Unix.
* Elvis est un clone libre de vi pour Unix et d'autres systèmes d'exploitation. Il possède des fonctionnalités supplémentaires, telles que la coloration syntaxique, ou une interface graphique pour différents systèmes.
* Vim, pour « Vi IMproved », est un clone de vi, moderne et extensible. Il est généralement fourni comme implémentation de vi dans les distributions Linux.
* svicc est un petit clone de vi pour Commodore (64)
* bvi « Binary VI » est un éditeur hexadécimal pour les fichiers binaires, basé sur l'éditeur de texte vi.
* VILE, pour « VI Like Emacs », est un éditeur de texte qui tente de réconcilier les utilisateurs de vi et de emacs en gardant ce qu'il estime être le meilleur des deux programmes.

## Débuter avec vi

Les utilisateurs, débutant avec vi, sont souvent confrontés à des difficultés, d'une part à cause des raccourcis utilisés pour chacune des commandes, ensuite parce que l'effet de ces raccourcis change selon le mode dans lequel se trouve vi.
Un moyen efficace de débuter avec vi est de suivre d'un bout à l'autre un tutoriel expliquant les commandes les plus simples. La plupart des systèmes fournissant une implémentation de vi contiennent également un tutoriel pour vi.
En comprenant son principe de fonctionnement avec quelques explications et des exemples simples, la majorité des utilisateurs peuvent parvenir à leurs fins avec vi. Toutefois, l'aisance avec vi est généralement considérée comme plus longue à venir qu'avec les autres éditeurs avec lequel il est souvent comparé. Les défenseurs de vi affirment que cette difficulté initiale est largement compensée par l'efficacité de l'éditeur une fois que l'on est à l'aise.

### Commandes et interface jugées obscures

Les débutants sont souvent déroutés par les commandes de vi. Ces dernières sont bien souvent réduites à une seule et unique lettre, et bien difficiles à mémoriser au premier abord, d'autant que l'éditeur présente différentes perspectives (lecture, insertion, open mode, etc.) qui ne sont pas clairement distinguées et la transition entre ces modes passe souvent inaperçue.
La plupart des commandes de vi sont choisies de façon à :
* limiter la frappe nécessaire. Les modificateurs tels que Ctrl, Maj ou Alt sont utilisés avec la plus grande parcimonie ;
* limiter les mouvements des doigts et des mains sur le clavier. Par exemple, en mode commande, les touches h, j, k et l permettent de déplacer le curseur. Comme il s'agit d'une des fonctions les plus importantes, les touches qui lui sont affectées sont celles que l'utilisateur a immédiatement sous les doigts ;
* faciliter les moyens mnémotechniques pour retenir leur(s) effet(s). Il faut toutefois garder à l'esprit que vi a été écrit par des programmeurs anglophones. Par exemple, en mode commande, d permet d'effacer (delete), i passe en mode insertion, w avance le curseur d'un mot (word). En combinant une commande d'édition (par exemple effacer : d) et une commande de mouvement (par exemple avancer d'un mot : w), on obtient la séquence dw, qui permet d'effacer un mot. D'une manière similaire, la commande d3w efface trois mots.

### Comportement modal

Lorsque l'on débute avec vi, il est primordial de comprendre que vi possède plusieurs modes de fonctionnement. Les deux principaux modes sont le mode commande (dans lequel vi démarre) et le mode insertion. Les commandes i (insertion) ou a (ajout) du mode commande permettent de passer en mode insertion, tandis que la touche Echap permet de quitter le mode insertion et retourner au mode commande.
vi possède également un autre mode de fonctionnement, qui offre la possibilité de définir des macro-commandes en intégrant un véritable langage de programmation pour automatiser des tâches d'édition de texte.
Il est aussi possible d'appeler vi avec des arguments afin qu'il exécute automatiquement des commandes lors de l'ouverture d'un fichier. Par exemple, la ligne de commande :
lance vi, qui ouvre le fichier "FICHIER", puis remplace tous les "Deux" par des "Trois" dans le fichier, et enfin enregistre le fichier et quitte.

## Fonctionnalités de vi
### Macros et abréviations

vi permet de définir des macro-commandes et des abréviations.
Les macros permettent de remplacer une séquence de touches par une autre, ce qui permet de définir de nouvelles commandes. Par exemple,
crée la commande v du mode commande, qui supprime des blocs de 10 lignes.
Les abréviations permettent d'éviter de taper une séquence de lettres plutôt longue. Par exemple :
crée l'abréviation GNU, qui en mode insertion est remplacée par gnu is not unix dès que suffisamment de caractères sont tapés pour lever toute ambiguïté (les abréviations sont généralement étendues quand une espace est insérée pour indiquer la fin du mot).

### Options

Le comportement de vi et de ses commandes peut être ajusté grâce à ce que vi appelle des « options ». La commande :set permet de les consulter et de les modifier. Certaines options sont booléennes, c'est-à-dire qu'elles peuvent prendre deux valeurs seulement : vrai ou faux, ou plus exactement activée et désactivée. Par exemple :
que l'on peut abréger par
ou encore
affiche le numéro de chaque ligne.
sont équivalentes et permettent de désactiver cette option.
Parmi les options booléennes, on peut trouver (liste non exhaustive) :
| Commande | Effet |
| :set ignorecase | ignore la casse lors de la recherche de chaînes de caractères |
| :set readonly | interdit la modification du fichier ouvert |
| :set autoindent | indente automatiquement le code lors de l'édition |
| :set ruler | indique le numéro de ligne et de colonne sur lesquelles se trouve le curseur |
| :set showmode | montre le mode dans lequel se trouve vi |
Les autres options prennent une valeur. Par exemple :
indique à vi où chercher le fichier de marqueurs.
L'ensemble de toutes les options disponibles peut être affiché avec

### Fichier de configuration

L'ensemble des options de vi (ainsi que les macros et les abréviations) peuvent être fixées pour chaque session d'édition en les ajoutant dans le fichier ~/.exrc. Ce fichier est lu automatiquement au démarrage de vi, et les commandes qu'il contient sont exécutées comme si elles étaient tapées par l'utilisateur (le : initial est inutile). Exemple :

## Exemples de commandes
### Exemples de commandes simples

Le tableau qui suit donne quelques commandes basiques de l'éditeur vi, nécessaires aux tâches d'édition les plus simples. Pour entrer ses commandes, il faut préalablement quitter le mode éditeur en appuyant sur la touche Echap.
| Commande | Effet |
| #commande | exécute # fois la commande (par exemple 5dd efface 5 lignes) |
| !commande | exécute une commande shell (par exemple :!gcc -o hello hello.c) |
| >> et << | ajoute et retire une tabulation en début de ligne respectivement |
| /toto et ?toto | recherche les occurrences de la chaîne de caractères toto après le curseur et avant le curseur respectivement (n va à l'occurrence suivante et N va à l'occurrence précédente) |
| :# | place le curseur à la ligne # |
| :$ | place le curseur à la dernière ligne |
| :.= | renvoie le numéro de la ligne courante |
| 0 | déplace le curseur au début de la ligne |
| $ | déplace le curseur à la fin de la ligne |
| h et l | déplace le curseur d'un caractère à gauche et à droite respectivement |
| j et k | déplace le curseur sur la ligne suivante et précédente respectivement |
| gg | déplace le curseur au début du fichier |
| G | déplace le curseur à la fin du fichier |
| H et L | déplace le curseur en haut et en bas de l'écran respectivement |
| a | déplace le curseur d'un caractère vers la droite et passe en mode insertion |
| A | déplace le curseur à la fin de la ligne courante et passe en mode insertion |
| c | efface un certain nombre de caractères en fonction de la sous-commande et passe en mode insertion (par exemple cl permet de changer le caractère courant, cw la fin du mot courant) |
| C | supprime les caractères de la position du curseur jusqu'à la fin de la ligne et passe en mode insertion |
| dd | supprime la ligne courante et la copie dans le buffer |
| dw | supprime le mot après le curseur et le copie dans le buffer |
| dW | supprime la chaîne de caractères après le curseur jusqu'au prochain caractère blanc |
| :e | suivi d'un nom de fichier, ouvre ce fichier pour l'éditer |
| D | supprime la fin de la ligne à partir du curseur |
| i | passe en mode insertion à la position du curseur |
| I | déplace le curseur au début de la ligne et passe en mode insertion |
| o | ouvre une nouvelle ligne en dessous de la ligne courante |
| O | ouvre une nouvelle ligne au-dessus de la ligne courante |
| p | insère le contenu du buffer après le curseur (ou après la ligne courante si le buffer contient des lignes) |
| P | insère le contenu du buffer avant le curseur (ou avant la ligne courante si le buffer contient des lignes) |
| :q | quitte vi |
| :q! | quitte vi même si les modifications n'ont pas été enregistrées |
| r | remplace le caractère sous le curseur |
| u | annule les effets de la commande précédente |
| w | place le curseur sur le premier caractère du mot suivant |
| :w | enregistre le fichier courant |
| :wq ou :x ou ZZ | enregistre le fichier courant et quitte |
| x | supprime le caractère sous le curseur |
| X | supprime le caractère à gauche du curseur |
| yy | copie la ligne courante dans le buffer (p insère la ligne copiée après la ligne courante) |
| yw | copie le mot après le curseur dans le buffer (p insère le mot copié après le curseur) |

### Exemples de commandes avancées

Les commandes suivantes montrent ce que permet vi quand un utilisateur cherche des commandes d'édition plus pointues.
| Commande | Effet |
| "ryy | mémorise la ligne courante dans le registre "r |
| "rp | insère le contenu du registre "r après la ligne courante ou après le curseur |
| :#1,#2t#3 | copie les lignes #1 à #2 après la ligne #3 |
| :#1,#2m#3 | déplace les lignes #1 à #2 après la ligne #3 |
| :#1,#2s/toto/tutu/g | remplace aux lignes #1 à #2 toutes les occurrences de la chaîne de caractères toto par tutu |
| :%s/toto/tutu/g | remplace à chaque ligne toutes les occurrences de la chaîne de caractères toto par tutu |
| :%s%to/to%tu/tu%g | remplace à chaque ligne toutes les occurrences de la chaîne de caractères to/to par tu/tu (cela montre que l'on peut utiliser un autre caractère séparateur que / — ici %) |
| :s/.*/\U&/ | passe la ligne courante en majuscule |
| :%s/^toto// | efface à chaque ligne la première occurrence de la chaîne de caractères toto si elle est en début de ligne |
| :#1,#2g/toto/d | efface parmi les lignes #1 à #2 les lignes contenant la chaîne de caractères toto |
| :g!/toto/d | efface les lignes ne contenant pas la chaîne de caractères toto |
| :g/^[\.]*$/d | supprime les lignes vides |
| :#1,#2g/toto/s/tutu/titi/gc | remplace après confirmations aux lignes #1 à #2 contenant la chaîne de caractères toto toutes les occurrences de la chaîne de caractères tutu par titi |
| :r toto.txt | insère le contenu du fichier toto.txt |
| :r!ls -l | insère le résultat de la commande ls -l dans le fichier courant |
| :#1,#2w toto.txt | enregistre les lignes #1 à #2 dans le fichier toto.txt |
| :e! | ouvre à nouveau le fichier courant (sert par exemple si le fichier a été modifié entretemps) |