Yoran 29 octobre, 2012 - 00:28 urxvt VIM xterm xtermcontrol couleurs
Changer dynamiquement la palette d'urxvt

L'un des avantages de gVIM par rapport à VIM/terminal est sa capacité à charger dynamique un thème de colorisation autonome. Dans un terminal, on est en effet lié à la palette qui ne peut pas être modifiée autrement qu'en passant par le fichier de ressources, et donc un redémarrage du terminal. Impossible donc de basculer de manière fluide d'un thème "light" en journée à un thème "dark" en soirée avec VIM/Terminal ? En fait non, comme souvent, il existe une solution élégante à cette problématique.

Pour quoi faire ?

Comme beaucoup j'ai commencé à utiliser VIM dans sa version graphique (gVIM). Mais n'étant pas un fanatique de menu déroulants et d'icônes, je me suis rapidement retrouvé avec un gVIM qui avait à peu prés la même tête qu'un VIM en console.

Je ne vais pas m'étendre longuement sur l'intérêt de la console. Disons en substance que cela me permet d'avoir le même système en local et en distant, ce qui dans mon métier est un atout énorme.

Il restait cependant deux points lacunaires par rapport à la version graphique : la souris et les couleurs. Le cas de la souris a été rapidement réglé dés que j'ai compris comment paramétrer VIM pour exploiter la gestion de la souris d'URxvt. Aujourd'hui mis à par un double-click un tantinet dure de la feuille, ma version console de VIM exploite la souris strictement de la même manière que sa soeur graphique.

Restait le cas des couleurs. Alors certes un terminal comme URxvt permet d'attaquer une palette de 88 couleurs et de nombreux thèmes VIM exploitent cette option. Malgré cela je me sentais bridé pour la création de mes propres thèmes, bloqué dans des choix de couleurs que je continuais à trouver limité. La vraie bonne solution était pour moi d'avoir possibilité 1/ de modifier dynamiquement la palette du terminal 2/ de pouvoir choisir strictement les couleurs que je désire dans la palette RGB classique, comme pour gVIM.

L'approche par échappement

Tout l'astuce pour résoudre mon problème tient en la capacité de nombreux terminaux à permettre la redéfinition dynamique de nombreux paramètres, dont leur palette, à travers une série de séquence d'échappement appartenant à la catégorie OSC (Operatin System Control). Ce qui suit a été testé sous URxvt mais certaines séquences fonctionnent parfaitement avec XTerm et même avec la tripotée de terminaux basés sur libvte.

Pour commencer par un exemple simple, imaginez vouloir changer la police de votre terminal à la volé en la passant en DejaVu sur 8 Pixels :

gastonecho -ne '\033]50;xft:DejaVu Sans Mono:size=8\007'
Changement dynamique de la police

A partir de là, il suffit de potasser un peu la spécification des séquences XTerm pour trouver comment modifier un élément de palette, mais aussi du fond et de l'encre par défaut. Attention ce qui suit va pourrir proprement votre terminal :)

# Changement de l'encre par défaut en mauve
gastonecho -ne '\033]10;#FF00FF\007'
 
# Changement du fond en bleu pétard
gastonecho -ne '\033]11;#0000FF\007'
 
# Changement de la couleur numéro n°0 (le rouge) en Vert
gastonecho -ne '\033]4;0;#00FF00\007'

Déjà à ce stade il est possible de définir en quelque chose de sympa les 16 couleurs de la palette de base d'un terminal en utilisant une notation classique RGB. Sympa mais pas suffisant pour obtenir un super thème sous VIM. Pas de soucis, car en réalité la dernière séquence peut aller beaucoup plus loin et définir chacune des 88 couleurs de la palette étendue. Si vous décidez donc que vos commentaires sous VIM doivent être en vert mousse (#8BAC56) il me suffit d'émettre la séquence '\033]4;17;#8BAC56\007' pour redéfinir la couleur d'index 17. Puis dans mon thème VIM d'utiliser l'index 17 dans mon fichier de syntax VIM (termfg=17) et le tour est joué.

Du coup les 88 couleurs d'URxvt qui peuvent sembler une limitation par rapport au 256 de XTerm, ne le sont en réalité pas si l'on définit chacune à sa convenance.

Après le mode d'initialisation de votre super palette est à votre convenance. Vous pouvez par exemple mettre les echo dans un script que vous lancez à partir de votre ~/.bashrc. Vous pouvez aussi les émettre directement dans le script de votre schéma de couleur VIM.

A noter que l'autre avantage de cette approche est qu'en redéfinissant les couleurs 17 et plus, vous conservez une compatibilité avec la palette des 16 couleurs de base ce qui est utile pour les outils qui ne permettent pas de changer leurs couleurs (htop, alsamixer, etc.).

Enfin, concernant spécifiquement VIM, il est possible de mettre en place cette technique de manière totalement automatisée. Un peu comme le plugin CSApprox, j'ai commencé un plugin qui transforme automatiquement les couleurs d'un schéma prévu pour gVIM et l'adapte en modifiant dynamiquement la palette. C'est plus pour jouer qu'autre chose mais en tout cas le "proof of concept" fonctionne.

Format de spécification de couleurs

Vous ne le trouvez pas encore suffisamment beau votre terminal maintenant qu'il est maquillé comme un camion volé ? Attendez un peu, il y a encore de quoi rigoler avec URxvt. Un truc en effet classiquement bien moche, sont les aplats de couleur lorsque l'on a une image en fond, que ce soit un pixmap custom ou le fond du burea (via inheritPixmap). Et bien figurez-vous qu'en jouant sur le format de spécification des couleurs, il est parfaitement possible d'injecter dans la palette des couleurs avec un niveau de transparence.

# on définir la couleur 17 en vert mousse avec un gentil niveau de transparence
gastonecho -ne '\033]4;17;rgba:8B00/AC00/5600/3000\007'
 
# On imprime un texte avec notre couleur 17 comme fond
gastonecho -ne '\033[48;5;17m-----------Coucou---------------\n'

Et voilà c'est pas zoli ? :)

Conclusion

Décidément j'aime bien ce terminal (URXvt) et cette petite manipulation le rend encore plus agréable à utiliser. Après l'exploitation de ces techniques peut aller assez loin comme définir des palettes par application, les charger/décharger à la demande, etc.

Vos remarques et commentaires...

ZaZ, le 21 avril, 2012 - 10:23

Dans vim (et gvim), pour changer les couleurs dynamiquement :colorcheme
En ce qui concerne le terminal, j'utilise lilyterm. Avec urxvt, j'avais un mal fou à configurer les polices de caractères (sur Arch, pas sur Debian).

Merci pour ton blog que je consulte régulièrement.

ZaZ

Yoran, le 21 avril, 2012 - 22:45

Dans gVim, les couleurs utilisées dans la coloration syntaxique peuvent être saisies à la mode RGB, ce que tu dis est donc vrai dans ce cas. Pas pas de celui de VIM en console où là les couleurs données sont des indexes faisant référence à la palette 16 ou 256 couleur du terminal. La technique décrite ici permet de redéfinir la palette elle-même, ou du moins ses 16 couleurs de base. Cela permet de garder le même schéma de couleur au sein de vim, mais de faire varier le thème du terminal. Pour moi c'est une approche plus pratique que de passer par exemple par un thème en 256 couleurs car ces derniers sont ultra-pénibles à réaliser. Là il suffit de définir 16 couleurs en RGB et d'avoir un schéma VIM générique exploitant ces 16 couleurs pour basculer très facilement d'une ambiance à l'autre. J'ai réalisé comme cela un thème "maya" (light), "zenBurn", "solarized" et même un thème bien débile que j'aime bien qui "émule" les vieux écrans ambre :)

Pour ce qui est d'urxvt, cela vaut le coup de forcer un peu histoire de comprendre ce qui pose problème. j'ai personnellement toujours trouvé que les terminaux basés sur libvte étaient un peu poussifs (tout est relatif évidement ;-)

Stophe, le 10 juin, 2012 - 12:46

J'ai recopié le script ci-dessus, mais...

stophe@darkstar:~/.config/xtermcontrol$ ./solarized.sh
xtermcontrol: TERM=rxvt-unicode: probably not xterm variant
xtermcontrol: TERM=rxvt-unicode: probably not xterm variant
xtermcontrol: TERM=rxvt-unicode: probably not xterm variant
xtermcontrol: TERM=rxvt-unicode: probably not xterm variant
......

J'ai dû louper une étape :o)

Yoran, le 10 juin, 2012 - 15:20

Ah oui c'est vrai, moi dans mon ~/.Xdefaults j'ai forcé le nom du terminal à xterm-256color

URxvt.termName: xterm-256color

Si tu n'as pas envie de faire cela, tu peux facilement tromper l'outil en ajoutant ce réglage temporaire à l'entrée de ton script :

#! /bin/bash

export TERM=xterm xtermcontrol
xtermcontrol --fg=red

Je vais modifier le tuto dans ce sens.

Stophe, le 10 juin, 2012 - 15:25

En lançant : urxvt -tn xterm, xtermcontrol ne renvoie plus de message d'erreur. Mais bon ça fait bricolage :)
Doit y avoir mieux...

Stophe, le 10 juin, 2012 - 15:34
URxvt.termName: xterm-256colors

me va très bien :o)

Stophe, le 10 juin, 2012 - 15:42

Maintenant, j'aimerais que xtermcontrol modifie la palette en fonction de "conditions".
Une certaine palette si je suis en root, une autre si je suis en SSH, ...
J'ai cru lire ça qq part.

Stophe, le 10 juin, 2012 - 15:52

Début de résultat, vu sur la page de XtermControl.
Dans ~/.bashrc :

su() {
   ~/.config/xtermcontrol/solarized.sh
   command su "$@"
}
Stophe, le 10 juin, 2012 - 16:01

C'est marrant ça...
Quand je mets xterm-256colors, vim souligne tous les caractères...
Quand je mets rxvt, ça redevient normal (?)

Yoran, le 10 juin, 2012 - 16:27

Je te disais ce que j'avais dans ma configuration expliquant que la commande fonctionne, je ne te donnais pas un conseil pour faire la même chose ;-) J'ai mis ce réglage dans mon ~/.Xdefaults de sorte rendre urxvt globalement compatible avec xterm. Mais pour que cela fonctionne, il y pas mal d'autres choses à faire, y compris dans VIM.

Je te conseille donc de retirer cette ligne et de passer par un "export TERM=xterm" qui n'aura aucun effet de bord.

pour la condition tu peux aussi tout simple faire un :

if [ "$USER"=="root ] ; then
  # tes réglages spécifiques ici
fi

Yoran, le 13 juin, 2012 - 23:06

Si cela t'intéresse j'ai rajouté un chapitre pour faire la même chose (changement de palette) mais sans xtermcontrol, juste avec un script bash.

Stophe, le 15 juin, 2012 - 20:52

OK, merci.

Hors sujet avec urxvt, en rapport avec .Xdefaults : xcalc.
Mis à part sa rapidité de lancement, xcalc est par défaut ... vraiment moche !
Mais après configuration dans le .Xdefaults :

xcalc*geometry: 200x275
xcalc.ti.bevel.background: #111111
xcalc.ti.bevel.screen.background: #000000
xcalc.ti.bevel.screen.DEG.background: #000000
xcalc.ti.bevel.screen.DEG.foreground: LightSeaGreen
xcalc.ti.bevel.screen.GRAD.background: #000000
xcalc.ti.bevel.screen.GRAD.foreground: LightSeaGreen
xcalc.ti.bevel.screen.RAD.background: #000000
xcalc.ti.bevel.screen.RAD.foreground: LightSeaGreen
xcalc.ti.bevel.screen.INV.background: #000000
xcalc.ti.bevel.screen.INV.foreground: Red
xcalc.ti.bevel.screen.LCD.background: #000000
xcalc.ti.bevel.screen.LCD.foreground: LightSeaGreen
xcalc.ti.bevel.screen.LCD.shadowWidth: 0
xcalc.ti.bevel.screen.M.background: #000000
xcalc.ti.bevel.screen.M.foreground: LightSeaGreen
xcalc.ti.bevel.screen.P.background: #000000
xcalc.ti.bevel.screen.P.foreground: Yellow
xcalc.ti.Command.foreground: White
xcalc.ti.Command.background: #777777
xcalc.ti.button5.background: Orange3
xcalc.ti.button19.background: #611161
xcalc.ti.button18.background: #611161
xcalc.ti.button20.background: #611111
xcalc.ti.button25.background: #722222
xcalc.ti.button30.background: #833333
xcalc.ti.button35.background: #944444
xcalc.ti.button40.background: #a55555
xcalc.ti.button22.background: #222262
xcalc.ti.button23.background: #222262
xcalc.ti.button24.background: #222272
xcalc.ti.button27.background: #333373
xcalc.ti.button28.background: #333373
xcalc.ti.button29.background: #333373
xcalc.ti.button32.background: #444484
xcalc.ti.button33.background: #444484
xcalc.ti.button34.background: #444484
xcalc.ti.button37.background: #555595
xcalc.ti.button38.background: #555595
xcalc.ti.button39.background: #555595
XCalc*Cursor:                 hand2
XCalc*ShapeStyle:             rectangle

Rendons à César, .... J'ai vu ça ici.
Ce monsieur semble être expert en thème Fluxbox, pour ceux que ça intéresse

Yoran, le 16 juin, 2012 - 16:37

Sympa :)

Perso j'aime bien les commandes standards bc et dc. Toutes deux sont des calculatrices en ligne de commande. La première utilise une notation classique (penser à utiliser bc -l pour une meilleur précision) du genre 1+1[Entré]. Et la seconde utilise la notation RPM 1 1 +p.

laluge, le 10 août, 2012 - 10:03

Bonjour,
je n'arrive pas à utiliser les couleurs systèmes 0 à 7 dans mon colorscheme. en gris foncé et pas en rouge
Elles sont systématiquement remplacées par les couleurs systèmes 8 à 15.
Avez- remarqué ce genre de désagrément ?

*color0:         red
*color8:         #444

hi Normal cterm=bold ctermfg=0

affiche le corps de texte en gris foncé au lieu de rouge

la commande :!256colors affiche la palette correctement.
Si quelqu'un peut tester ?
Je n'ai aucun problème avec les couleurs 16 à 231

Ce truc de palette dynamique m'intéresse, mais avec 8 couleurs seulement ??

Merci

Yoran, le 23 septembre, 2012 - 00:10
Ce truc de palette dynamique m'intéresse, mais avec 8 couleurs seulement ??

Je ne comprend pas...

laluge, le 23 septembre, 2012 - 12:00

Bonjour,
je vais essayer d'être plus clair, mais c'est pas gagné.

Les couleurs systèmes 0 à 7 sont systématiquement remplacées par les couleurs 8 à 15.
Avec le .Xresources de l'exemple ci-dessous, le texte normal s'affiche en gris foncé et non en rouge.

*color0:         red
*color8:         #444
hi Normal cterm=bold ctermfg=0

J'ai testé sur Debian et sur Archlinux avec le même résultat.

Merci

Yoran, le 23 septembre, 2012 - 15:35

Déjà j'imagine que la 3ième ligne est dans un fichier .vim et non dans le fichier .Xresources.

Sinon j'ai fait tout les mêmes texte que toi et de mon côté ça marche. Mais j'ai peut-êre une idée. Si tu enlèves le "bold" dans ton fichier de syntaxe vim, ça donne quoi ?

laluge, le 23 septembre, 2012 - 16:48

Bonne pioche et bravo, c'est bien le cterm=bold qui coince.

j'ai positionné la police dans le .Xresources :
vi*font: xft:monospace:size=10:bold

Mais je ne peux pas mixer du bold et du normal dans le colorscheme.

Yoran, le 24 septembre, 2012 - 00:22

Tu es bien configuré en 256 couleurs au niveau de ton terminal ? Sinon, tu peux essayer la ressource "intensityStyle" (si tu utilises urxvt).

laluge, le 24 septembre, 2012 - 20:18

deux fois bravo.

avec vi*intensityStyles: false, tout fonctionne impeccable.
J'aurais du lire le man plus attentivement, mais c'est un peu ardu.

Il semblerait, si j'ai bien tout compris, que dans le colorscheme de vim, le paramètre cterm doit être passé avant les paramètres de couleur.

Merci de ton aide précieuse et efficace,

Yoran, le 24 septembre, 2012 - 21:26

Nickel :)

Pour le coup de cterm, perso moi je le met après et ça fonctionne sans soucis...

laluge, le 24 septembre, 2012 - 23:40

j'ai vérifié,

de mon coté, le cterm est positionnel sur Normal,
et non positionnel sur comment, fonction, tabline.
???

accessoirement et ça n'a rien à voir, xterm et xfontsel ne supporte pas depth: 32

Yoran, le 25 septembre, 2012 - 08:30

Alors c'est vrai que "Normal", j'ai tendance à le laisse "Normal" ;-) Donc j'ai pu passer à côté.

Sinon pour depth:32, j'ai arrêté car même si c'est joli, un fond, même léger fait énormément perdre en lisibilité.

Chimrod, le 29 octobre, 2012 - 17:36

Si tu es sous debian, tu peux aussi installer « rxvt-unicode-256color », qui une version de urxvt, mais 256 colors inside.

Il doit exister des versions pour les autres distributions…

Yoran, le 29 octobre, 2012 - 17:42

Certes mais pour quel usage ? :) J'ai peur du coup de ne pas avoir été clair avec cet article... Le but est de créer ses propres palettes modifiables dynamiquement à partir de valeurs RGBA.

Pour cet usage les 88 couleurs de base d'URxvt ne sont pas une réelle limitation. Et toujours pour cette usage, 256 couleurs prédéfinies ne sont pas utilisables.

Chimrod, le 29 octobre, 2012 - 18:42

Si tu as été clair, mais par rapport au besoin que tu exprimes (avoir un jeu de couleur correct sous vim), il est plus simple d'avoir un terminal pouvant afficher 256 couleurs, que de passer par une solution de contournement.

Il fallait bien quelqu'un pour proposer la solution de facilité face à la complexité technique…

Yoran, le 29 octobre, 2012 - 18:52

Oh ok :)

Ceci dit c'est vrai que je n'ai pas super détaillé le besoin qui m'a amené à mettre en place mon usine à gaz. En résumé, j'ai une palette d'une 30aine de couleurs que j'applique à toutes mes applications (CLI ou graphiques). Pour mettre cela en oeuvre, j'ai un script python qui me génère mes diverses confs, dont le colorscheme vim, basé donc sur les indexes de cette palette. Ceci fait, en jouant sur la redéfinition dynamique des palettes au sein d'un terminal, je peux décider de passer mutt en palette "solarized", vim en palette "light", etc, tout cela à ma convenance et sans avoir à recharger les applications, ni écrire un colorscheme spécifique pour chaque palette. Pour compléter le tout, j'ai un greffon sous URXVT qui va régulièrement regarder le ctime des palettes et en fonction de celle qu'il utilise pour une console donner, la recharger si elle a été modifiée. Du coup je peux tuner mes palettes dynamiquement ce qui est assez pratique.

Maintenant tu as bien raison, pour qui ne change pas souvent de schema de couleur et/ou qui n'a pas la sale habitude de couper les cheveux en 4, l'option 256 couleurs dans URXvt est largement suffisante :)

laluge, le 29 octobre, 2012 - 17:57

Ton article était clair, si on le lit attentivement et que l'on a une connaissance minimum de vim et des ressources X.

Yoran, le 29 octobre, 2012 - 18:36

Ça devrait aller alors, car j'imagine que rare sont ceux qui ne présentent pas ces pré-requis et qui sont intéressé par ce genres de sujets :)

Publier un nouveau commentaire

Le contenu de ce champ sera maintenu privé et ne sera pas affiché publiquement.
  • To highlight piece of code, just surround them with <code type="language"> Your code &tl;/code>>. Language can be java,c++,bash,etc... Everything Geshi support.
  • Tags HTML autorisés : <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <blockquote> <div> <p> <br>
  • Les lignes et les paragraphes vont à la ligne automatiquement.
  • Les adresses de pages web et de courriels sont transformées en liens automatiquement.

Plus d'informations sur les options de formatage

CAPTCHA
Cette question est là pour déterminer si vous êtes humain ou pas...