6/26/10

vim and screen 256 colors - MacOS X Snow Leopard


Nature du problème

Je souhaite utiliser des thèmes 256 couleurs avec Vim et plus spécifiquement le thème railscasts que j'utilisais sous Linux (thème d'origine TextMate utilisé par Ryan Bates pour ses screencasts). Vim et iTerm sont capables d'utiliser des thèmes 256 couleurs. Concernant iTerm, il suffit de choisir 'xterm-256color' dans la section 'Terminal Profiles'. Quant à Vim, il suffit d'ajouter set t_Co=256 à son .vimrc.

Attention, le Terminal livré avec Leopard ne supporte toujours pas un mode 256 couleurs. De toute façon, vous avez tout à gagner à passer à iTerm si ce n'est pas déjà fait (full screen, profiles à gogo suivant l'activité, etc...)

Le réel problème vient de la version de screen livrée avec Leopard qui ne supporte pas le mode 256 couleurs. Evidemment, comme j'utilise à outrance 'screen', c'est plus qu'ennuyeux de se retrouver avec un Vim en mode dégradé (surtout lorsqu'on épluche du code Rails à gogo comme c'est mon cas depuis plus d'une semaine). J'ai donc craqué et pris le temps de recompiler 'screen' avec le support du mode 256 couleurs.


Choix des sources

A défaut de faire correctement son boulot pour les utilitaires et logiciels en ligne de commande, Apple propose, sans doute pour se faire pardonner, des pages sur les logiciels Open Source utilisés pour le Mac. Je suis donc parti des sources de 'screen' pour Mac OS X version 10.6.4.

Je récupère également les sources du 'screen' correspondant à la version '10.6.2' car il manque 3 patches à la version '10.6.4' pour qu'on puisse le compiler correctement en ligne de commande. Les autres patches sont inutiles car les fichiers précédemment concernés ont déjà été modifiés (ils sont __APPLE__ powered ^^).


Lignes de commande en mode Canal+

J'ai choisi d'utiliser des commandes qui paraitront un peu 'cryptées' pour la plupart. Compiler un programme n'a rien de passionnant, alors autant apporter un peu de fun 'bash' pour le faire. Il suffit de copier les lignes qui suivent en respectant l'ordre et sans rien taper de plus entre chaque commande pour que ça se passe parfaitement (copier-coller roxe des mamans ours). Une ligne est fortement exagérée (celle du 'cd') et j'avoue que je ne l'aurais jamais tapée si ce n'était pour l'exemple et par nostalgie (cette ligne me rappelle la belle époque du Obfuscated Perl Contest).


Compilation et installation de 'screen'

cd
mkdir -p src/tarball && cd !#:2:h
wget http://www.opensource.apple.com/tarballs/screen/screen-19.tar.gz -O tarball/!#:^:t
wget !*:gs/9/6
tar xvzf !$:gs/6/9
mkdir !$:t:r:r/patches
tar xvzf !w:$ -C !$ --strip-components=2 *.diff
cd !mk:$:h/!#:$:h:gs/-19/
patch -p0 < ../patches/Makefile.in.diff
patch -p0 < ../patches/config.h.in.diff
patch -p0 < ../patches/configure.diff
./configure --enable-locale --enable-telnet --enable-colors256 --enable-rxvt_osc --prefix=/usr/local --disable-dependency-tracing
make
sudo make install

Modification du .screenrc

Il suffit d'ajouter ces lignes à son .screenrc (comme indiqué dans l'en-tête de railscasts.vim)

attrcolor b ".I"
termcapinfo xterm-color 'Co#256:AB=\E[48;5;%dm:AF=\E[38;5;%dm'
defbce "on"
term screen-256color-bce
xterm-color doit correspondre à la réponse de echo $TERM

Utiliser son nouveau 'screen'

Je ne préfère pas toucher à l'installation d'Apple car je n'ai pas envie qu'une prochaine mise à jour vienne me compliquer la vie ^^. Pour utiliser des programmes recompilés (et donc, déjà existants sur le système), j'opte généralement pour l'utilisation de mon ~/bin. Il n'existe pas par défaut, il faut donc le créer si vous ne l'avez pas déjà fait.

mkdir ~/bin

Depuis son ~/bin, on fait simplement un lien vers son 'screen'.

ln -s /usr/local/bin/screen-4.0.3 screen

Si ce n'est pas déjà fait, on ajoute enfin son ~/bin à son PATH (dans son .bashrc ou son .bash_profile) en s'assurant qu'il sera bien le premier à être interrogé.

if [ -d ~/bin ]; then
    export PATH=~/bin:$PATH
fi

which screen doit vous dire que le système utilisera bien le screen nouvellement installé.

That's all.

1/13/07

remind & backtick screen


UPDATE 15/01 :
modif :
- section 1°) (>> au lieu de >)
- section 2°) (script modifié)
- section 4°) (alias r et vr)
motif :
une alerte non-consultée pouvait être écrasée par l'alerte suivante


Comme vu précédemment, l'affichage des alertes de remind peut se faire via des fenêtres pop-up (gxmessage ou autre). Néanmoins, cela représente des défauts majeurs dont celui de perdre le focus au moment le plus inopportun (lois de Murphy en action). Enfin, ce n'est pas le plus adapté pour des connexions ssh et ça n'a aucun intérêt lorsqu'on passe 95% de son temps dans des screen.

Reste à mettre en place une solution qui permette d'être alerté sans pour autant perturber l'activité en cours sur les différents écrans. Utiliser le « backtick » de screen est ce qui m'a paru le moins « obstrusif ».

1°) On commence par demander à remind d'écrire ses alertes dans un fichier qu'on appellera .rappels. Pour cela, on lance la commande suivante au démarrage de X et/ou lors du login de l'utilisateur.

remind -zk"echo %s >> /home/mon_user/.rappels" &

2°) On crée un script permettant de lire le nombre d'alertes envoyées par remind dans le fichier .rappels (script remind-me.sh à mettre dans ~/bin) :
#!/bin/sh
# remind-me.sh (bc 2007)
# modifier RAPPEL_FILE pour votre usage
RAPPEL_FILE='/home/mon_user/.rappels'

if [ -e $RAPPEL_FILE ] && [ -s $RAPPEL_FILE ]; then
sort -u $RAPPEL_FILE -o $RAPPEL_FILE
nbl=`wc -l $RAPPEL_FILE | cut -f1 -d' '`
case "$nbl" in
"1")
nbw=`wc -w $RAPPEL_FILE | cut -f1 -d' '`
if [ $nbw -gt 0 ]; then
echo "1 rappel"
else
exit 0
fi
;;
*)
echo "$nbl rappels"
;;
esac
else
exit 0
fi

3°) On modifie le .screenrc de l'utilisateur pour afficher le backtick qui utilise le script remind-me.sh. Voici une proposition pour la partie qui nous intéresse :
hardstatus on
hardstatus alwayslastline
hardstatus string '%{= kG}[%= %{= kw}%?%-Lw%?%{r}(%{W}%n*%f%t%?(%u)%?%{r})%{w}%?%+Lw%?%?%= %{g}][%{R}%{+B} %1` %{g}%{-B}][%{B} %D %d/%m %{W}%c %{g}]'
backtick 1 0 60 remind-me.sh

On demande que le rafraîchissement se fasse toutes les minutes.

4°) On crée 2 alias (dans son .bash_aliases ou son .bashrc). Le premier alias 'r' (comme 'rappels') affichera le contenu de .rappels alors que le second alias 'vr' (comme 'vider les rappels') videra le contenu du fichier ~/.rappels.
alias r='sort -u ~/.rappels'
alias vr='> ~/.rappels'

En résumé, ça donne ce résultat :

Pour la démo, le rafraîchissement du backtick est de 5 secondes.

12/22/06

bash prompt color pour screen (Debian Etch)


Quand on passe sa vie dans des consoles, il est préférable de repérer visuellement si on est dans un terminal screen ou non.

Une méthode consiste à changer la forme du prompt. A titre d'exemple, on peut paramétrer le prompt de l'utilisateur courant pour qu'il soit de couleur cyan et celui de root rouge. Lorsqu'on entre dans un terminal screen, on peut par exemple passer le prompt en gras pour indiquer qu'on est dans un screen. Cela ne choque pas et permet de savoir immédiatement s'il s'agit d'un screen lorsqu'on passe en revue les terminaux ouverts.

Il faut modifier le .bashrc par défaut de l'utilisateur (et le /etc/skel/.bashrc si vous créez régulièrement des utilisateurs) en rajoutant 2 sections pour le « case "$TERM" » :

xterm*|rxvt*)
PS1='${debian_chroot:+($debian_chroot)}\e[0;36m\u@\h:\e[0;37m\w\e[0;36m\$\e[0;37m '
;;
screen)
PS1='${debian_chroot:+($debian_chroot)}\e[1;36m\u@\h:\e[1;37m\w\e[1;36m\$\e[0;37m '
;;

Pour root, on rajoute la section :

case "$TERM" in
screen)
PS1='\e[1;31m\u@\h:\e[1;37m\w\e[1;31m\$\e[0;37m '
;;
xterm*|rxvt*)
PS1='\e[0;31m\u@\h:\e[0;37m\w\e[0;31m\$\e[0;37m '
;;
*)
PS1='\h:\w\$ '
;;
esac