Journal travailler sur de nombreux fichiers avec Vim et NeoVim, sur une seule vue

Posté par  (site web personnel, Mastodon) . Licence CC By‑SA.
Étiquettes :
23
8
déc.
2023

Sommaire

Ce premier journal, d’une série de trois, fait suite à ma réponse à une interrogation de martoni dans le forum.

L’objectif est de répondre, à travers des exemples pratiques, à la question de savoir comment on travaille avec plusieurs fichiers ; dans un premier temps dans une seule fenêtre…

Comme prérequis, il est demandé de :

  • avoir installé Vim ou Neovim ;
  • savoir utiliser une implémentation de vi pour un usage basique ;
  • savoir, optionnellement, utiliser un peu la ligne de commandes.
    (pas de panique, c’est surtout parce-que je n’ai pas testé en interface graphique.)

C’est parti ! 🏴‍☠️

la préparation

Avant d’entrer dans le vif du sujet, nous devons préparer le terrain.

Thé vert infusant dans un Zhong

alias

Afin d’éviter des commentaires de type « ça marche pas chez moi » ou « je n’obtiens pas la même chose » d’une part, et pour se focaliser sur le comportement par défaut d’autre part, on va lancer l’éditeur avec les options qui désactive toute personnalisation. Comme je privilégie une certain niveau de fainéantise et le fait de ne pas se répéter, on va se créer un alias au doux nom de dv pour « Default (Neo)Vim » tout simplement.

famille d’interpréteur de commandes pour Vim pour Neovim
Bourne shells (bash, ksh, zsh, etc.), Fish shell alias dv='vim --clean alias dv='nvim --clean
C shell (csh, tcsh, etc.) alias dv vim --clean alias dv nvim --clean
Microsoft PowerShell Function Default-Vim() { vim --clean } Set-Alias -Name dv -Value Default-Vim Function Default-Neo() { nvim --clean } Set-Alias -Name dv -Value Default-Neo
(PC/MS/Free/DR/etc.)-DOS ou (4/N)DOS, DR FlexOS, cmd.exe de Microsoft Windows (9x/ME/etc.), IBM OS/2, ReactOS doskey dv=vim --clean non disponible

Non vérifié, mais je pense que ça marche aussi si on lance l’implémentation GUI avec la même option --clean (sinon, pour Vim, il faut aussi ajouter l’option -U NONE.)

fichiers

On aura besoin de fichiers exemples. Créons un répertoire pour les accueillir (et pouvoir virer facilement l’ensemble quand on a fini.)

interpréteur de commandes commande de création de zt
shells Unix-like (sensibles à la casse) mkdir zt
Microsoft PowerShell New-Item -ItemType Directory -Path zt
*DOS, DR FlexOS, IBM OS/2, Microsoft Windows cmd.exe, ReactOS, etc. mkdir zt

On va se positionner dans ce répertoire (nommé ici zt comme « Zen Tests » par exemple, mais on peut choisir le nom de son choix) pour la suite.

interpréteur de commandes commande de position dans zt
shells Unix-like (sensibles à la casse) cd zt
Microsoft PowerShell Set-Location -Path zt
*DOS, DR FlexOS, IBM OS/2, Microsoft Windows cmd.exe, ReactOS, etc. chdir zt

Dans ce répertoire, créer un sous-répertoire d (comme « Directory » tout simplement) comme précédemment.
Ensuite, on va créer les fichiers suivants par les moyens de son choix :1

Sixth green yielding herb all form gathering him without given living a
cattle saying dry one rule female divide image seed darkness said in a
unto morning can't under saying.

fichier zt/bleu.txt

Great you'll winged cattle seas she'd, forth male saying under saying
stars abundantly days. Can't fowl under gathering moved spirit. Own
shall tree itself there appear. Creepeth meat life fly.

fichier zt/cyan.txt

You're darkness creepeth. A upon heaven. Bring he, years of male.
Moving female said morning us beast fruit two evening divide light
tree give evening it rule morning herb be.

fichier zt/jaune.txt

Whose whales bring moved female beginning fifth. Behold firmament rule
itself. Life. Wherein. Was. It thing upon bearing it abundantly tree
that. Them brought likeness multiply fifth us set. Fly.

fichier zt/magenta.txt

Made seasons is evening which. Their herb creeping have divided spirit
second is unto to set fifth light of after fruit made meat of fruitful
is whales lesser every. Lights.

fichier zt/rouge.txt

He gathering all all image whose midst Beast they're moving. Face god sea.
Fruitful. So fruit which he fruitful they're Beast.  Can't the fish,
night set. Form hath life divided.

fichier zt/vert.txt

Said life also give from beast god two good every that fifth that
called own lesser fowl won't she'd. Beast unto creepeth. Third
morning called. Sea rule great he firmament.

fichier zt/d/nb.txt

conventions

Pour la suite, je parlerai souvent de « commande Ex ». Pas de panique, il s’agit des genres de commandes que l’on saisie en « ligne de commandes » après avoir tapé « : » et en terminant par « ||↵|| » ou « ||⌅|| » …implicite. Dans ce contexte, on aura juste à saisir les commandes sans préfixer par les deux-points, c’est tout.

Je présenterai aussi, tout au long, des tableaux de synthèse des commandes en trois colonnes. La seconde, s’appellera « v.v » pour « version Vim » et comportera la version d’apparition de la commande sous cette forme.

Il y aura également des tableaux d’exercices en quatre colonnes dont la première, « exo », est la référence pour chaque ligne. On pourra utiliser ces références (un chiffre par sous-section, un point, un lettre minuscule) peuvent servir en commentaire pour pointer la ligne en question. La dernière et quatrième colonne indique un point de contrôle à réaliser obligatoirement.

Enfin, et surtout vers la fin, j’évoque des touches modificatrices et à un moment des touches directionnelles. Dans ce cas, j’utilise les symboles ISO/IEC 9995-7 & ISO 7000.2

On va maintenant pouvoir plonger au cœur de la préoccupation de ce journal. :)

— Pub non sponsorisée : Ces textes, auxquels il ne faut pas chercher de signification, ont été créé en utilisant le site Dummy Text Generator avec comme paramètres : texte anglais, 30 mots, 1 paragraphe.

— Note d’humour à l’adresse des plus geeks : Il est bien sûr possible d’utiliser cat (sous Unix-like) ou set-content (sous les dernières versions de Windows) pour créer les fichiers, ou juste avec l’éditeur que l’on va utiliser (cela aurait pu faire partir de l’exercice remarque…)

les arguments

Pour commencer, lançons l’éditeur, comme convenu, avec les couleurs primaires (en synthèse multiplicative) et leur fusion.

$ dv cyan.txt jaune.txt magenta.txt d/nb.txt

Les quatre fichiers sont chargés par l’éditeur, le premier est affiché, mais où sont les autres ?

Media keys from the Logitech G15 gamer's keyboard

navigation standard

Contrairement aux apparences, il est prévu de pouvoir travailler avec plusieurs fichiers.
Étrangement, c’est une fonctionnalité native de toute implémentation vi conforme POSIX, mais que peu de gens connaissent. Les commandes Ex prévues par le standard, pour naviguer entre les fichiers passés en argument, ne manqueront pas de faire penser aux lecteurs médias… dont l’interface perpétue l’héritage des enregistreurs à ruban

Voici la courte liste de ces commandes :

commandes POSIX ? icône ISO 7000 / IEC 60417 équivalent : pour…
:next, :n oui ⏭ : aller au fichier suivant
:previous, :prev non ⏮ : aller au fichier précédent
:rewind, :rew oui 🔃 : revenir au premier fichier
:file, :f oui ℹ : indiquer le fichier en cours, et sa position…3
:quit, :q oui ⏏ : tout fermer et quitter

Excepté :file, ces commandes sont affectées par les options autowrite et writeany de base…4 Tout comme :write, elles peuvent être suffixées de !.
Maintenant, sans entrer dans ces détails, voyons les à l’œuvre :

exo commande de l’exercice message d’erreur résultant résultat de :f ensuite
1.a :quit E173: 3 more files to edit "cyan.txt" 3 lines --33%-- (1 of 4)
1.b :next "jaune.txt" 3 lines --33%-- (2 of 4)
1.c :quit E173: 2 more files to edit "jaune.txt" 3 lines --33%-- (2 of 4)
1.d :next "magenta.txt" 3 lines --33%-- (3 of 4)
1.e :q E173: 2 more files to edit "magenta.txt" 3 lines --33%-- (3 of 4)
1.f :n "d/nb.txt" 3 lines --33%-- (4 of 4)
1.g :n E165: Cannot go beyond last file "d/nb.txt" 3 lines --33%-- (4 of 4)
1.h :previous "magenta.txt" 3 lines --33%-- (3 of 4)
1.i :previous "jaune.txt" 3 lines --33%-- (2 of 4)
1.j :prev "cyan.txt" 3 lines --33%-- (1 of 4)
1.k :prev E164: Cannot go before first file "cyan.txt" 3 lines --33%-- (1 of 4)
1.l :n "jaune.txt" 3 lines --33%-- (2 of 4)
1.m :n "magenta.txt" 3 lines --33%-- (3 of 4)
1.n :rewind "cyan.txt" 3 lines --33%-- (1 of 4)
1.o :prev E164: Cannot go before first file "cyan.txt" 3 lines --33%-- (1 of 4)
1.p :n "jaune.txt" 3 lines --33%-- (2 of 4)
1.q :prev "cyan.txt" 3 lines --33%-- (1 of 4)
1.r :n "jaune.txt" 3 lines --33%-- (2 of 4)
1.s :rew "cyan.txt" 3 lines --33%-- (1 of 4)
1.t :prev E164: Cannot go before first file "cyan.txt" 3 lines --33%-- (1 of 4)
1.u :rew "cyan.txt" 3 lines --33%-- (1 of 4)
1.v :rew "cyan.txt" 3 lines --33%-- (1 of 4)
1.w :s/'ll/'d/ "cyan.txt" 3 lines --33%-- (1 of 4)
1.x :n E37: No write since last change (add ! to override) "cyan.txt" 3 lines --33%-- (1 of 4)
1.y :n! "jaune.txt" 3 lines --33%-- (2 of 4)
1.z :n "magenta.txt" 3 lines --33%-- (3 of 4)

Jusqu’ici, heureusement, rien de nouveau quand on vient d’une autre implémentation.

navigation avancée

Vim a rajouté d’autres commandes pour compléter le tableau.

commandes v.v pour…
:args, :ar 1.? afficher la liste des arguments en encadrant le fichier courant
:last, :la 2.5 aller au dernier fichier
:first, :fir 6.0 revenir au premier fichier (synonyme de :rewind mais symétrique à :last)
:Next, :N 1.? aller au fichier précédent (synonyme de :previous mais symétrique à :next dans le principe des paires commandes n et N ou / et ?)
:wnext, :wn 1.? faire successivement :write puis :next (dans le même esprit que :wq)
:wprevious, :wp, :wNext, :wN 2.5 faire successivement :write puis :prev (dans le même esprit que :wq)

Plutôt que de longs discours, voyons cela en pratique :

exo commande de l’exercice message d’erreur résultant résultat de :args5 ensuite
2.a :Next cyan.txt [jaune.txt] magenta.txt d/nb.txt
2.b :n cyan.txt jaune.txt [magenta.txt] d/nb.txt et Press ENTER or type command to continue
2.c :first [cyan.txt] jaune.txt magenta.txt d/nb.txt
2.d :N E164: Cannot go before first file [cyan.txt] jaune.txt magenta.txt d/nb.txt
2.e :fir [cyan.txt] jaune.txt magenta.txt d/nb.txt
2.f :last cyan.txt jaune.txt magenta.txt [d/nb.txt]
2.g :n E165: Cannot go beyond last file cyan.txt jaune.txt magenta.txt [d/nb.txt]
2.h :la cyan.txt jaune.txt magenta.txt [d/nb.txt]
2.i :N cyan.txt jaune.txt [magenta.txt] d/nb.txt et Press ENTER or type command to continue
2.j :s/bring/wrote/ cyan.txt jaune.txt [magenta.txt] d/nb.txt
2.k :n E37: No write since last change (add ! to override) cyan.txt jaune.txt [magenta.txt] d/nb.txt
2.l :wn cyan.txt jaune.txt magenta.txt [d/nb.txt]
2.m :fir [cyan.txt] jaune.txt magenta.txt d/nb.txt

C’est un peu laborieux de se poser sur n’importe quel fichier dès que la liste est un peu longue… Sur une liste de dix fichiers par exemple, pouvoir passer de la deuxième à la neuvième nécessitait de faire « :n⏎ » sept fois ! Ici, on peut faire « :la:N⏎ » ; ce qui déjà un gain appréciable. Mais sur une liste de vingt fichiers, passer facilement de la troisième à la douzième reste un défi…

(Neo)Vim et d’autres implémentations ont également la possibilité d’ajouter un décompte…, et c’est bien pratique pour répondre à la problématique.

commandes v.v pour basculer sur l’édition du fichier qui est…
:𝓝next, :𝓝n 1.? 𝓝 rang(s) plus loin que le fichier en cours (cela revient à faire « :n⏎ » 𝓝 fois)
:𝓝wnext, :𝓝wn 1.? 𝓝 rang(s) plus loin, dans la liste, après avoir enregistré le fichier en cours
:𝓝previous, :𝓝prev, :𝓝Next, :𝓝N 1.? 𝓝 rang(s) plus tôt que le fichier en cours (cela revient à faire « :N⏎ » 𝓝 fois)
:𝓝wprevious, :𝓝wprev, :𝓝wNext, :𝓝wN 2.5 𝓝 rang(s) plus tôt, dans la liste, après avoir enregistré le fichier en cours
:𝓝argument, :𝓝argu, :argument𝓝, :argu𝓝 2.5 exactement en position 𝓝 dans la liste (i.e. « :f⏎ » indiquera « 𝓝 of » ⊤otal)

Le décompte « 𝓝 » est optionnel, et quand c’est omis c’est la valeur par défaut qui est utilisée. Hormis :argument dont la valeur par défaut est la position du fichier courant, c’est « 1 » pour les autres, ce qui nous ramène aux cas déjà vu.

exo commande de l’exercice message d’erreur résultant résultat de :args5 ensuite
2.n :2n cyan.txt jaune.txt [magenta.txt] d/nb.txt et Press ENTER or type command to continue
2.o :2n E165: Cannot go beyond last file cyan.txt jaune.txt [magenta.txt] d/nb.txt et Press ENTER or type command to continue
2.p :la cyan.txt jaune.txt magenta.txt [d/nb.txt]
2.q :2N cyan.txt [jaune.txt] magenta.txt d/nb.txt
2.r :2N E164: Cannot go before first file cyan.txt [jaune.txt] magenta.txt d/nb.txt
2.s :fir [cyan.txt] jaune.txt magenta.txt d/nb.txt
2.t :3argu cyan.txt jaune.txt [magenta.txt] d/nb.txt
2.u :s/wrote/bring/ cyan.txt jaune.txt [magenta.txt] d/nb.txt
2.v :2N E37: No write since last change (add ! to override) cyan.txt jaune.txt [magenta.txt] d/nb.txt
2.w :2wN [cyan.txt] jaune.txt magenta.txt d/nb.txt
2.x :1n cyan.txt [jaune.txt] magenta.txt d/nb.txt
2.y :1N [cyan.txt] jaune.txt magenta.txt d/nb.txt
2.z :1N E164: Cannot go before first file [cyan.txt] jaune.txt magenta.txt d/nb.txt

C’est sympa et j’apprécie personnellement ces petites attentions. Mais ce n’est pas tout…

liste manipulable

Pour permettre de remplacer nos couleurs primaires par leurs complémentaires (synthèse multiplicative), :args a été étendu pour accepter une nouvelle liste à la place de la liste courante. Dans un premier temps, on charge nos nouveaux fichiers dans l’ordre alphabétique. Ensuite, on change d’avis et on préfère l’ordre RVB et non BRV : la punition est toujours :args avec la liste dans le bon ordre. Idem si on décide de revenir à nos couleurs primaires.

exo commande de l’exercice message d’erreur résultant résultat de :args5 ensuite
3.a :args bleu.txt rouge.txt vert.txt [bleu.txt] rouge.txt vert.txt
3.b :args rouge.txt vert.txt bleu.txt [rouge.txt] vert.txt bleu.txt
3.c :ar cyan.txt jaune.txt magenta.txt [cyan.txt] jaune.txt magenta.txt

Si pendant longtemps les vimistes s’en sont contenté-e-s, ça reste pénible quand on plusieurs fichiers et que l’on souhaite en ajouter ou en retirer quelques uns car il faut ressaisir toute la liste. Avec la sixième version majeur, de nouvelles commandes vont simplifier la vie des usagers de l’éditeur sans pareil.6

exo commande de l’exercice message d’erreur résultant résultat de :args5 ensuite
3.d :$argadd d/nb.txt [cyan.txt] jaune.txt magenta.txt d/nb.txt
3.e :argadd rouge.txt [cyan.txt] rouge.txt jaune.txt magenta.txt d/nb.txt et Press ENTER or type command to continue
3.f :0arga vert.txt bleu.txt vert.txt bleu.txt [cyan.txt] rouge.txt jaune.txt magenta.txt d/nb.txt et Press ENTER or type command to continue
3.g :$argdelete vert.txt bleu.txt [cyan.txt] rouge.txt jaune.txt magenta.txt et Press ENTER or type command to continue
3.h :argdel *e.txt vert.txt bleu.txt [cyan.txt] magenta.txt
3.i :argd 404.txt E480 : No match: 404.txt vert.txt bleu.txt [cyan.txt] magenta.txt
3.j :2arga cyan.txt bleu.txt vert.txt bleu.txt bleu.txt cyan.txt [cyan.txt] magenta.txt et Press ENTER or type command to continue
3.k :argdedupe vert.txt bleu.txt [cyan.txt] magenta.txt

Au chapitre des nouvelles fonctionnalités, il y a la redoutable :argdo qui est peu connu…
Pour illustrer son fonctionnement, supposer que nous cherchons toutes les lignes contenant l’appostrephe (droite/dactylographique ici) suivie d’une lettre. La démarche, fastidieuse, qui fonctionne avec n’importe quelle implémentation est :

:" 3.l commencer par vert.txt
:rewind
:" 3.m y faire la recherche
:global/'[a-z]/#
  1 He gathering all all image whose mids Beast they're moving. Face god sea.
  2 Fruitful. So fruit which he fruitful they're Beast. Can't the fish,
Press ENTER or type command to continue
:" 3.n passer au fichier bleu.txt
:next
:" 3.o et faire la recherche ici
:global/'[a-z]/#
  3 unto morning can't under saying.
Press ENTER or type command to continue
:" 3.p passer au fichier cyan.txt
:n
:" 3.q et faire la recherche ici
:g/'[a-z]/#
  1 Great you'll winged cattle seas she'd, forth male saying under saying
  2 stars abundantly days. Can't fowl under gathering moved spirit. Own
Press ENTER or type command to continue
:" 3.r passer au fichier magenta.txt
:n
:" 3.s y faire la recherche aussi
:g/'[a-z]/#
Pattern not found: '[a-z]

Je vous laisse imaginer si on a une dizaine comme ça… Et là, arrive notre Circé :

:" 3.t depuis cyan.txt
:argument 3
:" 3.u faire la recherche partout
:argdo g/'[a-z]/#
"vert.txt" 3 lines, 179 bytes
  1 He gathering all all image whose mids Beast they're moving. Face god sea.
  2 Fruitful. So fruit which he fruitful they're Beast. Can't the fish,
"bleu.txt" 3 lines, 176 bytes
  3 unto morning can't under saying.
"cyan.txt" 3 lines, 194 bytes
  1 Great you'll winged cattle seas she'd, forth male saying under saying
  2 stars abundantly days. Can't fowl under gathering moved spirit. Own
"magenta.txt" 3 lines, 196 bytes
Pattern not found: '[a-z]
Press ENTER or type command to continue

Avec les implémentations autres que (Neo)Vim et ce :argdo, il aurait fallu demander à l’interpréteur de commandes du système avec le bon utilitaire et en lui ressaisissant la liste des arguments…

type d’interpréteur exemple de commande
shells Unix-like grep -n "'[a-z]" vert.txt bleu.txt cyan.txt magenta.txt
Microsoft PowerShell select-string -pattern "'[a-z]" -path vert.txt,bleu.txt,cyan.txt,magenta.txt
quelques *DOS pour PC find /n "'" vert.txt bleu.txt cyan.txt magenta.txt (cette commande ne connait pas d’expression rationnelle…)
Microsoft Windows cmd.exe findstr /n /r "'[a-z]" vert.txt bleu.txt cyan.txt magenta.txt

Mais toutes les opérations ne sont pas toujours réalisables ainsi, sans devoir scripter.

Au fait, :argdo et :argdelete utilisent aussi bien une plage (i.e. deux entiers « début,fin » dans l’ordre) qu’une position (i.e. un seul entier). Par défaut, c’est respectivement toute la liste et le fichier courant.

:" 3.v rechercher seulement dans bleu et cyan
:3,2argdo g/'[a-z]/#
Backwards range given, OK to swap (y/n)?y
"bleu.txt" 3 lines, 176 bytes
  3 unto morning can't under saying.
"cyan.txt" 3 lines, 194 bytes
  1 Great you'll winged cattle seas she'd, forth male saying under saying
  2 stars abundantly days. Can't fowl under gathering moved spirit. Own
Press ENTER or type command to continue

Pour en tirer pleinement profit, il faut connaître et pratiquer les commandes Ex. J’en profite pour glisser une réclame : le dernier « Atelier Vi » vous permettra de maîtriser pleinement cet aspect de cette famille d’éditeurs.
Mais avant, voici la synthèse des commandes que nous venons d’explorer :

commandes v.v pour…
:args𝓕, :ar𝓕 2.5 faire du(s) fichier(s) 𝓕 la nouvelle liste d’arguments
:next𝓕, :n𝓕 1.? faire du(s) fichier(s) 𝓕 la nouvelle liste d’arguments
:𝓝argadd𝓕, :𝓝arga𝓕 6.0 ajouter le(s) fichier(s) 𝓕 dans la liste, après le rang 𝓝 (par défaut courant), sans vérification de doublons… mais reste sur le fichier en cours
:𝓝argedit𝓕, :𝓝arge𝓕 6.0 ajouter le(s) fichier(s) 𝓕 dans la liste, après le rang 𝓝 (par défaut courant), sans vérification de doublons… puis bascule sur ce nouveau (premier) fichier
:𝓟argdelete, :𝓟argd 6.0 retirer le(s) fichier(s) de rang/plage 𝓟 de la liste
:argdeleteℳ, :argd 6.0 retirer de la liste, les fichiers correspondant au motif shell
:argdedupe, :argded 6.0 filtre la liste pour en retirer les doublons
:𝓟argdo𝓒 6.0 exécuter la commande Ex 𝓒 sur le(s) fichier(s) du/de rang/plage 𝓟 de la liste

Quand (Neo)Vim se lance, la liste des fichiers en argument est récupérée et mise à disposition. Mais les usagers sont libres de redéfinir cette liste, et cette particularité est présente dans toute implémentation respectant le standard : il faut juste utiliser :next comme mentionné…

Si un ou plusieurs fichiers sont indiqués :

  1. Définir la liste d’arguments suivant les noms de fichiers spécifiés.
  2. Définir la position actuelle dans la liste d’arguments comme étant la première entrée de la liste d’arguments.
  3. Définir le chemin d’accès actuel au premier nom de fichier spécifié.

Dans le cas contraire :

  1. Il s’agit d’une erreur s’il n’y a plus de noms de fichiers dans la liste d’arguments après le nom de fichier actuellement référencé.
  2. Fixer le nom de chemin actuel et la référence de la liste d’arguments actuelle au nom de fichier suivant le nom de fichier actuellement référencé dans la liste d’arguments.

Remplacer le contenu du tampon d’édition par le contenu du fichier nommé par le chemin d’accès actuel. Si, pour une raison quelconque, le contenu du fichier n’est pas accessible, le tampon d’édition sera vide.

Dit simplement, quand des chemins de fichiers sont indiqués, « :next𝓕 » a le même fonctionnement que « :args𝓕 »… Juste que le nom de commande peut prêter à confusion (en tout cas ça en piège beaucoup qui n’ont pas pris le temps de bien lire et comprendre cette partie.)
En général, ce que l’on cherche à faire est répondu par :argedit𝓕 …qui fait un :argadd𝓕 puis va basculer dessus.

exo commande de l’exercice message d’erreur résultant résultat de :args5 ensuite
3.w :argedit bleu.txt vert.txt bleu.txt cyan.txt [bleu.txt] magenta.txt et Press ENTER or type command to continue
3.x :argdedupe vert.txt [bleu.txt] cyan.txt magenta.txt
3.y :argedit rouge.txt vert.txt bleu.txt [rouge.txt] cyan.txt magenta.txt et Press ENTER or type command to continue

Sur ce, on peut maintenant tout fermer.

:" 3.z
:quit

les tampons

Pour poursuivre, lançons l’éditeur, comme convenu, avec les fichiers dont le nom (sans extension) se termine par une voyelle.

$ # sur les Unix-like et autres on peut juste faire
$ # dv *[aoeuiy].txt # mais y a que "eau" ici
$ dv bleu.txt jaune.txt magenta.txt rouge.txt

Les quatre fichiers sont chargés par l’éditeur, le premier est affiché et les autres sont en quelque sorte derrière…

tampon encreur

navigation renouvelée

Dans la session précédente, on avait vu que la liste de fichiers passés en argument est copié dans une liste d’arguments que nous pouvons manipuler à loisir. À partir de la version 2.4, Vim copie également la liste de fichiers passés en argument dans une nouvelle liste appelée liste des tampons… Cette nouvelle/seconde liste a ses commandes qui commencent par « b » comme « buffer », c’est à dire tampon.

commandes v.v icône : pour…
:bprevious, :bp, :bNext, :bN 2.4 ⏮ : aller au tampon précédent
:bnext, :bn 2.4 ⏭ : aller au tampon suivant
:brewind, :br 2.4 ↩️ : aller au premier tampon
:bfirst, :bf 6.0 ↩️ : aller au premier tampon
:blast, :bl 2.5 ↪️ : aller au dernier tampon
:buffers, :ls, :files 2.4 ℹ️ : afficher la liste des tampons

Excepté pour le listing, les commandes de navigation sont affectées par les options autowrite et writeany entre autres… et peuvent être suffixées de ! Il ne faut pas se fier à la ressemble avec l’autre liste ; déjà celle-ci boucle… et ne marque pas les fichiers comme édités de la même façon… (à partir de 4.g, après avoir fait le tour, on peut quitter ; mais jusque là le message indique toujours qu’il y a trois autres fichiers en attente…)

exo commande de l’exercice message d’erreur résultant tampon actif (ligne avec %a de :ls)7
4.a :quit E173: 3 more files to edit 1 "bleu.txt"
4.b :bnext 2 "jaune.txt"
4.c :quit E173: 3 more files to edit 2 "jaune.txt"
4.d :bnext 3 "magenta.txt"
4.e :q E173: 3 more files to edit 3 "magenta.txt"
4.f :bn 4 "rouge.txt"
4.g :bn 1 "bleu.txt"
4.h :blast 4 "rouge.txt"
4.i :bNext 3 "magenta.txt"
4.j :bfirst 1 "bleu.txt"
4.k :bprev 4 "rouge.txt"

Comme les tampons sont numérotés par ordre de création, et que cette numérotation ne changera pendant toute la session de travail, on peut s’aider de cette numérotation dans la navigation.

commandes v.v pour aller au tampon…
:𝓝bprevious, :𝓝bp, :bprevious𝓝, :bp𝓝, :b𝓝Next, :𝓝bN, :bNext𝓝, :bN𝓝 2.4 situé 𝓝 rang plus tôt dans toute la liste
:𝓝bnext, :𝓝bn, :bnext𝓝, :bn𝓝 2.4 situé 𝓝 rang plus loin dans toute la liste
:𝓝buffer, :𝓝b, :buffer𝓝, :b𝓝 2.5 exactement en position 𝓝 dans toute la liste
:edit #𝓝, :e #𝓝, 𝓝⎈^ ?.? exactement en position 𝓝 dans toute la liste
:buffer𝓕, :b𝓕 2.7 de nom 𝓕 (peut être partiel mais doit être distinct) dans la liste
:𝓝bmodified, :𝓝bm, :bmodified𝓝, :bm𝓝 2.4 en position 𝓝 dans la liste des tampons modifiés
:edit #, :e #, ⎈^ ?.? alternatif (i.e. où on était précédemment)

Certaines commandes nous sont déjà familières (cf. section précédente) ; les deux dernières seront élucidées plus loin. Ici aussi, l’indication du rang est optionnel et vaut celui du tampon actuel pour :buffer et l’unité pour les autres.

exo commande de l’exercice remarque tampon actif (vérifié par :ls)7
4.l :3bp de la position 4 (dernière position en 4.k), on recule de 3 1 "bleu.txt"
4.m :2bp de la position 1, on recule de 2 (sachant que la liste boucle) 3 "magenta.txt"
4.n :5bn de la position 3, on avance de 5 (sachant que la liste boucle) 4 "rouge.txt"
4.o :bn 2 de la position 4, on avance de 2 (toujours en bouclant) 2 "jaune.txt"
4.p :bp 3 de la position 2, on recule de 3 (toujours en bouclant) 3 "magenta.txt"
4.q :1b on se met exactement en première position (donc :bfirst) 1 "bleu.txt"
4.r :b 2 on se met pile en deuxième position (soit :bn ici) 2 "jaune.txt"
4.s :$b on se met exactement en dernière position (donc :blast) 4 "rouge.txt"
4.t :b 3 on se met exactement en troisième position (soit :bp ou :bN ici) 3 "magenta.txt"
4.u :bN 1 de la position 3, on recule de 1 (soit juste :bp ou :bN sans argument) 2 "jaune.txt"
4.v :bn 1 de la position 2, on avance de 1 (soit juste :bn sans argument) 3 "magenta.txt"
4.w :buffer ici, sans numéro, on reste à la même place 3 "magenta.txt"

Voilà pour l’introduction rapide.

tampons variés

Il va falloir maintenant décortiquer un peu plus ce concept (de tampon) et l’utilisation de cette liste (de tampons).

définitions et précisions

Le tampon (ou buffer en anglais) représente le contenu en mémoire (comprendre en cours de manipulation et donc pas l’état réel du fichier tant que la mémoire n’est pas écrite dans le fichier.) C’est le mode de fonctionnement de tout éditeur de texte (et pratiquement tous les programmes) : on n’écrit et lit pas le fichier sur le disque à chaque action, ce serait peu performant et augmenterait les risques de corruption du fichier.

Il arrive que le fichier ne puisse pas tenir en mémoire (peu de gens connaissent cette situation aujourd’hui n’est-ce pas ?) La stratégie hérité du Vi historique est d’utiliser un fichier d’échange (ou swap file en anglais) pour garder le travail en cours (le fichier effectif n’est écrit que si l’on demande d’une façon —explicite— ou d’une autre —implicite par des options de configuration— de le faire) et de ne charger que la portion en cours d’édition. Cela peut se ressentir.

Il n’y a que les éditeurs codés naïvement qui chargent tous les fichiers en mémoire. (Neo)Vim et d’autres vont, pour ne pas saturer la mémoire, travailler en pratique avec des listes chainée (ou linked lists en anglais). Il y en a plusieurs au cours de la session, et chacune a son jeu de commandes et son compteur…

des listes différentes

Chaque liste a ses références internes et son compteur, ce qui peut être source de confusion quand on ne comprend pas ce qu’on fait ou quand on manque de vigilance.

exo commande de l’exercice message d’information résultant tampon actif (ligne avec %a de :ls)7
5.a :args [bleu.txt] jaune.txt magenta.txt rouge.txt 3 "magenta.txt"
5.b :file "rouge.txt" 3 lines --33%-- ((1) of 4) 3 "magenta.txt"

Bien que les deux listes semblent avoir les mêmes éléments ici, on se trouve sur le troisième élément de la liste des tampons, mais sur le premier élément de la liste d’arguments : les commandes qui manipulent chacune de ces listes ne sont pas interchangeables !
Pour nous prévenir, :file dans (Neo)Vim met l’argument courant entre parenthèses pour dire que ce n’est pas celui qui est affiché/actif.

exo commande de l’exercice message d’information résultant tampon actif (ligne avec %a de :ls)7
5.c :argd *e.txt 3 "magenta.txt"
5.d :args [bleu.txt] magenta.txt 3 "magenta.txt"
5.e :file "rouge.txt" 3 lines --33%-- ((1) of 2) 3 "magenta.txt"

Les deux listes n’ont plus les mêmes éléments… Et là, on a un indice de l’utilité d’avoir deux listes :

  • Celui des tampons est, comme son nom l’indique, réservé aux documents “ouverts” dans l’éditeur ; tous.
  • Celui des arguments est par contre une “sélection”, parmi ces documents, sur laquelle on travaille (ou on va agir avec :argdo par exemple.)

On peut ainsi avoir une sélection de fichiers que l’on édite activement, tout ayant une série de fichiers ouverts pour référence (utile notamment en développement logiciel où c’est un peu ce que font des environnement de développement en référençant le répertoire du projet.)

dans divers états

Revenons à nos tampons. Ils sont listés par les commandes synonymes :buffers, :ls et :files (avec “s” final) …qui affichent quatre colonnes dans l’ordre :

  1. Le numéro du tampon, aligné à droite sur la troisième colonne.
  2. Les différents états sur cinq colonnes (de la quatrième à la huitième incluse.)
  3. Le nom du fichier, aligné à gauche, entre guillemets doubles droits (ce qui permet de distinguer ses espaces du reste.)
  4. La ligne du curseur dans le fichier à partir de la quarantième colonne chez moi. line 0 (ou peut-être ligne 0 chez vous) indique alors un tampon pas encore visité.

Pour les différents états justement, nous en avons déjà croisé deux :

  • actif quand le tampon (ou, pour simplifier, le fichier) est affiché à l’écran.
  • caché (ou juste masqué) quand, à l’inverse, le tampon n’est pas visible.

Cet état d’affichage est indiqué par un caractère en sixième colonne (en tout, soit la troisième colonne indiquant les états)

  • « a » pour indiquer que le fichier est chargé en mémoire et son tampon affiché (soit active en anglais.) Cette indication est apparue avec la version 6.0 de Vim.
  • « h » pour indiquer que le fichier est chargé en mémoire mais que son tampon est caché (soit hidden en anglais.)
  • «  » (espace) quand le fichier n’est pas chargé en mémoire, mais bien référencé dans la liste.

La colonne suivante (la quatrième ou septième), ajoutée à partir de la version 6.0 de Vim, donne le statut système du fichier. Actuellement, on a :

  • pour un fichier normal
    • « - » indique que (Neo)Vim n’a pas le droit de le modifier —typiquement quand on lance l’éditeur en mode lecture seule par exemple
    • « = » indique que le (Neo)Vim ne peut pas le modifier —typiquement quand le fichier est en lecture seule au niveau système
    • «  » (espace) indique le cas normal, donc rien à signaler.
  • pour un terminal
    • « ? » sans tâche (ou job en anglais) associée
    • « R » avec un tâche en cours (soit running en anglais)
    • « F » avec une tâche terminée (soit finished en anglais)

La dernière colonne, ajoutée à partir de la version 6.0 de Vim, va plus nous intéresser

  • « + » indique que le tampon a été changé (aussi bien une modification d’édition qu’un changement d’encodage par exemple) mais pas encore enregistré dans le fichier…
  • « x » indique que le tampon est en erreur de lecture (soit une corruption mémoire, soit une corruption de fichier)
exo commande de l’exercice message d’erreur résultant états du tampon 3 (dans :ls)
5.f :s/bring/carry %a +
5.g :bn E37: No write since last change (add ! to override) %a +
5.h :w %a
5.i :s/carry/bring %a +
5.j :bn! #h +
5.k :3b %a +
5.l :bf E37: No write since last change (add ! to override) %a +
5.n :bf! #h +
5.o :wa #h
5.p :bm E84: No modified buffer found #h
5.q :3b %a
5.r :s/bring/bring #a +
5.s :bl! #h +
5.t :bm %a +

C’est ici que :bmodified prend son sens. ;) Cette commande cycle dans une sous-liste (temporairement et automatiquement générée) de tampons modifiés.

Il est possible d’afficher diverses sous-listes de tampons en passant les caractères de statuts à filtrer en argument. À cela s’ajoute le caractère-filtre t pour afficher l’heure de modification au lieu de la ligne du curseur, et trier par horodatage décroissant au lieu de numéro d’ordre de création du tampon.

:" 5.u tous par défaut, par numéros croissant
:buffers
  1      "bleu.txt"                     line 1
  2      "jaune.txt"                    line 1
  3 %a + "magenta.txt"                  line 1
  4 #    "rouge.txt"                    line 1
Press ENTER or type command to continue
:" 5.v tous les modifiés
:ls +
  3 %a + "magenta.txt"                  line 1
Press ENTER or type command to continue
:" 5.w tous les modifiés et les actifs
:ls +a
  3 %a + "magenta.txt"                  line 1
Press ENTER or type command to continue
:" 5.x lister par horodatage décroissant
:ls t
  3 %a + "magenta.txt"                  20:11:43
  4 #    "rouge.txt"                    19:57:20
  1      "bleu.txt"                     19:50:47
  2      "jaune.txt"                    16:52:00
Press ENTER or type command to continue

Pour finir, il faut mentionner trois derniers caractères

  • « % », en deuxième position, représente le tampon courant…
  • « # », en deuxième position, représente le tampon alternatif…
  • « u », en première position, représente un tampon temporaire non listé par défaut (soit unlisted en anglais), sauf quand on suffixe la commande par !. Cela se produit par exemple quand on ouvre la fenêtre d’aide ou quand on donne un nom alternatif à un tampon.

courant et alternatif

Ç’est une fonctionnalité historique de Vi et qui est requise par la spécification

Deux noms de chemin, nommés courant et alternatif, sont maintenus par l'éditeur. Toutes les commandes Ex qui prennent des noms de fichiers comme arguments doivent les définir comme suit :

  1. Si un argument de fichier est spécifié aux commandes Ex :edit, :ex, ou :recover, ou si une commande Ex :tag remplace le contenu du tampon d’édition.
    1. Si la commande remplace le contenu du tampon d’édition, le nom de chemin courant doit être défini sur l’argument de fichier ou le fichier indiqué par la balise, et le nom de chemin alternatif doit être défini sur la valeur précédente du nom de chemin courant.
    2. Dans le cas contraire, le nom d’accès alternatif correspond à l’argument du fichier.
  2. Si un argument de fichier est spécifié pour la commande Ex :next :
    1. Si la commande remplace le contenu du tampon d’édition, le chemin d’accès actuel est défini sur le premier argument de fichier, et le chemin d’accès alternatif est défini sur la valeur précédente du chemin d’accès actuel.
  3. Si un argument de fichier est spécifié à la commande Ex :file, le nom d’accès courant est défini à l’argument de file, et le nom d’accès alternatif est défini à la valeur précédente du nom d’accès courant.
  4. Si un argument de fichier est spécifié aux commandes Ex :read et :write (c’est-à-dire lors de la lecture ou de l’écriture d’un fichier, et non par l’option de commande nommé :edit par l’appel de shell), ou si un argument de fichier est spécifié dans la commande Ex :xit, le nom du chemin d’accès actuel doit être défini comme l’argument de fichier :
    1. Si le chemin d’accès actuel n’a pas de valeur, il est remplacé par l’argument fichier.
    2. Dans le cas contraire, le nom d’accès alternatif est défini comme étant l’argument du fichier.

Si le nom d’accès alternatif est défini à la valeur précédente du nom d’accès actuel alors que le nom d’accès actuel n’avait pas de valeur précédente, le nom d’accès alternatif n'a pas de valeur en conséquence.

Pour la petite histoire, avant la version 2.5 de Vim, :files servait à afficher le fichier alternatif (et le fichier courant ?) Cela a été fusionné dans les listing en utilisant les caractères prévus par la spécifications par ailleurs.

Non--escaped % characters appearing in file arguments to any ex command shall be replaced by the current pathname; unescaped # characters shall be replaced by the alternate pathname. It shall be an error if % or # characters appear unescaped in an argument and their corresponding values are not set.

L’intégration est poussée au point de nous permettre de basculer sur le tampon alternatif sans connaitre son numéro, sous réserve que celui-ci soit nommé…

exo commande de l’exercice message d’erreur résultant tampon actif (ligne avec %a de :ls)7
5.y :e# 4 "rouge.txt"
5.z :e# 3 "magenta.txt"

Bon à savoir : on peut utiliser # avec toutes les commandes de tampon attendant une position 𝓝 …ou parfois un chemin 𝓕 !

modifiable aussi

Un certain nombre de commandes historiques, d’ouverture et d’écriture de fichiers, avec agissent sur cette liste.

exo commande de l’exercice remarque ou message résultant tampon actif (ligne avec %a de :ls)7 et état
:b3 position après 5.z 3 %a + "magenta.txt"
6.a :w enregistrement du tampon dans le fichier 3 %a "magenta.txt"
6.b :f fuchsia.txt nouveau tampon qui remplace l’autre (mais ls! nous montre un cinquième…) 3 %a "fuchsia.txt"
6.c :args [bleu.txt] fuchsia.txt 3 %a "fuchsia.txt"
6.d :s/fifth/sixth ce tampon est modifié et toujours pas enregistré (on peut même vérifier, depuis une autre session parallèle par exemple, que ce fichier n’existe pas encore dans notre répertoire de travail) 3 %a + "fuchsia.txt"
6.e :w pourpre.txt on va enregistrer une copie sous un nom alternatif (encore ls! pour exhiber le sixième…) 3 %a + "fuchsia.txt"
6.f :undo 1 change; before #1 23:30:02 (pareil que u ; par contre, noter que le tampon est dans son état initial mais toujours pas enregistré sur le disque…) 3 %a "fuchsia.txt"
6.g :bn comme ce n’est pas marqué comme modifié, on peut le quitter sans lever d’alerte `4 %a "rouge.txt"
6.h :bp on revient sur un tampon vide… (normal puisqu’on ne l’avait pas enregistré) 3 %a "fuchsia.txt"
6.i :r magenta.txt complétons le (sur les lignes suivantes) avec le contenu de magenta 3 %a + "fuchsia.txt"
6.j :w enregistrons cette fois sur le disque 3 %a "fuchsia.txt"
6.k :e pourpre.txt basculons sur pourpre, qui existe et n’est pas chargé (mais était dans la liste et on voit qu’il conserve son rang…) 6 %a + "pourpre.txt"
6.l :e violet.txt basculons sur violet, qui n’a jamais été dans la liste (et de toute façon n’existe pas) : on constate qu’on créé un nouveau tampon sur lequel on bascule 7 %a "violet.txt"
6.m :view pourpre.txt rebasculons sur pourpre en mode lecture 6 %a= "pourpre.txt"
6.n :s/sixth/fifth W10: Warning: Changing a readonly file 6 %a=+ "pourpre.txt"
6.o :w E45: 'readonly' option is set (add ! to override) 6 %a=+ "pourpre.txt"
6.p :e E37: No write since last change (add ! to override) 6 %a=+ "pourpre.txt"
6.q :e! rechargeons le tampon dans son état initial connu 6 %a "pourpre.txt"
6.r :e#7 rebasculons sur violet dont on connait le numéro (synonyme donc de :b7 qui aurait été plus rapide) 7 %a "violet.txt"

Ce petit tour dans la gamme violacée nous a permis de voir un peu les subtilités de :edit et :write, ainsi que d’approfondir la notion de fichier alternatif avec :file et :write. Au passage, nous avons observé divers états de tampon décrits plus tôt.

D’autres commandes Ex ont été ajoutées par la suite pour faciliter encore plus les manipulations de cette liste.

commandes v.v pour…
:edit𝓕, :e𝓕, :visual𝓕, :vi𝓕 1.? ajouter le fichier 𝓕 à la liste des tampons s’il n’y est pas encore, puis le charge et bascule dessus (comme :buffer𝓕)
:edit, :e, :visual, :vi 1.? recharger le tampon courant
:view𝓕, :vie𝓕 1.? ajouter le fichier 𝓕 à la liste des tampons s’il n’y est pas encore, puis le charge en lecture seule et bascule dessus
:file𝓕, :f𝓕 1.? donner un nom à un tampon anonyme (ce qui permet de faire plus tard :write sans spécifier de nom), ou donne un nouveau nom 𝓕 au tampon courant (l’ancien devient donc nom listé)
:badd𝓕, :bad𝓕 5.2 ajouter le fichier 𝓕 à la liste des tampons s’il n’y est pas encore, sans le charger (on reste sur le tampon courant)
:balt𝓕 9.0 faire comme « :badd𝓕 » et mettre aussi 𝓕 comme nom alternatif
:enew, :ene 6.0 créer un nouveau tampon anonyme (associé à aucun fichier) et basculer dessus
:0file, :0f 7.0 retirer le nom du tampon courant
:𝓟write, :𝓟w 1.? enregistrer le tampon courant (nommé) dans son fichier
:𝓟write𝓕, :𝓟w𝓕 1.? enregistrer le tampon anonyme (associé à aucun fichier) courant dans le chemin 𝓕 et en faire son nom dans la liste, ou donner un nouveau nom 𝓕 au tampon courant (l’ancien devient donc non listé) et l’enregistrer dans ce chemin
:saveas𝓕, :sav𝓕 6.0 faire « :write𝓕 » puis « :edit # » sans devoir recharger le fichier
:𝓟update, :𝓟up 5.0 faire « :𝓟write » si le tampon est dans un état modifié
:𝓟update𝓕, :𝓟up𝓕 5.0 faire « :𝓟write𝓕 » si le tampon a été modifié
:wall, :wa 6.? enregistrer tous les tampons modifiés
:𝓟bdelete, :𝓟bdel, :𝓟bd, :bdelete𝓟, :bdel𝓟, :bd𝓟 2.4 supprimer le(s) fichier(s) en position 𝓟 de la liste des tampons et le(s) décharger de la mémoire
:bdelete𝓕, :bdel𝓕, :bd𝓕 2.5 supprimer le fichier 𝓕 de la liste des tampons et le décharger de la mémoire
:bdelete𝓛, :bdel𝓛, :bd𝓛 2.7 supprimer les fichiers 𝓛 (noms et rangs séparés par la virgule) de la liste des tampons et le décharger de la mémoire
:𝓟bwipeout, :𝓟bwipe, :𝓟bw, :bwipeout𝓟, :bwipe𝓟, :bw𝓟 6.? supprimer le(s) fichier(s) en position 𝓟 de la liste des tampons, le(s) décharger de la mémoire et supprime tout élément lié en mémoire
:bwipeout𝓕, :bwipe𝓕, :bw𝓕 6.? supprimer le fichier 𝓕 de la liste des tampons, le décharger de la mémoire et supprime tout élément lié en mémoire
:𝓟bunload, :𝓟bun, :bunload𝓟, :bun𝓟 2.5 garder le(s) fichier(s) en position 𝓟 dans la liste des tampons mais le(s) décharger de la mémoire
:bunload𝓕, :bun𝓕 2.5 garder le fichier 𝓕 dans la liste des tampons mais le décharger de la mémoire
:bunload𝓛, :bun𝓛 2.7 garder les fichiers 𝓛 (noms et rangs séparés par la virgule) dans la liste des tampons mais le décharger de la mémoire
:𝓟bufdo𝓒 6.0 exécuter la commande Ex 𝓒 à la plage 𝓟 (par défaut tous) de tampons

Nous n’allons pas les passer (toutes) en revue car, au stade où nous en sommes, elles parlent d’elles-mêmes pour la plupart.

exo commande de l’exercice remarque ou message résultant tampon actif (ligne avec %a de :ls)7 et état
6.s :enew création d’un tampon anonyme vide et bascule dessus 8 "[No Name]" (ou peut-être "[Sans Nom]" chez vous)
6.t :w d/ti.txt lui donner un nom et l’enregistrer 8 "d/ti.txt"
6.u :badd d/nb.txt mettre dans la liste ce fichier aussi (un ls permet de s’en rendre compte) 8 "d/ti.txt"
6.v :args [bleu.txt] fuchsia.txt 8 "d/ti.txt"
6.w :bdelete d/nb.txt on change d’avis et on le retire (un ls permet de s’en rendre compte) 8 "d/ti.txt"
6.x :argadd d/nb.txt en change encore d’avis et on le rajoute (un ls permet de voir qu’il a retrouvé sa place) 8 "d/ti.txt"
6.y :args [bleu.txt] d/nb.txt fuchsia.txt 8 "d/ti.txt"

Les deux listes ont beau être indépendantes, il y a des commandes qui influent sur les deux et c’est logique…
:argadd ajoute bien un fichier à la liste d’arguments, mais comme les liste des tampons est le comptable de tous les tampons en cours alors il y est ajouté aussi s’il n’y était pas déjà. L’inverse n’est pas vrai : :badd ne rajoute rien dans la liste d’arguments. Mieux, les actions sur la liste des tampons n’impacte pas la liste des arguments, et :bdelete laissera le fichier dans la liste d’arguments s’il y est (et si on bascule sur cet argument, paf il se retrouve référencé dans la liste des tampons…) Sans surprise, :bufdo impactera tous les fichiers de la liste d’arguments (sauf, comme on vient de le dire, si retiré de la liste de tampons), tandis que :argdo ne vera qu’une portion de la liste de tampons.

Pour finir, Vim a aussi augmenter les commandes de sortie/arrêt…

commandes v.v pour…
:quit, :q 1.? quitter l’éditeur sans enregistrer
:wq 1.? quitter l’éditeur après avoir enregistré le tampon courant, soit successivement « :w puis :q »
:𝓟wq𝓕 1.? quitter l’éditeur après avoir enregistré sous 𝓕, soit successivement « :𝓟w𝓕 puis :q » avec une plage 𝓟 optionnelle (par défaut toutes les lignes)
:xit, :x, ZZ 1.? quitter l’éditeur après avoir enregistré le tampon courant s’il est modifié, soit successivement « :update puis :q »
:𝓟xit𝓕, :𝓟x𝓕 1.? quitter l’éditeur après avoir enregistré sous 𝓕 s’il y a eu modification, soit successivement « :𝓟up𝓕 puis :q » avec une plage 𝓟 optionnelle (par défaut toutes les lignes)
:exit, :exi 2.7 synonyme de :xit
:𝓟exit𝓕, :𝓟exi𝓕 2.7 synonyme de :𝓟xit
:quitall, :quita, :qa 6.0
:wqall, :wqa, :xall, :xa 2.5 quitter l’éditeur après avoir enregistrer tous les tampons nommés modifiés, soit successivement « :wa puis :q »

Sur ce, il est l’heure de plier bagage.

:"wall " enregistrer tous les fichiers (dont violet.txt vide)
:"quit " puis fermer la boutique pour aujourd'hui
:" 6.z les deux actions peuvent se faire en une fois
:wqall

les positions

Pour la route, lançons l’éditeur avec des fichiers choisis :

$ dv fuchsia.txt vert.txt cyan.txt bleu.txt

Le premier des quatre tampons est affiché, nous connaissons la chanson.

marqueur de scène de crime

positions remarquables

Il y a une fonctionnalité historique peu connue, ou sous-estimée, et pourtant bien utile : on peut, comme des experts sur une scène d’infraction, poser des marqueurs à des points clés du tampon.

commande v.v pour…
` 1.? sauter à la ligne et la colonne du marqueur ℳ
' 1.? sauter au premier caractère non blanc de la ligne du marqueur ℳ ; indiquer, dans une commande Ex, la ligne du marqueur ℳ
m 1.? poser le marqueur ℳ à la position du curseur
:𝓟markℳ, :𝓟maℳ, :𝓟k 1.? poser le marqueur ℳ sur la première colonne de la dernière ligne de la plage 𝓟 optionnelle (par défaut la ligne courante)

Les marqueurs, équivalents donc des cavaliers en plastique jaune, ou des plots, ne sont par contre en aucun cas visibles… Il s’agit d’un/une tableau/liste interne de positions dans la session et sont utilisables avec les opérateurs8

(Neo)Vim et certaines implémentations rajoutent deux commandes de gestion sympatiques.

commande v.v pour…
:marks 1.? lister les marqueurs de la liste ℒ optionnelle (par défaut tous)
:delmarksℒ, :delm 1.? supprimer les marqueurs de la liste ℒ obligatoire
:delmarks!, :delm! 1.? supprimer tous les marqueurs du tampon courant

La première, :marks va afficher un tableau des marqueurs utilisables dans le tampon (il peuvent avoir été définis par nous ou être des marqueurs internes) en quatre colonnes :

  1. Le caractère associé au marqueur, qui est aussi son nom ou la marque ℳ.
    La liste est triée lexicographiquement sur cette colonne.
  2. La ligne où ce marqueur est posé, en comptant à partir de un.
  3. La colonne où ce marqueur est posé, en comptant à partir de zéro…
  4. Le fichier (le nom du tampon) ou le début de la ligne (pour le tampon courant)

Il y a au moins deux marqueurs internes actifs.

:" 7.a afficher les marqueurs de fuchsia.txt
:marks
mark line  col file/text
 '      1    0
 "      1    0
 [      1    0
 ]      4    0 that. Them brought likeness multiply fifth us set. Fly.
Press ENTER or type command to continue
:" 7.b re-set des marqueurs dans fuchsia.txt
:delmarks!
:" 7.b re-lister les marqueurs de fuchsia.txt
mark line  col file/text
 '      1    0
 "      1    0
Press ENTER or type command to continue

Les marqueurs assignables par les usagers sont des lettres non accentuées. (Neo)Vim utilise quelques autres symboles (dont « ' » et « " » dans l’exemple), que nous n’allons pas détailler, et qui sont disponibles uniquement en utilisation pour des mouvements. On va distinguer deux9 sortes de marqueurs.

des marques locales

Dans la plupart des implémentations, ce sont les lettres minuscules « a » à « z » auxquelles (Neo)Vim ajoute la possibilité de redéfinir « ' ». Ces marqueurs :

  • sont propres à chaque tampon (i.e. chaque tampon a sa liste distincte),
  • sont mis à jour (plus précisément la position associée) lors des insertions de lignes,
  • sont restaurés lors des annulations de suppression par exemple,
  • disparaissent avec la suppression de la ligne associée, sauf exception.
exo commande de l’exercice remarque ou message résultant variation de :marks10
7.c mz on pose le marqueur « zéro » +z 1 0
7.d jf.mu on passe à la seconde ligne et on pose le marqueur « *u*n » sur le point +u 2 47
7.e yyp on recopie cette ligne en dessous : le marqueur « u » est toujours attaché à la seconde ligne et pour l’opération on a utilisé des marqueurs internes +[ 3 0, +] 3 69, +. 3 0
7.f kdd on supprime la ligne du marqueur « u » : celui-ci disparait de la liste et les autres sont mis à jour -u 2 47 et ~[ 2 0 et ~] 2 0 et ~. 2 0
7.g u on annule la suppression : le marqueur « u » est restauré… +u 2 47
7.h jdd on supprime la ligne qu’on avait ajoutée ~[ 3 0, ~] 3 0, ~. 3 0
7.i 0f.md on passe à la ligne suivante et on pose le marqueur « *d*eux » sur le premier point de la ligne +d 3 6
7.j ;mt on pose le marqueur « *t*rois » sur le point suivant de la ligne +t 3 12
7.k ;mq on pose le marqueur « *q*uatre » sur le point suivant +q 3 21
7.l ;mc on pose le marqueur « *c*inq » sur le point suivant +c 3 26
7.m j0;ms on pose le marqueur « *s*ix » sur le premier point de la ligne suivante +s 4 4 that. Them brought likeness multiply fifth us set. Fly.
7.n 2;mh on pose le marqueur « *h*uit » sur le dernier point +h 4 54
7.o ,ms on pose le marqueur « *s*ept » sur l’avant-dernier point : remarquer que le marqueur a changé d’affectation (les noms sont à usage unique et on peut les déplacer) ~s 4 49
7.p 'u on se positionne au début de la ligne du marqueur « u »
7.q `q on se positionne à l’emplacement marqué « q » ~' 2 0
7.r d`c on supprime de la position du curseur à la position marquée « c » : le marqueur trace la même position dont le contenu a changé ~[ 3 21, ~] 3 21, ~. 3 21
7.s u restauration de la suppression ~[ 3 0, ~] 3 0, ~. 3 0
7.t :delmarks utc on supprime les marqueurs « c », « u », « t » : l’ordre importe peu et on peut séparer par des espaces -t 3 12, -u 2 47, -c 3 26
7.u :1d on supprime la première ligne : le marquer « z » est supprimé, et les autres numéros de lignes ajustés -z 1 0, ~' 2 21, ~d 2 21, ~h 3 54, ~q 2 21, ~s 3 49, ~[ 1 0, ~] 1 0, ~. 1 0
7.v :wn on enregistre et on passe au fichier suivant : nos marqueurs ne sont plus visibles ici…
7.w 3wms on défini un marqueur « s » trois mots plus loin +s 1 17
7.x :N retour sur le fichier initial (noter que le fichier n’est pas modifié) : notre marqueur « s » est là et différent
7.y :delm s pour en avoir le cœur net, supprimons le… -s 4 49
7.z :n repassons au vert (aucun des deux fichiers n’a été modifié) : son marquer à lui est toujours là…

+ pour indiquer l’apparition dans la liste,

- pour indiquer la disparition de la liste,

~ pour indiquer le changement dans la liste.

des marques globales

La spécification dit que

Les implémentations doivent supporter les caractères minuscules de la locale POSIX donc non accentuées et plus précisément ASCII ainsi que l’apostrophe inversée et l’apostrophe dactylographique](https://fr.wikipedia.org/wiki/Apostrophe_%28typographie%29#Signes_proches). Le support d’autres caractères est laissé à chaque implémentation.

Et là, Vim a fait un choix intéressant qui nous ramène au sujet de ce journal. Les lettres majuscules non accentuées sont partagées par tous les tampons… En plus de vingt-six marqueurs par tampon, on a en plus vingt-six marqueurs visibles de tous (raison pour laquelle je les appelle globaux et les autres locaux.)

exo commande de l’exercice remarque ou message résultant variation de :marks10
8.a f'mG marquer le premier apostrophe comme « *G*reen » +G 1 49
8.b j;mV descendre sur la seconde ligne et marquer le premier apostrophe comme « *V*ert » +V 2 41
8.c G se mettre sur la dernière ligne (pour que :ls indique la troisième ligne)
8.d :n au suivant… (noter que c’est le nom du fichier qui est indiqué pour les marques « G » et « V »)
8.e j;mC descendre sur la seconde ligne et marquer le premier apostrophe comme « *C*yan » +C 2 26
8.f k;mT passer sur la première ligne et marquer l’apostrophe comme « *T*urquoise » +T 1 35
8.g G passer au début de la dernière ligne (afin que :ls indique que c’est la ligne trois)
8.h :n au dernier… (même remarque pour les marques « C » et « T »)
8.i G;mB marquer l’apostrophe comme « *B*leu » +B 3 16
8.j gg ici on veut la première ligne (pour :buffers)
8.k :rew retour sur fuchsia : on voit les marques en majuscule avec les noms des tampons
8.l 'V basculer sur vert.txt mais non sur la troisième ligne mais plutôt sur la deuxième
8.m `C basculer sur cyan.txt en position « 2,27 » et non « 3,1 »
8.n `G revenir sur vert.txt en position « 1,50 » et non « 2.1 »
8.o 'B et cette ligne de bleu.txt au lieu de la première ?
8.p :delm B on supprime le marqueur comme les autres -B 3 16
8.q :delm T comme c’est global on peut supprimer de n’importe où… -T 1 35
8.r :delm! on ne supprime que les marqueurs locaux du tampon -[ 1 0, -] 3 0
8.s :bp bah oui, :args nous dit que nos saut avec ' et ` n’affectent pas la liste d’arguments
8.t :delm! on ne supprime que les marqueurs locaux du tampon -[ 1 0, -] 3 0
8.u :bf on rembobine et on aligne les chakras
8.v :bdel 3 le fichier n’est plus dans la liste mais le marqueur C est toujours visible
8.w :bwip 3 maintenant tout ce qui y associé est retiré aussi… -C 2 26
8.x :bwip 3 E517: No buffers were wiped out
8.y :bdel 3 E516: No buffers were deleted
8.z :bunl 2

Voilà, ça fait un moyen de plus de parcourir les nombreux fichiers ouverts. Au passage, nous avons vu la différence entre :bdelete (qui supprime de la mémoire —comme :bunload— et de la liste) et :bwipeout (qui lance en plus le ramasse-miettes…)

des marques exclusives

(Neo)Vim offre la possibilité de conserver les marqueurs lors de certaines actions Ex.

commande v.v pour…
:lockmarks𝓒, :lock𝓒, :loc𝓒 ?.? exécuter la commande Ex 𝓒 sans toucher au tableau/liste des marqueurs
:keepmarks𝓒, :keep𝓒, :kee𝓒 ?.? exécuter la commande Ex 𝓒 (en fait que 𝓟! pour l’instant) en n’ajustant que les positions des marqueurs en dessous de cette plage 𝓟 par rapport au nombre de lignes en retour

Je les mentionne à titre informatif et nous n’allons pas plus nous en préoccuper.

historiques associées

On a vu que (Neo)Vim travaille avec des listes dans tous les sens. Elles sont utilisées aussi pour gérer les historiques valables tout au long de la session et indépendamment des tampons.

lignes de commandes

Il y a un historique distinct pour chaque type de ligne de commandes (recherche, commandes Ex, etc.) Les touches pour utiliser l’historique de la ligne de commande en cours sont :

touche v.v pour rappeler la plus…
?.? ancienne ligne correspondant au début de texte saisi
⇧↑, ?.? vieille ligne (i.e. le début) de l’historique
?.? récente ligne correspondant au début de texte saisi
⇧↓, ?.? récente ligne (i.e. la fin) de l’historique

(Neo)Vim permet d’utiliser, dans une ligne de commande en cours, les touches : « ||←|| », « ||→|| », « ||⇱|| » ou « ||⎈|| ||b|| », « ||⇲|| » ou « ||⎈|| ||e|| », « ||⇧|| ||←|| » ou « ||⎈|| ||←|| », « ||⇧|| ||→|| » ou « ||⎈|| ||←|| », « ||⌫|| » ou « ||⎈|| ||h|| », « ||⌦|| », la bascule « ||⎀|| ».

Il y a quelques commandes dédiées aux historiques.

commande v.v pour…
:history, :his ?.? afficher l’historique des dernières commandes
:history𝓣 𝓟, :his𝓣 𝓟 ?.? afficher la plage 𝓟 optionnelle (les dernières par défaut) l’historique de type 𝓣 optionnel (commandes par défaut) : cette seconde forme nécessite d’avoir au moins l’un des arguments optionnels
:keeppatterns𝓒, :keepp𝓒 ?.? exécuter la commande Ex 𝓒 sans mettre à jour l’historique de recherche

Le type d’historique, 𝓣, peut être donné par un mot clé réductible à son initial, ou par l’un des caractères utilisé pour l’invite de commande

type activation
cmd : commande Ex
search /, ? recherche
expr = registre d’expression
input @ saisie spécifique
debug > commande de débogage
all tout

La plage d’historique, 𝓟, est soit un entier pour indiquer le début, soit deux entiers séparés par une virgule pour indiquer « début,fin ». Ces entiers peuvent être sans signe pour indiquer la position absolue, ou être précédé du signe « - » pour indiquer le rang depuis la fin…

Les historiques sont affichés comme un tableau de deux colonnes :

  • Le numéro/rang de l’historique, aligné à droite sur sept colonnes.
    La dernière entrée est marquée par > en première colonne.
  • Le contenu de la ligne sans l’invite, aligné à gauche à partir de neuvième colonne.

La taille de l’historique est déterminée par l’option history qui a une valeur de 50 entrées par défaut.

exo commande de l’exercice remarque
9.a :history c voir l’historique des dernières commandes
9.b /if chercher le prochain « if » (dans « Life »)
9.c 2n search hit BOTTOM, continuing at TOP
9.d ?ly seach hit TOP, continuing at BOTTOM
9.e :↑⌫s voir l’historique des dernières recherches : on a fait :history search
9.f :↑↑ 5,20 voir l’historique des commandes entre les rang 5 et 20

Il y a enfin la complétion de ligne sur laquelle on pourrait écrire toute une session, mais c’est pour une autre fois.

sauts et changements

Il y a deux autres historiques, actuellement de cent entrées, qu’il convient d’évoquer.

commande v.v pour…
:jumps, :ju ?.? afficher l’historique des sauts
:clearjumps, :cle ?.? supprimer de l’historique les sauts liés à la fenêtre en cours
:changes ?.? afficher l’historique des changements de lignes
:keepjumps𝓒, :keepj𝓒 ?.? exécuter la commande Ex 𝓒 sans mettre à jour les listes de sauts et changements

Commençons par les sauts. Certaines commandes ont été classées historiquement comme étant des sauts (ou jumps en anglais) car déplaçant (presque toujours) le curseur plusieurs lignes au delà de sa position courante : « ' », « ` », « G », « / », « ? », « n », « N », « % », « ( », « ) », « [[ », « ]] », « { », « } », « :s », « :tag », « L », « M », « H », et toutes les commandes commençant l’édition d’un nouveau fichier.

La liste des sauts est affichée comme la liste des marqueurs, la première colonne (la marque) étant remplacée par le rang du saut, et la position courante est indiquée par > en première colonne.

:" 9.g afficher la liste des sauts
:" les sauts 3/2/1 sont respectivement pour : 9.b/9.c/9.d
:" les sauts 4/9 absents sont respectivement pour : 8.l/8.n
:jumps
 jump line  col file/text
  10     3    0 vert.txt
   8     1    0 bleu.txt
   7     1   49 vert.txt
   6     2    0 vert.txt
   5     3    0 bleu.txt
   3     3   38 that. Them brought likeness multiply fifth us set. Fly.
   2     2    9 itself. Life. Wherein. Was. It thing upon bearing it abundantly
   1     1   43 Whose whales bring moved female beginning fifth. Behold firmame
>
Press ENTER or type command to continue

Il est prévu des raccourcis pour revenir sur une des positions de liste, mais ce ne sont pas des mouvements (i.e. pas utilisable avec des opérateurs.) Le rang, 𝓝, utilisé avec ces combinaisons de touches, est toujours par rapport à la position courante > (qui est toujours le rang 0.)

touche v.v pour aller 𝓝 rang (optionnel, par défaut 1)…
𝓝⎈o ?.? avant (plus tôt/haut dans la liste)
𝓝⎈i, 𝓝 ou 𝓝 ou 𝓝 après (plus tard/bas dans la liste)

Fait curieux : Il semble que « o » a été choisi pour avoir « ancien/+vieux (soit older en anglais) » comme mnémonique ; mais à l’inverse, « n » pour « nouveau/+jeune (soit newer en anglais) » n’était pas possible… La touche la plus proche était la « i » et du coup ce n’est pas dans l’ordre sur les claviers qwerty/qwertz/azerty 🥲 Mais ça reste dans la même logique que les paires : « ( et ) », « { et } », « [[ et ]] », « < et > », en qwerty… (on retrouve la même chose pour la paire « , et ; » en azerty…)

exo commande de l’exercice remarque position courante d’après :jumps
9.h 2⎈o 2 9 fuchsia.txt
9.i 3⎈o 2 0 vert.txt
9.j ⎈i 3 0 bleu.txt
9.k '' on revient à la dernière marque automatiquement posée fuchsia.txt

C’est donc là un moyen pratique de se revisiter les positions remarquables des tampons déjà visité.

La liste des changements (ajouts/suppressions) fonctionne de manière similaire.

:" 9.l afficher la liste des modifs
:" sauf erreur, 1/2/3/4/5 sont respectivement pour 7.u/7.r,7.s/7.h/7.f,7.g/7.e
:changes
change line  col text
    5     3    0 itself. Life. Wherein. Was. It thing upon bearing it abundantl
    4     1    0 Whose whales bring moved female beginning fifth. Behold firmam
    3     3    0 itself. Life. Wherein. Was. It thing upon bearing it abundantl
    2     2    0 Whose whales bring moved female beginning fifth. Behold firmam
    1     1    0 Whose whales bring moved female beginning fifth. Behold firmam
>
Press ENTER or type command to continue

Il est prévu des combinaisons de touches pour revenir sur une des positions de liste, mais ce ne sont pas des mouvements (i.e. donc inutilisables avec des opérateurs.) Le rang, 𝓝, utilisé avec ces combinaisons de touches, est toujours par rapport à la position courante > (qui est toujours le rang 0.)

touche v.v pour aller 𝓝 rang (optionnel, par défaut 1)…
𝓝g; ?.? avant (plus tôt/haut dans la liste)
𝓝g, après (plus tard/bas dans la liste)

Ici on a repris la paire connue « ; et , » qui, contrairement aux apparences, opère (presque) avec la même logique que les paires « f et F » ainsi que « / et ? » en qwerty.

exo commande de l’exercice remarque position courante d’après :changes
9.m 4g; 1 0 fuchsia.txt
9.n g; 3 0 fuchsia.txt
9.o 3g, 2 0 fuchsia.txt
9.p g, 1 0 fuchsia.txt
9.q dd fuchsia.txt
9.r '' fuchsia.txt

À noter que, pour des changements proches sur une même ligne, il n’y a qu’une seule entrée avec la dernière colonne. C’est contrôlé par l’option textwidth …qui par défaut est 0, ce qui désactive l’effet…

exo commande de l’exercice remarque position courante d’après :changes
9.s 2wdw g; 1 13 fuchsia.txt
9.t e dt. g; 1 18 fuchsia.txt
9.u :qa!

C’est tout pour cette fois. さようなら


J’espère qu’après cette lecture pratique que :

  • ça ne fait plus peur de se retrouver avec un tas de fichiers chargés 😉
  • l’on sait comment chercher (et remplacer) dans plusieurs fichiers ouverts 😁
  • l’on n’a besoin d’aucun plugin pour s’y retrouver dans les tampons 😊

Petit sondage maintenant : quels sont, parmi les commandes découvertes, vos trois nouveaux favoris ?


  1. Concernant les fichiers…  

  2. Plus précisément, ISO-7000 “Graphical symbols for use on equipment”. Dans tous les cas, il faut avoir le support Unicode pour lire ce document. 

  3. L’option shortmess ou shm contient une liste de caractères indiquant les messages à raccourcir. Comme il contient « f », alors (Neo)Vim affiche la position du fichier sous la forme « (𝓝 of ⊤) » —en anglais— ou « (𝓝 sur ⊤) » —en français— au lieu de « (file 𝓝 of ⊤) » ou « (fichier 𝓝 sur ⊤) » respectivement. 

  4. Pour rappel ou information, writeany ou wa indique de forcer l’écriture sans devoir ajouter ! ; tandis que autowrite indique d’enregistrer les modifications avant d’exécuter une des commandes de navigation évoquées dans ce journal et toute commande de bascule en dehors d’un fichier modifié. Parmi les autres options qui peuvent influencer, sous (Neo)Vim, il y a en vrac et non exhaustivement : hidden, autowriteall, swapfile, writebackup ou wb, backup ou bk, backupcopy ou bkc, backupdir ou bdir, backupext ou bex, backupskip ou bsk, updatecount ou uc, updatetime ou ut, swapfile

  5. Les noms sont alignés sur des colonnes multiples de huit au moins, comme la commande ls sans argument des Unix-like. Ici, cet affichage n’est pas respecté et les noms sont juste séparés par une espace. 

  6. Je ne doute pas que les adeptes de l’église Emacs me démontreront le contraire ; je n’ai juste pas cherché —ou comme dirait Bram, « I’m more of a vi-type of person » 😉 Attention que ceci n’est ni un appel au troll ni une invitation à quelque guerre d’éditeurs de texte

  7. Nous ne reproduisons pas toute la sortie de la commande :buffers ou :ls ni exactement la ligne qui nous intéresse (celle avec %a dans la seconde colonne) ; nous indiquons juste le numéro (première colonne) et le nom (troisième colonne)… 

  8. Si, si, vous savez ; ce sont les commandes qui indiquent une action et nécessitent d’être doublée pour prendre la(s) ligne(s) entière(s) ou d’être suffixée par un mouvement qui indique la portée. « change », « delete », « yank », « move > (indent) », « move < (unindent) », « ! (though shell filter) » 

  9. Trois en fait, mais on n’en parlera que de deux ici. 

  10. Ici, l’affichage exact ne sera pas respecté et on omettra la ligne de texte et les champs seront séparés par une espace ; et précèdera de :  

  • # Difficulté de lecture

    Posté par  . Évalué à 5.

    Gil, ça a l'air super, mais j'arrive pas à suivre, les tableaux sont très dur à lire et plutôt nombreux :(.

    Comment faire pour faire apparaître des bordures sur les tableaux ? Avec GreaseMonkey ?

    Une solution qui marche sur d'autres site m'intéresse aussi :).

    • [^] # Re: Difficulté de lecture

      Posté par  (site web personnel, Mastodon) . Évalué à 3.

      Comment faire pour faire apparaître des bordures sur les tableaux ?

      Arf, j’avais oublié ce point au moment où j’ai fait l’aperçu avant publication :( Et pour cause, j’ai testé ma proposition d’habillage des tableaux dans la feuille de style perso que j’utilise. Je la poste ici, sans commentaire :

      @import url("https://linuxfr.org/assets/application.css");
      @import url("https://linuxfr.org/assets/contrib/RonRonnement-Orange.css");
      
      #container #contents article .content table {
        border-collapse: collapse;
      }
      #container #contents article .content table td {
        padding: 5px;
      }
      #container #contents article .content table tbody tr {
        border-bottom: thin solid;
      }
      #container #contents article .content table tbody tr:last-child {
        empty-cells: hide;
      }
      #container #contents article .content table tbody tr:hover {
        background: #f1f1f1;
      }

      Je me note qu’il faudra éviter les tableaux pour les prochains épisodes (triste, ça m’a permis de compacter sinon ce serait probablement cinq fois plus long.)

      GreaseMonkey ?

      Bonne idée ! J’ai l’extension installée mais je n’avais pas pensé à passer par là, ce qui aurait en plus facilité le partage…

      autre site

      GreaseMonkey me semble une bonne solution. C’est juste qu’avec la possibilité de LinuxFr j’y ai pas pensé.
      On peut charger ses propres styles dans certains navigateurs (dont Firefox que j’utilise —enfin pas testé si c’est toujours le cas), mais cela ne réglait pas tous les problèmes (ou il fallait refuser les styles du site pour n’appliquer que les siens…)

      Si tu parlais du contenu, je l’ai initialement publié sur ZdS en faisant attention à ne pas avoir à faire trop de modifs au moment de l’importer ici (ça m’a quand même pris un peu plus d’un quart d’heure.)

      “It is seldom that liberty of any kind is lost all at once.” ― David Hume

      • [^] # Re: Difficulté de lecture

        Posté par  . Évalué à 5. Dernière modification le 09 décembre 2023 à 11:56.

        Merci ! Inspiré par tes pointeurs, j'ai finalement installé l'extension Stylus, et fait ceci :

        /* Make borders visible on tables on linuxfr */
        
        #container #contents article .content table {
            border-collapse: collapse;
        }
        
        #container #contents article .content table thead th {
            padding: 5px;
            border: thin solid;
            border-color: #808080;
            background-color: #eeeeee;
        }
        
        #container #contents article .content table tbody tr td {
            padding: 5px;
            border: thin solid;
            border-color: #808080;
        }
        
        #container #contents article .content table tbody tr td code {
            font-size: 0.8em;
        }
        

        Ce qui donne :

        Capture d'écran d'un tableau avec bordures

        (Aussi, bravo pour la bonne orthographe de fuchsia, tout le monde se plante d'habitude, fais le test autour de toi :D)

        • [^] # Re: Difficulté de lecture

          Posté par  (site web personnel, Mastodon) . Évalué à 3.

          C’est très beau la coloration des entêtes ; je ne sais plus si je l’avais testé.
          Il faudra que tu passes sur la page des primés d’octobre qui est un cas courant (de publication) et particulier (de tableau)…

          “It is seldom that liberty of any kind is lost all at once.” ― David Hume

          • [^] # Re: Difficulté de lecture

            Posté par  . Évalué à 2.

            Ah oui, ça devient moyen bof d'un coup.

            Ceci étant, c'est un usage un peu dévoyé d'un tableau, qui sert ici à contourner le display: block des images, et à garantir que les trois sponsors sont bien sur la même ligne. Une autre solution comme faire une seule image contenant les trois logos, avec un `' n'est pas forcément plus simple.

            • [^] # détournements de tableaux

              Posté par  (site web personnel, Mastodon) . Évalué à 2. Dernière modification le 09 décembre 2023 à 17:28.

              :D C’est cet usage dévoyé qui bloque l’évolution du stylisage (tant pis pour le néologisme mais ça va plus vite que de trouver une autre formulation) des tableaux ;( (…ou alors faudrait réécrire tous les journaux et le gabarit.)

              Moi aussi j’ai dévoyé les tableaux /o\ typiquement les successions de lignes en quatre colonnes…

              ref-exo | `commande de l'exercice` | remarque ou `message` | `check output` 
              

              …aurait dû/pu être des blocs (que le markdown de LinuxFr ne sait pas faire) un peu complexe ?

              ┌-----------------------------------------
              | ref-exo
              ├-----------------------------------------
              | `commande de l'exercice`
              | `message`
              | remarque
              ├-----------------------------------------
              | `check command` (redondance à réfléchir)
              | `check output`
              | remarque
              └-----------------------------------------
              

              Je voyais bien en HTML une structure de <dl>…</dl> (chose que le markdown dlfr ne permet pas non plus)

              <dt>ref-exo</dt>
              <dd><pre><code>commande de l'exercice</code>
              <code>message</code></pre> remarque</dd>
              <dd><pre><code>check command</code>
              <code>check output</code></pre> remarque</dd>

              …ou de <div>…</div> imbriquées avec les classes qui vont bien (le markdown de ZdS permet de produire quelque chose comme ça)
              En rédigeant ce commentaire, je me rend compte avec mon schéma que chaque ligne pourrait être un tableau en soi (bon, par contre faudrait pouvoir l’aligner à gauche, ou lui faire prendre toute la largeur d’écran, et non le centrer.)

              Dans tous ces cas, ça en fait plus de lignes pour le même contenu ; raison pour laquelle j’écrivais que l’usage du tableau de quatre colonnes m’a permis de compacter. Par contre j’avais complétement oublié que les tableaux (aussi denses) ne sont pas lisibles par défaut ici (sans hacks persos j’entends) :(

              “It is seldom that liberty of any kind is lost all at once.” ― David Hume

              • [^] # propositions de reformatage

                Posté par  (site web personnel, Mastodon) . Évalué à 2.

                Après réflexions pour trouver une alternative aux tableaux de quatre colonnes, j’ai pensé à ceci :

                proposition 1

                Faire une liste dont les entrées/éléments sont les lignes… Et pour chacune, avoir une sous-liste avec une colonne par entrée…

                - 
                  - ref-exo
                  - `commande de l'exercice`
                  - `message` ou remarque
                  - `check output`

                ou peut-être mieux (le résultat me plait plus)

                - ref-exo
                  - `commande de l'exercice`
                  - `message` ou remarque
                  - `check output`

                Ce qui donnerait, illustré :

                  • 5.g
                  • :bn
                  • E37: No write since last change (add ! to override)
                  • %a +
                  • 6.a
                  • :w
                  • enregistrement du tampon dans le fichier
                  • 3 %a "magenta.txt"

                ou alors (ma préférence)

                • 5.g
                  • :bn
                  • E37: No write since last change (add ! to override)
                  • %a +
                • 6.a
                  • :w
                  • enregistrement du tampon dans le fichier
                  • 3 %a "magenta.txt"

                Bon, parfois il n’y a ni message ni remarque nécessaire (cf. 5.y et 5.z par exemple…) Parfois c’est la dernière colonne qui peut être vide… (cf. 7.x par exemple…)
                Soit je laisse une puce vide (équivalent des cases vides actuelles),
                soit je rajoute un pictogramme/emoji (à trouver) au début de chaque ligne pour indiquer quel type de colonne c’est et on peut virer les lignes vides…

                • 5.g
                  • (picto-commande) :bn
                  • (picto-erreur) E37: No write since last change (add ! to override)
                  • (picto-vérif) %a +
                • 5.z
                  • (picto-commande) :e#
                  • (picto-vérif) 3 "magenta.txt"
                • 6.a
                  • (picto-commande) :w
                  • (picto-blablah) enregistrement du tampon dans le fichier
                  • (picto-vérif) 3 %a "magenta.txt"

                Et dans tout ça je n’ai pas trouvé comment ne pas répéter la consigne de vérification (décidément trop pratique les tableaux…)

                proposition 2

                Sur l’idée de blocs complexes précédemment dessinée, on peut utiliser l’exception que j’ai faite par moment (cf. 7.a et 7.b par exemples) —parce-que le markdown ici ne permet pas de mettre des blocs de code dans les tableaux… Je pensais réaménager et généraliser ainsi :

                '''vim
                commande de l'exercice  " ref-exo remarque mini
                message
                '''
                remarque complémentaire éventuellement
                `check out`

                ce qui donnerait, en espérant que la coloration ne pisse pas trop dans la colle (ou alors faudra faire sans couleur aussi)

                :bn    " 5.g
                E37: No write since last change (add ! to override)

                %a +

                :e#    " 5.z

                3 "magenta.txt"

                :w     " 6.a enregistrement du tampon dans le fichier

                3 %a "magenta.txt"

                Ici aussi, je n’ai pas trouvé comment ne pas répéter la consigne de vérification (mais comme les tableaux passent mal…)

                proposition 3

                Toute autre suggestion est la bienvenue.

                “It is seldom that liberty of any kind is lost all at once.” ― David Hume

        • [^] # Re: Difficulté de lecture

          Posté par  . Évalué à 2.

          Salut,

          Pour ma part, je n'ai rien eu à faire.

          J'utilise le thème contrib/opensuse

          • [^] # Re: Difficulté de lecture

            Posté par  (site web personnel, Mastodon) . Évalué à 2. Dernière modification le 11 décembre 2023 à 12:32.

            Merci, c’est bon à savoir (tous les styles ne sont pas concernés… mais celui par défaut l’est…)

            “It is seldom that liberty of any kind is lost all at once.” ― David Hume

      • [^] # Re: Difficulté de lecture

        Posté par  (site web personnel) . Évalué à 4.

        • [^] # Re: Difficulté de lecture

          Posté par  (site web personnel, Mastodon) . Évalué à 2.

          Bien vu, je ne l’avais pas copié du bon endroit et pas fait gaffe à l’URL (la portion contenus vs billets qui fait toute la différence.) Il n’est même pas certain qu’en étant connecté on puisse y accéder avec l’autre adresse puisque c’est la vue/espace perso.

          “It is seldom that liberty of any kind is lost all at once.” ― David Hume

  • # corrections…

    Posté par  (site web personnel, Mastodon) . Évalué à 4. Dernière modification le 10 décembre 2023 à 18:12.

    Certaines choses ont hélas échappé à ma prévisualisation (comme le fait que les notes de bas de page ne pouvant pas avoir de saut de ligne… la coloration de code qui part en vrille sur les commentaires quand il y a deux points devant… les doubles barres au lieu des backticks… et quelques coquilles qui étaient présentes aussi sur l’autre site.) J’ai mis le diff -U1 à l’adresse https://paste.chapril.org/?79112fccf4aa81d9#61JphwDZyRmKWA9aYtor9ucUp9p7CLbaVJbe3fZ2w4Na ; mais je peux lister chaque modif en commentaire ici si c’est mieux.

    Merci aux modos à qui j’inflige cette tâche.

    “It is seldom that liberty of any kind is lost all at once.” ― David Hume

  • # Ajout

    Posté par  . Évalué à 2.

    hello,

    je ne crois pas l'avoir vu mais :b string avec string étant tout ou partie d'un nom de fichier permet facilement de circuler entre les buffers. Ajouter :vs :sp pour cinder l'affichage et je n'ai besoin de rien de plus. A oui :e file pour ouvrir un fichier.

    vim c'est bien pour coder mangez en :)

    • [^] # Re: Ajout

      Posté par  (site web personnel, Mastodon) . Évalué à 2.

      Si, si, c’est dans le tableau des commandes, juste après avoir introduit la navigation dans les tampons (§ navigation renouvelée …ceci me fait penser que j’aurais du numéroter ces tableaux…)

      commande v.v pour aller au tampon…
      :buffer 𝓕, :b 𝓕 2.7 de nom 𝓕 (peut être partiel mais doit être distinct) dans la liste

      Par contre il n’intervient dans aucun exercice :( (initialement, je voulais montrer la différence avec :edit 𝓕 puis j’ai oublié de la caser.)

      Pour scinder l’affichage, c’est dans un prochain morceau (puisque, comme annoncé en intro, c’est une trilogie…) ;)

      Les Vi c’est bien, même quand on ne code pas : j’aime l’aspect modal et la grande connexion avec le reste du système, ainsi que le fait de littéralement parler à mon éditeur tout en faisant économie de caractères. Vim a su pousser le concept bien bien plus loin que d’autres, et si on code c’est un bonheur. :)

      “It is seldom that liberty of any kind is lost all at once.” ― David Hume

      • [^] # Re: Ajout

        Posté par  . Évalué à 3.

        Je code avec vi depuis 1997. Aujourd'hui c'est même mon métier et ça marche très bien. Python/Django/vuejs/k8s.

        Je ne manque de rien 🤗

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.