aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Kavanagh <rak@debian.org>2018-03-21 11:39:59 -0400
committerRyan Kavanagh <rak@debian.org>2018-03-21 11:51:13 -0400
commit8c0412269bd4a90145ec74cca00b337c571d3fb8 (patch)
tree52d9b34e77f4f0d00465a246b6af8f30395311c3
parentirssi (diff)
Update irssi config
-rw-r--r--.irssi/config11
-rw-r--r--.irssi/envy.theme2
-rw-r--r--.irssi/scripts/autoaway.pl133
l---------.irssi/scripts/autorun/autoaway.pl1
l---------.irssi/scripts/autorun/tmux_away.pl1
l---------.irssi/scripts/autorun/trackbar.pl1
l---------.irssi/scripts/autorun/trackbar22.pl1
-rw-r--r--.irssi/scripts/nickcolor.pl122
-rw-r--r--.irssi/scripts/old/nickcolor.pl.old145
-rw-r--r--.irssi/scripts/old/trackbar22.pl.old (renamed from .irssi/scripts/trackbar22.pl)0
-rw-r--r--.irssi/scripts/scriptassist.pl1229
-rw-r--r--.irssi/scripts/tmux_away.pl202
-rw-r--r--.irssi/scripts/trackbar.pl579
13 files changed, 2416 insertions, 11 deletions
diff --git a/.irssi/config b/.irssi/config
index a707392..78cb476 100644
--- a/.irssi/config
+++ b/.irssi/config
@@ -334,8 +334,9 @@ settings = {
twtopic_min_scroll = "no";
twtopic_ar_padding = "0";
twtopic_init_pause = "200";
- recdep_channels = "Freenode/ OFTC/";
+ recdep_channels = "Freenode/ OFTC/ snoonet/";
recdep_period = "3600";
+ autoaway_timeout = "300";
};
"irc/core" = { alternate_nick = "ryanakca_"; };
};
@@ -380,7 +381,13 @@ channels = (
autojoin = "yes";
},
{ name = "#sml"; chatnet = "Freenode"; autojoin = "yes"; },
- { name = "#personalfinance"; chatnet = "snoonet"; autojoin = "yes"; }
+ { name = "#personalfinance"; chatnet = "snoonet"; },
+ { name = "#debian-haskell"; chatnet = "OFTC"; autojoin = "yes"; },
+ { name = "#beer"; chatnet = "snoonet"; },
+ { name = "#canada"; chatnet = "snoonet"; },
+ { name = "#news"; chatnet = "snoonet"; autojoin = "yes"; },
+ { name = "#reddit"; chatnet = "snoonet"; autojoin = "yes"; },
+ { name = "#russian"; chatnet = "snoonet"; }
);
windows = {
1 = { immortal = "yes"; name = "(status)"; level = "ALL"; };
diff --git a/.irssi/envy.theme b/.irssi/envy.theme
index cef0c30..557ee02 100644
--- a/.irssi/envy.theme
+++ b/.irssi/envy.theme
@@ -304,7 +304,7 @@ formats = {
set_not_boolean = "%r:%K:: Setting {hilight $0} isn't boolean, use /SET";
translation_not_found = "%r:%K:: %rError%K opening translation table file $0: $1";
translation_file_error = "%r:%K:: %rError%K parsing translation table file $0";
- pubmsg = "{pubmsgnick $2 {pubnick \00313$0}}$1";
+ pubmsg = "{pubmsgnick $2 {pubnick \00311$[0]0}}$1";
};
"fe-common/irc/dcc" = {
dcc_list_header = "{line_start_irssi}{dcc DCC connections:}";
diff --git a/.irssi/scripts/autoaway.pl b/.irssi/scripts/autoaway.pl
new file mode 100644
index 0000000..ef3c485
--- /dev/null
+++ b/.irssi/scripts/autoaway.pl
@@ -0,0 +1,133 @@
+# /AUTOAWAY <n> - Mark user away after <n> seconds of inactivity
+# /AWAY - play nice with autoaway
+# New, brighter, whiter version of my autoaway script. Actually works :)
+# (c) 2000 Larry Daffner (vizzie@airmail.net)
+# You may freely use, modify and distribute this script, as long as
+# 1) you leave this notice intact
+# 2) you don't pretend my code is yours
+# 3) you don't pretend your code is mine
+#
+# share and enjoy!
+
+# A simple script. /autoaway <n> will mark you as away automatically if
+# you have not typed any commands in <n> seconds. (<n>=0 disables the feature)
+# It will also automatically unmark you away the next time you type a command.
+# Note that using the /away command will disable the autoaway mechanism, as
+# well as the autoreturn. (when you unmark yourself, the autoaway wil
+# restart again)
+
+# Thanks to Adam Monsen for multiserver and config file fix
+
+use strict;
+use Irssi;
+use Irssi::Irc;
+
+use vars qw($VERSION %IRSSI);
+$VERSION = "0.4";
+%IRSSI = (
+ authors => 'Larry "Vizzie" Daffner',
+ contact => 'vizzie@airmail.net',
+ name => 'Automagic away setting',
+ description => 'Automatically goes away after defined inactivity',
+ license => 'BSD',
+ url => 'http://www.flamingpackets.net/~vizzie/irssi/',
+ changed => 'Tue Apr 26 19:30:00 CDT 2016',
+ changes => 'Applied multiserver/store config patch from Adam Monsen'
+);
+
+my ($autoaway_sec, $autoaway_to_tag, $autoaway_state);
+$autoaway_state = 0;
+
+#
+# /AUTOAWAY - set the autoaway timeout
+#
+sub cmd_autoaway {
+ my ($data, $server, $channel) = @_;
+
+ if (!($data =~ /^[0-9]+$/)) {
+ Irssi::print("autoaway: usage: /autoaway <seconds>");
+ return 1;
+ }
+
+ $autoaway_sec = $data;
+
+ if ($autoaway_sec) {
+ Irssi::settings_set_int("autoaway_timeout", $autoaway_sec);
+ Irssi::print("autoaway timeout set to $autoaway_sec seconds");
+ } else {
+ Irssi::print("autoway disabled");
+ }
+
+ if (defined($autoaway_to_tag)) {
+ Irssi::timeout_remove($autoaway_to_tag);
+ $autoaway_to_tag = undef;
+ }
+
+ if ($autoaway_sec) {
+ $autoaway_to_tag =
+ Irssi::timeout_add($autoaway_sec*1000, "auto_timeout", "");
+ }
+}
+
+#
+# away = Set us away or back, within the autoaway system
+sub cmd_away {
+ my ($data, $server, $channel) = @_;
+
+ if ($data eq "") {
+ $autoaway_state = 0;
+ } else {
+ if ($autoaway_state eq 0) {
+ Irssi::timeout_remove($autoaway_to_tag);
+ $autoaway_to_tag = undef;
+ $autoaway_state = 2;
+ }
+ }
+}
+
+sub auto_timeout {
+ my ($data, $server) = @_;
+
+ # we're in the process.. don't touch anything.
+ $autoaway_state = 3;
+ foreach my $server (Irssi::servers()) {
+ $server->command("/AWAY autoaway after $autoaway_sec seconds");
+ }
+
+ Irssi::timeout_remove($autoaway_to_tag);
+ $autoaway_state = 1;
+}
+
+sub reset_timer {
+ if ($autoaway_state eq 1) {
+ $autoaway_state = 3;
+ foreach my $server (Irssi::servers()) {
+ $server->command("/AWAY");
+ }
+
+ $autoaway_state = 0;
+ }
+ if ($autoaway_state eq 0) {
+ if (defined($autoaway_to_tag)) {
+ Irssi::timeout_remove($autoaway_to_tag);
+ $autoaway_to_tag = undef();
+ }
+ if ($autoaway_sec) {
+ $autoaway_to_tag = Irssi::timeout_add($autoaway_sec*1000
+ , "auto_timeout", "");
+ }
+ }
+}
+
+Irssi::settings_add_int("misc", "autoaway_timeout", 0);
+
+my $autoaway_default = Irssi::settings_get_int("autoaway_timeout");
+if ($autoaway_default) {
+ $autoaway_to_tag =
+ Irssi::timeout_add($autoaway_default*1000, "auto_timeout", "");
+
+}
+
+Irssi::command_bind('autoaway', 'cmd_autoaway');
+Irssi::command_bind('away', 'cmd_away');
+Irssi::signal_add('send command', 'reset_timer');
diff --git a/.irssi/scripts/autorun/autoaway.pl b/.irssi/scripts/autorun/autoaway.pl
new file mode 120000
index 0000000..a6c9910
--- /dev/null
+++ b/.irssi/scripts/autorun/autoaway.pl
@@ -0,0 +1 @@
+../autoaway.pl \ No newline at end of file
diff --git a/.irssi/scripts/autorun/tmux_away.pl b/.irssi/scripts/autorun/tmux_away.pl
new file mode 120000
index 0000000..70df40e
--- /dev/null
+++ b/.irssi/scripts/autorun/tmux_away.pl
@@ -0,0 +1 @@
+../tmux_away.pl \ No newline at end of file
diff --git a/.irssi/scripts/autorun/trackbar.pl b/.irssi/scripts/autorun/trackbar.pl
new file mode 120000
index 0000000..8c5a483
--- /dev/null
+++ b/.irssi/scripts/autorun/trackbar.pl
@@ -0,0 +1 @@
+../trackbar.pl \ No newline at end of file
diff --git a/.irssi/scripts/autorun/trackbar22.pl b/.irssi/scripts/autorun/trackbar22.pl
deleted file mode 120000
index 09c98ff..0000000
--- a/.irssi/scripts/autorun/trackbar22.pl
+++ /dev/null
@@ -1 +0,0 @@
-../trackbar22.pl \ No newline at end of file
diff --git a/.irssi/scripts/nickcolor.pl b/.irssi/scripts/nickcolor.pl
index ff9915d..95b7b63 100644
--- a/.irssi/scripts/nickcolor.pl
+++ b/.irssi/scripts/nickcolor.pl
@@ -1,24 +1,36 @@
use strict;
use Irssi 20020101.0250 ();
-use vars qw($VERSION %IRSSI);
-$VERSION = "2";
+use vars qw($VERSION %IRSSI);
+$VERSION = "2.1";
%IRSSI = (
- authors => "Timo Sirainen, Ian Peters, David Leadbeater",
- contact => "tss\@iki.fi",
+ authors => "Timo Sirainen, Ian Peters, David Leadbeater, Bruno Cattáneo",
+ contact => "tss\@iki.fi",
name => "Nick Color",
description => "assign a different color for each nick",
license => "Public Domain",
url => "http://irssi.org/",
- changed => "Sun 15 Jun 19:10:44 BST 2014",
+ changed => "Mon 08 Jan 21:28:53 BST 2018",
);
# Settings:
# nickcolor_colors: List of color codes to use.
# e.g. /set nickcolor_colors 2 3 4 5 6 7 9 10 11 12 13
# (avoid 8, as used for hilights in the default theme).
+#
+# nickcolor_enable_prefix: Enables prefix for same nick.
+#
+# nickcolor_enable_truncate: Enables nick truncation.
+#
+# nickcolor_prefix_text: Prefix text for succesive messages.
+# e.g. /set nickcolor_prefix_text -
+#
+# nickcolor_truncate_value: Truncate nick value.
+# e.g. /set nickcolor_truncate_value -7
+# This will truncate nicknames at 7 characters and make them right aligned
my %saved_colors;
my %session_colors = {};
+my %saved_nicks; # To store each channel's last nickname
sub load_colors {
open my $color_fh, "<", "$ENV{HOME}/.irssi/saved_colors";
@@ -75,9 +87,21 @@ sub simple_hash {
return $counter;
}
+# process public (others) messages
sub sig_public {
my ($server, $msg, $nick, $address, $target) = @_;
+ my $enable_prefix = Irssi::settings_get_bool('nickcolor_enable_prefix');
+ my $enable_truncate = Irssi::settings_get_bool('nickcolor_enable_truncate');
+ my $prefix_text = Irssi::settings_get_str('nickcolor_prefix_text');
+ my $truncate_value = Irssi::settings_get_int('nickcolor_truncate_value');
+
+ # Reference for server/channel
+ my $tagtarget = "$server->{tag}/$target";
+
+ # Set default nick truncate value to 0 if option is disabled
+ $truncate_value = 0 if (!$enable_truncate);
+
# Has the user assigned this nick a color?
my $color = $saved_colors{$nick};
@@ -93,7 +117,84 @@ sub sig_public {
}
$color = sprintf "\003%02d", $color;
- $server->command('/^format pubmsg {pubmsgnick $2 {pubnick ' . $color . '$0}}$1');
+
+ # Optional: We check if it's the same nickname for current target
+ if ($saved_nicks{$tagtarget} eq $nick && $enable_prefix)
+ {
+ # Grouped message
+ Irssi::command('/^format pubmsg ' . $prefix_text . '$1');
+ }
+ else
+ {
+ # Normal message
+ Irssi::command('/^format pubmsg {pubmsgnick $2 {pubnick ' . $color . '$[' . $truncate_value . ']0}}$1');
+
+ # Save nickname for next message
+ $saved_nicks{$tagtarget} = $nick;
+ }
+
+}
+
+# process public (me) messages
+sub sig_me {
+ my ($server, $msg, $target) = @_;
+ my $nick = $server->{nick};
+
+ my $enable_prefix = Irssi::settings_get_bool('nickcolor_enable_prefix');
+ my $enable_truncate = Irssi::settings_get_bool('nickcolor_enable_truncate');
+ my $prefix_text = Irssi::settings_get_str('nickcolor_prefix_text');
+ my $truncate_value = Irssi::settings_get_int('nickcolor_truncate_value');
+
+ # Reference for server/channel
+ my $tagtarget = "$server->{tag}/$target";
+
+ # Set default nick truncate value to 0 if option is disabled
+ $truncate_value = 0 if (!$enable_truncate);
+
+ # Optional: We check if it's the same nickname for current target
+ if ($saved_nicks{$tagtarget} eq $nick && $enable_prefix)
+ {
+ # Grouped message
+ Irssi::command('/^format own_msg ' . $prefix_text . '$1');
+ }
+ else
+ {
+ # Normal message
+ Irssi::command('/^format own_msg {ownmsgnick $2 {ownnick $[' . $truncate_value . ']0}}$1');
+
+ # Save nickname for next message
+ $saved_nicks{$tagtarget} = $nick;
+ }
+
+}
+
+# process public (others) actions
+sub sig_action_public {
+ my ($server, $msg, $nick, $address, $target) = @_;
+
+ my $enable_prefix = Irssi::settings_get_bool('nickcolor_enable_prefix');
+
+ # Reference for server/channel
+ my $tagtarget = "$server->{tag}/$target";
+
+ # Empty current target nick if prefix option is enabled
+ $saved_nicks{$tagtarget} = '' if ($enable_prefix);
+
+}
+
+# process public (me) actions
+sub sig_action_me {
+ my ($server, $msg, $target) = @_;
+ my $nick = $server->{nick};
+
+ my $enable_prefix = Irssi::settings_get_bool('nickcolor_enable_prefix');
+
+ # Reference for server/channel
+ my $tagtarget = "$server->{tag}/$target";
+
+ # Empty current target nick if prefix option is enabled
+ $saved_nicks{$tagtarget} = '' if ($enable_prefix);
+
}
sub cmd_color {
@@ -125,7 +226,7 @@ sub cmd_color {
} elsif ($op eq "list") {
Irssi::print ("\nSaved Colors:");
foreach my $nick (keys %saved_colors) {
- Irssi::print (chr (3) . "$saved_colors{$nick}$nick" .
+ Irssi::print (chr (3) . sprintf("%02d", $saved_colors{$nick}) . "$nick" .
chr (3) . "1 ($saved_colors{$nick})");
}
} elsif ($op eq "preview") {
@@ -139,7 +240,14 @@ sub cmd_color {
load_colors;
Irssi::settings_add_str('misc', 'nickcolor_colors', '2 3 4 5 6 7 9 10 11 12 13');
+Irssi::settings_add_bool('misc', 'nickcolor_enable_prefix', 0);
+Irssi::settings_add_bool('misc', 'nickcolor_enable_truncate', 0);
+Irssi::settings_add_str('misc', 'nickcolor_prefix_text' => '- ');
+Irssi::settings_add_int('misc', 'nickcolor_truncate_value' => 0);
Irssi::command_bind('color', 'cmd_color');
Irssi::signal_add('message public', 'sig_public');
+Irssi::signal_add('message own_public', 'sig_me');
+Irssi::signal_add('message irc action', 'sig_action_public');
+Irssi::signal_add('message irc own_action', 'sig_action_me');
Irssi::signal_add('event nick', 'sig_nick');
diff --git a/.irssi/scripts/old/nickcolor.pl.old b/.irssi/scripts/old/nickcolor.pl.old
new file mode 100644
index 0000000..ff9915d
--- /dev/null
+++ b/.irssi/scripts/old/nickcolor.pl.old
@@ -0,0 +1,145 @@
+use strict;
+use Irssi 20020101.0250 ();
+use vars qw($VERSION %IRSSI);
+$VERSION = "2";
+%IRSSI = (
+ authors => "Timo Sirainen, Ian Peters, David Leadbeater",
+ contact => "tss\@iki.fi",
+ name => "Nick Color",
+ description => "assign a different color for each nick",
+ license => "Public Domain",
+ url => "http://irssi.org/",
+ changed => "Sun 15 Jun 19:10:44 BST 2014",
+);
+
+# Settings:
+# nickcolor_colors: List of color codes to use.
+# e.g. /set nickcolor_colors 2 3 4 5 6 7 9 10 11 12 13
+# (avoid 8, as used for hilights in the default theme).
+
+my %saved_colors;
+my %session_colors = {};
+
+sub load_colors {
+ open my $color_fh, "<", "$ENV{HOME}/.irssi/saved_colors";
+ while (<$color_fh>) {
+ chomp;
+ my($nick, $color) = split ":";
+ $saved_colors{$nick} = $color;
+ }
+}
+
+sub save_colors {
+ open COLORS, ">", "$ENV{HOME}/.irssi/saved_colors";
+
+ foreach my $nick (keys %saved_colors) {
+ print COLORS "$nick:$saved_colors{$nick}\n";
+ }
+
+ close COLORS;
+}
+
+# If someone we've colored (either through the saved colors, or the hash
+# function) changes their nick, we'd like to keep the same color associated
+# with them (but only in the session_colors, ie a temporary mapping).
+
+sub sig_nick {
+ my ($server, $newnick, $nick, $address) = @_;
+ my $color;
+
+ $newnick = substr ($newnick, 1) if ($newnick =~ /^:/);
+
+ if ($color = $saved_colors{$nick}) {
+ $session_colors{$newnick} = $color;
+ } elsif ($color = $session_colors{$nick}) {
+ $session_colors{$newnick} = $color;
+ }
+}
+
+# This gave reasonable distribution values when run across
+# /usr/share/dict/words
+
+sub simple_hash {
+ my ($string) = @_;
+ chomp $string;
+ my @chars = split //, $string;
+ my $counter;
+
+ foreach my $char (@chars) {
+ $counter += ord $char;
+ }
+
+ my @colors = split / /, Irssi::settings_get_str('nickcolor_colors');
+ $counter = $colors[$counter % @colors];
+
+ return $counter;
+}
+
+sub sig_public {
+ my ($server, $msg, $nick, $address, $target) = @_;
+
+ # Has the user assigned this nick a color?
+ my $color = $saved_colors{$nick};
+
+ # Have -we- already assigned this nick a color?
+ if (!$color) {
+ $color = $session_colors{$nick};
+ }
+
+ # Let's assign this nick a color
+ if (!$color) {
+ $color = simple_hash $nick;
+ $session_colors{$nick} = $color;
+ }
+
+ $color = sprintf "\003%02d", $color;
+ $server->command('/^format pubmsg {pubmsgnick $2 {pubnick ' . $color . '$0}}$1');
+}
+
+sub cmd_color {
+ my ($data, $server, $witem) = @_;
+ my ($op, $nick, $color) = split " ", $data;
+
+ $op = lc $op;
+
+ if (!$op) {
+ Irssi::print ("No operation given (save/set/clear/list/preview)");
+ } elsif ($op eq "save") {
+ save_colors;
+ } elsif ($op eq "set") {
+ if (!$nick) {
+ Irssi::print ("Nick not given");
+ } elsif (!$color) {
+ Irssi::print ("Color not given");
+ } elsif ($color < 2 || $color > 14) {
+ Irssi::print ("Color must be between 2 and 14 inclusive");
+ } else {
+ $saved_colors{$nick} = $color;
+ }
+ } elsif ($op eq "clear") {
+ if (!$nick) {
+ Irssi::print ("Nick not given");
+ } else {
+ delete ($saved_colors{$nick});
+ }
+ } elsif ($op eq "list") {
+ Irssi::print ("\nSaved Colors:");
+ foreach my $nick (keys %saved_colors) {
+ Irssi::print (chr (3) . "$saved_colors{$nick}$nick" .
+ chr (3) . "1 ($saved_colors{$nick})");
+ }
+ } elsif ($op eq "preview") {
+ Irssi::print ("\nAvailable colors:");
+ foreach my $i (2..14) {
+ Irssi::print (chr (3) . "$i" . "Color #$i");
+ }
+ }
+}
+
+load_colors;
+
+Irssi::settings_add_str('misc', 'nickcolor_colors', '2 3 4 5 6 7 9 10 11 12 13');
+Irssi::command_bind('color', 'cmd_color');
+
+Irssi::signal_add('message public', 'sig_public');
+Irssi::signal_add('event nick', 'sig_nick');
diff --git a/.irssi/scripts/trackbar22.pl b/.irssi/scripts/old/trackbar22.pl.old
index 0d10882..0d10882 100644
--- a/.irssi/scripts/trackbar22.pl
+++ b/.irssi/scripts/old/trackbar22.pl.old
diff --git a/.irssi/scripts/scriptassist.pl b/.irssi/scripts/scriptassist.pl
new file mode 100644
index 0000000..6870894
--- /dev/null
+++ b/.irssi/scripts/scriptassist.pl
@@ -0,0 +1,1229 @@
+# by Stefan "tommie" Tomanek
+#
+# scriptassist.pl
+
+
+use strict;
+
+our $VERSION = '2003020806';
+our %IRSSI = (
+ authors => 'Stefan \'tommie\' Tomanek',
+ contact => 'stefan@pico.ruhr.de',
+ name => 'scriptassist',
+ description => 'keeps your scripts on the cutting edge',
+ license => 'GPLv2',
+ url => 'http://irssi.org/scripts/',
+ modules => 'Data::Dumper LWP::UserAgent (GnuPG)',
+ commands => "scriptassist"
+);
+
+our ($forked, %remote_db, $have_gpg, @complist);
+
+use Irssi 20020324;
+use Data::Dumper;
+use LWP::UserAgent;
+use POSIX;
+
+# GnuPG is not always needed
+$have_gpg = 0;
+eval "use GnuPG qw(:algo :trust);";
+$have_gpg = 1 if not ($@);
+
+sub show_help {
+ my $help = "scriptassist $VERSION
+/scriptassist check
+ Check all loaded scripts for new available versions
+/scriptassist update <script|all>
+ Update the selected or all script to the newest version
+/scriptassist search <query>
+ Search the script database
+/scriptassist info <scripts>
+ Display information about <scripts>
+".#/scriptassist ratings <scripts>
+# Retrieve the average ratings of the the scripts
+#/scriptassist top <num>
+# Retrieve the first <num> top rated scripts
+"/scriptassist new <num>
+ Display the newest <num> scripts
+".#/scriptassist rate <script> <stars>
+# Rate the script with a number of stars ranging from 0-5
+"/scriptassist contact <script>
+ Write an email to the author of the script
+ (Requires OpenURL)
+/scriptassist cpan <module>
+ Visit CPAN to look for missing Perl modules
+ (Requires OpenURL)
+/scriptassist install <script>
+ Retrieve and load the script
+/scriptassist autorun <script>
+ Toggles automatic loading of <script>
+";
+ my $text='';
+ foreach (split(/\n/, $help)) {
+ $_ =~ s/^\/(.*)$/%9\/$1%9/;
+ $text .= $_."\n";
+ }
+ print CLIENTCRAP &draw_box("ScriptAssist", $text, "scriptassist help", 1);
+ #theme_box("ScriptAssist", $text, "scriptassist help", 1);
+}
+
+sub theme_box {
+ my ($title, $text, $footer, $colour) = @_;
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'box_header', $title);
+ foreach (split(/\n/, $text)) {
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'box_inside', $_);
+ }
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'box_footer', $footer);
+}
+
+sub draw_box {
+ my ($title, $text, $footer, $colour) = @_;
+ my $box = '';
+ $box .= '%R,--[%n%9%U'.$title.'%U%9%R]%n'."\n";
+ foreach (split(/\n/, $text)) {
+ $box .= '%R|%n '.$_."\n";
+ }
+ $box .= '%R`--<%n'.$footer.'%R>->%n';
+ $box =~ s/%.//g unless $colour;
+ return $box;
+}
+
+sub call_openurl {
+ my ($url) = @_;
+ # check for a loaded openurl
+ if (my $code = Irssi::Script::openurl::->can('launch_url')) {
+ $code->($url);
+ } else {
+ print CLIENTCRAP "%R>>%n Please install openurl.pl";
+ }
+}
+
+sub bg_do {
+ my ($func) = @_;
+ my ($rh, $wh);
+ pipe($rh, $wh);
+ if ($forked) {
+ print CLIENTCRAP "%R>>%n Please wait until your earlier request has been finished.";
+ return;
+ }
+ my $pid = fork();
+ $forked = 1;
+ if ($pid > 0) {
+ print CLIENTCRAP "%R>>%n Please wait...";
+ close $wh;
+ Irssi::pidwait_add($pid);
+ my $pipetag;
+ my @args = ($rh, \$pipetag, $func);
+ $pipetag = Irssi::input_add(fileno($rh), INPUT_READ, \&pipe_input, \@args);
+ } else {
+ eval {
+ my @items = split(/ /, $func);
+ my %result;
+ my $ts1 = $remote_db{timestamp};
+ my $xml = get_scripts();
+ my $ts2 = $remote_db{timestamp};
+ if (not($ts1 eq $ts2) && Irssi::settings_get_bool('scriptassist_cache_sources')) {
+ $result{db} = $remote_db{db};
+ $result{timestamp} = $remote_db{timestamp};
+ }
+ if ($items[0] eq 'check') {
+ $result{data}{check} = check_scripts($xml);
+ } elsif ($items[0] eq 'update') {
+ shift(@items);
+ $result{data}{update} = update_scripts(\@items, $xml);
+ } elsif ($items[0] eq 'search') {
+ shift(@items);
+ foreach (@items) {
+ $result{data}{search}{$_} = search_scripts($_, $xml);
+ }
+ } elsif ($items[0] eq 'install') {
+ shift(@items);
+ $result{data}{install} = install_scripts(\@items, $xml);
+ } elsif ($items[0] eq 'debug') {
+ shift(@items);
+ $result{data}{debug} = debug_scripts(\@items);
+ } elsif ($items[0] eq 'ratings') {
+ shift(@items);
+ @items = @{ loaded_scripts() } if $items[0] eq "all";
+ my %ratings = %{ get_ratings(\@items, '') };
+ foreach (keys %ratings) {
+ $result{data}{rating}{$_}{rating} = $ratings{$_}->[0];
+ $result{data}{rating}{$_}{votes} = $ratings{$_}->[1];
+ }
+ } elsif ($items[0] eq 'rate') {
+ $result{data}{rate}{$items[1]} = rate_script($items[1], $items[2]);
+ } elsif ($items[0] eq 'info') {
+ shift(@items);
+ $result{data}{info} = script_info(\@items);
+ } elsif ($items[0] eq 'echo') {
+ $result{data}{echo} = 1;
+ } elsif ($items[0] eq 'top') {
+ my %ratings = %{ get_ratings([], $items[1]) };
+ foreach (keys %ratings) {
+ $result{data}{rating}{$_}{rating} = $ratings{$_}->[0];
+ $result{data}{rating}{$_}{votes} = $ratings{$_}->[1];
+ }
+ } elsif ($items[0] eq 'new') {
+ my $new = get_new($items[1]);
+ $result{data}{new} = $new;
+ } elsif ($items[0] eq 'unknown') {
+ my $cmd = $items[1];
+ $result{data}{unknown}{$cmd} = get_unknown($cmd, $xml);
+ }
+ my $dumper = Data::Dumper->new([\%result]);
+ $dumper->Purity(1)->Deepcopy(1)->Indent(0);
+ my $data = $dumper->Dump;
+ print($wh $data);
+ };
+ if ($@) {
+ print($wh Data::Dumper->new([+{data=>+{error=>$@}}])
+ ->Purity(1)->Deepcopy(1)->Indent(0)->Dump);
+ }
+ close($wh);
+ POSIX::_exit(1);
+ }
+}
+
+sub get_unknown {
+ my ($cmd, $db) = @_;
+ foreach (keys %$db) {
+ next unless defined $db->{$_}{commands};
+ foreach my $item (split / /, $db->{$_}{commands}) {
+ return { $_ => $db->{$_} } if ($item =~ /^$cmd$/i);
+ }
+ }
+ return undef;
+}
+
+sub get_names {
+ my ($sname, $db) = shift;
+ $sname =~ s/\s+$//;
+ $sname =~ s/\.pl$//;
+ my $plname = "$sname.pl";
+ $sname =~ s/^.*\///;
+ my $xname = $sname;
+ $xname =~ s/\W/_/g;
+ my $pname = "${xname}::";
+ if ($xname ne $sname || $sname =~ /_/) {
+ my $dir = Irssi::get_irssi_dir()."/scripts/";
+ if ($db && exists $db->{"$sname.pl"}) {
+ # $found = 1;
+ } elsif (-e $dir.$plname || -e $dir."$sname.pl" || -e $dir."autorun/$sname.pl") {
+ # $found = 1;
+ } else {
+ # not found
+ my $pat = $xname; $pat =~ y/_/?/;
+ my $re = "\Q$xname"; $re =~ s/\Q_/./g;
+ if ($db) {
+ my ($cand) = grep /^$re\.pl$/, sort keys %$db;
+ if ($cand) {
+ return get_names($cand, $db);
+ }
+ }
+ my ($cand) = glob "'$dir$pat.pl' '${dir}autorun/$pat.pl'";
+ if ($cand) {
+ $cand =~ s/^.*\///;
+ return get_names($cand, $db);
+ }
+ }
+ }
+ ($sname, $plname, $pname, $xname)
+}
+
+sub script_info {
+ my ($scripts) = @_;
+ my %result;
+ my $xml = get_scripts();
+ foreach (@{$scripts}) {
+ my ($sname, $plname, $pname) = get_names($_, $xml);
+ next unless (defined $xml->{$plname} || ( exists $Irssi::Script::{$pname} && exists $Irssi::Script::{$pname}{IRSSI} ));
+ $result{$sname}{version} = get_remote_version($sname, $xml);
+ my @headers = ('authors', 'contact', 'description', 'license', 'source');
+ foreach my $entry (@headers) {
+ $result{$sname}{$entry} = $Irssi::Script::{$pname}{IRSSI}{$entry};
+ if (defined $xml->{$plname}{$entry}) {
+ $result{$sname}{$entry} = $xml->{$plname}{$entry};
+ }
+ }
+ if ($xml->{$plname}{signature_available}) {
+ $result{$sname}{signature_available} = 1;
+ }
+ if (defined $xml->{$plname}{modules}) {
+ my $modules = $xml->{$plname}{modules};
+ foreach my $mod (split(/ /, $modules)) {
+ my $opt = ($mod =~ /\((.*)\)/)? 1 : 0;
+ $mod = $1 if $1;
+ $result{$sname}{modules}{$mod}{optional} = $opt;
+ $result{$sname}{modules}{$mod}{installed} = module_exist($mod);
+ }
+ } elsif (defined $Irssi::Script::{$pname}{IRSSI}{modules}) {
+ my $modules = $Irssi::Script::{$pname}{IRSSI}{modules};
+ foreach my $mod (split(/ /, $modules)) {
+ my $opt = ($mod =~ /\((.*)\)/)? 1 : 0;
+ $mod = $1 if $1;
+ $result{$sname}{modules}{$mod}{optional} = $opt;
+ $result{$sname}{modules}{$mod}{installed} = module_exist($mod);
+ }
+ }
+ if (defined $xml->{$plname}{depends}) {
+ my $depends = $xml->{$plname}{depends};
+ foreach my $dep (split(/ /, $depends)) {
+ $result{$sname}{depends}{$dep}{installed} = 1;
+ }
+ }
+ }
+ return \%result;
+}
+
+sub rate_script {
+ my ($script, $stars) = @_;
+ my $ua = LWP::UserAgent->new(env_proxy=>1, keep_alive=>1, timeout=>30);
+ $ua->agent('ScriptAssist/'.2003020803);
+ my $request = HTTP::Request->new('GET', 'http://ratings.irssi.de/irssirate.pl?&stars='.$stars.'&mode=rate&script='.$script);
+ my $response = $ua->request($request);
+ unless ($response->is_success() && $response->content() =~ /You already rated this script/) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+sub get_ratings {
+ my ($scripts, $limit) = @_;
+ my $ua = LWP::UserAgent->new(env_proxy=>1, keep_alive=>1, timeout=>30);
+ $ua->agent('ScriptAssist/'.2003020803);
+ my $script = join(',', @{$scripts});
+ my $request = HTTP::Request->new('GET', 'http://ratings.irssi.de/irssirate.pl?script='.$script.'&sort=rating&limit='.$limit);
+ my $response = $ua->request($request);
+ my %result;
+ if ($response->is_success()) {
+ foreach (split /\n/, $response->content()) {
+ if (/<tr><td><a href=".*?">(.*?)<\/a>/) {
+ my $entry = $1;
+ if (/"><\/td><td>([0-9.]+)<\/td><td>(.*?)<\/td><td>/) {
+ $result{$entry} = [$1, $2];
+ }
+ }
+ }
+ }
+ return \%result;
+}
+
+sub get_new {
+ my ($num) = @_;
+ my $result;
+ my $xml = get_scripts();
+ foreach (sort {$xml->{$b}{last_modified} cmp $xml->{$a}{last_modified}} keys %$xml) {
+ my %entry = %{ $xml->{$_} };
+ next if $entry{HIDDEN};
+ $result->{$_} = \%entry;
+ $num--;
+ last unless $num;
+ }
+ return $result;
+}
+sub module_exist {
+ my ($module) = @_;
+ $module =~ s/::/\//g;
+ foreach (@INC) {
+ return 1 if (-e $_."/".$module.".pm");
+ }
+ return 0;
+}
+
+sub debug_scripts {
+ my ($scripts) = @_;
+ my %result;
+ my $xml = get_scripts();
+ foreach (@{$scripts}) {
+ my ($sname, $plname) = get_names($_, $xml);
+ if (defined $xml->{$plname}{modules}) {
+ my $modules = $xml->{$plname}{modules};
+ foreach my $mod (split(/ /, $modules)) {
+ my $opt = ($mod =~ /\((.*)\)/)? 1 : 0;
+ $mod = $1 if $1;
+ $result{$sname}{$mod}{optional} = $opt;
+ $result{$sname}{$mod}{installed} = module_exist($mod);
+ }
+ }
+ }
+ return(\%result);
+}
+
+sub install_scripts {
+ my ($scripts, $xml) = @_;
+ my %success;
+ my $dir = Irssi::get_irssi_dir()."/scripts/";
+ foreach (@{$scripts}) {
+ my ($sname, $plname, $pname) = get_names($_, $xml);
+ if (get_local_version($sname) && (-e $dir.$plname)) {
+ $success{$sname}{installed} = -2;
+ } else {
+ $success{$sname} = download_script($sname, $xml);
+ }
+ }
+ return \%success;
+}
+
+sub update_scripts {
+ my ($list, $database) = @_;
+ $list = loaded_scripts() if ($list->[0] eq "all" || scalar(@$list) == 0);
+ my %status;
+ foreach (@{$list}) {
+ my ($sname) = get_names($_, $database);
+ my $local = get_local_version($sname);
+ my $remote = get_remote_version($sname, $database);
+ next if $local eq '' || $remote eq '';
+ if (compare_versions($local, $remote) eq "older") {
+ $status{$sname} = download_script($sname, $database);
+ } else {
+ $status{$sname}{installed} = -2;
+ }
+ $status{$sname}{remote} = $remote;
+ $status{$sname}{local} = $local;
+ }
+ return \%status;
+}
+
+sub search_scripts {
+ my ($query, $database) = @_;
+ $query =~ s/\.pl\Z//;
+ my %result;
+ foreach (sort keys %{$database}) {
+ my %entry = %{$database->{$_}};
+ next if $entry{HIDDEN};
+ my $string = $_." ";
+ $string .= $entry{description} if defined $entry{description};
+ if ($string =~ /$query/i) {
+ my $name = $_;
+ $name =~ s/\.pl$//;
+ if (defined $entry{description}) {
+ $result{$name}{desc} = $entry{description};
+ } else {
+ $result{$name}{desc} = "";
+ }
+ if (defined $entry{authors}) {
+ $result{$name}{authors} = $entry{authors};
+ } else {
+ $result{$name}{authors} = "";
+ }
+ if (get_local_version($name)) {
+ $result{$name}{installed} = 1;
+ } else {
+ $result{$name}{installed} = 0;
+ }
+ }
+ }
+ return \%result;
+}
+
+sub pipe_input {
+ my ($rh, $pipetag) = @{$_[0]};
+ my $text = do { local $/; <$rh>; };
+ close($rh);
+ Irssi::input_remove($$pipetag);
+ $forked = 0;
+ unless ($text) {
+ print CLIENTCRAP "%R<<%n Something weird happend (no text)";
+ return();
+ }
+ local our $VAR1;
+ my $incoming = eval($text);
+ if ($incoming->{db} && $incoming->{timestamp}) {
+ $remote_db{db} = $incoming->{db};
+ $remote_db{timestamp} = $incoming->{timestamp};
+ }
+ unless (defined $incoming->{data}) {
+ print CLIENTCRAP "%R<<%n Something weird happend (no data)";
+ return;
+ }
+ my %result = %{ $incoming->{data} };
+ @complist = ();
+ if (defined $result{new}) {
+ print_new($result{new});
+ push @complist, $_ foreach keys %{ $result{new} };
+ }
+ if (defined $result{check}) {
+ print_check(%{$result{check}});
+ push @complist, $_ foreach keys %{ $result{check} };
+ }
+ if (defined $result{update}) {
+ print_update(%{ $result{update} });
+ push @complist, $_ foreach keys %{ $result{update} };
+ }
+ if (defined $result{search}) {
+ foreach (keys %{$result{search}}) {
+ print_search($_, %{$result{search}{$_}});
+ push @complist, keys(%{$result{search}{$_}});
+ }
+ }
+ if (defined $result{install}) {
+ print_install(%{ $result{install} });
+ push @complist, $_ foreach keys %{ $result{install} };
+ }
+ if (defined $result{debug}) {
+ print_debug(%{ $result{debug} });
+ }
+ if (defined $result{rating}) {
+ print_ratings(%{ $result{rating} });
+ push @complist, $_ foreach keys %{ $result{rating} };
+ }
+ if (defined $result{rate}) {
+ print_rate(%{ $result{rate} });
+ }
+ if (defined $result{info}) {
+ print_info(%{ $result{info} });
+ }
+ if (defined $result{echo}) {
+ Irssi::print "ECHO";
+ }
+ if ($result{unknown}) {
+ print_unknown($result{unknown});
+ }
+ if (defined $result{error}) {
+ print CLIENTCRAP "%R<<%n There was an error in background processing:"; chomp($result{error});
+ print CLIENTERROR $result{error};
+ }
+
+}
+
+sub print_unknown {
+ my ($data) = @_;
+ foreach my $cmd (keys %$data) {
+ print CLIENTCRAP "%R<<%n No script provides '/$cmd'" unless $data->{$cmd};
+ foreach (keys %{ $data->{$cmd} }) {
+ my $text .= "The command '/".$cmd."' is provided by the script '".$data->{$cmd}{$_}{name}."'.\n";
+ $text .= "This script is currently not installed on your system.\n";
+ $text .= "If you want to install the script, enter\n";
+ my ($name) = get_names($_);
+ $text .= " %U/script install ".$name."%U ";
+ my $output = draw_box("ScriptAssist", $text, "'".$_."' missing", 1);
+ print CLIENTCRAP $output;
+ }
+ }
+}
+
+sub check_autorun {
+ my ($script) = @_;
+ my (undef, $plname) = get_names($script);
+ my $dir = Irssi::get_irssi_dir()."/scripts/";
+ if (-e $dir."/autorun/".$plname) {
+ if (readlink($dir."/autorun/".$plname) eq "../".$plname) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+sub array2table {
+ my (@array) = @_;
+ my @width;
+ foreach my $line (@array) {
+ for (0..scalar(@$line)-1) {
+ my $l = $line->[$_];
+ $l =~ s/%[^%]//g;
+ $l =~ s/%%/%/g;
+ $width[$_] = length($l) if $width[$_]<length($l);
+ }
+ }
+ my $text;
+ foreach my $line (@array) {
+ for (0..scalar(@$line)-1) {
+ my $l = $line->[$_];
+ $text .= $line->[$_];
+ $l =~ s/%[^%]//g;
+ $l =~ s/%%/%/g;
+ $text .= " "x($width[$_]-length($l)+1) unless ($_ == scalar(@$line)-1);
+ }
+ $text .= "\n";
+ }
+ return $text;
+}
+
+
+sub print_info {
+ my (%data) = @_;
+ my $line;
+ foreach my $script (sort keys(%data)) {
+ my ($local, $autorun);
+ if (get_local_version($script)) {
+ $line .= "%go%n ";
+ $local = get_local_version($script);
+ } else {
+ $line .= "%ro%n ";
+ $local = undef;
+ }
+ if (defined $local || check_autorun($script)) {
+ $autorun = "no";
+ $autorun = "yes" if check_autorun($script);
+ } else {
+ $autorun = undef;
+ }
+ $line .= "%9".$script."%9\n";
+ $line .= " Version : ".$data{$script}{version}."\n";
+ $line .= " Source : ".$data{$script}{source}."\n";
+ $line .= " Installed : ".$local."\n" if defined $local;
+ $line .= " Autorun : ".$autorun."\n" if defined $autorun;
+ $line .= " Authors : ".$data{$script}{authors};
+ $line .= " %Go-m signed%n" if $data{$script}{signature_available};
+ $line .= "\n";
+ $line .= " Contact : ".$data{$script}{contact}."\n";
+ $line .= " Description: ".$data{$script}{description}."\n";
+ $line .= "\n" if $data{$script}{modules};
+ $line .= " Needed Perl modules:\n" if $data{$script}{modules};
+
+ foreach (sort keys %{$data{$script}{modules}}) {
+ if ( $data{$script}{modules}{$_}{installed} == 1 ) {
+ $line .= " %g->%n ".$_." (found)";
+ } else {
+ $line .= " %r->%n ".$_." (not found)";
+ }
+ $line .= " <optional>" if $data{$script}{modules}{$_}{optional};
+ $line .= "\n";
+ }
+ $line .= " Needed Irssi Scripts:\n" if $data{$script}{depends};
+ foreach (sort keys %{$data{$script}{depends}}) {
+ if ( $data{$script}{depends}{$_}{installed} == 1 ) {
+ $line .= " %g->%n ".$_." (loaded)";
+ } else {
+ $line .= " %r->%n ".$_." (not loaded)";
+ }
+ $line .= "\n";
+ }
+ }
+ print CLIENTCRAP draw_box('ScriptAssist', $line, 'info', 1) ;
+}
+
+sub print_rate {
+ my (%data) = @_;
+ my $line;
+ foreach my $script (sort keys(%data)) {
+ if ($data{$script}) {
+ $line .= "%go%n %9".$script."%9 has been rated";
+ } else {
+ $line .= "%ro%n %9".$script."%9 : Already rated this script";
+ }
+ }
+ print CLIENTCRAP draw_box('ScriptAssist', $line, 'rating', 1) ;
+}
+
+sub print_ratings {
+ my (%data) = @_;
+ my @table;
+ foreach my $script (sort {$data{$b}{rating}<=>$data{$a}{rating}} keys(%data)) {
+ my @line;
+ if (get_local_version($script)) {
+ push @line, "%go%n";
+ } else {
+ push @line, "%yo%n";
+ }
+ push @line, "%9".$script."%9";
+ push @line, $data{$script}{rating};
+ push @line, "[".$data{$script}{votes}." votes]";
+ push @table, \@line;
+ }
+ print CLIENTCRAP draw_box('ScriptAssist', array2table(@table), 'ratings', 1) ;
+}
+
+sub print_new {
+ my ($list) = @_;
+ my @table;
+ foreach (sort {$list->{$b}{last_modified} cmp $list->{$a}{last_modified}} keys %$list) {
+ my @line;
+ my ($name) = get_names($_);
+ if (get_local_version($name)) {
+ push @line, "%go%n";
+ } else {
+ push @line, "%yo%n";
+ }
+ push @line, "%9".$name."%9";
+ push @line, $list->{$_}{last_modified};
+ push @table, \@line;
+ }
+ print CLIENTCRAP draw_box('ScriptAssist', array2table(@table), 'new scripts', 1) ;
+}
+
+sub print_debug {
+ my (%data) = @_;
+ my $line;
+ foreach my $script (sort keys %data) {
+ $line .= "%ro%n %9".$script."%9 failed to load\n";
+ $line .= " Make sure you have the following perl modules installed:\n";
+ foreach (sort keys %{$data{$script}}) {
+ if ( $data{$script}{$_}{installed} == 1 ) {
+ $line .= " %g->%n ".$_." (found)";
+ } else {
+ $line .= " %r->%n ".$_." (not found)\n";
+ $line .= " [This module is optional]\n" if $data{$script}{$_}{optional};
+ $line .= " [Try /scriptassist cpan ".$_."]";
+ }
+ $line .= "\n";
+ }
+ print CLIENTCRAP draw_box('ScriptAssist', $line, 'debug', 1) ;
+ }
+}
+
+sub load_script {
+ my ($script) = @_;
+ Irssi::command('script load '.$script);
+}
+
+sub print_install {
+ my (%data) = @_;
+ my $text;
+ my ($crashed, @installed);
+ foreach my $script (sort keys %data) {
+ my $line;
+ if ($data{$script}{installed} == 1) {
+ my $hacked;
+ if ($have_gpg && Irssi::settings_get_bool('scriptassist_use_gpg')) {
+ if ($data{$script}{signed} >= 0) {
+ load_script($script) unless (lc($script) eq lc($IRSSI{name}));
+ } else {
+ $hacked = 1;
+ }
+ } else {
+ load_script($script) unless (lc($script) eq lc($IRSSI{name}));
+ }
+ if (get_local_version($script) && not lc($script) eq lc($IRSSI{name})) {
+ $line .= "%go%n %9".$script."%9 installed\n";
+ push @installed, $script;
+ } elsif (lc($script) eq lc($IRSSI{name})) {
+ $line .= "%yo%n %9".$script."%9 installed, please reload manually\n";
+ } else {
+ $line .= "%Ro%n %9".$script."%9 fetched, but unable to load\n";
+ $crashed .= $script." " unless $hacked;
+ }
+ if ($have_gpg && Irssi::settings_get_bool('scriptassist_use_gpg')) {
+ foreach (split /\n/, check_sig($data{$script})) {
+ $line .= " ".$_."\n";
+ }
+ }
+ } elsif ($data{$script}{installed} == -2) {
+ $line .= "%ro%n %9".$script."%9 already loaded, please try \"update\"\n";
+ } elsif ($data{$script}{installed} <= 0) {
+ $line .= "%ro%n %9".$script."%9 not installed\n";
+ foreach (split /\n/, check_sig($data{$script})) {
+ $line .= " ".$_."\n";
+ }
+ } else {
+ $line .= "%Ro%n %9".$script."%9 not found on server\n";
+ }
+ $text .= $line;
+ }
+ # Inspect crashed scripts
+ bg_do("debug ".$crashed) if $crashed;
+ print CLIENTCRAP draw_box('ScriptAssist', $text, 'install', 1);
+ list_sbitems(\@installed);
+}
+
+sub list_sbitems {
+ my ($scripts) = @_;
+ my $text;
+ foreach (@$scripts) {
+ next unless exists $Irssi::Script::{"${_}::"};
+ next unless exists $Irssi::Script::{"${_}::"}{IRSSI};
+ my $header = $Irssi::Script::{"${_}::"}{IRSSI};
+ next unless $header->{sbitems};
+ $text .= '%9"'.$_.'"%9 provides the following statusbar item(s):'."\n";
+ $text .= ' ->'.$_."\n" foreach (split / /, $header->{sbitems});
+ }
+ return unless $text;
+ $text .= "\n";
+ $text .= "Enter '/statusbar window add <item>' to add an item.";
+ print CLIENTCRAP draw_box('ScriptAssist', $text, 'sbitems', 1);
+}
+
+sub check_sig {
+ my ($sig) = @_;
+ my $line;
+ my %trust = ( -1 => 'undefined',
+ 0 => 'never',
+ 1 => 'marginal',
+ 2 => 'fully',
+ 3 => 'ultimate'
+ );
+ if ($sig->{signed} == 1) {
+ $line .= "Signature found from ".$sig->{sig}{user}."\n";
+ $line .= "Timestamp : ".$sig->{sig}{date}."\n";
+ $line .= "Fingerprint: ".$sig->{sig}{fingerprint}."\n";
+ $line .= "KeyID : ".$sig->{sig}{keyid}."\n";
+ $line .= "Trust : ".$trust{$sig->{sig}{trust}}."\n";
+ } elsif ($sig->{signed} == -1) {
+ $line .= "%1Warning, unable to verify signature%n\n";
+ } elsif ($sig->{signed} == 0) {
+ $line .= "%1No signature found%n\n" unless Irssi::settings_get_bool('scriptassist_install_unsigned_scripts');
+ }
+ return $line;
+}
+
+sub print_search {
+ my ($query, %data) = @_;
+ my $text;
+ foreach (sort keys %data) {
+ my $line;
+ $line .= "%go%n" if $data{$_}{installed};
+ $line .= "%yo%n" if not $data{$_}{installed};
+ $line .= " %9".$_."%9 ";
+ $line .= $data{$_}{desc};
+ $line =~ s/($query)/%U$1%U/gi;
+ $line .= ' ('.$data{$_}{authors}.')';
+ $text .= $line." \n";
+ }
+ print CLIENTCRAP draw_box('ScriptAssist', $text, 'search: '.$query, 1) ;
+}
+
+sub print_update {
+ my (%data) = @_;
+ my $text;
+ my @table;
+ my $verbose = Irssi::settings_get_bool('scriptassist_update_verbose');
+ foreach (sort keys %data) {
+ my $signed = 0;
+ if ($data{$_}{installed} == 1) {
+ my $local = $data{$_}{local};
+ my $remote = $data{$_}{remote};
+ push @table, ['%yo%n', '%9'.$_.'%9', 'upgraded ('.$local.'->'.$remote.')'];
+ foreach (split /\n/, check_sig($data{$_})) {
+ push @table, ['', '', $_];
+ }
+ if (lc($_) eq lc($IRSSI{name})) {
+ push @table, ['', '', "%R%9Please reload manually%9%n"];
+ } else {
+ load_script($_);
+ }
+ } elsif ($data{$_}{installed} == 0 || $data{$_}{installed} == -1) {
+ push @table, ['%yo%n', '%9'.$_.'%9', 'not upgraded'];
+ foreach (split /\n/, check_sig($data{$_})) {
+ push @table, ['', '', $_];
+ }
+ } elsif ($data{$_}{installed} == -2 && $verbose) {
+ my $local = $data{$_}{local};
+ push @table, ['%go%n', '%9'.$_.'%9', 'already at the latest version ('.$local.')'];
+ }
+ }
+ $text = array2table(@table);
+ print CLIENTCRAP draw_box('ScriptAssist', $text, 'update', 1) ;
+}
+
+sub contact_author {
+ my ($script) = @_;
+ my ($sname, $plname, $pname) = get_names($script);
+ return unless exists $Irssi::Script::{$pname};
+ my $header = $Irssi::Script::{$pname}{IRSSI};
+ if ($header && defined $header->{contact}) {
+ my @ads = split(/ |,/, $header->{contact});
+ my $address = $ads[0];
+ $address .= '?subject='.$script;
+ $address .= '_'.get_local_version($script) if defined get_local_version($script);
+ call_openurl($address) if $address =~ /[\@:]/;
+ }
+}
+
+sub get_scripts {
+ my $ua = LWP::UserAgent->new(env_proxy=>1, keep_alive=>1, timeout=>30);
+ $ua->agent('ScriptAssist/'.2003020803);
+ $ua->env_proxy();
+ my @mirrors = split(/ /, Irssi::settings_get_str('scriptassist_script_sources'));
+ my %sites_db;
+ my $not_modified = 0;
+ my $fetched = 0;
+ my @sources;
+ my $error;
+ foreach my $site (@mirrors) {
+ my $request = HTTP::Request->new('GET', $site);
+ if ($remote_db{timestamp}) {
+ $request->if_modified_since($remote_db{timestamp});
+ }
+ my $response = $ua->request($request);
+ if ($response->code == 304) { # HTTP_NOT_MODIFIED
+ $not_modified = 1;
+ next;
+ }
+ unless ($response->is_success) {
+ $error = join "\n", $response->status_line(), (grep / at .* line \d+/, split "\n", $response->content()), '';
+ next;
+ }
+ $fetched = 1;
+ my $data = $response->content();
+ my ($src, $type);
+ if ($site =~ /(.*\/).+\.(.+)/) {
+ $src = $1;
+ $type = $2;
+ }
+ push @sources, $src;
+ #my @header = ('name', 'contact', 'authors', 'description', 'version', 'modules', 'last_modified');
+ if ($type eq 'dmp') {
+ no strict 'vars';
+ my $new_db = eval "$data";
+ foreach (keys %$new_db) {
+ if (defined $sites_db{script}{$_}) {
+ my $old = $sites_db{$_}{version};
+ my $new = $new_db->{$_}{version};
+ next if (compare_versions($old, $new) eq 'newer');
+ }
+ #foreach my $key (@header) {
+ foreach my $key (keys %{ $new_db->{$_} }) {
+ next unless defined $new_db->{$_}{$key};
+ $sites_db{$_}{$key} = $new_db->{$_}{$key};
+ }
+ $sites_db{$_}{source} = $src;
+ }
+ } else {
+ die("Unknown script database type ($type).\n");
+ }
+ }
+ if ($fetched) {
+ # Clean database
+ foreach (keys %{$remote_db{db}}) {
+ foreach my $site (@sources) {
+ if ($remote_db{db}{$_}{source} eq $site) {
+ delete $remote_db{db}{$_};
+ last;
+ }
+ }
+ }
+ $remote_db{db}{$_} = $sites_db{$_} foreach (keys %sites_db);
+ $remote_db{timestamp} = time();
+ } elsif ($not_modified) {
+ # nothing to do
+ } else {
+ die("No script database sources defined in /set scriptassist_script_sources\n") unless @mirrors;
+ die("Fetching script database failed: $error") if $error;
+ die("Unknown error while fetching script database\n");
+ }
+ return $remote_db{db};
+}
+
+sub get_remote_version {
+ my ($script, $database) = @_;
+ my $plname = (get_names($script, $database))[1];
+ return $database->{$plname}{version};
+}
+
+sub get_local_version {
+ my ($script) = @_;
+ my $pname = (get_names($script))[2];
+ return unless exists $Irssi::Script::{$pname};
+ my $vref = $Irssi::Script::{$pname}{VERSION};
+ return $vref ? $$vref : undef;
+}
+
+sub compare_versions {
+ my ($ver1, $ver2) = @_;
+ for ($ver1, $ver2) {
+ $_ = "0:$_" unless /:/;
+ }
+ my @ver1 = split /[.:]/, $ver1;
+ my @ver2 = split /[.:]/, $ver2;
+ my $cmp = 0;
+ ### Special thanks to Clemens Heidinger
+ no warnings 'uninitialized';
+ $cmp ||= $ver1[$_] <=> $ver2[$_] || $ver1[$_] cmp $ver2[$_] for 0..scalar(@ver2);
+ return 'newer' if $cmp == 1;
+ return 'older' if $cmp == -1;
+ return 'equal';
+}
+
+sub loaded_scripts {
+ my @modules;
+ foreach (sort grep(s/::$//, keys %Irssi::Script::)) {
+ push @modules, $_;
+ }
+ return \@modules;
+}
+
+sub check_scripts {
+ my ($data) = @_;
+ my %versions;
+ foreach (@{loaded_scripts()}) {
+ my ($sname) = get_names($_, $data);
+ my $remote = get_remote_version($sname, $data);
+ my $local = get_local_version($sname);
+ my $state;
+ if ($local && $remote) {
+ $state = compare_versions($local, $remote);
+ } elsif ($local) {
+ $state = 'noversion';
+ $remote = '/';
+ } else {
+ $state = 'noheader';
+ $local = '/';
+ $remote = '/';
+ }
+ if ($state) {
+ $versions{$sname}{state} = $state;
+ $versions{$sname}{remote} = $remote;
+ $versions{$sname}{local} = $local;
+ }
+ }
+ return \%versions;
+}
+
+sub download_script {
+ my ($script, $xml) = @_;
+ my ($sname, $plname) = get_names($script, $xml);
+ my %result;
+ my $site = $xml->{$plname}{source};
+ $result{installed} = 0;
+ $result{signed} = 0;
+ my $dir = Irssi::get_irssi_dir();
+ my $ua = LWP::UserAgent->new(env_proxy => 1,keep_alive => 1,timeout => 30);
+ $ua->agent('ScriptAssist/'.2003020803);
+ my $request = HTTP::Request->new('GET', $site.'/scripts/'.$script.'.pl');
+ my $response = $ua->request($request);
+ if ($response->is_success()) {
+ my $file = $response->content();
+ mkdir $dir.'/scripts/' unless (-e $dir.'/scripts/');
+ open(my $F, '>', $dir.'/scripts/'.$plname.'.new');
+ print $F $file;
+ close($F);
+ if ($have_gpg && Irssi::settings_get_bool('scriptassist_use_gpg')) {
+ my $ua2 = LWP::UserAgent->new(env_proxy => 1,keep_alive => 1,timeout => 30);
+ $ua->agent('ScriptAssist/'.2003020803);
+ my $request2 = HTTP::Request->new('GET', $site.'/signatures/'.$plname.'.asc');
+ my $response2 = $ua->request($request2);
+ if ($response2->is_success()) {
+ my $sig_dir = $dir.'/scripts/signatures/';
+ mkdir $sig_dir unless (-e $sig_dir);
+ open(my $S, '>', $sig_dir.$plname.'.asc');
+ my $file2 = $response2->content();
+ print $S $file2;
+ close($S);
+ my $sig;
+ foreach (1..2) {
+ # FIXME gpg needs two rounds to load the key
+ my $gpg = new GnuPG();
+ eval {
+ $sig = $gpg->verify( file => $dir.'/scripts/'.$plname.'.new', signature => $sig_dir.$plname.'.asc' );
+ };
+ }
+ if (defined $sig->{user}) {
+ $result{installed} = 1;
+ $result{signed} = 1;
+ $result{sig}{$_} = $sig->{$_} foreach (keys %{$sig});
+ } else {
+ # Signature broken?
+ $result{installed} = 0;
+ $result{signed} = -1;
+ }
+ } else {
+ $result{signed} = 0;
+ $result{installed} = -1;
+ $result{installed} = 1 if Irssi::settings_get_bool('scriptassist_install_unsigned_scripts');
+ }
+ } else {
+ $result{signed} = 0;
+ $result{installed} = -1;
+ $result{installed} = 1 if Irssi::settings_get_bool('scriptassist_install_unsigned_scripts');
+ }
+ }
+ if ($result{installed}) {
+ my $old_dir = "$dir/scripts/old/";
+ mkdir $old_dir unless (-e $old_dir);
+ rename "$dir/scripts/$plname", "$old_dir/$plname.old" if -e "$dir/scripts/$plname";
+ rename "$dir/scripts/$plname.new", "$dir/scripts/$plname";
+ }
+ return \%result;
+}
+
+sub print_check {
+ my (%data) = @_;
+ my $text;
+ my @table;
+ foreach (sort keys %data) {
+ my $state = $data{$_}{state};
+ my $remote = $data{$_}{remote};
+ my $local = $data{$_}{local};
+ if (Irssi::settings_get_bool('scriptassist_check_verbose')) {
+ push @table, ['%go%n', '%9'.$_.'%9', 'Up to date. ('.$local.')'] if $state eq 'equal';
+ }
+ push @table, ['%mo%n', '%9'.$_.'%9', "No version information available on network."] if $state eq "noversion";
+ push @table, ['%mo%n', '%9'.$_.'%9', 'No header in script.'] if $state eq "noheader";
+ push @table, ['%bo%n', '%9'.$_.'%9', "Your version is newer (".$local."->".$remote.")"] if $state eq "newer";
+ push @table, ['%ro%n', '%9'.$_.'%9', "A new version is available (".$local."->".$remote.")"] if $state eq "older";;
+ }
+ $text = array2table(@table);
+ print CLIENTCRAP draw_box('ScriptAssist', $text, 'check', 1) ;
+}
+
+sub toggle_autorun {
+ my ($script) = @_;
+ my ($sname, $plname) = get_names($script);
+ my $dir = Irssi::get_irssi_dir()."/scripts/";
+ mkdir $dir."autorun/" unless (-e $dir."autorun/");
+ return unless (-e $dir.$plname);
+ if (-e $dir."/autorun/".$plname) {
+ if (readlink($dir."/autorun/".$plname) eq "../".$plname) {
+ if (unlink($dir."/autorun/".$plname)) {
+ print CLIENTCRAP "%R>>%n Autorun of ".$sname." disabled";
+ } else {
+ print CLIENTCRAP "%R>>%n Unable to delete link";
+ }
+ } else {
+ print CLIENTCRAP "%R>>%n ".$dir."/autorun/".$plname." is not a correct link";
+ }
+ } else {
+ if (symlink("../".$plname, $dir."/autorun/".$plname)) {
+ print CLIENTCRAP "%R>>%n Autorun of ".$sname." enabled";
+ } else {
+ print CLIENTCRAP "%R>>%n Unable to create autorun link";
+ }
+ }
+}
+
+sub sig_script_error {
+ my ($script, $msg) = @_;
+ return unless Irssi::settings_get_bool('scriptassist_catch_script_errors');
+ if ($msg =~ /Can't locate (.*?)\.pm in \@INC \(\@INC contains:(.*?) at/) {
+ my $module = $1;
+ $module =~ s/\//::/g;
+ missing_module($module);
+ }
+}
+
+sub missing_module {
+ my ($module) = @_;
+ my $text;
+ $text .= "The perl module %9".$module."%9 is missing on your system.\n";
+ $text .= "Please ask your administrator about it.\n";
+ $text .= "You can also check CPAN via '/scriptassist cpan ".$module."'.\n";
+ print CLIENTCRAP &draw_box('ScriptAssist', $text, $module, 1);
+}
+
+sub cmd_scripassist {
+ my ($arg, $server, $witem) = @_;
+ my @args = split(/ /, $arg);
+ if ($args[0] eq 'help' || $args[0] eq '-h') {
+ show_help();
+ } elsif ($args[0] eq 'check') {
+ bg_do("check");
+ } elsif ($args[0] eq 'update') {
+ shift @args;
+ bg_do("update ".join(' ', @args));
+ } elsif ($args[0] eq 'search' && defined $args[1]) {
+ shift @args;
+ bg_do("search ".join(" ", @args));
+ } elsif ($args[0] eq 'install' && defined $args[1]) {
+ shift @args;
+ bg_do("install ".join(' ', @args));
+ } elsif ($args[0] eq 'contact' && defined $args[1]) {
+ contact_author($args[1]);
+ } elsif ($args[0] eq 'ratings' && defined $args[1]) {
+ shift @args;
+ bg_do("ratings ".join(' ', @args));
+ } elsif ($args[0] eq 'rate' && defined $args[1] && defined $args[2]) {
+ shift @args;
+ bg_do("rate ".join(' ', @args)) if ($args[2] >= 0 && $args[2] < 6);
+ } elsif ($args[0] eq 'info' && defined $args[1]) {
+ shift @args;
+ bg_do("info ".join(' ', @args));
+ } elsif ($args[0] eq 'echo') {
+ bg_do("echo");
+ } elsif ($args[0] eq 'top') {
+ my $number = defined $args[1] ? $args[1] : 10;
+ bg_do("top ".$number);
+ } elsif ($args[0] eq 'cpan' && defined $args[1]) {
+ call_openurl('http://search.cpan.org/search?mode=module&query='.$args[1]);
+ } elsif ($args[0] eq 'autorun' && defined $args[1]) {
+ toggle_autorun($args[1]);
+ } elsif ($args[0] eq 'new') {
+ my $number = defined $args[1] ? $args[1] : 5;
+ bg_do("new ".$number);
+ }
+}
+
+sub cmd_help {
+ my ($arg, $server, $witem) = @_;
+ $arg =~ s/\s+$//;
+ if ($arg =~ /^scriptassist/i) {
+ show_help();
+ }
+}
+
+sub sig_command_script_load {
+ my ($script, $server, $witem) = @_;
+ my ($sname, $plname, $pname, $xname) = get_names($script);
+ if ( exists $Irssi::Script::{$pname} ) {
+ if (my $code = "Irssi::Script::${pname}"->can('pre_unload')) {
+ print CLIENTCRAP "%R>>%n Triggering pre_unload function of $script...";
+ $code->();
+ }
+ }
+}
+
+sub sig_default_command {
+ my ($cmd, $server) = @_;
+ return unless Irssi::settings_get_bool("scriptassist_check_unknown_commands");
+ bg_do('unknown '.$cmd);
+}
+
+sub sig_complete {
+ my ($list, $window, $word, $linestart, $want_space) = @_;
+ return unless $linestart =~ /^.script(assist)? (install|rate|ratings|update|check|contact|info|autorun)/i;
+ my @newlist;
+ my $str = $word;
+ foreach (@complist) {
+ if ($_ =~ /^(\Q$str\E.*)?$/) {
+ push @newlist, $_;
+ }
+ }
+ foreach (@{loaded_scripts()}) {
+ push @newlist, $_ if /^(\Q$str\E.*)?$/;
+ }
+ push @$list, $_ foreach @newlist;
+ Irssi::signal_stop();
+}
+
+
+Irssi::settings_add_str($IRSSI{name}, 'scriptassist_script_sources', 'https://scripts.irssi.org/scripts.dmp');
+Irssi::settings_add_bool($IRSSI{name}, 'scriptassist_cache_sources', 1);
+Irssi::settings_add_bool($IRSSI{name}, 'scriptassist_update_verbose', 1);
+Irssi::settings_add_bool($IRSSI{name}, 'scriptassist_check_verbose', 1);
+Irssi::settings_add_bool($IRSSI{name}, 'scriptassist_catch_script_errors', 1);
+
+Irssi::settings_add_bool($IRSSI{name}, 'scriptassist_install_unsigned_scripts', 1);
+Irssi::settings_add_bool($IRSSI{name}, 'scriptassist_use_gpg', 1);
+Irssi::settings_add_bool($IRSSI{name}, 'scriptassist_integrate', 1);
+Irssi::settings_add_bool($IRSSI{name}, 'scriptassist_check_unknown_commands', 1);
+
+Irssi::signal_add_first("default command", 'sig_default_command');
+Irssi::signal_add_first('complete word', 'sig_complete');
+Irssi::signal_add_first('command script load', 'sig_command_script_load');
+Irssi::signal_add_first('command script unload', 'sig_command_script_load');
+
+Irssi::signal_register({ 'script error' => [ 'Irssi::Script', 'string' ] });
+Irssi::signal_add_last('script error', 'sig_script_error');
+
+Irssi::command_bind('scriptassist', 'cmd_scripassist');
+Irssi::command_bind('help', 'cmd_help');
+
+Irssi::theme_register(['box_header', '%R,--[%n$*%R]%n',
+'box_inside', '%R|%n $*',
+'box_footer', '%R`--<%n$*%R>->%n',
+]);
+
+foreach my $cmd ( ( 'check',
+ 'install',
+ 'update',
+ 'contact',
+ 'search',
+# '-h',
+ 'help',
+# 'ratings',
+# 'rate',
+ 'info',
+# 'echo',
+# 'top',
+ 'cpan',
+ 'autorun',
+ 'new' ) ) {
+ Irssi::command_bind('scriptassist '.$cmd => sub {
+ cmd_scripassist("$cmd ".$_[0], $_[1], $_[2]); });
+ if (Irssi::settings_get_bool('scriptassist_integrate')) {
+ Irssi::command_bind('script '.$cmd => sub {
+ cmd_scripassist("$cmd ".$_[0], $_[1], $_[2]); });
+ }
+}
+
+print CLIENTCRAP '%B>>%n '.$IRSSI{name}.' '.$VERSION.' loaded: /scriptassist help for help';
diff --git a/.irssi/scripts/tmux_away.pl b/.irssi/scripts/tmux_away.pl
new file mode 100644
index 0000000..36fb160
--- /dev/null
+++ b/.irssi/scripts/tmux_away.pl
@@ -0,0 +1,202 @@
+use Irssi;
+use strict;
+use FileHandle;
+
+use vars qw($VERSION %IRSSI);
+
+$VERSION = "2.1"; # e8934ed1ce04461
+%IRSSI = (
+ authors => 'cdidier',
+ name => 'tmux_away',
+ description => 'set (un)away if tmux session is attached/detached',
+ license => 'GPL v2',
+ url => 'http://cybione.org',
+);
+
+# tmux_away irssi module
+#
+# Written by Colin Didier <cdidier@cybione.org> and heavily based on
+# screen_away irssi module version 0.9.7.1 written by Andreas 'ads' Scherbaum
+# <ads@ufp.de>.
+#
+# Updated by John C. Vernaleo <john@netpurgatory.com> to handle tmux with
+# named sessions and other code cleanup and forked as version 2.0.
+#
+# usage:
+#
+# put this script into your autorun directory and/or load it with
+# /SCRIPT LOAD <name>
+#
+# there are 5 settings available:
+#
+# /set tmux_away_active ON/OFF/TOGGLE
+# /set tmux_away_repeat <integer>
+# /set tmux_away_grace <integer>
+# /set tmux_away_message <string>
+# /set tmux_away_window <string>
+# /set tmux_away_nick <string>
+#
+# active means that you will be only set away/unaway, if this
+# flag is set, default is ON
+# repeat is the number of seconds, after the script will check the
+# tmux session status again, default is 5 seconds
+# grace is the number of seconds, to wait additionally, before
+# setting you away, default is disabled (0)
+# message is the away message sent to the server, default: not here ...
+# window is a window number or name, if set, the script will switch
+# to this window, if it sets you away, default is '1'
+# nick is the new nick, if the script goes away
+# will only be used it not empty
+
+
+# variables
+my $timer_name = undef;
+my $away_status = 0;
+my %old_nicks = ();
+my %away = ();
+
+# Register formats
+Irssi::theme_register(
+[
+ 'tmux_away_crap',
+ '{line_start}{hilight ' . $IRSSI{'name'} . ':} $0'
+]);
+
+# try to find out if we are running in a tmux session
+# (see if $ENV{TMUX} is set)
+if (!defined($ENV{TMUX})) {
+ # just return, we will never be called again
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'tmux_away_crap',
+ "no tmux session!");
+ return;
+}
+
+my @args_env = split(',', $ENV{TMUX});
+my $tmux_socket = $args_env[0];
+
+# register config variables
+Irssi::settings_add_bool('misc', $IRSSI{'name'} . '_active', 1);
+Irssi::settings_add_int('misc', $IRSSI{'name'} . '_repeat', 5);
+Irssi::settings_add_int('misc', $IRSSI{'name'} . '_grace', 0);
+Irssi::settings_add_str('misc', $IRSSI{'name'} . '_message', "not here...");
+Irssi::settings_add_str('misc', $IRSSI{'name'} . '_window', "1");
+Irssi::settings_add_str('misc', $IRSSI{'name'} . '_nick', "");
+
+
+# check, set or reset the away status
+sub tmux_away {
+ my ($immediate) = @_;
+ my ($status, @res);
+
+ # only run, if activated
+ if (Irssi::settings_get_bool($IRSSI{'name'} . '_active') != 1) {
+ $away_status = 0;
+ } else {
+ if ($away_status == 0) {
+ # display init message at first time
+ my $grace = Irssi::settings_get_int($IRSSI{'name'} . '_grace');
+ $grace = ", $grace seconds grace" if $grace;
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'tmux_away_crap',
+ "activating $IRSSI{'name'} (interval: " . Irssi::settings_get_int($IRSSI{'name'} . '_repeat') . " seconds$grace)");
+ $away_status = 2;
+ }
+
+ # get actual tmux session status
+ chomp(@res = `tmux -S '$tmux_socket' lsc 2>&1`);
+ chomp(my $tmux_session = `tmux -S '$tmux_socket' display -p '#S' 2>/dev/null`);
+ if ($res[0] =~ /^server not found/ || $? >> 8) {
+ die "error getting tmux session status.";
+ }
+ $status = 1; # away, assumes the session is detached
+ foreach (@res) {
+ my @args_st = split(' ');
+ if ($args_st[1] eq $tmux_session) {
+ $status = 2; # unaway
+ }
+ }
+
+ # unaway -> away
+ if ($status == 1 and $away_status != 1) {
+ if (my $grace = Irssi::settings_get_int($IRSSI{'name'} . '_grace')) {
+ if (!$immediate) {
+ Irssi::timeout_add_once($grace * 1000, 'tmux_away', '1');
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'tmux_away_crap',
+ "(in grace for away: $grace seconds)");
+ return 1;
+ }
+ }
+ if (length(Irssi::settings_get_str($IRSSI{'name'} . '_window')) > 0) {
+ # if length of window is greater then 0, make this window active
+ Irssi::command('window goto ' . Irssi::settings_get_str($IRSSI{'name'} . '_window'));
+ }
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'tmux_away_crap', "Set away");
+ my $message = Irssi::settings_get_str($IRSSI{'name'} . '_message');
+ if (length($message) == 0) {
+ # we have to set a message or we wouldnt go away
+ $message = "not here ...";
+ }
+ foreach (Irssi::servers()) {
+ if (!$_->{usermode_away}) {
+ # user isn't yet away
+ $away{$_->{'tag'}} = 0;
+ $_->command("^AWAY " . ($_->{chat_type} ne 'SILC' ? "-one " : "") . "$message");
+ if ($_->{chat_type} ne 'XMPP' and length(Irssi::settings_get_str($IRSSI{'name'} . '_nick')) > 0) {
+ # only change if actual nick isn't already the away nick
+ if (Irssi::settings_get_str($IRSSI{'name'} . '_nick') ne $_->{nick}) {
+ # keep old nick
+ $old_nicks{$_->{'tag'}} = $_->{nick};
+ # set new nick
+ $_->command("NICK " . Irssi::settings_get_str($IRSSI{'name'} . '_nick'));
+ }
+ }
+ } else {
+ # user is already away, remember this
+ $away{$_->{'tag'}} = 1;
+ }
+ }
+ $away_status = $status;
+
+ # away -> unaway
+ } elsif ($status == 2 and $away_status != 2) {
+ if (my $grace = Irssi::settings_get_int($IRSSI{'name'} . '_grace')) {
+ if (!$immediate) {
+ Irssi::timeout_add_once($grace * 1000, 'tmux_away', '1');
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'tmux_away_crap',
+ "(in grace for unaway: $grace seconds)");
+ return 1;
+ }
+ }
+ # unset away
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'tmux_away_crap', "Reset away");
+ foreach (Irssi::servers()) {
+ if ($away{$_->{'tag'}} == 1) {
+ # user was already away, don't reset away
+ $away{$_->{'tag'}} = 0;
+ next;
+ }
+ $_->command("^AWAY" . (($_->{chat_type} ne 'SILC') ? " -one" : "")) if ($_->{usermode_away});
+ if ($_->{chat_type} ne 'XMPP' and defined($old_nicks{$_->{'tag'}}) and length($old_nicks{$_->{'tag'}}) > 0) {
+ # set old nick
+ $_->command("NICK " . $old_nicks{$_->{'tag'}});
+ $old_nicks{$_->{'tag'}} = "";
+ }
+ }
+ $away_status = $status;
+ } elsif ($immediate) {
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'tmux_away_crap',
+ "in grace aborted");
+ }
+ }
+ # but everytimes install a new timer
+ register_tmux_away_timer();
+ return 0;
+}
+
+# remove old timer and install a new one
+sub register_tmux_away_timer {
+ # add new timer with new timeout (maybe the timeout has been changed)
+ Irssi::timeout_add_once(Irssi::settings_get_int($IRSSI{'name'} . '_repeat') * 1000, 'tmux_away', '');
+}
+
+# init process
+tmux_away();
diff --git a/.irssi/scripts/trackbar.pl b/.irssi/scripts/trackbar.pl
new file mode 100644
index 0000000..7ac9965
--- /dev/null
+++ b/.irssi/scripts/trackbar.pl
@@ -0,0 +1,579 @@
+## trackbar.pl
+#
+# This little script will do just one thing: it will draw a line each time you
+# switch away from a window. This way, you always know just upto where you've
+# been reading that window :) It also removes the previous drawn line, so you
+# don't see double lines.
+#
+# redraw trackbar only works on irssi 0.8.17 or higher.
+#
+##
+
+## Usage:
+#
+# The script works right out of the box, but if you want you can change
+# the working by /set'ing the following variables:
+#
+# Setting: trackbar_style
+# Description: This setting will be the color of your trackbar line.
+# By default the value will be '%K', only Irssi color
+# formats are allowed. If you don't know the color formats
+# by heart, you can take a look at the formats documentation.
+# You will find the proper docs on http://www.irssi.org/docs.
+#
+# Setting: trackbar_string
+# Description: This is the string that your line will display. This can
+# be multiple characters or just one. For example: '~-~-'
+# The default setting is '-'.
+# Here are some unicode characters you can try:
+# "───" => U+2500 => a line
+# "═══" => U+2550 => a double line
+# "━━━" => U+2501 => a wide line
+# "▭ " => U+25ad => a white rectangle
+#
+# Setting: trackbar_use_status_window
+# Description: If this setting is set to OFF, Irssi won't print a trackbar
+# in the statuswindow
+#
+# Setting: trackbar_ignore_windows
+# Description: A list of windows where no trackbar should be printed
+#
+# Setting: trackbar_print_timestamp
+# Description: If this setting is set to ON, Irssi will print the formatted
+# timestamp in front of the trackbar.
+#
+# Setting: trackbar_require_seen
+# Description: Only clear the trackbar if it has been scrolled to.
+#
+# /mark is a command that will redraw the line at the bottom.
+#
+# Command: /trackbar, /trackbar goto
+# Description: Jump to where the trackbar is, to pick up reading
+#
+# Command: /trackbar keep
+# Description: Keep this window's trackbar where it is the next time
+# you switch windows (then this flag is cleared again)
+#
+# Command: /mark, /trackbar mark
+# Description: Remove the old trackbar and mark the bottom of this
+# window with a new trackbar
+#
+# Command: /trackbar markvisible
+# Description: Like mark for all visible windows
+#
+# Command: /trackbar markall
+# Description: Like mark for all windows
+#
+# Command: /trackbar remove
+# Description: Remove this window's trackbar
+#
+# Command: /trackbar removeall
+# Description: Remove all windows' trackbars
+#
+# Command: /trackbar redraw
+# Description: Force redraw of trackbars
+#
+##
+
+##
+#
+# For bugreports and other improvements contact one of the authors.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this script; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+##
+
+use strict;
+use warnings;
+use vars qw($VERSION %IRSSI);
+
+$VERSION = "2.5"; # 56e983314dc1b85
+
+%IRSSI = (
+ authors => "Peter 'kinlo' Leurs, Uwe Dudenhoeffer, " .
+ "Michiel Holtkamp, Nico R. Wohlgemuth, " .
+ "Geert Hauwaerts",
+ contact => 'peter@pfoe.be',
+ patchers => 'Johan Kiviniemi (UTF-8), Uwe Dudenhoeffer (on-upgrade-remove-line)',
+ name => 'trackbar',
+ description => 'Shows a bar where you have last read a window.',
+ license => 'GNU General Public License',
+ url => 'http://www.pfoe.be/~peter/trackbar/',
+ commands => 'trackbar',
+);
+
+## Comments and remarks.
+#
+# This script uses settings.
+# Use /SET to change the value or /TOGGLE to switch it on or off.
+#
+#
+# Tip: The command 'trackbar' is very usefull if you bind that to a key,
+# so you can easily jump to the trackbar. Please see 'help bind' for
+# more information about keybindings in Irssi.
+#
+# Command: /BIND meta2-P key F1
+# /BIND F1 command trackbar
+#
+##
+
+## Bugfixes and new items in this rewrite.
+#
+# * Remove all the trackbars before upgrading.
+# * New setting trackbar_use_status_window to control the statuswindow trackbar.
+# * New setting trackbar_print_timestamp to print a timestamp or not.
+# * New command 'trackbar' to scroll up to the trackbar.
+# * When resizing your terminal, Irssi will update all the trackbars to the new size.
+# * When changing trackbar settings, change all the trackbars to the new settings.
+# * New command 'trackbar mark' to draw a new trackbar (The old '/mark').
+# * New command 'trackbar markall' to draw a new trackbar in each window.
+# * New command 'trackbar remove' to remove the trackbar from the current window.
+# * New command 'trackbar removeall' to remove all the trackbars.
+# * Don't draw a trackbar in empty windows.
+# * Added a version check to prevent Irssi redraw errors.
+# * Fixed a bookmark NULL versus 0 bug.
+# * Fixed a remove-line bug in Uwe Dudenhoeffer his patch.
+# * New command 'help trackbar' to display the trackbar commands.
+# * Fixed an Irssi startup bug, now processing each auto-created window.
+#
+##
+
+## Known bugs and the todolist.
+#
+# Todo: * Instead of drawing a line, invert the line.
+#
+##
+
+## Authors:
+#
+# - Main maintainer & author: Peter 'kinlo' Leurs
+# - Many thanks to Timo 'cras' Sirainen for placing me on my way
+# - on-upgrade-remove-line patch by Uwe Dudenhoeffer
+# - trackbar resizing by Michiel Holtkamp (02 Jul 2012)
+# - scroll to trackbar, window excludes, and timestamp options by Nico R.
+# Wohlgemuth (22 Sep 2012)
+#
+##
+
+## Version history:
+#
+# 2.5: - merge back on scripts.irssi.org
+# - fix /trackbar redraw broken in 2.4
+# - fix legacy encodings
+# - add workaround for irssi issue #271
+# 2.4: - add support for horizontal splits
+# 2.3: - add some features for seen tracking using other scripts
+# 2.0: - big rewrite based on 1.4
+# * removed /tb, you can have it with /alias tb trackbar if you want
+# * subcommand and settings changes:
+# /trackbar vmark => /trackbar markvisible
+# /trackbar scroll => /trackbar goto (or just /trackbar)
+# /trackbar help => /help trackbar
+# /set trackbar_hide_windows => /set trackbar_ignore_windows
+# /set trackbar_timestamp => /set trackbar_print_timestamp
+# * magic line strings were removed, just paste the unicode you want!
+# * trackbar_timestamp_styled is not currently supported
+# 1.9: - add version guard
+# 1.8: - sub draw_bar
+# 1.7: - Added /tb scroll, trackbar_hide_windows, trackbar_timestamp_timestamp
+# and trackbar_timestamp_styled
+# 1.6: - Work around Irssi resize bug, please do /upgrade! (see below)
+# 1.5: - Resize trackbars in all windows when terminal is resized
+# 1.4: - Changed our's by my's so the irssi script header is valid
+# - Removed utf-8 support. In theory, the script should work w/o any
+# problems for utf-8, just set trackbar_string to a valid utf-8 character
+# and everything *should* work. However, this script is being plagued by
+# irssi internal bugs. The function Irssi::settings_get_str does NOT handle
+# unicode strings properly, hence you will notice problems when setting the bar
+# to a unicode char. For changing your bar to utf-8 symbols, read the line sub.
+# 1.3: - Upgrade now removes the trackbars.
+# - Some code cleanups, other defaults
+# - /mark sets the line to the bottom
+# 1.2: - Support for utf-8
+# - How the bar looks can now be configured with trackbar_string
+# and trackbar_style
+# 1.1: - Fixed bug when closing window
+# 1.0: - Initial release
+#
+##
+
+use Irssi;
+use Irssi::TextUI;
+use Encode;
+
+use POSIX qw(strftime);
+
+sub cmd_help {
+ my ($args) = @_;
+ if ($args =~ /^trackbar *$/i) {
+ print CLIENTCRAP <<HELP
+%9Syntax:%9
+
+TRACKBAR
+TRACKBAR GOTO
+TRACKBAR KEEP
+TRACKBAR MARK
+TRACKBAR MARKVISIBLE
+TRACKBAR MARKALL
+TRACKBAR REMOVE
+TRACKBAR REMOVEALL
+TRACKBAR REDRAW
+
+%9Parameters:%9
+
+ GOTO: Jump to where the trackbar is, to pick up reading
+ KEEP: Keep this window's trackbar where it is the next time
+ you switch windows (then this flag is cleared again)
+ MARK: Remove the old trackbar and mark the bottom of this
+ window with a new trackbar
+ MARKVISIBLE: Like mark for all visible windows
+ MARKALL: Like mark for all windows
+ REMOVE: Remove this window's trackbar
+ REMOVEALL: Remove all windows' trackbars
+ REDRAW: Force redraw of trackbars
+
+%9Description:%9
+
+ Manage a trackbar. Without arguments, it will scroll up to the trackbar.
+
+%9Examples:%9
+
+ /TRACKBAR MARK
+ /TRACKBAR REMOVE
+HELP
+ }
+}
+
+Irssi::theme_register([
+ 'trackbar_loaded', '%R>>%n %_Scriptinfo:%_ Loaded $0 version $1 by $2.',
+ 'trackbar_wrong_version', '%R>>%n %_Trackbar:%_ Please upgrade your client to 0.8.17 or above if you would like to use this feature of trackbar.',
+ 'trackbar_all_removed', '%R>>%n %_Trackbar:%_ All the trackbars have been removed.',
+ 'trackbar_not_found', '%R>>%n %_Trackbar:%_ No trackbar found in this window.',
+]);
+
+my $old_irssi = Irssi::version < 20140701;
+sub check_version {
+ if ($old_irssi) {
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'trackbar_wrong_version');
+ return;
+ } else {
+ return 1;
+ }
+}
+
+sub is_utf8 {
+ lc Irssi::settings_get_str('term_charset') eq 'utf-8'
+}
+
+my (%config, %keep_trackbar, %unseen_trackbar);
+
+sub remove_one_trackbar {
+ my $win = shift;
+ my $view = shift || $win->view;
+ my $line = $view->get_bookmark('trackbar');
+ if (defined $line) {
+ my $bottom = $view->{bottom};
+ $view->remove_line($line);
+ $win->command('^scrollback end') if $bottom && !$win->view->{bottom};
+ $view->redraw;
+ }
+}
+
+sub add_one_trackbar {
+ my $win = shift;
+ my $view = shift || $win->view;
+ $win->print(line($win->{width}), MSGLEVEL_NEVER);
+ $view->set_bookmark_bottom('trackbar');
+ $unseen_trackbar{ $win->{_irssi} } = 1;
+ Irssi::signal_emit("window trackbar added", $win);
+ $view->redraw;
+}
+
+sub update_one_trackbar {
+ my $win = shift;
+ my $view = shift || $win->view;
+ my $force = shift;
+ my $ignored = win_ignored($win, $view);
+ remove_one_trackbar($win, $view)
+ if $force || !defined $force || !$ignored;
+ add_one_trackbar($win, $view)
+ if $force || !$ignored;
+}
+
+sub win_ignored {
+ my $win = shift;
+ my $view = shift || $win->view;
+ return 1 unless $view->{buffer}{lines_count};
+ return 1 if $win->{name} eq '(status)' && !$config{use_status_window};
+ no warnings 'uninitialized';
+ return 1 if grep { $win->{name} eq $_ || $win->{refnum} eq $_
+ || $win->get_active_name eq $_ } @{ $config{ignore_windows} };
+ return 0;
+}
+
+sub sig_window_changed {
+ my ($newwindow, $oldwindow) = @_;
+ return unless $oldwindow;
+ redraw_one_trackbar($newwindow) unless $old_irssi;
+ trackbar_update_seen($newwindow);
+ return if delete $keep_trackbar{ $oldwindow->{_irssi} };
+ trackbar_update_seen($oldwindow);
+ return if $config{require_seen} && $unseen_trackbar{ $oldwindow->{_irssi } };
+ update_one_trackbar($oldwindow, undef, 0);
+}
+
+sub trackbar_update_seen {
+ my $win = shift;
+ return unless $win;
+ return unless $unseen_trackbar{ $win->{_irssi} };
+
+ my $view = $win->view;
+ my $line = $view->get_bookmark('trackbar');
+ unless ($line) {
+ delete $unseen_trackbar{ $win->{_irssi} };
+ Irssi::signal_emit("window trackbar seen", $win);
+ return;
+ }
+ my $startline = $view->{startline};
+ return unless $startline;
+
+ if ($startline->{info}{time} < $line->{info}{time}
+ || $startline->{_irssi} == $line->{_irssi}) {
+ delete $unseen_trackbar{ $win->{_irssi} };
+ Irssi::signal_emit("window trackbar seen", $win);
+ }
+}
+
+sub screen_length;
+{ local $@;
+ eval { require Text::CharWidth; };
+ unless ($@) {
+ *screen_length = sub { Text::CharWidth::mbswidth($_[0]) };
+ }
+ else {
+ *screen_length = sub {
+ my $temp = shift;
+ Encode::_utf8_on($temp) if is_utf8();
+ length($temp)
+ };
+ }
+}
+
+{ my %strip_table = (
+ (map { $_ => '' } (split //, '04261537' . 'kbgcrmyw' . 'KBGCRMYW' . 'U9_8I:|FnN>#[' . 'pP')),
+ (map { $_ => $_ } (split //, '{}%')),
+ );
+ sub c_length {
+ my $o = Irssi::strip_codes($_[0]);
+ $o =~ s/(%(%|Z.{6}|z.{6}|X..|x..|.))/exists $strip_table{$2} ? $strip_table{$2} :
+ $2 =~ m{x(?:0[a-f]|[1-6][0-9a-z]|7[a-x])|z[0-9a-f]{6}}i ? '' : $1/gex;
+ screen_length($o)
+ }
+}
+
+sub line {
+ my ($width, $time) = @_;
+ my $string = $config{string};
+ $string = ' ' unless length $string;
+ $time ||= time;
+
+ Encode::_utf8_on($string) if is_utf8();
+ my $length = c_length($string);
+
+ my $format = '';
+ if ($config{print_timestamp}) {
+ $format = $config{timestamp_str};
+ $format =~ y/%/\01/;
+ $format =~ s/\01\01/%/g;
+ $format = strftime($format, localtime $time);
+ $format =~ y/\01/%/;
+ }
+
+ my $times = $width / $length;
+ $times += 1 if $times != int $times;
+ my $style = "$config{style}";
+ Encode::_utf8_on($style) if is_utf8();
+ $format .= $style;
+ $width -= c_length($format);
+ $string x= $times;
+ chop $string while length $string && c_length($string) > $width;
+ return $format . $string;
+}
+
+sub remove_all_trackbars {
+ for my $window (Irssi::windows) {
+ next unless ref $window;
+ remove_one_trackbar($window);
+ }
+}
+
+sub UNLOAD {
+ remove_all_trackbars();
+}
+
+sub redraw_one_trackbar {
+ my $win = shift;
+ my $view = $win->view;
+ my $line = $view->get_bookmark('trackbar');
+ return unless $line;
+ my $bottom = $view->{bottom};
+ $win->print_after($line, MSGLEVEL_NEVER, line($win->{width}, $line->{info}{time}),
+ $line->{info}{time});
+ $view->set_bookmark('trackbar', $win->last_line_insert);
+ $view->remove_line($line);
+ $win->command('^scrollback end') if $bottom && !$win->view->{bottom};
+ $view->redraw;
+}
+
+sub redraw_trackbars {
+ return unless check_version();
+ for my $win (Irssi::windows) {
+ next unless ref $win;
+ redraw_one_trackbar($win);
+ }
+}
+
+sub goto_trackbar {
+ my $win = Irssi::active_win;
+ my $line = $win->view->get_bookmark('trackbar');
+
+ if ($line) {
+ $win->command("scrollback goto ". strftime("%d %H:%M:%S", localtime($line->{info}{time})));
+ } else {
+ $win->printformat(MSGLEVEL_CLIENTCRAP, 'trackbar_not_found');
+ }
+}
+
+sub cmd_mark {
+ update_one_trackbar(Irssi::active_win, undef, 1);
+}
+
+sub cmd_markall {
+ for my $window (Irssi::windows) {
+ next unless ref $window;
+ update_one_trackbar($window);
+ }
+}
+
+sub signal_stop {
+ Irssi::signal_stop;
+}
+
+sub cmd_markvisible {
+ my @wins = Irssi::windows;
+ my $awin =
+ my $bwin = Irssi::active_win;
+ my $awin_counter = 0;
+ Irssi::signal_add_priority('window changed' => 'signal_stop', -99);
+ do {
+ Irssi::active_win->command('window up');
+ $awin = Irssi::active_win;
+ update_one_trackbar($awin);
+ ++$awin_counter;
+ } until ($awin->{refnum} == $bwin->{refnum} || $awin_counter >= @wins);
+ Irssi::signal_remove('window changed' => 'signal_stop');
+}
+
+sub cmd_trackbar_remove_one {
+ remove_one_trackbar(Irssi::active_win);
+}
+
+sub cmd_remove_all_trackbars {
+ remove_all_trackbars();
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'trackbar_all_removed');
+}
+
+sub cmd_keep_once {
+ $keep_trackbar{ Irssi::active_win->{_irssi} } = 1;
+}
+
+sub trackbar_runsub {
+ my ($data, $server, $item) = @_;
+ $data =~ s/\s+$//g;
+
+ if ($data) {
+ Irssi::command_runsub('trackbar', $data, $server, $item);
+ } else {
+ goto_trackbar();
+ }
+}
+
+sub update_config {
+ my $was_status_window = $config{use_status_window};
+ $config{style} = Irssi::settings_get_str('trackbar_style');
+ $config{string} = Irssi::settings_get_str('trackbar_string');
+ $config{require_seen} = Irssi::settings_get_bool('trackbar_require_seen');
+ $config{ignore_windows} = [ split /[,\s]+/, Irssi::settings_get_str('trackbar_ignore_windows') ];
+ $config{use_status_window} = Irssi::settings_get_bool('trackbar_use_status_window');
+ $config{print_timestamp} = Irssi::settings_get_bool('trackbar_print_timestamp');
+ if (defined $was_status_window && $was_status_window != $config{use_status_window}) {
+ if (my $swin = Irssi::window_find_name('(status)')) {
+ if ($config{use_status_window}) {
+ update_one_trackbar($swin);
+ }
+ else {
+ remove_one_trackbar($swin);
+ }
+ }
+ }
+ if ($config{print_timestamp}) {
+ my $ts_format = Irssi::settings_get_str('timestamp_format');
+ my $ts_theme = Irssi::current_theme->get_format('fe-common/core', 'timestamp');
+ my $render_str = Irssi::current_theme->format_expand($ts_theme);
+ (my $ts_escaped = $ts_format) =~ s/([%\$])/$1$1/g;
+ $render_str =~ s/(?|\$(.)(?!\w)|\$\{(\w+)\})/$1 eq 'Z' ? $ts_escaped : $1/ge;
+ $config{timestamp_str} = $render_str;
+ }
+ redraw_trackbars() unless $old_irssi;
+}
+
+Irssi::settings_add_str('trackbar', 'trackbar_string', is_utf8() ? "\x{2500}" : '-');
+Irssi::settings_add_str('trackbar', 'trackbar_style', '%K');
+Irssi::settings_add_str('trackbar', 'trackbar_ignore_windows', '');
+Irssi::settings_add_bool('trackbar', 'trackbar_use_status_window', 1);
+Irssi::settings_add_bool('trackbar', 'trackbar_print_timestamp', 0);
+Irssi::settings_add_bool('trackbar', 'trackbar_require_seen', 0);
+
+update_config();
+
+Irssi::signal_add_last( 'mainwindow resized' => 'redraw_trackbars')
+ unless $old_irssi;
+
+Irssi::signal_register({'window trackbar added' => [qw/Irssi::UI::Window/]});
+Irssi::signal_register({'window trackbar seen' => [qw/Irssi::UI::Window/]});
+Irssi::signal_register({'gui page scrolled' => [qw/Irssi::UI::Window/]});
+Irssi::signal_add_last('gui page scrolled' => 'trackbar_update_seen');
+
+Irssi::signal_add('setup changed' => 'update_config');
+Irssi::signal_add_priority('session save' => 'remove_all_trackbars', Irssi::SIGNAL_PRIORITY_HIGH-1);
+
+Irssi::signal_add('window changed' => 'sig_window_changed');
+
+Irssi::command_bind('trackbar goto' => 'goto_trackbar');
+Irssi::command_bind('trackbar keep' => 'cmd_keep_once');
+Irssi::command_bind('trackbar mark' => 'cmd_mark');
+Irssi::command_bind('trackbar markvisible' => 'cmd_markvisible');
+Irssi::command_bind('trackbar markall' => 'cmd_markall');
+Irssi::command_bind('trackbar remove' => 'cmd_trackbar_remove_one');
+Irssi::command_bind('trackbar removeall' => 'cmd_remove_all_trackbars');
+Irssi::command_bind('trackbar redraw' => 'redraw_trackbars');
+Irssi::command_bind('trackbar' => 'trackbar_runsub');
+Irssi::command_bind('mark' => 'cmd_mark');
+Irssi::command_bind_last('help' => 'cmd_help');
+
+Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'trackbar_loaded', $IRSSI{name}, $VERSION, $IRSSI{authors});
+
+# workaround for issue #271
+{ package Irssi::Nick }