S’amuser avec irssi screen et zsh.

Screen est un multiplexeur de terminaux virtuels.
Irssi est sûrement l’un des clients IRC en mode console parmis les plus « puissants ».
Zsh fait quant à lui partie des shells les plus prisés pour ses options de scripting, d’aliasing, et bien plus encore.

Pour commencer, comme j’oublie régulierement de lancer mon Irssi dans screen, j’ai utilisé un alias et une astuce pour lancer screen automatiquement quand je tappe « irssi ».

(zmx@localhost)[~]-% cat irssiscr
#!/bin/bash
# Run/Load IRC Script
# This script runs irssi in screen if it has not already been done.
# If irssi in screen is already running, it will then attach to
# the irc screen session for you.
if screen -ls | egrep '^[[:space:]]+[^[:space:]]' | awk '{print $1}' | egrep '.irc$'
then # running
screen -x irc
else # not running
screen -c ~/.screenrc.irc -S irc -t irssi irssi
fi

Et l’alias dans votre .zshrc

alias irssi=~/irssiscr

Le fichier .screenrc.irc contient quant à lui votre config screen spécifique pour votre « screen spécial irc »

# detach on hangup
autodetach on
# multiusers
multiuser on
# no copyright notice during startup
startup_message off
# remove some bad bindings
bind k  #kill
bind ^k #kill
bind .  # dump termcap
bind ^h # hardcopy
bind h  # hardcopy
bind A  # title (clashes with vim's increment)
 
# don't use the hardstatus line for system messages, use reverse video instead
# # (we'll be using it for the list of tab windows - see hardstatus alwayslastline
# # below)
hardstatus off
hardstatus alwayslastline "%{= bW} %-Lw%{=b BR} %n%f %t %{-}%+Lw %-024=%{+b} %c %D %d %M %Y%=%{= dd}"

La ligne hardstatus va nous permettre, comme expliqué ici, d’avoir des « onglets » en bas de l’écran pour les différentes windows ouvertes dans votre screen.
Pour plus de détails sur la syntaxe de la ligne hardstatus, vous pouvez faire un tour ici
Le nom de ses tabs sera mis à jour dynamiquement par zsh grâce aux méthodes preexec() et precmd() appelées avant l’affichage du prompt ou avant l’exécution d’une commande respectivement.

# if using GNU screen, let the zsh tell screen what the title and hardstatus
# of the tab window should be.
if [[ $TERM == "screen" ]]; then
# use the current user as the prefix of the current tab title (since that's
# fairly important, and I change it fairly often)
TAB_TITLE_PREFIX=''
# when at the shell prompt, show a truncated version of the current path (with
# standard ~ replacement) as the rest of the title.
TAB_TITLE_PROMPT='`print -Pn "%~" | sed "s:\([~/][^/]*\)/.*/:\1...:"`'
 
# when running a command, show the title of the command as the rest of the
# title (truncate to drop the path to the command)
TAB_TITLE_EXEC='$cmd[1]:t'
 
# use the current path (with standard ~ replacement) in square brackets as the
# prefix of the tab window hardstatus.
TAB_HARDSTATUS_PREFIX='`print -Pn "[%~] "`'
# when at the shell prompt, use the shell name (truncated to remove the path to
# the shell) as the rest of the title
TAB_HARDSTATUS_PROMPT='$SHELL:t'
# when running a command, show the command name and arguments as the rest of
# the title
TAB_HARDSTATUS_EXEC='$cmd'
 
# tell GNU screen what the tab window title ($1) and the hardstatus($2) should be
function screen_set()
{
#  set the tab window title (%t) for screen
print -nR $'33k'$1$'33'\\\
 
# set hardstatus of tab window (%h) for screen
print -nR $'33]0;'$2$'\a'
}
# called by zsh before executing a command
function preexec()
{
local -a cmd; cmd=(${(z)1}) # the command string
eval "tab_title=$TAB_TITLE_PREFIX$TAB_TITLE_EXEC"
eval "tab_hardstatus=$TAB_HARDSTATUS_PREFIX$TAB_HARDSTATUS_EXEC"
screen_set $tab_title $tab_hardstatus
}
# called by zsh before showing the prompt
function precmd()
{
eval "tab_title=$TAB_TITLE_PREFIX$TAB_TITLE_PROMPT"
eval "tab_hardstatus=$TAB_HARDSTATUS_PREFIX$TAB_HARDSTATUS_PROMPT"
screen_set $tab_title $tab_hardstatus
}
fi

Bon avec ça, on a un joli screen, autant de windows qu’on veut dedans, mais si on nous « parle » sur l’irc et qu’on est sur un autre onglet on le voit pas trop …
J’ai donc fait le script suivant pour irssi qui permet de mettre à jour le nom de l’onglet screen en fonction de la derniere activité « highlightée » dans irssi.

use strict;
use vars qw($VERSION %IRSSI);
 
use Irssi 20011211;
$VERSION = "0.01";
%IRSSI = (
authors     => "Zmx",
contact     => "larouanne\@gmail.com",
name        => "Screen tab autorename",
description => "Change the screen tab name to the last HiLite information",
license     => "Public Domain",
url         => "http://zmx.cc/irssi/",
);
 
sub update_status {
my ($origitem, $oldstatus) = @_;
my $active = 0;
my $activeName = $origitem->{name};
if ($origitem->{data_level} != 3 ){
for my $window ( sort { $a->{refnum} <=> $b->{refnum} } Irssi::windows() ) {
 
for my $item ( $window->items() ) {
if ($item->{data_level} > 2 ){
$active = 1;
$activeName = $item->{name};
}
}
}
}else{
$active = 1;
}
if ($active) {
#  set the tab window title (%t) for screen
print STDERR "33k$activeName33\\";
}else{
print STDERR "33k" . Irssi::settings_get_str('screentitle') . "33\\";
}
}

On peut ainsi configurer le nom de l’onglet irssi « au repos » grâce à la commande /set screentitle <nom> dans irssi.

Author: Zmx

Tags: , ,

2 Comments

  • Enila dit :

    Sympa ce post, toujours utile de savoir faire tout ça quand on a pas un x-chat sous la main, ou quand on préfère les consoles qu’aux gui :).
    J’pourrais enfin voir irssi d’une autre façon =)

  • Zmx dit :

    Note pour certaine distrib.
    Il se peut que lorsque votre connexion coupe, irssi « perdent » ses connexion aussi.
    Pour résoudre ce soucis il faut ajouter la ligne:
    defnonblock on
    dans votre fichier .screenrc.irc (ou dans /etc/screenrc si vous voulez cette conf pour tous vos screen)

    Reference

Leave a Reply

XHTML: You can use these tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">