Piloter la frise au clavier, à la vim
Les flèches décalaient déjà une phase, mais rien ne permettait de la choisir :
`selection` n'était posée qu'au clic, si bien qu'il fallait la souris pour
commencer. Elle devient `curseur`, désigne une ligne — celle d'un projet en est
une, d'où l'on plie, renomme et ajoute — et survit à Échap, sans quoi elle ne
pourrait servir de point de départ au déplacement suivant. `dessiner` le
normalise, la ligne du projet servant de refuge quand la sienne disparaît.
Deux couches qui ne se recouvrent pas : les flèches modifient, les lettres
déplacent et commandent. Aucun raccourci documenté ne change de sens. Les
touches se taisent dès que le clavier est à quelqu'un d'autre — une saisie, un
dialogue, le menu, un glisser —, faute de quoi `a` dans un nom créerait une
phase. AltGr est toléré : sur un clavier français `{` et `}` n'existent qu'avec
lui, et Windows le présente comme Ctrl+Alt.
Les phases étant triées par date, `o` et `O` insèrent dans le temps et non dans
un rang. `P` reste hors de cette famille : un projet naît sans position.
Le curseur se peint dans la colonne des libellés, seul endroit qui porte une
ligne pour chaque position atteignable — projet plié, projet masqué, ligne de
projet. Et `?` ouvre la table des raccourcis, qui ne se devinent pas.
Décision 26.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -718,3 +718,112 @@ reconstruit chaque projet champ par champ et laisse tomber ce qu'il ne connaît
|
||||
incrémenter, un binaire antérieur ouvrirait un fichier plus riche que lui sans broncher et en
|
||||
effacerait toutes les notes de projet à la première sauvegarde. Le numéro ne sert qu'à cela : faire
|
||||
échouer bruyamment ce qui échouerait silencieusement.
|
||||
|
||||
## 26. Un curseur clavier, et des raccourcis à la vim
|
||||
|
||||
L'outil savait déjà décaler une phase aux flèches, mais pas la **choisir** : `selection` n'était
|
||||
posée que par `ouvrirPhase`, appelée depuis un clic. Il fallait donc la souris pour commencer, et
|
||||
tout raccourci ajouté par-dessus aurait hérité de cette dépendance.
|
||||
|
||||
### `selection` devient `curseur`, et survit à la fermeture
|
||||
|
||||
L'ancienne variable disait deux choses à la fois : « voici la phase que je manipule » et « le
|
||||
panneau est ouvert dessus ». Les deux se séparent.
|
||||
|
||||
Le curseur désigne une **ligne de la frise**, et la ligne d'un projet en est une : c'est de là qu'on
|
||||
plie, qu'on renomme, qu'on ajoute une phase et qu'on supprime le projet. D'où `{ projet, phase }`
|
||||
avec `phase` à `null`, plutôt que deux curseurs concurrents dont l'un serait toujours à ignorer.
|
||||
|
||||
Il **survit à `Échap`**, alors que `selection` s'effaçait : un curseur qui disparaît à la fermeture
|
||||
du volet ne peut pas servir de point de départ au déplacement suivant. En contrepartie, la marque
|
||||
reste visible après un clic dans le vide — c'est le prix d'un curseur, et il se paie une fois.
|
||||
|
||||
Comme il peut désigner une ligne qu'un changement vient d'emporter — phase supprimée, projet replié,
|
||||
filtre resserré —, `dessiner` commence par le **normaliser** : la ligne du projet sert de refuge,
|
||||
puisqu'elle survit à ces trois cas, et l'effacement n'est que le dernier recours. Placer ce contrôle
|
||||
dans `dessiner` plutôt qu'à chaque appelant garantit qu'aucun chemin ne l'oublie.
|
||||
|
||||
### Le volet suit le curseur
|
||||
|
||||
Ce n'est pas un agrément mais une nécessité : les raccourcis agissent sur le curseur, et un panneau
|
||||
resté sur une autre phase donnerait deux cibles concurrentes à l'écran. On éditerait dans les champs
|
||||
une phase que `Espace` ou `dd` n'atteindraient pas. Ouvert, le panneau est donc la vue détaillée du
|
||||
curseur — ce qui fait de `j` et `k` le moyen le plus rapide de relire tout un projet.
|
||||
|
||||
Ce parcours passe par un **clic** sur une barre, qui ouvre le volet sans prendre le champ. Ouvrir au
|
||||
clavier place la frappe dans le nom, où les raccourcis se taisent, et `Échap` referme tout : les deux
|
||||
usages ne se rejoignent pas, et c'est un compromis assumé plutôt qu'un oubli. Le rendre continu
|
||||
demanderait de faire d'`Échap` une sortie de champ avant d'être une fermeture — deux appuis là où il
|
||||
en faut un aujourd'hui, y compris à la souris.
|
||||
|
||||
### Deux couches qui ne se recouvrent pas
|
||||
|
||||
Les **flèches modifient** la phase du curseur, les **lettres déplacent** et commandent. Aucun
|
||||
raccourci documenté n'a changé de sens.
|
||||
|
||||
La décision 17 tient, mais son partage se déplace. Elle laissait le focus sur le panneau et non dans
|
||||
un champ, pour que les flèches restent atteignables juste après avoir sélectionné une phase — au
|
||||
clic, c'est toujours le cas. Ouvrir le volet **au clavier**, en revanche, est une demande explicite
|
||||
d'écrire : `Entrée` et `e` saisissent donc le nom tous les deux. Ce qui protège les flèches n'est
|
||||
plus le focus mais `Échap`, qui referme le volet sans déplacer le curseur — « `e`, taper, `Échap`,
|
||||
flèches » enchaîne sans la souris.
|
||||
|
||||
Ce qui ne doit **jamais** prendre le focus, c'est le volet qui suit un déplacement du curseur : la
|
||||
frappe suivante partirait dans le champ, où les raccourcis se taisent, et on ne saisirait plus jamais
|
||||
qu'un nom. D'où le paramètre `saisir` de `ouvrirSousCurseur`, vrai sur commande, faux au passage.
|
||||
|
||||
`clavier.js` ne connaît rien du planning : il traduit des frappes en noms d'actions, que `app.js`
|
||||
lui fournit. Les séquences à deux temps se déclarent dans la même table que les autres, et les
|
||||
préfixes — `g` aller, `z` plis, `d` détruire — s'en déduisent au lieu d'être listés à part. Un
|
||||
préfixe resté en attente s'oublie au bout de deux secondes : vim ne le fait pas, mais vim n'est pas
|
||||
posé sur un écran qu'on quitte des yeux, et un `d` abandonné puis retrouvé cinq minutes plus tard
|
||||
viserait une autre ligne.
|
||||
|
||||
Les touches **se taisent** dès que le clavier appartient à quelqu'un d'autre : une saisie en cours,
|
||||
un dialogue modal, le menu contextuel — qui navigue déjà aux flèches — ou un glisser en cours. Sans
|
||||
cela, `a` dans un nom de phase créerait une phase au lieu d'écrire un `a`.
|
||||
|
||||
`AltGr` est la seule combinaison tolérée avec `Maj`, et il n'y a pas le choix : sur un clavier
|
||||
français, `{` et `}` ne s'obtiennent qu'avec lui. Windows le présente comme `Ctrl`+`Alt`, si bien
|
||||
que refuser les deux ensemble rendrait ces deux touches inatteignables sur les binaires Windows.
|
||||
|
||||
### Insérer se dit en dates
|
||||
|
||||
`model.js` trie les phases par date de début. « Avant » et « après » ne peuvent donc pas s'exprimer
|
||||
en rangs : `o` et `O` calculent une date et laissent le tri faire le reste. Les quatre points
|
||||
d'insertion — `A` à la fin du projet, `a` au début, `o` après la phase du curseur, `O` avant — ne
|
||||
diffèrent que par ce calcul, et passent tous par `ajouterUnePhase`, qui garde son comportement
|
||||
d'origine quand aucune date ne lui est donnée.
|
||||
|
||||
`P` reste à part : un projet naît **hors de tout curseur**, sans date et sans ligne de référence.
|
||||
L'agréger à la famille `a`/`o` aurait suggéré une position qu'il n'a pas.
|
||||
|
||||
### Le curseur se peint dans la colonne, pas seulement sur la barre
|
||||
|
||||
La barre portait déjà un contour. Il ne suffit pas : le curseur se pose sur des lignes qui n'ont
|
||||
aucune barre en face — celle d'un projet, un projet plié, un projet masqué. La colonne des libellés
|
||||
est le seul endroit qui porte une ligne pour *chaque* position atteignable, et c'est aussi ce qui
|
||||
permet à `app.js` d'y compter les enfants pour amener le défilement au bon endroit. L'énumération de
|
||||
`lignesFrise` et celle de `construireLibelles` doivent donc rester d'accord.
|
||||
|
||||
Sur la ligne d'un projet, le trait d'accent seul se noyait dans son fond coloré et son triangle de
|
||||
pli : elle prend aussi une teinte, mélangée à sa couleur propre plutôt qu'au fond de la surface. La
|
||||
teinte passe par une redéfinition de `--fond-libelle` et non par `background`, parce que le dégradé
|
||||
qui donne un fond aux commandes du projet s'appuie sur cette même variable — un fond posé en direct
|
||||
y laissait une couture.
|
||||
|
||||
### Le `?` n'est pas facultatif
|
||||
|
||||
Des raccourcis d'une lettre ne se devinent pas. Un bouton dans la barre d'outils et la touche `?`
|
||||
ouvrent la même table, dans un `<dialog>` **modal** — contrairement aux deux panneaux : celui-ci ne
|
||||
sert qu'à lire, et laisser `j` déplacer le curseur derrière la table qui explique `j` serait absurde.
|
||||
|
||||
La table est écrite à la main plutôt que bâtie depuis `SEQUENCES`, qui associe une touche à un nom
|
||||
d'action : cela ne dit ni ce que l'action fait, ni dans quel ordre la présenter, ni quelles touches
|
||||
vont par paires. La génération aurait produit une liste exacte et illisible.
|
||||
|
||||
### La vue par mois n'a pas de curseur
|
||||
|
||||
Elle se lit, elle ne s'édite pas (décision 24) : rien n'y aurait de sens à désigner. `j`, `k`, `gg`
|
||||
et `G` y font donc ce qu'ils font dans un document — ils déroulent la liste. `gm` et `ga` marchent
|
||||
dans les deux vues, le reste attend le retour à la frise.
|
||||
|
||||
Reference in New Issue
Block a user