arthur.bebou

Le site arthur.bebou.netlib.re - retour accueil

git clone git://bebou.netlib.re/arthur.bebou
Log | Files | Refs |

index.sh (10400B)


      1 #! page
      2 title: Évaluer ses scripts en temps réel
      3 author: Arthur Pons
      4 description: Il est parfois fatiguant de faire l\'aller retour entre l\'écriture d\'une commande et son exécution. Créons, avec vim et/ou tmux des environnements permettant de fondre les deux
      5 publication: 2024-05-09
      6 
      7 sectionmd: main
      8 
      9 > ATTENTION : Ce script est vraiment dangereux, ne l'utilisez pas si vous ne
     10 > savez pas ce que vous faîtes. N'écrivez jamais de script contenant `rm` avec.
     11 > Si vous écrivez une commande qui lit dans stdin il faudra le fermer en insérant
     12 > un caractère de fin de fichier, en sortant du mode inserstion, en réinsérant un
     13 > caractère de fin de fichier puis finalement en supprimant la commande qui pose
     14 > souci. Vous êtes prévenu·es, c'est expérimental est tout cassé.
     15 
     16 ## Objectif
     17 
     18 L'objectif est d'avoir, l'un à côté de l'autre, un script et ses sorties STDERR
     19 et STDOUT, en temps réel avec une mise à jour à chaque fois que l'on modifie le
     20 script. Une interface comme celle-ci devrait permettre de faciliter l'écriture
     21 de scripts dont la sortie nous intéresse, typiquement lorsqu'il faut traiter du
     22 texte et quand itérer souvent et rapidement est souhaitable[^1]. Elle pourrait
     23 également être un bon outil pour l'enseignement de `sed`, `awk`, `paste`, `cut`,
     24 `tr` et toute la bande que j'aime bien.
     25 
     26 Il n'est pas question ici d'analyser les actions du script et d'afficher en
     27 français les impacts qu'il a eu sur le système (création/suppression de fichier
     28 etc). Il est question de faciliter l'écriture d'une commande `sed` un peu
     29 dantesque sans avoir à systématiquement exécuter le script à la main.
     30 
     31 L'idée me vient de
     32 [fzrepl](https://github.com/DanielFGray/fzf-scripts/blob/master/fzrepl) de
     33 Daniel F Gray. Je voulais quelque chose de similaire mais qui fonctionne
     34 pour une quantité arbitraire de commandes et éditable dans vim.
     35 
     36 Au passage je découvre sans l'avoir prévu que ce système me permet de résoudre
     37 d'une manière bien plus puissante qu'auparavant un problème que j'avais documenté
     38 dans ce [vieil article](/benchmarkcatium/#et-alors-), section :
     39 "L’utilisation d’éditeurs de texte s’interfaçant bien avec le système permet de
     40 tester des bouts de markdown".  En effet, si j'ouvre l'un des fichiers sources
     41 de ce site avec la configuration vim qui va suivre j'obtiens automatiquement le
     42 résultat html dans la fenêtre droite.
     43 
     44 ## Implémentation
     45 
     46 J'ai pour le moment la flemme de gérer les arguments de façon à faire des
     47 choses différentes selon si on passe un argument un script déjà existant ou
     48 pas, selon si le chemin est absolu ou relatif etc. Les scripts tels que
     49 présentés en dessous vont donc systématiquement tout créer en tant que fichier
     50 temporaire. Si à la fin de votre expérimentation vous voulez sauvegarder le
     51 script vous pouvez toujours lancer `:w votre_script.sh`.
     52 
     53 ### Avec vim tout seul
     54 
     55 Commençons d'abord par créer les fichiers qui vont contenir le script et sa
     56 sortie et rendre le script exécutable :
     57 
     58     script=$(mktemp)
     59     data=$(mktemp)
     60     chmod +x "$script"
     61 
     62 Vient ensuite l'ouverture de vim et sa configuration :
     63 
     64     vim -c "set autowrite"\
     65         -c "autocmd TextChanged * silent! !$script > $data 2>&1"\
     66         -c "autocmd TextChangedI * silent! !$script > $data 2>&1"\
     67         -c "vnew $data"\
     68         -c "set updatetime=100 | set autoread | autocommand CursorHoldI * checktime | autocommand CursorHold * checktime"\
     69         -c "wincmd h | doautocmd TextChanged"\
     70         "$script"
     71 
     72 Vim est appelé avec tout un tas de commandes suivant l'option `-c` qui
     73 s'exécuteront automatiquement au lancement.  Le denier argument est le chemin
     74 vers le script.
     75 
     76 Expliquons chacune des commandes vim :
     77 
     78   * `set aw` : le fichier sera automatiquement écrit à chaque fois qu'une
     79     commande externe sera lancée
     80   * `autocmd TextChanged * silent! !$script > $data 2>&1` : A chaque fois que
     81     le texte change en mode normal on exécute, en ignorant sa sortie et ses
     82     erreurs éventuelles (`silent!`), le script dont on redirige tout vers le
     83     fichier de sortie
     84   * Idem mais en mode insertion
     85   * `vnew $data` : on ouvre une fenêtre verticale avec le fichier de sortie
     86   * `set updatetime=100 | set autoread | autocommand CursorHoldI * checktime |
     87     autocommand CursorHold * checktime` : On modifie l'intervalle de mise à jour
     88     à 100ms, on met le buffer avec e fichier de sortie en lecture automatique
     89     (il se rafraichit à chaque changement), on force l'exécution de `checktime`
     90     à chaque première fois que le curseur ne bouge plus pendant 100ms après
     91     qu'il a bougé
     92   * `wincmd h | doautocmd TextChanged` : on revient sur la fenêtre avec le
     93     script et on déclenche une première fois l'un des évènements pour peupler
     94     le fichier de sortie (utile si l'on ouvre un script déjà existant)
     95 
     96 Finalement on affiche les chemins des deux fichiers temporaire quand on ferme
     97 vim au cas-où l'on en est besoin :
     98 
     99     echo "script : $script"
    100     echo "données : $data"
    101 
    102 Les avantages de cette version sont de ne pas dépendre de watch ni de tmux et
    103 de pouvoir parcourir la sortie dans un buffer vim avec tout ce que cela
    104 implique comme possibilité.
    105 
    106 ### Avec vim + tmux + watch
    107 
    108 Les dépendances sont :
    109 
    110   * Une version relativement à jour de vim (qui a les évènements `TextChanged*`)
    111   * tmux
    112   * watch
    113 
    114 On commence de la même manière :
    115 
    116     script=$(mktemp)
    117     data=$(mktemp)
    118     chmod +x "$script"
    119 
    120 Puis on crée la session tmux :
    121 
    122     tmux new \
    123     vim -c "set aw"\
    124         -c "autocmd TextChanged * silent! !$script > $data 2>&1"\
    125         -c "autocmd TextChangedI * silent! !$script > $data 2>&1"\
    126         -c "doautocmd TextChanged"\
    127         "$script"\
    128     \; split-window -h "watch -c -d -t -n 0.1 cat $data" \; select-pane -L
    129 
    130 Finalement on affiche les chemins en sortie de session :
    131 
    132     echo "script : $script"
    133     echo "données : $data"
    134 
    135 Les avantages sont de ne pas avoir à utiliser le hack vim un peu étrange à base
    136 de CursorHold pour que tout soit à jour, de voir ce qui a été modifié en sortie
    137 à l'aide de `-d` de watch et être directement déposé dans tmux ce qui peut se
    138 révéler utile pour retrouver votre travail plus tard. Évidemment ce dernier
    139 point n'est pas essentiel si vous avez de toute façon l'habitude d'être dans
    140 une session tmux quoi qu'il arrive.
    141 
    142 ## L'espace entre les CLI des années 80 et les GUI
    143 
    144 Au delà des raisons évoquées [en intro](/liverepl/#objectif) j'ai une autre
    145 motivation à écrire ce genre d'outils.
    146 
    147 De nombreuses critiques sont formulées envers les interfaces en ligne de
    148 commande. Même si je pense qu'elles sont parfois injustes et le fruit d'apriori
    149 culturels et techniques plus que de réelles limitations qui seraient par
    150 ailleurs inexistantes dans les autres formes d'interfaces, il convient
    151 d'admettre que l'expérience initiale dans un terminal linux est aride.
    152 [Aurélien Tabard](https://tabard.fr/) en résume bien les principales raisons :
    153 
    154 > Si la découvrabilité est en effet un point important, la gestion des erreurs
    155 > l'est tout autant. Le undo n'est pas tellement développé dans les cli, pourtant
    156 > la capacité d'essai-erreur-correction est facteur d'apprentissage important
    157 > (oui il y a des façons de se tromper élégamment dans un terminal, mais le jour
    158 > ou tu te trompes pour une raison ou une autre, le undo n'est pas là). D'autre
    159 > notions permettent comme celles de gouffre d'évaluation et d'exécution peuvent
    160 > expliquer le succès des gui. Enfin la capacité des systèmes à communiquer sur
    161 > ce qu'ils permettent de faire (voir [par exemple ce
    162 > papier](http://jovermeulen.com/Research/FeedforwardCHI2013) sur les
    163 > affordances percues et le feedforward) est peu présente dans les cli.
    164 
    165 De fait beaucoup de personnes sont introduites aux cli via des cours, des
    166 tutos, des outils ne cherchant pas à faciliter l'apprentissage et l'usage des
    167 cli et tombant la tête la première dans chacun des points soulevés par
    168 Aurélien. Personnellement j'ai fait mes premières années de shell en école
    169 d'ingénieur sans jamais savoir que l'on pouvait chercher dans l'historique des
    170 commandes avec `ctrl+r`, que beaucoup de commandes avaient des options pour
    171 lister ce qu'elles allaient faire avant de les faire, que l'on pouvait mettre
    172 beaucoup de couleurs dans les terminaux modernes, que l'existence des TUI
    173 implique que l'on puisse faire des choses comme fzy, qu'il existait des shells
    174 moins complexes que bash et avec une super auto-complétion pour un large
    175 ensemble de commande ou une simple liste, même un peu indigeste, des commandes
    176 généralement disponibles sur un Unix. J'ai le sentiment que la conséquence de
    177 cela est que de nombreuses personnes, même dans le métier, n'ont qu'une vision
    178 très limitée de ce que peuvent les cli et a fortiori des TUI qui fonctionnent
    179 dans un terminal. Il est donc naturel que la plupart des personnes perçoivent
    180 ces interfaces comme bloquées dans les années 70/80 et ne s'y tournent que pour
    181 les usages à raison catalogués comme les plus appropriés. Et pourtant on peut
    182 y mener la majorité de sa vie numérique.
    183 
    184 Attention, contrairement à l'impression que j'ai trop souvent donné lorsque je
    185 parle de ce sujet, l'idée n'est pas de tout faire dans un terminal simplement
    186 parce que je kiffe le terminal. C'est parce que l'usage de GUI modernes me
    187 pousse à changer mon matériel, à mettre de la distance entre les personnes qui
    188 produisent les logiciels que j'utilise et moi et à cloisonner mes logiciels
    189 plutôt que de les faire causer entre eux que je m'intéresse à autre chose. Ne
    190 sachant pas où me tourner pour trouver une communauté et une culture
    191 ingénieurale axées sur le développement de GUI sobres, interopérables et
    192 techniquement simples, je me tourne vers une communauté et une culture qui, la
    193 plupart du temps, regroupe toutes ces qualités, j'ai nommé celle des personnes
    194 qui vivent dans un terminal Unix.
    195 
    196 Je cherche donc, avec des outils comme celui décrit dans cet article, à montrer
    197 qu'il existe un espace entre les GUI d'aujourd'hui et les CLI des années 80
    198 dans lequel on peut aborder les points soulevés par Aurélien tout en profitant
    199 des propriétés techniques plus avantageuses pour la sobriété de nos usages du
    200 numérique.
    201 
    202 [^1]: typiquement l'écriture d'une regex un peu complexe d'où le succès d'interfaces type [regex101](https://regex101.com/)