
                      Comment changer le titre d'un xterm

Ric Lister, ric@giccs.georgetown.edu
traduction Jean-Albert Ferrez, Jean-Albert.Ferrez@epfl.ch

   Dernire modification : 22.11.1999, v2.0
     _________________________________________________________________

   _Ce document explique comment utiliser des squences d'chappement
   pour modifier dynamiquement le titre de la fentre et de l'icne d'un
   xterm. Des exemples sont donns pour plusieurs shells, et l'annexe
   donne les squences pour d'autres types de terminaux._
     _________________________________________________________________

1. O trouver ce document

   Ce document fait dsormais partie des HOWTOs Linux et peut tre trouv
    : http://sunsite.unc.edu/LDP/HOWTO/mini/Xterm-Title.html.

   La dernire version en date se trouve  :
   http://www.giccs.georgetown.edu/~ric/howto/Xterm-Title/.

   Ce document remplace le howto initial crit par Winfried Trmper.

   Ndt : La version franaise de ce document se trouve  :
   http://www.freenix.fr/linux/HOWTO/mini/Xterm-Title.html

2. Titres statiques

   Les titres des mulateurs de terminaux xterm, color-xterm ou rxvt
   peuvent tre donns sur la ligne de commande avec les options -T et
   -n :

xterm -T "Le titre de mon XTerm" -n "Le titre de son icne"

3. Titres dynamiques

   Bon nombre de personnes trouvent utile de faire apparatre dans le
   titre de leur terminal une information qui change dynamiquement, telle
   que le nom du serveur sur lequel on est connect, le rpertoire
   courant, etc.

3.1 Les squences d'chappement xterm

   On peut changer le titre de la fentre et de l'icne dans un xterm
   lanc en utilisant les squences d'chappement XTerm. Les squences
   suivantes sont utiles dans ce but :
     * ESC]0;_nom_BEL -- Change le titre de la fentre et de l'icne
     * ESC]1;_nom_BEL -- Change le titre de l'icne
     * ESC]2;_nom_BEL -- Change le titre de la fentre

   o ESC est le caractre escape (chappement, \033), et BEL est le
   caractre bell (bip, \007).

   Afficher l'une de ces squences dans un xterm causera le changement du
   titre de la fentre ou de l'icne.

   _Note_: Ces squences fonctionnent galement avec la plupart des
   drivs de xterm, tels que nxterm, color-xterm et rxvt. D'autres
   mulateurs de terminaux utilisent d'autres squences ; quelques
   exemples sont donns en annexe. La liste complte des squences
   d'chappement est donne dans le fichier ctlseq2.txt de la
   distribution de xterm, ou dans le fichier xterm.seq de la distribution
   de rxvt.

3.2 Afficher les squences d'chappement

   Pour les informations qui ne changent pas au cours de l'xcution du
   shell, telles que le serveur et le nom d'utilisateur, il suffit
   d'afficher les squences depuis le fichier rc du shell :

echo -ne "\033]0;${USER}@${HOST}\007"

   devrait donner un titre du genre nom@serveur, pour autant que les
   variables $USER et $HOST soient correctes. Les options requises pour
   echo peuvent dpendre du shell (cf ci-dessous).

   Pour les informations qui peuvent changer au cours de l'excution du
   shell, telles que le rpertoire courant, ces squences doivent
   vraiment tre donnes lors de chaque changement de l'invite. De cette
   faon, le titre est mis  jour lors de chaque commande et peut ainsi
   reflter des informations telles que le rpertoire en cours, le nom
   d'utilisateur, le nom du serveur, etc. Certains shells offrent des
   fonctions spciales pour y parvenir, d'autres pas : il faut dans ce
   cas insrer la chane directement dans le texte de l'invite.

4. Exemples pour quelques shells

   Nous donnons ci-dessous des exemples pour les shells les plus
   courants. Nous commenons avec zsh car il offre des possibilits qui
   facilitent grandement notre tche. Nous progresserons ensuite vers des
   exemples de plus en plus difficiles.

   Dans tous les exemples ci-dessous, on teste la variable
   d'environnement TERM pour tre certain de n'appliquer ces squences
   que si l'on est dans un xterm (ou driv). Le test est fait sur
   TERM=xterm*, de manire  inclure au passage les variantes telles que
   TERM=xterm-color (dfini par rxvt).

   Encore une remarque au sujet des drivs du C shell tels que tcsh et
   csh. Dans ces shells, les variables non-dfinies causent des erreurs
   fatales. Il est ds lors ncessaire avant de tester la valeur de la
   variable $TERM, de tester si elle existe pour ne pas interrompre un
   shell non-interactif. Pour y parvenir, il faut inclure les exemples
   ci-dessous dans quelque chose du genre :

  if ($?TERM) then
      ...
  endif

   ( notre avis, il s'agit d'une raison parmi beaucoup d'autres de ne
   pas utiliser les C shells. Voir _Csh Programming Considered Harmful_
   pour une discussion utile).

   Pour utiliser les exemples suivants, placez-les dans le fichier
   d'initialisation du shell apropri, c'est--dire un fichier lu lors du
   lancement d'un shell interactif. Le plus souvent il s'agit de
   ._shell_rc (ex : .zshrc, .tcshrc, etc.)

4.1 zsh

   On utilise quelques fonctions et codes offerts par zsh :

precmd ()   fonction excute juste avant chaque invite
chpwd ()    fonction excute lors de chaque changement de rpertoire
\e          code du caractre escape (ESC)
\a          code du caractre bip (BEL)
%n          code remplac par $USERNAME
%m          code remplac par le hostname jusqu'au premier '.'
%~          code remplac par le rpertoire, avec '~'  la place de $HOME

   De nombreux autres codes sont disponibles, voir 'man zshmisc'.

   Ainsi, le code suivant, mis dans ~/.zshrc, affiche
   "nom@serveur:rpertoire" dans le titre de la fentre (et de l'icne).

case $TERM in
   xterm*)
       precmd () {print -Pn "\e]0;%n@%m: %~\a"}
       ;;
esac

   On arrive au mme rsultat en utilisant chpwd() au lieu de precmd().
   La commande interne print fonctionne comme echo, mais donne accs aux
   squences %.

4.2 tcsh

   tcsh offre des possibilits similaires  celles de zsh :

precmd ()   fonction excute juste avant chaque invite
chpwd ()    fonction excute lors de chaque changement de rpertoire
%n          code remplac par $USERNAME
%m          code remplac par le hostname jusqu'au premier '.'
%~          code remplac par le rpertoire, avec '~'  la place de $HOME

   Malheureusement, il n'y a pas d'quivalent  la fonction print de zsh
   qui permette d'utiliser les codes de l'invite dans la chane du
   titre ; le mieux que l'on puisse faire est d'utiliser les variables du
   shell (dans ~/.tcshrc) :

switch ($TERM)
   case "xterm*":
       alias precmd 'echo -n "\033]0;${HOST}:$cwd\007"'
       breaksw
endsw

   mais on obtient alors le chemin complet du rpertoire, sans '~'. Par
   contre, on peut mettre la chane dans l'invite :

switch ($TERM)
   case "xterm*":
       set prompt="%{\033]0;%n@%m:%~\007%}tcsh%# "
       breaksw
   default:
       set prompt="tcsh%# "
       breaksw
endsw

   ce qui donne "tcsh% " comme invite, et "_nom_@_serveur_: _rpertoire_"
   dans le titre (et l'icne) de xterm. Les "%{...%}" doivent tre placs
   autour des squences d'chappement (et ne peuvent pas tre le dernier
   lment de l'invite, 'man tcsh' donne plus de dtails).

4.3 bash

   bash offre la variable PROMPT_COMMAND qui contient une commande 
   excuter avant d'afficher l'invite. Ce code (insr dans ~/.bashrc)
   affiche nom@serveur: rpertoire dans le titre de la fentre (et de
   l'icne).

PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD}\007"'

   o \033 est le caractre ESC et \007 BEL.

   Il convient de noter que les guillemets jouent un rle important : les
   variables entre "..." sont values, alors que celles entre "..." ne
   le sont pas. Ainsi, PROMPT_COMMAND reoit bien le nom des variables,
   ces dernires tant values lorsque PROMPT_COMMAND est invoque.

   Cependant, $PWD donne le rpertoire complet. Si l'on veut utiliser le
   raccourci ~, il faut placer toute la squence d'chappement dans
   l'invite pour avoir accs aux codes suivants :

\u          est remplac par $USERNAME
\h          est remplac par le hostname jusqu'au premier '.'
\w          est remplac par le repertoire, avec '~'  la place de $HOME
\[...\]     signale une suite de caractre non-imprimables

   Ainsi le code suivant produit l'invite bash$ , et place nom@serveur:
   rpertoire dans le titre (et l'icne) de xterm.

case $TERM in
   xterm*)
       PS1="\[\033]0;\u@\h: \w\007\]bash\$ "
       ;;
   *)
       PS1="bash\$ "
       ;;
esac

   L'utilisation de \[...\] signale  bash la prsence de caractres
   non-imprimables, information dont il a besoin lorsqu'il calcule la
   longueur de l'invite. Sans cette prcaution, les commandes d'dition
   de ligne ne savent plus trs bien o placer le curseur.

4.4 ksh

   ksh n'offre pas grand chose en terme de fonctions et codes, il faut
   donc mettre notre chane dans l'invite pour qu'elle soit mise  jour
   dynamiquement. L'exemple suivant produit l'invite ksh$ , et place
   nom@serveur: rpertoire dans le titre (et l'icne) de xterm.

case $TERM in
   xterm*)
       HOST=`hostname`
       PS1='^[]0;${USER}@${HOST}: ${PWD}^Gksh$ '
       ;;
   *)
       PS1='ksh$ '
       ;;
esac

   Cependant, $PWD donne le rpertoire complet. On peut ter le prfixe
   $HOME/ en utilisant la construction ${...##...}. De mme, on peut
   tronquer le nom du serveur  l'aide de ${...%%...}.

HOST=`hostname`
HOST=${HOST%%.*}
PS1='^[]0;${USER}@${HOST}: ${PWD##${HOME}/}^Gksh$ '

   Les caractres ^[ et ^G dsignent ESC et BEL (ils peuvent tre saisis
   dans emacs  l'aide de C-q ESC et C-q C-g).

4.5 csh

   C'est assez difficile  raliser avec csh. On finit par mettre ce qui
   suit dans le ~/.cshrc :

switch ($TERM)
   case "xterm*":
       set host=`hostname`
       alias cd 'cd \!*; echo -n "^[]0;${user}@${host}: ${cwd}^Gcsh% "'
       breaksw
   default:
       set prompt='csh% '
       breaksw
endsw

   Il a fallu faire un alias de la commande cd pour mettre  jour
   l'invite. Les caractres ^[ et ^G dsignent ESC et BEL (ils peuvent
   tre saisis dans emacs  l'aide de C-q ESC et C-q C-g).

   Notes : sur certains systmes hostname -s peut tre utilis pour
   obtenir le nom de la machine au lieu du nom qualifi. Les utilisateurs
   ayant des liens symboliques sur des rpertoires trouveront `pwd` plus
   prcis que $cwd.

5. Afficher le nom de la commande en cours d'excution

   Souvent un utilisateur lance une longue commande en avant plan telle
   que top, un diteur, un lecteur de courrier lectronique, etc, et
   voudrait que le nom de cette commande figure dans le titre de la
   fentre. C'est un problme dlicat qui n'est facile  rsoudre qu'avec
   zsh.

5.1 zsh

   zsh offre une fonction idale pour cet objectif :

preexec()   fonction excute juste avant qu'une commande soit excute
$*,$1,...   arguments passs  preexec()

   On peut donc insrer le nom de la commande de la manire suivante :

case $TERM in
    xterm*)
      preexec () {
        print -Pn "\e]0;$*\a"
      }
    ;;
esac

   Note: la fonction preexec() est apparue vers la version 3.1.2 de zsh,
   vous devrez peut-tre mettre  jour votre ancienne version.

5.2 Autres shells

   Ce n'est pas facile avec les autres shells qui n'ont pas l'quivalent
   de la fonction preexec(). Si quelqu'un a des exemples, merci de les
   communiquer par email  l'auteur.

6. Annexe : squences d'chappement pour d'autres mulateurs determinaux

   De nombreux mulateurs de terminaux modernes sont des drivs de xterm
   ou rxvt et acceptent les squences d'chappement que nous avons
   utilises jusqu'ici. Certains terminaux propritaires fournis avec les
   diverses variantes d'unix utilisent leur propres squences.

6.1 aixterm d'IBM

   aixterm reconnat les squences d'chappement de xterm.

6.2 wsh, xwsh et winterm de SGI

   Ces terminaux dfinissent $TERM=iris-ansi et utilisent :
     * ESCP1.y_texte_ESC\ Pour le titre de la fentre
     * ESCP3.y_texte_ESC\ Pour le titre de l'icne

   La liste complte des squences est donne dans la page man xwsh(1G).

   Les terminaux d'Irix supportent galement les squences de xterm pour
   dfinir individuellement le titre de la fentre et de l'icne, mais
   pas celle pour dfinir les deux en mme temps.

6.3 cmdtool et shelltool de Sun

   cmdtool et shelltool dfinissent $TERM=sun-cmd et utilisent :
     * ESC]l_texte_ESC\ Pour le titre de la fentre
     * ESC]L_texte_ESC\ Pour le titre de l'icne

   Ce sont des programmes vraiment horribles, il vaut mieux utiliser
   autre chose.

6.4 CDE dtterm

   dtterm dfinit $TERM=dtterm. Il semble qu'il reconnaisse  la fois les
   squences xterm standard ainsi que celles du cmdtool de Sun (test sur
   Solaris 2.5.1, Digital Unix 4.0, HP-UX 10.20).

6.5 HPterm

   hpterm dfinit $TERM=hpterm et utilise les squences suivantes :
     * ESC&f0k_longueur_D_texte_ Donne le texte _texte_ de longueur
       _longueur_ comme titre de fentre
     * ESC&f-1k_longueur_D_texte_ Donne le texte _texte_ de longueur
       _longueur_ comme nom de l'icne

   Un programme C simple pour calculer la longueur et afficher la bonne
   squence ressemble  :

#include <string.h>
int main(int argc, char *argv[])
{
    printf("\033&f0k%dD%s", strlen(argv[1]), argv[1]);
    printf("\033&f-1k%dD%s", strlen(argv[1]), argv[1]);
    return(0);
}

   On peut galement crire un shell-script quivalent, utilisant
   ${#string} (zsh, bash, ksh) ou ${%string} (tcsh) pour obtenir la
   longueur d'une chane. L'exemple suivant est pour zsh :

case $TERM in
    hpterm)
        str="\e]0;%n@%m: %~\a"
        precmd () {print -Pn "\e&f0k${#str}D${str}"}
        precmd () {print -Pn "\e&f-1k${#str}D${str}"}
        ;;
esac

7. Annexe : exemples dans d'autres langages

   Il peut tre utile d'crire des bouts de codes pour changer le titre
   de la fentre  l'aide des squences xterm. Voici quelques exemples :

7.1 C

#include <stdio.h>

int main (int argc, char *argv[]) {
  printf("%c]0;%s%c", '\033', argv[1], '\007');
  return(0);
}

7.2 Perl

#!/usr/bin/perl
print "\033]0;@ARGV\007";

8. Crdits

   Merci aux personnes suivantes pour leur contribution  ce document.

   Paul D. Smith <psmith@BayNetworks.COM> et Christophe Martin
   <cmartin@ipnl.in2p3.fr> ont tous les deux remarqu que j'avais
   interverti les guillemets dans le PROMPT_COMMAND pour bash. Les avoir
   dans le bon ordre garantit que les variables sont values
   dynamiquement.

   Paul D. Smith <psmith@BayNetworks.COM> a propos de protger les
   caractres non-imprimables dans l'invite de bash.

   Christophe Martin <cmartin@ipnl.in2p3.fr> a donn la solution pour
   ksh.

   Keith Turner <keith@silvaco.com> a donn les squences d'chappement
   pour les cmdtool et shelltool de Sun.

   Jean-Albert Ferrez <ferrez@dma.epfl.ch> a signal un manque de
   cohrence dans l'utilisation de "PWD" et "$PWD", ainsi que de "\" et
   "\\".

   Bob Ellison <papillo@hpellis.fc.hp.com> et Jim Searle
   <jims@broadcom.com> ont test dtterm sur HP-UX.

   Teng-Fong Seak <seak@drfc.cad.cea.fr> a suggr l'option -s de
   hostname, l'utilisation de `pwd`, et de echo sous csh.

   Trilia <trilia@nmia.com> a suggr les exemples dans d'autres
   langages.

   Brian Miller <bmiller@telstra.com.au> a fourni les squences
   d'chappement et les exemples pour hpterm.

   Lenny Mastrototaro <lenny@click3x.com> a expliqu l'utilisation des
   squences xterm dans les mulateurs de terminaux Irix.

   Paolo Supino <paolo@init.co.il> a suggr l'utilisation de \\$ dans le
   prompt de bash.
