Artisan Numérique

/cli/terminal/urxvt/ urxvt et les styles de curseur

Aujourd'hui nous allons traiter un problème terrible : URxvt est bien trop limité du curseur :-) Entre autres griefs, on aimerait un curseur qui clignote, un curseur "souligné" qui se voit sur du texte souligné, un curseur "barre verticale" qui symbolise l'insertion de texte, mais surtout la possibilité de changer tout cela dynamiquement par une séquence, et non en passant par d

es options.

Voyant dans mon dernier billet que je n'étais pas le seul à être enquiquiné par tout cela, je me suis dit que ça valait peut-être le coup de dérouiller un peu mon C++.

État des lieux

En standard, URxvt dispose donc de deux curseurs : le curseur "bloc" et le curseur "souligné". Dans un cas comme dans l'autre ce ne sont pas de vrais curseurs mais un trucage exploitant les attributs standards : l'inversion vidéo pour le "bloc" et le soulignement pour le "souligné".

Le soucis dans cette histoire est que du coup comment discerner un curseur souligné d'un soulignement, ou (plus rare) un caractère en vidéo inversé d'un curseur bloc. La "solution" trouvé est d'ajouter un réglage permettant aux curseurs d'être colorés soit via ~/.Xdefault, soit plus simplement en passant par une séquence OSC. Ainsi pour passer le curseur en rouge, cela donne:

gastonecho -en "\033]12;red\007"

Généralement cette magouille s'utilise dans Vim pour discerner visuellement le mode insertion du mode normal :

let &t_SI = "\033]12;white\007"
let &t_EI = "\033]12;#0000FF\007"

Ainsi le curseur passe en blanc en mode Insertion (t_SI) et en bleu en mode Normal (t_EI).

Autre petite subtilité, il est possible de faire clignoter le dit curseur mais uniquement en passant par les options, en ajoutant URxvt.cursorBlink: true à votre ~/.Xdefault.

Tout ceci est donc bien sympa mais on aimerait bien avoir quelque chose de plus comparable à ce que l'on trouve sur d'autres terminaux, en vrac un curseur "barre vertical", une sélection dynamique, etc.

Patch time...

Mon modeste patch cherche donc à corriger ces "problèmes" et quelques autres en apportant les fonctionnalités suivantes :

  • L'ajout d'un curseur "ligne verticale" qui au passage est colorisable par les séquences données plus haut.
  • La modification du curseur "souligné" pour qui soit de deux pixels de haut, de sorte à le discerner d'un soulignement réel. Dans l'avenir il faudra que je fasse comme XTerm, à savoir caler ce curseur sous le soulignement réel.
  • L'implémentation d'une séquence CSI dites DECSCUSR (VT520). Cette séquence permet de modifier le style du curseur de la manière suivante :
    • echo -ne "\033[0 q" et echo -ne "\033[1 q" donnent un curseur de type "block" qui clignote. À noter que pour activer le clignotement du curseur dans URxvt vous devez rajouter URxvt.cursorBlink: true à votre fichier ~/.Xdefaults.
    • echo -ne "\033[2 q" pour un curseur "block" qui ne clignote pas,
    • echo -ne "\033[3 q" pour un curseur "souligné" qui clignote,
    • echo -ne "\033[4 q" pour un curseur "souligné" qui ne clignote pas,
    • echo -ne "\033[5 q" pour un curseur "barre verticale" qui clignote,
    • echo -ne "\033[6 q" pour un curseur "barre verticale" qui ne clignote pas.

Voilà c'est à peu prés tout. Pas de quoi casser trois pattes à un canard non plus mais c'est un début.

Pour exploiter ces fonctionnalités, il va vous falloir compiler votre propre version d'URxvt.

gastoncvs -z3 -d :pserver:anonymous@cvs.schmorp.de/schmorpforge co rxvt-unicode
gastoncd rxvt-unicode
gastonwget https://raw.github.com/yoran-brault/patchs/master/rxvt-unicode_cursorstyle.patch
gastonpatch -p1 < rxvt-unicode_cursorstyle.patch
gaston./autogen.sh
gaston./configure --prefix=/usr
gastonmake -j 4
gastonsudo make install

Si vous ne voulez pas "polluer" votre système, ne lancez pas la dernière commande (sudo make install) et une fois compilé, lancez urxvt par ./src/rxvt.

Pour tester, vous pouvez lancer une des commandes echo données plus haut, par exemple echo -ne "\033[5 q" pour un curseur "barre" et "clignotant"

Après, dans ~/.vimrc on pourrait avoir quelque chose comme cela :

let &t_SI = "\033]12;white\007\033[5 q"
let &t_EI = "\033]12;orange\007\033[0 q"

Ainsi en mode insertion, le curseur sera une barre verticale blanche, et en mode normal un bloc orange. Dans les deux cas clignotants.

Conclusion

Alors bien évidemment j'ai soumis ce patch à ce qui semblait être le co-maintenaur d'URxvt sur freenode/#rxvt-unicode-dev. Mais disons que je n'ai pas eu le sentiment que son acceptation était gagnée. L'accueil était plutôt du genre "euh, mais pour quoi faire...". Pourtant, même si la modification est très conne et ne va pas cracher bien loin, elle améliorer clairement au moins l'utilisabilité de Vim en mode terminal, gommant encore un peu la différence avec gVim. Maintenant on verra bien, ce n'était pas une fin de non recevoir non plus. Le co-mainteneur devant en parler à son chef (c'est en tout cas comme cela que j'ai perçu la relation ;-)

En tout cas j'espère que cela va servir à certains ici, ce qui au fond serait l'essentiel.