summaryrefslogtreecommitdiffstats
path: root/irssi
diff options
context:
space:
mode:
authorjluehrs2 <jluehrs2@uiuc.edu>2008-11-13 13:21:04 -0500
committerjluehrs2 <jluehrs2@uiuc.edu>2008-11-13 13:21:04 -0500
commitead7fb900518ba6e11676268ce6bc37495adf5a6 (patch)
tree1a64b21b70a2ff961b5b3fad68a3e594cedf476c /irssi
parent4a9f06a419bd1fbd1c5216d3c6268f6b9938a075 (diff)
downloadconf-ead7fb900518ba6e11676268ce6bc37495adf5a6.tar.gz
conf-ead7fb900518ba6e11676268ce6bc37495adf5a6.zip
add my irssi configuration
Diffstat (limited to 'irssi')
-rw-r--r--irssi/config353
-rw-r--r--irssi/scripts/all.pl30
-rw-r--r--irssi/scripts/autowrap.pl38
-rw-r--r--irssi/scripts/bitlbee_join_notice.pl94
-rw-r--r--irssi/scripts/bitlbee_status_notice.pl172
-rw-r--r--irssi/scripts/bitlbee_typing_notice.pl320
-rw-r--r--irssi/scripts/chanact.pl481
-rw-r--r--irssi/scripts/gobots.pl37
-rw-r--r--irssi/scripts/hilightwin.pl44
-rw-r--r--irssi/scripts/nickcolor.pl156
-rw-r--r--irssi/scripts/nicklist.pl611
-rw-r--r--irssi/scripts/thistory.pl159
-rw-r--r--irssi/scripts/trackbar.pl189
13 files changed, 2684 insertions, 0 deletions
diff --git a/irssi/config b/irssi/config
new file mode 100644
index 0000000..7d3db05
--- /dev/null
+++ b/irssi/config
@@ -0,0 +1,353 @@
+servers = (
+ { address = "irc.stealth.net"; chatnet = "IRCnet"; port = "6668"; },
+ {
+ address = "irc.efnet.net";
+ chatnet = "EFNet";
+ port = "6667";
+ autoconnect = "yes";
+ },
+ {
+ address = "irc.undernet.org";
+ chatnet = "Undernet";
+ port = "6667";
+ },
+ { address = "irc.dal.net"; chatnet = "DALnet"; port = "6667"; },
+ {
+ address = "irc.quakenet.org";
+ chatnet = "QuakeNet";
+ port = "6667";
+ },
+ { address = "silc.silcnet.org"; chatnet = "SILC"; port = "706"; },
+ {
+ address = "irc.freenode.net";
+ chatnet = "freenode";
+ port = "6667";
+ use_ssl = "no";
+ ssl_verify = "no";
+ autoconnect = "yes";
+ }
+);
+
+chatnets = {
+ IRCnet = {
+ type = "IRC";
+ max_kicks = "4";
+ max_msgs = "5";
+ max_whois = "4";
+ max_query_chans = "5";
+ };
+ EFNet = {
+ type = "IRC";
+ max_kicks = "4";
+ max_msgs = "3";
+ max_whois = "1";
+ };
+ Undernet = {
+ type = "IRC";
+ max_kicks = "1";
+ max_msgs = "3";
+ max_whois = "30";
+ };
+ DALnet = {
+ type = "IRC";
+ max_kicks = "4";
+ max_msgs = "3";
+ max_whois = "30";
+ };
+ QuakeNet = {
+ type = "IRC";
+ max_kicks = "1";
+ max_msgs = "3";
+ max_whois = "30";
+ };
+ SILC = { type = "SILC"; };
+ freenode = { type = "IRC"; };
+};
+
+channels = (
+ { name = "##nethack-elite"; chatnet = "freenode"; autojoin = "yes"; },
+ { name = "#interhack"; chatnet = "freenode"; autojoin = "yes"; },
+ { name = "#rodney"; chatnet = "freenode"; autojoin = "yes"; },
+ { name = "#netmonster"; chatnet = "EFNet"; autojoin = "yes"; },
+ { name = "#alephone"; chatnet = "freenode"; autojoin = "yes"; },
+ { name = "##crawl"; chatnet = "freenode"; autojoin = "yes"; }
+);
+
+aliases = {
+ J = "join";
+ WJOIN = "join -window";
+ WQUERY = "query -window";
+ LEAVE = "part";
+ BYE = "quit";
+ EXIT = "quit";
+ SIGNOFF = "quit";
+ DESCRIBE = "action";
+ DATE = "time";
+ HOST = "userhost";
+ LAST = "lastlog";
+ SAY = "msg *";
+ WI = "whois";
+ WII = "whois $0 $0";
+ WW = "whowas";
+ W = "who";
+ N = "names";
+ M = "msg";
+ T = "topic";
+ C = "clear";
+ CL = "clear";
+ K = "kick";
+ KB = "kickban";
+ KN = "knockout";
+ BANS = "ban";
+ B = "ban";
+ MUB = "unban *";
+ UB = "unban";
+ IG = "ignore";
+ UNIG = "unignore";
+ SB = "scrollback";
+ UMODE = "mode $N";
+ WC = "window close";
+ WN = "window new hide";
+ SV = "say Irssi $J ($V) - http://irssi.org/";
+ GOTO = "sb goto";
+ CHAT = "dcc chat";
+ RUN = "SCRIPT LOAD";
+ UPTIME = "eval exec - expr `date +%s` - \\$F | awk '{print \"Irssi uptime: \"int(\\\\\\$1/3600/24)\"d \"int(\\\\\\$1/3600%24)\"h \"int(\\\\\\$1/60%60)\"m \"int(\\\\\\$1%60)\"s\" }'";
+ CALC = "exec - if which bc &>/dev/null\\; then echo '$*' | bc | awk '{print \"$*=\"$$1}'\\; else echo bc was not found\\; fi";
+ SBAR = "STATUSBAR";
+ INVITELIST = "mode $C +I";
+ Q = "QUERY";
+ "MANUAL-WINDOWS" = "set use_status_window off;set autocreate_windows off;set autocreate_query_level none;set autoclose_windows off;set reuse_unused_windows on;save";
+ EXEMPTLIST = "mode $C +e";
+ ATAG = "WINDOW SERVER";
+};
+
+statusbar = {
+ # formats:
+ # when using {templates}, the template is shown only if it's argument isn't
+ # empty unless no argument is given. for example {sb} is printed always,
+ # but {sb $T} is printed only if $T isn't empty.
+
+ items = {
+ # start/end text in statusbars
+ barstart = "{sbstart}";
+ barend = "{sbend}";
+
+ topicbarstart = "{topicsbstart}";
+ topicbarend = "{topicsbend}";
+
+ # treated "normally", you could change the time/user name to whatever
+ time = "{sb $Z}";
+ user = "{sb {sbnickmode $cumode}$N{sbmode $usermode}{sbaway $A}}";
+
+ # treated specially .. window is printed with non-empty windows,
+ # window_empty is printed with empty windows
+ window = "{sb $winref:$itemname{sbmode $M}}";
+ window_empty = "{sb $winref{sbservertag $tag}}";
+ prompt = "{prompt $[.15]itemname}";
+ prompt_empty = "{prompt $winname}";
+ topic = " $topic";
+ topic_empty = " Irssi v$J - http://irssi.org/help/";
+
+ # all of these treated specially, they're only displayed when needed
+ lag = "{sb Lag: $0-}";
+ act = "{sb Act: $0-}";
+ more = "-- more --";
+ };
+
+ # there's two type of statusbars. root statusbars are either at the top
+ # of the screen or at the bottom of the screen. window statusbars are at
+ # the top/bottom of each split window in screen.
+ default = {
+ # the "default statusbar" to be displayed at the bottom of the window.
+ # contains all the normal items.
+ window = {
+ disabled = "no";
+
+ # window, root
+ type = "window";
+ # top, bottom
+ placement = "bottom";
+ # number
+ position = "1";
+ # active, inactive, always
+ visible = "active";
+
+ # list of items in statusbar in the display order
+ items = {
+ barstart = { priority = "100"; };
+ time = { };
+ user = { };
+ window = { };
+ window_empty = { };
+ lag = { priority = "-1"; };
+ more = { priority = "-1"; alignment = "right"; };
+ barend = { priority = "100"; alignment = "right"; };
+ typing_notice = { };
+ };
+ };
+
+ # statusbar to use in inactive split windows
+ window_inact = {
+ type = "window";
+ placement = "bottom";
+ position = "1";
+ visible = "inactive";
+ items = {
+ barstart = { priority = "100"; };
+ window = { };
+ window_empty = { };
+ more = { priority = "-1"; alignment = "right"; };
+ barend = { priority = "100"; alignment = "right"; };
+ };
+ };
+
+ # we treat input line as yet another statusbar :) It's possible to
+ # add other items before or after the input line item.
+ prompt = {
+ type = "root";
+ placement = "bottom";
+ # we want to be at the bottom always
+ position = "100";
+ visible = "always";
+ items = {
+ prompt = { priority = "-1"; };
+ prompt_empty = { priority = "-1"; };
+ # treated specially, this is the real input line.
+ input = { priority = "10"; };
+ };
+ };
+
+ # topicbar
+ topic = {
+ type = "root";
+ placement = "top";
+ position = "1";
+ visible = "always";
+ items = {
+ topicbarstart = { priority = "100"; };
+ topic = { };
+ topic_empty = { };
+ topicbarend = { priority = "100"; alignment = "right"; };
+ };
+ disabled = "yes";
+ };
+ chanact = {
+ type = "root";
+ placement = "top";
+ position = "1";
+ visible = "always";
+ items = { chanact = { priority = "10"; }; };
+ };
+ };
+};
+settings = {
+ core = {
+ real_name = "doy";
+ user_name = "doy";
+ nick = "doy";
+ awaylog_level = "";
+ awaylog_file = "";
+ };
+ "fe-common/core" = { autolog = "yes"; };
+ "perl/core/scripts" = {
+ chanact_abbreviate_names = "2";
+ chanact_show_all = "yes";
+ gobots_filter_nicks = "Henzell,Gretell";
+ nicklist_width = "13";
+ chanact_chop_status = "yes";
+ bitlbee_typing_allwin = "yes";
+ };
+ "fe-text" = { autostick_split_windows = "no"; };
+ "irc/core" = { usermode = "+i"; };
+};
+logs = { };
+hilights = ( { text = "doy"; nick = "yes"; word = "yes"; } );
+notifies = { };
+windows = {
+ 1 = {
+ immortal = "yes";
+ name = "(status)";
+ level = "ALL";
+ sticky = "yes";
+ };
+ 2 = {
+ items = (
+ {
+ type = "CHANNEL";
+ chat_type = "IRC";
+ name = "##nethack-elite";
+ tag = "freenode";
+ }
+ );
+ sticky = "yes";
+ parent = "1";
+ };
+ 17 = { name = "all"; sticky = "yes"; parent = "1"; };
+ 7 = {
+ items = (
+ {
+ type = "CHANNEL";
+ chat_type = "IRC";
+ name = "##crawl";
+ tag = "freenode";
+ }
+ );
+ sticky = "yes";
+ parent = "1";
+ };
+ 3 = {
+ items = (
+ {
+ type = "CHANNEL";
+ chat_type = "IRC";
+ name = "#interhack";
+ tag = "freenode";
+ }
+ );
+ sticky = "yes";
+ parent = "1";
+ };
+ 4 = {
+ items = (
+ {
+ type = "CHANNEL";
+ chat_type = "IRC";
+ name = "#rodney";
+ tag = "freenode";
+ }
+ );
+ sticky = "yes";
+ parent = "1";
+ };
+ 19 = { sticky_refnum = "yes"; name = "bots"; sticky = "yes"; };
+ 6 = {
+ items = (
+ {
+ type = "CHANNEL";
+ chat_type = "IRC";
+ name = "#alephone";
+ tag = "freenode";
+ }
+ );
+ sticky = "yes";
+ parent = "1";
+ };
+ 5 = {
+ items = (
+ {
+ type = "CHANNEL";
+ chat_type = "IRC";
+ name = "#netmonster";
+ tag = "EFNet";
+ }
+ );
+ sticky = "yes";
+ parent = "1";
+ };
+ 18 = { name = "hilight"; sticky = "yes"; parent = "19"; };
+};
+mainwindows = {
+ 1 = { first_line = "6"; lines = "17"; };
+ 19 = { first_line = "0"; lines = "6"; };
+};
diff --git a/irssi/scripts/all.pl b/irssi/scripts/all.pl
new file mode 100644
index 0000000..4093bbe
--- /dev/null
+++ b/irssi/scripts/all.pl
@@ -0,0 +1,30 @@
+use strict;
+use vars qw($VERSION %IRSSI);
+
+use Irssi qw(signal_add signal_stop window_find_name settings_add_str
+ settings_get_str);
+$VERSION = "0.01";
+%IRSSI = (
+ authors => 'Jesse Luehrs',
+ contact => 'jluehrs2@uiuc.edu',
+ name => 'all',
+ license => 'BSD',
+ changed => 'September 22, 2008',
+ description => 'Copy all incoming messages into a separate "all" window',
+);
+
+use warnings;
+
+signal_add 'message public' => sub {
+ my ($server, $msg, $nick, $address, $target) = @_;
+ my $window = window_find_name 'all';
+ return unless $window;
+ return if $nick eq 'Henzell' || $nick eq 'Gretell' || $nick eq 'Doryen' ||
+ $nick eq 'dataninja' || $nick eq 'arcaneh1' ||
+ $msg =~ /^(?:\?\?|!|\@|#|arcaneh1:)/;
+ $window->print(sprintf("%s: <%s> %s", $target, $nick, $msg),
+ MSGLEVEL_CLIENTCRAP | MSGLEVEL_NO_ACT);
+};
+
+my $window = window_find_name 'all';
+print 'Create a window named \'all\'' unless $window;
diff --git a/irssi/scripts/autowrap.pl b/irssi/scripts/autowrap.pl
new file mode 100644
index 0000000..c110c91
--- /dev/null
+++ b/irssi/scripts/autowrap.pl
@@ -0,0 +1,38 @@
+use strict;
+use Text::Wrap;
+
+use vars qw($VERSION %IRSSI);
+$VERSION = '2007031900';
+%IRSSI = (
+ authors => 'Bitt Faulk',
+ contact => 'lxsfx3h02@sneakemail.com',
+ name => 'autowrap',
+ description => 'Automatically wraps long sent messages into multiple shorter sent messages',
+ license => 'BSD',
+ url => 'none',
+ modules => 'Text::Wrap',
+);
+
+sub event_send_text () {
+ my ($line, $server_rec, $wi_item_rec) = @_;
+ my @shortlines;
+ if (length($line) <= 400) {
+ return;
+ } else {
+ # split line, recreate multiple "send text" events
+ local($Text::Wrap::columns) = 400;
+ @shortlines = split(/\n/,wrap('','',$line));
+ foreach (@shortlines) {
+ if ($_ >= 400) {
+ Irssi::print("autowrap: unable to split long line. sent as-is");
+ return;
+ }
+ }
+ foreach (@shortlines) {
+ Irssi::signal_emit('send text', $_, $server_rec, $wi_item_rec);
+ }
+ Irssi::signal_stop();
+ }
+}
+
+Irssi::signal_add_first('send text', "event_send_text");
diff --git a/irssi/scripts/bitlbee_join_notice.pl b/irssi/scripts/bitlbee_join_notice.pl
new file mode 100644
index 0000000..d9ec5ac
--- /dev/null
+++ b/irssi/scripts/bitlbee_join_notice.pl
@@ -0,0 +1,94 @@
+#CHANGELOG:
+#
+#28-11-2004:
+#it gives a join message in a query if a user joins &bitlbee and you hve a query open with that person.
+#
+#/statusbar window add join_notice
+#use Data::Dumper;
+
+use strict;
+#use Irssi::TextUI;
+#use Irssi::Themes;
+
+use vars qw($VERSION %IRSSI);
+
+$VERSION = '1.2';
+%IRSSI = (
+ authors => 'Tijmen "timing" Ruizendaal',
+ contact => 'tijmen.ruizendaal@gmail.com',
+ name => 'BitlBee_join_notice',
+ description => ' 1. Adds an item to the status bar wich shows [joined: <nicks>] when someone is joining &bitlbee.
+ 2. Shows join messages in the query.',
+ license => 'GPLv2',
+ url => 'http://the-timing.nl/stuff/irssi-bitlbee',
+ changed => '2006-10-27',
+);
+my %online;
+my %tag;
+my $bitlbee_channel= "&bitlbee";
+my $bitlbee_server_tag="localhost";
+
+get_channel();
+
+Irssi::signal_add_last 'channel sync' => sub {
+ my( $channel ) = @_;
+ if( $channel->{topic} eq "Welcome to the control channel. Type \x02help\x02 for help information." ){
+ $bitlbee_server_tag = $channel->{server}->{tag};
+ $bitlbee_channel = $channel->{name};
+ }
+};
+
+sub get_channel {
+ my @channels = Irssi::channels();
+ foreach my $channel(@channels) {
+ if ($channel->{topic} eq "Welcome to the control channel. Type \x02help\x02 for help information.") {
+ $bitlbee_channel = $channel->{name};
+ $bitlbee_server_tag = $channel->{server}->{tag};
+ return 1;
+ }
+ }
+ return 0;
+}
+
+sub event_join {
+ my ($server, $channel, $nick, $address) = @_;
+ if ($channel eq ":$bitlbee_channel" && $server->{tag} eq $bitlbee_server_tag){
+ $online{$nick} = 1;
+ Irssi::timeout_remove($tag{$nick});
+ $tag{$nick} = Irssi::timeout_add(7000, 'empty', $nick);
+ Irssi::statusbar_items_redraw('join_notice');
+ my $window = Irssi::window_find_item($nick);
+ if($window){
+ $window->printformat(MSGLEVEL_JOINS, 'join', $nick, $address, $bitlbee_channel);
+ }
+ }
+}
+sub join_notice {
+ my ($item, $get_size_only) = @_;
+ my $line;
+ foreach my $key (keys(%online) )
+ {
+ $line = $line." ".$key;
+ }
+ if ($line ne "" ){
+ $item->default_handler($get_size_only, "{sb joined:$line}", undef, 1);
+ $line = "";
+ }else{
+ $item->default_handler($get_size_only, "", undef, 1);
+ }
+}
+sub empty{
+ my $nick = shift;
+ delete($online{$nick});
+ Irssi::timeout_remove($tag{$nick});
+ Irssi::statusbar_items_redraw('join_notice');
+}
+
+Irssi::signal_add("event join", "event_join");
+Irssi::statusbar_item_register('join_notice', undef, 'join_notice');
+Irssi::statusbars_recreate_items();
+Irssi::theme_register([
+ 'join', '{channick_hilight $0} {chanhost $1} has joined {channel $2}',
+]);
+
+
diff --git a/irssi/scripts/bitlbee_status_notice.pl b/irssi/scripts/bitlbee_status_notice.pl
new file mode 100644
index 0000000..839d453
--- /dev/null
+++ b/irssi/scripts/bitlbee_status_notice.pl
@@ -0,0 +1,172 @@
+# bitlbee_status_notice.pl
+# Adds detailed information about status changed to bitlbee query windows
+# Information about known offline, online, and away durations will be printed
+# to open query windows of buddies. Away messages will also be asked for when
+# using the Oscar network.
+
+# To use:
+# Set the correct values for $bitlbee_* below, and then:
+# /script load bitlbee_status_notice.pl
+
+# Settings:
+# /set bitlbee_hide_joins ON|OFF
+# Prevents joins from showing up in #bitlbee control channel when buddies
+# sign on
+# /set bitlbee_hide_quits ON|OFF
+# Same for buddies signing off, except it also applies to query windows,
+# because Irssi shows quit notices in query windows automatically.
+# Both settings are ON by default (joins and quits are hidden)
+
+# Tip: to ignore root's mode changes (when away_devoice = true), use:
+# /ignore -channels &bitlbee root!*@* MODES
+
+
+# TODO
+# Make server tag and channel settings
+
+use Data::Dumper;
+use strict;
+use Irssi::TextUI;
+use Time::Duration;
+
+use vars qw($VERSION %IRSSI);
+
+$VERSION = '1.3';
+%IRSSI = (
+ authors => 'Matt "f0rked" Sparks',
+ contact => 'root@f0rked.com',
+ name => 'bitlbee_status_notice',
+ description => 'Adds detailed information about status changes to bitlbee query windows',
+ license => 'GPLv2',
+ url => 'http://f0rked.com',
+ changed => '2005-12-05',
+);
+
+my $bitlbee_channel="&bitlbee";
+my $bitlbee_server_tag="localhost";
+
+my %away_watch;
+my %away_times;
+my %online_times;
+my %offline_times;
+
+my $hide_it;
+my $requested_info;
+
+Irssi::theme_register([
+ 'state_away', '{channick $0} {chanhost $1} has gone away',
+ 'state_back', '{channick_hilight $0} {chanhost_hilight $1} has come back$2',
+ 'away_msg', '{chanhost msg} $0',
+ 'join', '{channick_hilight $0} {chanhost_hilight $1} has signed on$2',
+ 'quit', '{channick $0} {chanhost $1} has signed off$2',
+]);
+
+Irssi::signal_add_last 'channel sync' => sub {
+ my($channel)=@_;
+ if ($channel->{topic} eq "Welcome to the control channel. Type \x02help\x02 for help information.") {
+ $bitlbee_server_tag=$channel->{server}->{tag};
+ $bitlbee_channel=$channel->{name};
+ }
+};
+
+sub event_join {
+ my($server,$channel,$nick,$address)=@_;
+ if ($channel eq $bitlbee_channel && $server->{tag} eq $bitlbee_server_tag) {
+ my $off_time; $off_time=time-$offline_times{$nick} if $offline_times{$nick};
+ delete($offline_times{$nick}) if $offline_times{$nick};
+ my $str; $str=" (last seen: ".ago_exact($off_time).")" if $off_time;
+ $online_times{$nick}=time;
+ my $window = $server->query_find($nick);
+ if ($window) {
+ $window->printformat(MSGLEVEL_JOINS,"join",$nick,$address,$str);
+ }
+ Irssi::signal_stop() # don't print the join announcement in &bitlbee
+ if Irssi::settings_get_bool("bitlbee_hide_joins");
+ }
+}
+
+sub event_quit {
+ my($server,$nick,$address,$reason)=@_;
+ if ($server->{tag} eq $bitlbee_server_tag) {
+ my $on_time; $on_time=time-$online_times{$nick} if $online_times{$nick};
+ delete($online_times{$nick}) if $online_times{$nick};
+ my $str; $str=" (duration: ".duration($on_time).")" if $on_time;
+ $offline_times{$nick}=time;
+ my $window = $server->query_find($nick);
+ if ($window) {
+ $window->printformat(MSGLEVEL_QUITS,"quit",$nick,$address,$str);
+ }
+ Irssi::signal_stop() # don't print the quit announcement anywhere
+ if Irssi::settings_get_bool("bitlbee_hide_quits");
+ }
+}
+
+sub event_mode {
+ my($channel,$nick,$setby,$mode,$type)=@_;
+ #print Dumper $nick;
+ #print Dumper $channel;
+ if ($mode eq "+" && $channel->{name} eq $bitlbee_channel && $channel->{server}->{tag} eq $bitlbee_server_tag) {
+ my $window=$channel->{server}->query_find($nick->{nick});
+ my $gone_time;
+
+ if ($type eq "-") {
+ $away_times{$nick->{nick}}=time;
+ }
+ elsif ($type eq "+") {
+ if (my $time=$away_times{$nick->{nick}}) {
+ $gone_time=time-$time;
+ delete($away_times{$nick->{nick}});
+ }
+ }
+
+ if ($window) {
+ if ($type eq "+") {
+ my $gone_str; $gone_str=" (gone: ".duration($gone_time).")" if $gone_time;
+ $window->printformat(MSGLEVEL_MODES,"state_back",$nick->{nick},$nick->{host},$gone_str)
+ if (time-$online_times{$nick->{nick}} > 2);
+ }
+ elsif ($type eq "-") {
+ $window->printformat(MSGLEVEL_MODES,"state_away",$nick->{nick},$nick->{host});
+ if ($nick->{host} =~ /login\.oscar\.aol\.com$/) {
+ $away_watch{nick}=$nick->{nick};
+ $channel->{server}->send_message($channel->{name},"info $nick->{nick}",0);
+ $requested_info=1;
+ }
+ }
+ }
+ }
+}
+
+sub pub_msg {
+ my($server,$msg,$nick,$address,$target)=@_;
+ #print "$msg $nick $address $target";
+ if ($nick eq "root" && $server->{tag} eq $bitlbee_server_tag && $target eq $bitlbee_channel) {
+ my $window=$server->channel_find($target);
+ if ($window) {
+ my $qwin;
+ $qwin = $server->query_find($away_watch{nick}) if $away_watch{nick};
+ if ($msg =~ /TOC\(?.*\)? - Away Message/g) {
+ $away_watch{watch}=1;
+ $hide_it=1 if $requested_info;
+ Irssi::timeout_add_once(400,sub{$hide_it=0;$requested_info=0;},"");
+ #$qwin->print("Away message:",MSGLEVEL_CRAP) if $qwin;
+ }
+ elsif ($msg =~ /^TOC\(?.*\)? \- .+$/) {
+ delete($away_watch{watch});
+ delete($away_watch{nick});
+ }
+ elsif ($away_watch{watch} && $qwin) {
+ $qwin->printformat(MSGLEVEL_CRAP,"away_msg",$msg) if $qwin;
+ }
+ }
+ Irssi::signal_stop if $hide_it;
+ }
+}
+
+Irssi::settings_add_bool("bitlbee","bitlbee_hide_joins",1);
+Irssi::settings_add_bool("bitlbee","bitlbee_hide_quits",1);
+
+Irssi::signal_add("message public","pub_msg");
+Irssi::signal_add("nick mode changed","event_mode");
+Irssi::signal_add("message join", "event_join");
+Irssi::signal_add("message quit", "event_quit");
diff --git a/irssi/scripts/bitlbee_typing_notice.pl b/irssi/scripts/bitlbee_typing_notice.pl
new file mode 100644
index 0000000..3c2968c
--- /dev/null
+++ b/irssi/scripts/bitlbee_typing_notice.pl
@@ -0,0 +1,320 @@
+# INSTALLATION
+# [&bitlbee] set typing_notice true
+# <@root> typing_notice = `true'
+# AND
+# /statusbar window add typing_notice
+#
+# SETTINGS
+# [bitlbee]
+# bitlbee_send_typing = ON
+# -> send typing messages to buddies
+# bitlbee_typing_allwin = OFF
+# -> show typing notifications in all windows
+#
+#
+# Changelog:
+#
+# 2006-11-02 (version 1.6.1_
+# * Sending typing works again.
+#
+# 2006-10-27 (version 1.6)
+# * 'channel sync' re-implemented.
+# * bitlbee_send_typing was a string setting, It's a boolean now, like it should.
+#
+# 2006-10-24 (version 1.5)
+#
+# * Sending notices to online users only.
+# * Using the new get_channel function;
+#
+# 2005-12-15 (version 1.42):
+# * Fixed small bug with typing notices disappearing under certain circumstances
+# in channels
+# * Fixed bug that caused outgoing notifications not to work
+# * root cares not about our typing status.
+#
+# 2005-12-04 (version 1.41):
+# * Implemented stale states in statusbar (shows "(stale)" for OSCAR connections)
+# * Introduced bitlbee_typing_allwin (default OFF). Set this to ON to make
+# typing notifications visible in all windows.
+#
+# 2005-12-03 (version 1.4):
+# * Major code cleanups and rewrites for bitlbee 1.0 with the updated typing
+# scheme. TYPING 0, TYPING 1, and TYPING 2 are now supported from the server.
+# * Stale states (where user has typed in text but has stopped typing) are now
+# recognized.
+# * Bug where user thinks you are still typing if you close the window after
+# typing something and then erasing it quickly.. fixed.
+# * If a user signs off while they are still typing, the notification is removed
+# This update by Matt "f0rked" Sparks
+#
+# 2005-08-26:
+# Some fixes for AIM, Thanks to Dracula.
+#
+# 2005-08-16:
+# AIM supported, for sending notices, using CTCP TYPING 0. (Use the AIM patch from Hanji http://get.bitlbee.org/patches/)
+#
+# 2004-10-31:
+# Sends typing notice to the bitlbee server when typing a message in irssi. bitlbee > 0.92
+#
+# 2004-06-11:
+# shows [typing: ] in &bitlbee with multiple users.
+#
+use strict;
+use Irssi::TextUI;
+
+use vars qw($VERSION %IRSSI);
+
+$VERSION = '1.6.1';
+%IRSSI = (
+ authors => 'Tijmen "timing" Ruizendaal, Matt "f0rked" Sparks',
+ contact => 'tijmen.ruizendaal@gmail.com, root@f0rked.com',
+ name => 'BitlBee_typing_notice',
+ description => '1. Adds an item to the status bar wich shows [typing] when someone is typing a message on the supported IM-networks
+ 2. Sending typing notices to the supported IM networks (the other way arround)',
+ license => 'GPLv2',
+ url => 'http://the-timing.nl/stuff/irssi-bitlbee,
+ http://f0rked.com',
+ changed => '2006-11-02',
+);
+
+my $bitlbee_channel = "&bitlbee";
+my $bitlbee_server_tag = "localhost";
+
+my $KEEP_TYPING_TIMEOUT = 1;
+my $STOP_TYPING_TIMEOUT = 7; # How often to check if we are typing, or on msn,
+ # how long to keep the typing notice up, or check
+ # if the other user is still typing...
+
+my %timer_tag;
+
+my %typing;
+my %tag;
+my $line;
+my %out_typing;
+my $lastkey;
+my $keylog_active = 1;
+my $command_char = Irssi::settings_get_str('cmdchars');
+my $to_char = Irssi::settings_get_str("completion_char");
+
+get_channel();
+
+Irssi::signal_add_last 'channel sync' => sub {
+ my( $channel ) = @_;
+ if( $channel->{topic} eq "Welcome to the control channel. Type \x02help\x02 for help information." ){
+ $bitlbee_server_tag = $channel->{server}->{tag};
+ $bitlbee_channel = $channel->{name};
+ }
+};
+
+sub get_channel {
+ my @channels = Irssi::channels();
+ foreach my $channel(@channels) {
+ if ($channel->{topic} eq "Welcome to the control channel. Type \x02help\x02 for help information.") {
+ $bitlbee_channel = $channel->{name};
+ $bitlbee_server_tag = $channel->{server}->{tag};
+ return 1;
+ }
+ }
+ return 0;
+}
+
+sub event_ctcp_msg {
+ my ($server, $msg, $from, $address) = @_;
+ #print "CTCP: $msg $from $address";
+ return if $server->{tag} ne $bitlbee_server_tag;
+ if (my($type) = $msg =~ "TYPING ([0-9])") {
+ Irssi::signal_stop();
+ if ($type == 0) {
+ unset_typing($from);
+ }
+ elsif ($type == 1) {
+ $typing{$from}=1;
+ if ($address !~ /\@login\.oscar\.aol\.com/
+ and $address !~ /\@YAHOO/
+ and $address !~ /\@login\.icq\.com/) {
+ Irssi::timeout_remove($tag{$from});
+ $tag{$from}=Irssi::timeout_add_once($STOP_TYPING_TIMEOUT*1000,"unset_typing",$from);
+ }
+ redraw($from);
+ }
+ elsif ($type == 2) {
+ stale_typing($from);
+ }
+ }
+}
+
+sub unset_typing {
+ my($from,$no_redraw)=@_;
+ delete $typing{$from} if $typing{$from};
+ Irssi::timeout_remove($tag{$from});
+ redraw($from) if !$no_redraw;
+}
+
+sub stale_typing {
+ my($from)=@_;
+ $typing{$from}=2;
+ redraw($from);
+}
+
+sub redraw {
+ my($from)=@_;
+ my $window = Irssi::active_win();
+ my $channel = $window->get_active_name();
+ if ($from eq $channel || $channel eq $bitlbee_channel
+ || $channel =~ /&chat_0/
+ || Irssi::settings_get_bool("bitlbee_typing_allwin")) {
+ Irssi::statusbar_items_redraw('typing_notice');
+ }
+}
+
+sub event_msg {
+ my ($server,$data,$from,$address,$target) = @_;
+ return if $server->{tag} ne $bitlbee_server_tag;
+ my $channel=Irssi::active_win()->get_active_name();
+ unset_typing $from, "no redraw";
+ unset_typing $channel;
+}
+
+sub event_quit {
+ my($server,$nick,$address,$reason)=@_;
+ return if $server->{tag} ne $bitlbee_server_tag;
+ unset_typing $nick;
+}
+
+sub typing_notice {
+ my ($item, $get_size_only) = @_;
+ my $window = Irssi::active_win();
+ my $channel = $window->get_active_name();
+
+ if (exists($typing{$channel})) {
+ my $append=$typing{$channel}==2 ? " (stale)" : "";
+ $item->default_handler($get_size_only, "{sb typing$append}", 0, 1);
+ }
+ else {
+ $item->default_handler($get_size_only, "", 0, 1);
+ Irssi::timeout_remove($tag{$channel});
+ }
+ if ($channel eq $bitlbee_channel || $channel =~ /&chat_0/
+ || Irssi::settings_get_bool("bitlbee_typing_allwin")) {
+ foreach my $key (keys(%typing)) {
+ $line .= " ".$key;
+ if ($typing{$key}==2) { $line .= " (stale)"; }
+ }
+ if ($line ne "") {
+ $item->default_handler($get_size_only, "{sb typing:$line}", 0, 1);
+ $line = "";
+ }
+ }
+}
+
+sub empty {
+ my $from = shift;
+ delete($typing{$from});
+ Irssi::statusbar_items_redraw('typing_notice');
+}
+
+sub window_change {
+ Irssi::statusbar_items_redraw('typing_notice');
+ my $win = !Irssi::active_win() ? undef : Irssi::active_win()->{active};
+ if (ref $win && ($win->{server}->{tag} eq $bitlbee_server_tag)) {
+ if (!$keylog_active) {
+ $keylog_active = 1;
+ Irssi::signal_add_last('gui key pressed', 'key_pressed');
+ #print "Keylog started";
+ }
+ }
+ else {
+ if ($keylog_active) {
+ $keylog_active = 0;
+ Irssi::signal_remove('gui key pressed', 'key_pressed');
+ #print "Keylog stopped";
+ }
+ }
+}
+
+sub key_pressed {
+ return if !Irssi::settings_get_bool("bitlbee_send_typing");
+ my $key = shift;
+ if ($key != 9 && $key != 10 && $lastkey != 27 && $key != 27
+ && $lastkey != 91 && $key != 126 && $key != 127)
+ {
+ my $server = Irssi::active_server();
+ my $window = Irssi::active_win();
+ my $nick = $window->get_active_name();
+ if ($server->{tag} eq $bitlbee_server_tag &&
+ $nick ne "(status)" &&
+ $nick ne "root")
+ {
+ if ($nick eq $bitlbee_channel) {
+ my $input = Irssi::parse_special("\$L");
+ my ($first_word) = split(/ /,$input);
+ if ($input !~ /^$command_char.*/ && $first_word =~ s/$to_char$//){
+ send_typing($first_word);
+ }
+ }
+ else {
+ my $input = Irssi::parse_special("\$L");
+ if ($input !~ /^$command_char.*/ && length($input) > 0){
+ send_typing($nick);
+ }
+ }
+ }
+ }
+ $lastkey = $key;
+}
+
+sub out_empty {
+ my ($a) = @_;
+ my($nick,$tag)=@{$a};
+ delete($out_typing{$nick});
+ #print $winnum."|".$nick;
+ if (my $server=Irssi::server_find_tag($tag)) {
+ $server->command("^CTCP $nick TYPING 0");
+ }
+}
+
+sub send_typing {
+ my $nick = shift;
+ if (!exists($out_typing{$nick}) || time - $out_typing{$nick} > $KEEP_TYPING_TIMEOUT) {
+
+ my @nicks = Irssi::server_find_tag($bitlbee_server_tag)->channel_find($bitlbee_channel)->nicks();
+ my $exists=0;
+ foreach my $nick1(@nicks) { #check if the nickname is in the BitlBee channel
+ if($nick1->{'nick'} eq $nick) {
+ # print "Exists!";
+ $exists=1;
+ }
+ }
+ if (!$exists) {
+ #print "Does not exist";
+ return;
+ }
+
+ #print "Send typing";
+ my $server = Irssi::active_server();
+ $server->command("^CTCP $nick TYPING 1");
+
+ $out_typing{$nick} = time;
+
+ ### Reset 'stop-typing' timer
+ if ($timer_tag{$nick}) {
+ Irssi::timeout_remove($timer_tag{$nick});
+ delete($timer_tag{$nick});
+ }
+ $timer_tag{$nick} = Irssi::timeout_add_once($STOP_TYPING_TIMEOUT*1000, 'out_empty', ["$nick", $server->{tag}]);
+ }
+}
+
+ #README: Delete the old bitlbee_send_typing string from ~/.irssi/config. A boolean is better.
+
+Irssi::settings_add_bool("bitlbee","bitlbee_send_typing",1);
+Irssi::settings_add_bool("bitlbee","bitlbee_typing_allwin",0);
+
+Irssi::signal_add("ctcp msg", "event_ctcp_msg");
+Irssi::signal_add("message private", "event_msg");
+Irssi::signal_add("message public", "event_msg");
+Irssi::signal_add("message quit", "event_quit");
+Irssi::signal_add_last('window changed', 'window_change');
+Irssi::signal_add_last('gui key pressed', 'key_pressed');
+Irssi::statusbar_item_register('typing_notice', undef, 'typing_notice');
+Irssi::statusbars_recreate_items();
diff --git a/irssi/scripts/chanact.pl b/irssi/scripts/chanact.pl
new file mode 100644
index 0000000..732aecb
--- /dev/null
+++ b/irssi/scripts/chanact.pl
@@ -0,0 +1,481 @@
+use Irssi 20020101.0001 ();
+use strict;
+use Irssi::TextUI;
+
+use vars qw($VERSION %IRSSI);
+
+$VERSION = "0.5.5";
+%IRSSI = (
+ authors => 'BC-bd, Veli',
+ contact => 'bd@bc-bd.org, veli@piipiip.net',
+ name => 'chanact',
+ description => 'Adds new powerful and customizable [Act: ...] item (chanelnames,modes,alias). Lets you give alias characters to windows so that you can select those with meta-<char>',
+ license => 'GNU GPLv2 or later',
+ url => 'http://bc-bd.org/software.php3#irssi'
+);
+
+# Adds new powerful and customizable [Act: ...] item (chanelnames,modes,alias).
+# Lets you give alias characters to windows so that you can select those with
+# meta-<char>.
+#
+# for irssi 0.8.2 by bd@bc-bd.org
+#
+# inspired by chanlist.pl by 'cumol@hammerhart.de'
+#
+#########
+# Contributors
+#########
+#
+# veli@piipiip.net /window_alias code
+# qrczak@knm.org.pl chanact_abbreviate_names
+# qerub@home.se Extra chanact_show_mode and chanact_chop_status
+#
+#########
+# USAGE
+###
+#
+# copy the script to ~/.irssi/scripts/
+#
+# In irssi:
+#
+# /script load chanact
+# /statusbar window add chanact -after act
+#
+# If you want the item to appear on another position read the help
+# for /statusbar.
+# To remove the [Act: 1,2,3] item type:
+#
+# /statusbar window remove act
+#
+# To see all chanact options type:
+#
+# / set chanact_
+#
+# After these steps you have your new statusbar item and you can start giving
+# aliases to your windows. Go to the window you want to give the alias to
+# and say:
+#
+# /window_alias <alias char>
+#
+# You can also remove the aliases with:
+#
+# /window_unalias <alias char>
+#
+# or in aliased window:
+#
+# /window_unalias
+#
+# To see a list of your windows use:
+#
+# /window list
+#
+#########
+# OPTIONS
+#########
+#
+# /set chanact_show_all <ON|OFF>
+# * ON : show all windows
+# * OFF : show only those with activity
+#
+# /set chanact_display <string>
+# * string : Format String for one Channel. The following $'s are expanded:
+# $C : Channel
+# $N : Number of the Window
+# $M : Mode in that channel
+# $H : Start highlightning
+# $S : Stop highlightning
+# * example:
+#
+# /set chanact_display $H$N:$M.$S$C
+#
+# will give you on #irssi.de if you have voice
+#
+# [3:+.#irssi.de]
+#
+# with '3:+.' highlighted and the channel name printed in regular color
+#
+# /set chanact_display_alias <string>
+# as 'chanact_display' but is used if the window has an alias and
+# 'chanact_show_alias' is set to on.
+#
+# /set chanact_show_names <ON|OFF>
+# * ON : show the channelnames after the number/alias
+# * OFF : don't show the names
+#
+# /set chanact_abbreviate_names <int>
+# * 0 : don't abbreviate
+# * <int> : strip channel name prefix character and leave only
+# that many characters of the proper name
+#
+# /set chanact_show_alias <ON|OFF>
+# * ON : show the aliase instead of the refnum
+# * OFF : shot the refnum
+#
+# /set chanact_separator <str>
+# * <str> : Characters to be displayed at the start of the item.
+# Defaults to: "Act: "
+#
+# /set chanact_separator <str>
+# * <str> : Charater to use between the channel entries
+#
+# /set chanact_autorenumber <ON|OFF>
+# * ON : Move the window automatically to first available slot
+# starting from "chanact_renumber_start" when assigning
+# an alias to window. Also moves the window back to a
+# first available slot from refnum 1 when the window
+# loses it's alias.
+# * OFF : Don't move the windows automatically
+#
+# /set chanact_renumber_start <int>
+# * <int> : Move the window to first available slot after this
+# num when "chanact_autorenumber" is ON.
+#
+#
+#########
+# HINTS
+#########
+#
+# If you have trouble with wrong colored entries your 'default.theme' might
+# be too old. Try on a shell:
+#
+# $ mv ~/.irssi/default.theme /tmp/
+#
+# And in irssi:
+# /reload
+# /save
+#
+###
+#################
+
+my ($actString,$needRemake);
+
+sub expand {
+ my ($string, %format) = @_;
+ my ($exp, $repl);
+ $string =~ s/\$$exp/$repl/g while (($exp, $repl) = each(%format));
+ return $string;
+}
+
+# method will get called every time the statusbar item will be displayed
+# but we dont need to recreate the item every time so we first
+# check if something has changed and only then we recreate the string
+# this might just save some cycles
+# FIXME implement $get_size_only check, and user $item->{min|max-size}
+sub chanact {
+ my ($item, $get_size_only) = @_;
+
+ if ($needRemake) {
+ remake();
+ }
+
+ $item->default_handler($get_size_only, $actString, undef, 1);
+}
+
+# this is the real creation method
+sub remake() {
+ my ($afternumber,$finish,$hilight,$mode,$number,$display);
+ my $separator = Irssi::settings_get_str('chanact_separator');
+ my $abbrev = Irssi::settings_get_int('chanact_abbreviate_names');
+
+ $actString = "";
+ foreach my $win (sort { ($a->{refnum}) <=> ($b->{refnum})} Irssi::windows) {
+
+ # since irssi is single threaded this shouldn't happen
+ !ref($win) && next;
+
+ my $name = $win->get_active_name;
+ my $active = $win->{active};
+
+ !ref($win) && next;
+
+ $name eq "all" && next;
+ $name eq "bots" && next;
+ $name eq "hilight" && next;
+
+ # (status) is an awfull long name, so make it short to 'S'
+ # some people don't like it, so make it configurable
+ if (Irssi::settings_get_bool('chanact_chop_status')
+ && $name eq "(status)") {
+ $name = "S";
+ }
+
+ # check if we should show the mode
+ $mode = "";
+ if ($active->{type} eq "CHANNEL") {
+ my $server = $win->{active_server};
+ !ref($server) && next;
+
+ my $channel = $server->channel_find($name);
+ !ref($channel) && next;
+
+ my $nick = $channel->nick_find($server->{nick});
+ !ref($nick) && next;
+
+ if ($nick->{op}) {
+ $mode = "@";
+ } elsif ($nick->{voice}) {
+ $mode = "+";
+ } elsif ($nick->{halfop}) {
+ $mode = "%";
+ }
+ }
+
+ # find the right color
+ if ($win->{data_level} == 1) {
+ $hilight = "{sb_act_text ";
+ } elsif ($win->{data_level} == 2) {
+ $hilight = "{sb_act_msg ";
+ } elsif ($win->{data_level} == 3) {
+ $hilight = "{sb_act_hilight ";
+ } else {
+ if (Irssi::settings_get_bool('chanact_show_all') == 1) {
+ $hilight = "{sb_act_hilight_color %K ";
+ } else {
+ next;
+ }
+ }
+
+ if ($abbrev) {
+ if ($name =~ /^[&#+!=]*(.*)/) {
+ $name = substr($1, 0, $abbrev);
+ }
+ }
+
+ if (Irssi::settings_get_bool('chanact_show_alias') == 1 &&
+ $win->{name} =~ /^[a-zA-Z+]$/) {
+ $number = $win->{name};
+ $display = Irssi::settings_get_str('chanact_display_alias');
+ } else {
+ $number = $win->{refnum};
+ $display = Irssi::settings_get_str('chanact_display');
+ }
+
+ $actString .= expand($display,"C",$name,"N",$number,"M",$mode,"H",$hilight,"S","}{sb_background}").$separator;
+ }
+
+ # assemble the final string
+ if ($actString ne "") {
+ # Remove the last separator
+ $actString =~ s/$separator$//;
+
+ if (Irssi::settings_get_bool('chanact_show_all') == 1) {
+ $actString = "{sb ".$actString."}";
+ } else {
+ $actString = "{sb ".Irssi::settings_get_str('chanact_header').$actString."}";
+ }
+ }
+
+ # no remake needed any longer
+ $needRemake = 0;
+}
+
+# method called because of some events. here we dont remake the item but just
+# remember that we have to remake it the next time we are called
+sub chanactHasChanged()
+{
+ $needRemake = 1;
+
+ Irssi::statusbar_items_redraw('chanact');
+}
+
+# function by veli@piipiip.net
+# Remove alias
+sub cmd_window_unalias {
+ my ($data, $server, $witem) = @_;
+ my $rn_start = Irssi::settings_get_int('chanact_renumber_start');
+
+ unless ($data =~ /^[a-zA-Z]$/ ||
+ Irssi::active_win()->{name} =~ /^[a-zA-Z]$/) {
+ Irssi::print("Usage: /window_unalias <char>");
+ Irssi::print("or /window_alias in window that has an alias.");
+ return;
+ }
+
+ if ($data eq '') { $data = Irssi::active_win()->{name}; }
+
+ if (my $oldwin = Irssi::window_find_name($data)) {
+ $oldwin->set_name(undef);
+ Irssi::print("Removed alias with the key '$data'.");
+
+ if (Irssi::settings_get_bool('chanact_autorenumber') == 1 &&
+ $oldwin->{refnum} >= $rn_start) {
+ my $old_refnum = $oldwin->{refnum};
+
+ # Find the first available slot and move the window
+ my $newnum = 1;
+ while (Irssi::window_find_refnum($newnum) ne "") { $newnum++; }
+ $oldwin->set_refnum($newnum);
+
+ Irssi::print("and moved it to from $old_refnum to $newnum");
+ }
+ }
+}
+
+# function by veli@piipiip.net
+# Make an alias
+sub cmd_window_alias {
+ my ($data, $server, $witem) = @_;
+ my $rn_start = Irssi::settings_get_int('chanact_renumber_start');
+
+ unless ($data =~ /^[a-zA-Z+]$/) {
+ Irssi::print("Usage: /window_alias <char>");
+ return;
+ }
+
+ cmd_window_unalias($data, $server, $witem);
+
+ my $window = $witem->window();
+ my $winnum = $window->{refnum};
+
+ if (Irssi::settings_get_bool('chanact_autorenumber') == 1 &&
+ $window->{refnum} < $rn_start) {
+ my $old_refnum = $window->{refnum};
+
+ $winnum = $rn_start;
+
+ # Find the first available slot and move the window
+ while (Irssi::window_find_refnum($winnum) ne "") { $winnum++; }
+ $window->set_refnum($winnum);
+
+ Irssi::print("Moved the window from $old_refnum to $winnum");
+ }
+
+ $window->set_name($data);
+ $server->command("/bind meta-$data change_window $winnum");
+ Irssi::print("Window $winnum is now known as '$data'");
+}
+
+# function by veli@piipiip.net
+# Makes the aliases if names have already been set
+sub cmd_rebuild_aliases {
+ foreach (sort { $a->{refnum} <=> $b->{refnum} } Irssi::windows) {
+ if ($_->{name} =~ /^[a-zA-Z]$/) {
+ cmd_window_alias($_->{name}, $_->{active_server}, $_->{active});
+ }
+ }
+}
+
+# function by veli@piipiip.net
+# Change the binding if the window refnum changes.
+sub refnum_changed {
+ my ($window, $oldref) = @_;
+ my $server = Irssi::active_server();
+
+ if ($window->{name} =~ /^[a-zA-Z]$/) {
+ $server->command("/bind meta-".$window->{name}." change_window ".$window->{refnum});
+ }
+}
+
+$needRemake = 1;
+
+# Window alias command
+Irssi::command_bind('window_alias','cmd_window_alias');
+Irssi::command_bind('window_unalias','cmd_window_unalias');
+# Irssi::command_bind('window_alias_rebuild','cmd_rebuild_aliases');
+
+# our config item
+Irssi::settings_add_str('chanact', 'chanact_display', '$H$N:$M$C$S');
+Irssi::settings_add_str('chanact', 'chanact_display_alias', '$H$N$M$S');
+Irssi::settings_add_bool('chanact', 'chanact_show_all', 0);
+Irssi::settings_add_int('chanact', 'chanact_abbreviate_names', 0);
+Irssi::settings_add_bool('chanact', 'chanact_show_alias', 1);
+Irssi::settings_add_str('chanact', 'chanact_separator', " ");
+Irssi::settings_add_bool('chanact', 'chanact_autorenumber', 0);
+Irssi::settings_add_int('chanact', 'chanact_renumber_start', 50);
+Irssi::settings_add_str('chanact', 'chanact_header', "Act: ");
+Irssi::settings_add_bool('chanact', 'chanact_chop_status', 1);
+
+# register the statusbar item
+Irssi::statusbar_item_register('chanact', '$0', 'chanact');
+# according to cras we shall not call this
+# Irssi::statusbars_recreate_items();
+
+# register all that nifty callbacks on special events
+Irssi::signal_add_last('setup changed', 'chanactHasChanged');
+Irssi::signal_add_last('window hilight', 'chanactHasChanged');
+Irssi::signal_add("window created", "chanactHasChanged");
+Irssi::signal_add("window destroyed", "chanactHasChanged");
+Irssi::signal_add("window name changed", "chanactHasChanged");
+Irssi::signal_add('nick mode changed', 'chanactHasChanged');
+
+Irssi::signal_add_last('window refnum changed', 'refnum_changed');
+
+###############
+###
+#
+# Changelog
+#
+# 0.5.5
+# - some speedups from David Leadbeater <dgl@dgl.cx>
+#
+# 0.5.4
+# - added help for chanact_display_alias
+#
+# 0.5.3
+# - added '+' to the available chars of aliase's
+# - added chanact_display_alias to allow different display modes if the window
+# has an alias
+#
+# 0.5.2
+# - removed unused chanact_show_name settings (thx to Qerub)
+# - fixed $mode display
+# - guarded reference operations to (hopefully) fix errors on server disconnect
+#
+# 0.5.1
+# - small typo fixed
+#
+# 0.5.0
+# - changed chanact_show_mode to chanact_display. reversed changes from
+# Qerub through that, but kept funcionality.
+# - removed chanact_color_all since it is no longer needed
+#
+# 0.4.3
+# - changes by Qerub
+# + added chanact_show_mode to show the mode just before the channel name
+# + added chanact_chop_status to be able to control the (status) chopping
+# [bd] minor implementation changes
+# - moved Changelog to the end of the file since it is getting pretty big
+#
+# 0.4.2
+# - changed back to old version numbering sheme
+# - added '=' to Qrczak's chanact_abbreviate_names stuff :)
+# - added chanact_header
+#
+# 0.41q
+# - changes by Qrczak
+# + added setting 'chanact_abbreviate_names'
+# + windows are sorted by refnum; I didn't understand the old
+# logic and it broke sorting for numbers above 9
+#
+# 0.41
+# - minor updates
+# + fixed channel sort [veli]
+# + removed few typos and added some documentation [veli]
+#
+# 0.4
+# - merge with window_alias.pl
+# + added /window_alias from window_alias.pl by veli@piipiip.net
+# + added setting 'chanact_show_alias'
+# + added setting 'chanact_show_names'
+# + changed setting 'chanact_show_mode' to int
+# + added setting 'chanact_separator' [veli]
+# + added setting 'chanact_autorenumber' [veli]
+# + added setting 'chanact_renumber_start' [veli]
+# + added /window_unalias [veli]
+# + moved setting to their own group 'chanact' [veli]
+#
+# 0.3
+# - merge with chanlist.pl
+# + added setting 'chanact_show_mode'
+# + added setting 'chanact_show_all'
+#
+# 0.2
+# - added 'Act' to the item
+# - added setting 'chanact_color_all'
+# - finally found format for statusbar hilight
+#
+# 0.1
+# - Initial Release
+#
+###
+################
diff --git a/irssi/scripts/gobots.pl b/irssi/scripts/gobots.pl
new file mode 100644
index 0000000..a3cc2ef
--- /dev/null
+++ b/irssi/scripts/gobots.pl
@@ -0,0 +1,37 @@
+use strict;
+use vars qw($VERSION %IRSSI);
+
+use Irssi qw(signal_add signal_stop window_find_name settings_add_str
+ settings_get_str);
+$VERSION = "0.01";
+%IRSSI = (
+ authors => 'Jesse Luehrs',
+ contact => 'jluehrs2@uiuc.edu',
+ name => 'gobots',
+ license => 'BSD',
+ changed => 'July 29, 2008',
+ description => 'Filters a list of nicks (typically bots) into a separate '.
+ '"bots" window',
+);
+
+use warnings;
+
+signal_add 'message public' => sub {
+ my ($server, $msg, $nick, $address, $target) = @_;
+ my $window = window_find_name 'bots';
+ return unless $window;
+
+ my $botlist = settings_get_str 'gobots_filter_nicks';
+ for (split /,/, $botlist) {
+ if ($_ eq $nick) {
+ $window->print(sprintf("<%s> %s", $nick, $msg),
+ MSGLEVEL_CLIENTCRAP | MSGLEVEL_NO_ACT);
+ signal_stop;
+ return;
+ }
+ }
+};
+
+my $window = window_find_name 'bots';
+print 'Create a window named \'bots\'' unless $window;
+settings_add_str 'misc', 'gobots_filter_nicks', '';
diff --git a/irssi/scripts/hilightwin.pl b/irssi/scripts/hilightwin.pl
new file mode 100644
index 0000000..251a405
--- /dev/null
+++ b/irssi/scripts/hilightwin.pl
@@ -0,0 +1,44 @@
+# Print hilighted messages & private messages to window named "hilight"
+# for irssi 0.7.99 by Timo Sirainen
+use Irssi;
+use vars qw($VERSION %IRSSI);
+use POSIX qw(strftime);
+
+# Tom <tom@tomaw.net:
+# Timestamps
+# Replace colour codes in text
+# Timestamps format
+
+$VERSION = "0.03";
+%IRSSI = (
+ authors => "Timo \'cras\' Sirainen",
+ contact => "tss\@iki.fi",
+ name => "hilightwin",
+ description => "Print hilighted messages & private messages to window named \"hilight\"",
+ license => "Public Domain",
+ url => "http://irssi.org/",
+ changed => "2007-04-17T08:38-0500"
+);
+
+sub sig_printtext {
+ my ($dest, $text, $stripped) = @_;
+
+ if (($dest->{level} & (MSGLEVEL_HILIGHT|MSGLEVEL_MSGS|MSGLEVEL_DCCMSGS)) &&
+ ($dest->{level} & MSGLEVEL_NOHILIGHT) == 0) {
+ $window = Irssi::window_find_name('hilight');
+
+ if ($dest->{level} & MSGLEVEL_PUBLIC) {
+ $text = $dest->{target}.": ".$text;
+ }
+ $text =~ s/\%/%%/g;
+ $now_string = strftime(Irssi::settings_get_str('hilightwin_timestamp'), localtime);
+ $window->print($now_string . ": " . $text, MSGLEVEL_NEVER) if ($window);
+ }
+}
+
+$window = Irssi::window_find_name('hilight');
+Irssi::print("Create a window named 'hilight'") if (!$window);
+
+Irssi::signal_add('print text', 'sig_printtext');
+
+Irssi::settings_add_str('misc', 'hilightwin_timestamp', Irssi::settings_get_str('timestamp_format'));
diff --git a/irssi/scripts/nickcolor.pl b/irssi/scripts/nickcolor.pl
new file mode 100644
index 0000000..69f2936
--- /dev/null
+++ b/irssi/scripts/nickcolor.pl
@@ -0,0 +1,156 @@
+use strict;
+use Irssi 20020101.0250 ();
+use vars qw($VERSION %IRSSI);
+$VERSION = "1";
+%IRSSI = (
+ authors => "Timo Sirainen, Ian Peters",
+ contact => "tss\@iki.fi",
+ name => "Nick Color",
+ description => "assign a different color for each nick",
+ license => "Public Domain",
+ url => "http://irssi.org/",
+ changed => "2002-03-04T22:47+0100"
+);
+
+# hm.. i should make it possible to use the existing one..
+Irssi::theme_register([
+ 'pubmsg_hilight', '{pubmsghinick $0 $3 $1}$2'
+]);
+
+my %saved_colors;
+my %session_colors = {};
+my @colors = qw/2 3 4 5 6 7 9 10 11 12 13/;
+
+sub load_colors {
+ open COLORS, "$ENV{HOME}/.irssi/saved_colors";
+
+ while (<COLORS>) {
+ # I don't know why this is necessary only inside of irssi
+ my @lines = split "\n";
+ foreach my $line (@lines) {
+ my($nick, $color) = split ":", $line;
+ $saved_colors{$nick} = $color;
+ }
+ }
+
+ close COLORS;
+}
+
+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;
+ }
+
+ $counter = $colors[$counter % 11];
+
+ return $counter;
+}
+
+# FIXME: breaks /HILIGHT etc.
+sub sig_public {
+ my ($server, $msg, $nick, $address, $target) = @_;
+ my $chanrec = $server->channel_find($target);
+ return if not $chanrec;
+ my $nickrec = $chanrec->nick_find($nick);
+ return if not $nickrec;
+ my $nickmode = $nickrec->{op} ? "@" : $nickrec->{voice} ? "+" : "";
+
+ # 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 = "0".$color if ($color < 10);
+ $server->command('/^format pubmsg {pubmsgnick $2 {pubnick '.chr(3).$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");
+ } 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::command_bind('color', 'cmd_color');
+
+Irssi::signal_add('message public', 'sig_public');
+Irssi::signal_add('event nick', 'sig_nick');
diff --git a/irssi/scripts/nicklist.pl b/irssi/scripts/nicklist.pl
new file mode 100644
index 0000000..d6d00c6
--- /dev/null
+++ b/irssi/scripts/nicklist.pl
@@ -0,0 +1,611 @@
+# for documentation: see http://wouter.coekaerts.be/site/irssi/nicklist
+
+use Irssi;
+use strict;
+use IO::Handle; # for (auto)flush
+use Fcntl; # for sysopen
+use vars qw($VERSION %IRSSI);
+$VERSION = '0.4.6';
+%IRSSI = (
+ authors => 'Wouter Coekaerts',
+ contact => 'coekie@irssi.org',
+ name => 'nicklist',
+ description => 'draws a nicklist to another terminal, or at the right of your irssi in the same terminal',
+ license => 'GPLv2',
+ url => 'http://wouter.coekaerts.be/irssi',
+ changed => '29/06/2004'
+);
+
+sub cmd_help {
+ print ( <<EOF
+Commands:
+NICKLIST HELP
+NICKLIST SCROLL <nr of lines>
+NICKLIST SCREEN
+NICKLIST FIFO
+NICKLIST OFF
+NICKLIST UPDATE
+
+For help see: http://wouter.coekaerts.be/site/irssi/nicklist
+
+in short:
+
+1. FIFO MODE
+- in irssi: /NICKLIST FIFO (only the first time, to create the fifo)
+- in a shell, in a window where you want the nicklist: cat ~/.irssi/nicklistfifo
+- back in irssi:
+ /SET nicklist_heigth <height of nicklist>
+ /SET nicklist_width <width of nicklist>
+ /NICKLIST FIFO
+
+2. SCREEN MODE
+- start irssi inside screen ("screen irssi")
+- /NICKLIST SCREEN
+EOF
+ );
+}
+
+my $prev_lines = 0; # number of lines in previous written nicklist
+my $scroll_pos = 0; # scrolling position
+my $cursor_line; # line the cursor is currently on
+my ($OFF, $SCREEN, $FIFO) = (0,1,2); # modes
+my $mode = $OFF; # current mode
+my $need_redraw = 0; # nicklist needs redrawing
+my $screen_resizing = 0; # terminal is being resized
+my $active_channel; # (REC)
+
+my @nicklist=(); # array of hashes, containing the internal nicklist of the active channel
+ # nick => realnick
+ # mode =>
+ my ($MODE_OP, $MODE_HALFOP, $MODE_VOICE, $MODE_NORMAL) = (0,1,2,3);
+ # status =>
+ my ($STATUS_NORMAL, $STATUS_JOINING, $STATUS_PARTING, $STATUS_QUITING, $STATUS_KICKED, $STATUS_SPLIT) = (0,1,2,3,4,5);
+ # text => text to be printed
+ # cmp => text used to compare (sort) nicks
+
+
+# 'cached' settings
+my ($screen_prefix, $irssi_width, @prefix_mode, @prefix_status, $height, $nicklist_width);
+
+sub read_settings {
+ ($screen_prefix = Irssi::settings_get_str('nicklist_screen_prefix')) =~ s/\\e/\033/g;
+
+ ($prefix_mode[$MODE_OP] = Irssi::settings_get_str('nicklist_prefix_mode_op')) =~ s/\\e/\033/g;
+ ($prefix_mode[$MODE_HALFOP] = Irssi::settings_get_str('nicklist_prefix_mode_halfop')) =~ s/\\e/\033/g;
+ ($prefix_mode[$MODE_VOICE] = Irssi::settings_get_str('nicklist_prefix_mode_voice')) =~ s/\\e/\033/g;
+ ($prefix_mode[$MODE_NORMAL] = Irssi::settings_get_str('nicklist_prefix_mode_normal')) =~ s/\\e/\033/g;
+
+ if ($mode != $SCREEN) {
+ $height = Irssi::settings_get_int('nicklist_height');
+ }
+ my $new_nicklist_width = Irssi::settings_get_int('nicklist_width');
+ if ($new_nicklist_width != $nicklist_width && $mode == $SCREEN) {
+ sig_terminal_resized();
+ }
+ $nicklist_width = $new_nicklist_width;
+}
+
+sub update {
+ read_settings();
+ make_nicklist();
+}
+
+##################
+##### OUTPUT #####
+##################
+
+### off ###
+
+sub cmd_off {
+ if ($mode == $SCREEN) {
+ screen_stop();
+ } elsif ($mode == $FIFO) {
+ fifo_stop();
+ }
+}
+
+### fifo ###
+
+sub cmd_fifo_start {
+ read_settings();
+ my $path = Irssi::settings_get_str('nicklist_fifo_path');
+ unless (-p $path) { # not a pipe
+ if (-e _) { # but a something else
+ die "$0: $path exists and is not a pipe, please remove it\n";
+ } else {
+ require POSIX;
+ POSIX::mkfifo($path, 0666) or die "can\'t mkfifo $path: $!";
+ Irssi::print("Fifo created. Start reading it (\"cat $path\") and try again.");
+ return;
+ }
+ }
+ if (!sysopen(FIFO, $path, O_WRONLY | O_NONBLOCK)) { # or die "can't write $path: $!";
+ Irssi::print("Couldn\'t write to the fifo ($!). Please start reading the fifo (\"cat $path\") and try again.");
+ return;
+ }
+ FIFO->autoflush(1);
+ print FIFO "\033[2J\033[1;1H"; # erase screen & jump to 0,0
+ $cursor_line = 0;
+ if ($mode == $SCREEN) {
+ screen_stop();
+ }
+ $mode = $FIFO;
+ make_nicklist();
+}
+
+sub fifo_stop {
+ close FIFO;
+ $mode = $OFF;
+ Irssi::print("Fifo closed.");
+}
+
+### screen ###
+
+sub cmd_screen_start {
+ if (!defined($ENV{'STY'})) {
+ Irssi::print 'screen not detected, screen mode only works inside screen';
+ return;
+ }
+ read_settings();
+ if ($mode == $SCREEN) {return;}
+ if ($mode == $FIFO) {
+ fifo_stop();
+ }
+ $mode = $SCREEN;
+ Irssi::signal_add_last('gui print text finished', \&sig_gui_print_text_finished);
+ Irssi::signal_add_last('gui page scrolled', \&sig_page_scrolled);
+ Irssi::signal_add('terminal resized', \&sig_terminal_resized);
+ screen_size();
+ make_nicklist();
+}
+
+sub screen_stop {
+ $mode = $OFF;
+ Irssi::signal_remove('gui print text finished', \&sig_gui_print_text_finished);
+ Irssi::signal_remove('gui page scrolled', \&sig_page_scrolled);
+ Irssi::signal_remove('terminal resized', \&sig_terminal_resized);
+ system 'screen -x '.$ENV{'STY'}.' -X fit';
+}
+
+sub screen_size {
+ if ($mode != $SCREEN) {
+ return;
+ }
+ $screen_resizing = 1;
+ # fit screen
+ system 'screen -x '.$ENV{'STY'}.' -X fit';
+ # get size (from perldoc -q size)
+ my ($winsize, $row, $col, $xpixel, $ypixel);
+ eval 'use Term::ReadKey; ($col, $row, $xpixel, $ypixel) = GetTerminalSize';
+ # require Term::ReadKey 'GetTerminalSize';
+ # ($col, $row, $xpixel, $ypixel) = Term::ReadKey::GetTerminalSize;
+ #};
+ if ($@) { # no Term::ReadKey, try the ugly way
+ eval {
+ require 'sys/ioctl.ph';
+ # without this reloading doesn't work. workaround for some unknown bug
+ do 'asm/ioctls.ph';
+ };
+
+ # ugly way not working, let's try something uglier, the dg-hack(tm) (constant for linux only?)
+ if($@) { no strict 'refs'; *TIOCGWINSZ = sub { return 0x5413 } }
+
+ unless (defined &TIOCGWINSZ) {
+ die "Term::ReadKey not found, and ioctl 'workaround' failed. Install the Term::ReadKey perl module to use screen mode.\n";
+ }
+ open(TTY, "+</dev/tty") or die "No tty: $!";
+ unless (ioctl(TTY, &TIOCGWINSZ, $winsize='')) {
+ die "Term::ReadKey not found, and ioctl 'workaround' failed ($!). Install the Term::ReadKey perl module to use screen mode.\n";
+ }
+ close(TTY);
+ ($row, $col, $xpixel, $ypixel) = unpack('S4', $winsize);
+ }
+
+ # set screen width
+ $irssi_width = $col-$nicklist_width-1;
+ $height = $row-1;
+
+ # on some recent systems, "screen -X fit; screen -X width -w 50" doesn't work, needs a sleep in between the 2 commands
+ # so we wait a second before setting the width
+ Irssi::timeout_add_once(1000, sub {
+ my ($new_irssi_width) = @_;
+ system 'screen -x '.$ENV{'STY'}.' -X width -w ' . $new_irssi_width;
+ # and then we wait another second for the resizing, and then redraw.
+ Irssi::timeout_add_once(1000,sub {$screen_resizing = 0; redraw()}, []);
+ }, $irssi_width);
+}
+
+sub sig_terminal_resized {
+ if ($screen_resizing) {
+ return;
+ }
+ $screen_resizing = 1;
+ Irssi::timeout_add_once(1000,\&screen_size,[]);
+}
+
+
+### both ###
+
+sub nicklist_write_start {
+ if ($mode == $SCREEN) {
+ print STDERR "\033P\033[s\033\\"; # save cursor
+ }
+}
+
+sub nicklist_write_end {
+ if ($mode == $SCREEN) {
+ print STDERR "\033P\033[u\033\\"; # restore cursor
+ }
+}
+
+sub nicklist_write_line {
+ my ($line, $data) = @_;
+ if ($mode == $SCREEN) {
+ print STDERR "\033P\033[" . ($line+1) . ';'. ($irssi_width+1) .'H'. $screen_prefix . $data . "\033\\";
+ } elsif ($mode == $FIFO) {
+ $data = "\033[m$data"; # reset color
+ if ($line == $cursor_line+1) {
+ $data = "\n$data"; # next line
+ } elsif ($line == $cursor_line) {
+ $data = "\033[1G".$data; # back to beginning of line
+ } else {
+ $data = "\033[".($line+1).";0H".$data; # jump
+ }
+ $cursor_line=$line;
+ print(FIFO $data) or fifo_stop();
+ }
+}
+
+# recalc the text of the nicklist item
+sub calc_text {
+ my ($nick) = @_;
+ my $tmp = $nicklist_width-3;
+ (my $text = $nick->{'nick'}) =~ s/^(.{$tmp})..+$/$1\033[34m~\033[m/;
+ $nick->{'text'} = '|'.$prefix_mode[$nick->{'mode'}] . $text . (' ' x ($nicklist_width-length($nick->{'nick'})-2));
+ $nick->{'cmp'} = $nick->{'mode'}.lc($nick->{'nick'});
+}
+
+# redraw the given nick (nr) if it is visible
+sub redraw_nick_nr {
+ my ($nr) = @_;
+ my $line = $nr - $scroll_pos;
+ if ($line >= 0 && $line < $height) {
+ nicklist_write_line($line, $nicklist[$nr]->{'text'});
+ }
+}
+
+# nick was inserted, redraw area if necessary
+sub draw_insert_nick_nr {
+ my ($nr) = @_;
+ my $line = $nr - $scroll_pos;
+ if ($line < 0) { # nick is inserted above visible area
+ $scroll_pos++; # 'scroll' down :)
+ } elsif ($line < $height) { # line is visible
+ if ($mode == $SCREEN) {
+ need_redraw();
+ } elsif ($mode == $FIFO) {
+ my $data = "\033[m\033[L". $nicklist[$nr]->{'text'}; # reset color & insert line & write nick
+ if ($line == $cursor_line) {
+ $data = "\033[1G".$data; # back to beginning of line
+ } else {
+ $data = "\033[".($line+1).";1H".$data; # jump
+ }
+ $cursor_line=$line;
+ print(FIFO $data) or fifo_stop();
+ if ($prev_lines < $height) {
+ $prev_lines++; # the nicklist has one line more
+ }
+ }
+ }
+}
+
+sub draw_remove_nick_nr {
+ my ($nr) = @_;
+ my $line = $nr - $scroll_pos;
+ if ($line < 0) { # nick removed above visible area
+ $scroll_pos--; # 'scroll' up :)
+ } elsif ($line < $height) { # line is visible
+ if ($mode == $SCREEN) {
+ need_redraw();
+ } elsif ($mode == $FIFO) {
+ #my $data = "\033[m\033[L[i$line]". $nicklist[$nr]->{'text'}; # reset color & insert line & write nick
+ my $data = "\033[M"; # delete line
+ if ($line != $cursor_line) {
+ $data = "\033[".($line+1)."d".$data; # jump
+ }
+ $cursor_line=$line;
+ print(FIFO $data) or fifo_stop();
+ if (@nicklist-$scroll_pos >= $height) {
+ redraw_nick_nr($scroll_pos+$height-1);
+ }
+ }
+ }
+}
+
+# redraw the whole nicklist
+sub redraw {
+ $need_redraw = 0;
+ #make_nicklist();
+ nicklist_write_start();
+ my $line = 0;
+ ### draw nicklist ###
+ for (my $i=$scroll_pos;$line < $height && $i < @nicklist; $i++) {
+ nicklist_write_line($line++, $nicklist[$i]->{'text'});
+ }
+
+ ### clean up other lines ###
+ my $real_lines = $line;
+ while($line < $height) {
+ nicklist_write_line($line++,'|' . (' ' x ($nicklist_width - 1)));
+ }
+ $prev_lines = $real_lines;
+ nicklist_write_end();
+}
+
+# redraw (with little delay to avoid redrawing to much)
+sub need_redraw {
+ if(!$need_redraw) {
+ $need_redraw = 1;
+ Irssi::timeout_add_once(10,\&redraw,[]);
+ }
+}
+
+sub sig_page_scrolled {
+ $prev_lines = $height; # we'll need to redraw everything if he scrolled up
+ need_redraw;
+}
+
+# redraw (with delay) if the window is visible (only in screen mode)
+sub sig_gui_print_text_finished {
+ if ($need_redraw) { # there's already a redraw 'queued'
+ return;
+ }
+ my $window = @_[0];
+ if ($window->{'refnum'} == Irssi::active_win->{'refnum'} || Irssi::settings_get_str('nicklist_screen_split_windows') eq '*') {
+ need_redraw;
+ return;
+ }
+ foreach my $win (split(/[ ,]/, Irssi::settings_get_str('nicklist_screen_split_windows'))) {
+ if ($window->{'refnum'} == $win || $window->{'name'} eq $win) {
+ need_redraw;
+ return;
+ }
+ }
+}
+
+####################
+##### NICKLIST #####
+####################
+
+# returns the position of the given nick(as string) in the (internal) nicklist
+sub find_nick {
+ my ($nick) = @_;
+ for (my $i=0;$i < @nicklist; $i++) {
+ if ($nicklist[$i]->{'nick'} eq $nick) {
+ return $i;
+ }
+ }
+ return -1;
+}
+
+# find position where nick should be inserted into the list
+sub find_insert_pos {
+ my ($cmp)= @_;
+ for (my $i=0;$i < @nicklist; $i++) {
+ if ($nicklist[$i]->{'cmp'} gt $cmp) {
+ return $i;
+ }
+ }
+ return scalar(@nicklist); #last
+}
+
+# make the (internal) nicklist (@nicklist)
+sub make_nicklist {
+ @nicklist = ();
+ $scroll_pos = 0;
+
+ ### get & check channel ###
+ my $channel = Irssi::active_win->{active};
+
+ if (!$channel || (ref($channel) ne 'Irssi::Irc::Channel' && ref($channel) ne 'Irssi::Silc::Channel') || $channel->{'type'} ne 'CHANNEL' || ($channel->{chat_type} ne 'SILC' && !$channel->{'names_got'}) ) {
+ $active_channel = undef;
+ # no nicklist
+ } else {
+ $active_channel = $channel;
+ ### make nicklist ###
+ my $thisnick;
+ foreach my $nick (sort {(($a->{'op'}?'1':$a->{'halfop'}?'2':$a->{'voice'}?'3':'4').lc($a->{'nick'}))
+ cmp (($b->{'op'}?'1':$b->{'halfop'}?'2':$b->{'voice'}?'3':'4').lc($b->{'nick'}))} $channel->nicks()) {
+ $thisnick = {'nick' => $nick->{'nick'}, 'mode' => ($nick->{'op'}?$MODE_OP:$nick->{'halfop'}?$MODE_HALFOP:$nick->{'voice'}?$MODE_VOICE:$MODE_NORMAL)};
+ calc_text($thisnick);
+ push @nicklist, $thisnick;
+ }
+ }
+ need_redraw();
+}
+
+# insert nick(as hash) into nicklist
+# pre: cmp has to be calculated
+sub insert_nick {
+ my ($nick) = @_;
+ my $nr = find_insert_pos($nick->{'cmp'});
+ splice @nicklist, $nr, 0, $nick;
+ draw_insert_nick_nr($nr);
+}
+
+# remove nick(as nr) from nicklist
+sub remove_nick {
+ my ($nr) = @_;
+ splice @nicklist, $nr, 1;
+ draw_remove_nick_nr($nr);
+}
+
+###################
+##### ACTIONS #####
+###################
+
+# scroll the nicklist, arg = number of lines to scroll, positive = down, negative = up
+sub cmd_scroll {
+ if (!$active_channel) { # not a channel active
+ return;
+ }
+ my @nicks=Irssi::active_win->{active}->nicks;
+ my $nick_count = scalar(@nicks)+0;
+ my $channel = Irssi::active_win->{active};
+ if (!$channel || $channel->{type} ne 'CHANNEL' || !$channel->{names_got} || $nick_count <= Irssi::settings_get_int('nicklist_height')) {
+ return;
+ }
+ $scroll_pos += @_[0];
+
+ if ($scroll_pos > $nick_count - $height) {
+ $scroll_pos = $nick_count - $height;
+ }
+ if ($scroll_pos <= 0) {
+ $scroll_pos = 0;
+ }
+ need_redraw();
+}
+
+sub is_active_channel {
+ my ($server,$channel) = @_; # (channel as string)
+ return ($server && $server->{'tag'} eq $active_channel->{'server'}->{'tag'} && $server->channel_find($channel) && $active_channel && $server->channel_find($channel)->{'name'} eq $active_channel->{'name'});
+}
+
+sub sig_channel_wholist { # this is actualy a little late, when the names are received would be better
+ my ($channel) = @_;
+ if (Irssi::active_win->{'active'} && Irssi::active_win->{'active'}->{'name'} eq $channel->{'name'}) { # the channel joined is active
+ make_nicklist
+ }
+}
+
+sub sig_join {
+ my ($server,$channel,$nick,$address) = @_;
+ if (!is_active_channel($server,$channel)) {
+ return;
+ }
+ my $newnick = {'nick' => $nick, 'mode' => $MODE_NORMAL};
+ calc_text($newnick);
+ insert_nick($newnick);
+}
+
+sub sig_kick {
+ my ($server, $channel, $nick, $kicker, $address, $reason) = @_;
+ if (!is_active_channel($server,$channel)) {
+ return;
+ }
+ my $nr = find_nick($nick);
+ if ($nr == -1) {
+ Irssi::print("nicklist warning: $nick was kicked from $channel, but not found in nicklist");
+ } else {
+ remove_nick($nr);
+ }
+}
+
+sub sig_part {
+ my ($server,$channel,$nick,$address, $reason) = @_;
+ if (!is_active_channel($server,$channel)) {
+ return;
+ }
+ my $nr = find_nick($nick);
+ if ($nr == -1) {
+ Irssi::print("nicklist warning: $nick has parted $channel, but was not found in nicklist");
+ } else {
+ remove_nick($nr);
+ }
+
+}
+
+sub sig_quit {
+ my ($server,$nick,$address, $reason) = @_;
+ if ($server->{'tag'} ne $active_channel->{'server'}->{'tag'}) {
+ return;
+ }
+ my $nr = find_nick($nick);
+ if ($nr != -1) {
+ remove_nick($nr);
+ }
+}
+
+sub sig_nick {
+ my ($server, $newnick, $oldnick, $address) = @_;
+ if ($server->{'tag'} ne $active_channel->{'server'}->{'tag'}) {
+ return;
+ }
+ my $nr = find_nick($oldnick);
+ if ($nr != -1) { # if nick was found (nickchange is in current channel)
+ my $nick = $nicklist[$nr];
+ remove_nick($nr);
+ $nick->{'nick'} = $newnick;
+ calc_text($nick);
+ insert_nick($nick);
+ }
+}
+
+sub sig_mode {
+ my ($channel, $nick, $setby, $mode, $type) = @_; # (nick and channel as rec)
+ if ($channel->{'server'}->{'tag'} ne $active_channel->{'server'}->{'tag'} || $channel->{'name'} ne $active_channel->{'name'}) {
+ return;
+ }
+ my $nr = find_nick($nick->{'nick'});
+ if ($nr == -1) {
+ Irssi::print("nicklist warning: $nick->{'nick'} had mode set on $channel->{'name'}, but was not found in nicklist");
+ } else {
+ my $nicklist_item = $nicklist[$nr];
+ remove_nick($nr);
+ $nicklist_item->{'mode'} = ($nick->{'op'}?$MODE_OP:$nick->{'halfop'}?$MODE_HALFOP:$nick->{'voice'}?$MODE_VOICE:$MODE_NORMAL);
+ calc_text($nicklist_item);
+ insert_nick($nicklist_item);
+ }
+}
+
+##### command binds #####
+Irssi::command_bind 'nicklist' => sub {
+ my ( $data, $server, $item ) = @_;
+ $data =~ s/\s+$//g;
+ Irssi::command_runsub ('nicklist', $data, $server, $item ) ;
+};
+Irssi::signal_add_first 'default command nicklist' => sub {
+ # gets triggered if called with unknown subcommand
+ cmd_help();
+};
+Irssi::command_bind('nicklist update',\&update);
+Irssi::command_bind('nicklist help',\&cmd_help);
+Irssi::command_bind('nicklist scroll',\&cmd_scroll);
+Irssi::command_bind('nicklist fifo',\&cmd_fifo_start);
+Irssi::command_bind('nicklist screen',\&cmd_screen_start);
+Irssi::command_bind('nicklist screensize',\&screen_size);
+Irssi::command_bind('nicklist off',\&cmd_off);
+
+##### signals #####
+Irssi::signal_add_last('window item changed', \&make_nicklist);
+Irssi::signal_add_last('window changed', \&make_nicklist);
+Irssi::signal_add_last('channel wholist', \&sig_channel_wholist);
+Irssi::signal_add_first('message join', \&sig_join); # first, to be before ignores
+Irssi::signal_add_first('message part', \&sig_part);
+Irssi::signal_add_first('message kick', \&sig_kick);
+Irssi::signal_add_first('message quit', \&sig_quit);
+Irssi::signal_add_first('message nick', \&sig_nick);
+Irssi::signal_add_first('message own_nick', \&sig_nick);
+Irssi::signal_add_first('nick mode changed', \&sig_mode);
+
+Irssi::signal_add('setup changed', \&read_settings);
+
+##### settings #####
+Irssi::settings_add_str('nicklist', 'nicklist_screen_prefix', '\e[m ');
+Irssi::settings_add_str('nicklist', 'nicklist_prefix_mode_op', '\e[32m@\e[39m');
+Irssi::settings_add_str('nicklist', 'nicklist_prefix_mode_halfop', '\e[34m%\e[39m');
+Irssi::settings_add_str('nicklist', 'nicklist_prefix_mode_voice', '\e[33m+\e[39m');
+Irssi::settings_add_str('nicklist', 'nicklist_prefix_mode_normal', ' ');
+
+Irssi::settings_add_int('nicklist', 'nicklist_width',11);
+Irssi::settings_add_int('nicklist', 'nicklist_height',24);
+Irssi::settings_add_str('nicklist', 'nicklist_fifo_path', Irssi::get_irssi_dir . '/nicklistfifo');
+Irssi::settings_add_str('nicklist', 'nicklist_screen_split_windows', '');
+Irssi::settings_add_str('nicklist', 'nicklist_automode', '');
+
+read_settings();
+if (uc(Irssi::settings_get_str('nicklist_automode')) eq 'SCREEN') {
+ cmd_screen_start();
+} elsif (uc(Irssi::settings_get_str('nicklist_automode')) eq 'FIFO') {
+ cmd_fifo_start();
+}
diff --git a/irssi/scripts/thistory.pl b/irssi/scripts/thistory.pl
new file mode 100644
index 0000000..a1f5b3a
--- /dev/null
+++ b/irssi/scripts/thistory.pl
@@ -0,0 +1,159 @@
+# thistory.pl v1.05 [10.03.2002]
+# Copyright (C) 2001, 2002 Teemu Hjelt <temex@iki.fi>
+#
+# Written for irssi 0.7.98 and later, idea from JSuvanto.
+#
+# Many thanks to fuchs, shasta, Paladin, Koffa and people
+# on #irssi for their help and suggestions.
+#
+# Keeps information about the most recent topics of the
+# channels you are on.
+# Usage: /thistory [channel] and /tinfo [channel]
+#
+# v1.00 - Initial release.
+# v1.02 - Months and topics with formatting were shown
+# incorrectly. (Found by fuchs and shasta)
+# v1.03 - event_topic was occasionally using the wrong
+# server tag. Also added few variables to ease
+# changing the settings and behaviour of this
+# script.
+# v1.04 - Minor bug-fixes.
+# v1.05 - Made the script more consistent with other
+# Irssi scripts.
+
+use Irssi;
+use Irssi::Irc;
+use vars qw($VERSION %IRSSI);
+
+# Formatting character.
+my $fchar = '%';
+
+# Format of the line.
+my $format = '"%topic" %nick (%address) [%mday.%mon.%year %hour:%min:%sec]';
+
+# Amount of topics stored.
+my $tamount = 10;
+
+###### Don't edit below this unless you know what you're doing ######
+
+$VERSION = "1.05";
+%IRSSI = (
+ authors => "Teemu Hjelt",
+ contact => "temex\@iki.fi",
+ name => "topic history",
+ description => "Keeps information about the most recent topics of the channels you are on.",
+ license => "GNU GPLv2 or later",
+ url => "http://www.iki.fi/temex/",
+ changed => "Sun Mar 10 14:53:59 EET 2002",
+);
+
+sub cmd_topicinfo {
+ my ($channel) = @_;
+ my $tag = Irssi::active_server()->{'tag'};
+ $channel =~ s/\s+//;
+ $channel =~ s/\s+$//;
+
+ if ($channel eq "") {
+ if (Irssi::channel_find(Irssi::active_win()->get_active_name())) {
+ $channel = Irssi::active_win()->get_active_name();
+ }
+ }
+ if ($channel ne "") {
+ if ($topiclist{lc($tag)}{lc($channel)}{0}) {
+ Irssi::print("%W$channel%n: " . $topiclist{lc($tag)}{lc($channel)}{0}, MSGLEVEL_CRAP);
+ } else {
+ Irssi::print("No topic information for %W$channel%n", MSGLEVEL_CRAP);
+ }
+ } else {
+ Irssi::print("Usage: /tinfo <channel>");
+ }
+}
+
+sub cmd_topichistory {
+ my ($channel) = @_;
+ my $tag = Irssi::active_server()->{'tag'};
+ $channel =~ s/\s+//;
+ $channel =~ s/\s+$//;
+
+ if ($channel eq "") {
+ if (Irssi::channel_find(Irssi::active_win()->get_active_name())) {
+ $channel = Irssi::active_win()->get_active_name();
+ }
+ }
+ if ($channel ne "") {
+ if ($topiclist{lc($tag)}{lc($channel)}{0}) {
+ my $amount = &getamount($tag, $channel);
+ Irssi::print("Topic history for %W$channel%n:", MSGLEVEL_CRAP);
+ for (my $i = 0; $i < $amount; $i++) {
+ if ($topiclist{lc($tag)}{lc($channel)}{$i}) {
+ my $num = $i + 1;
+ if (length($amount) >= length($tamount) && length($i + 1) < length($tamount)) {
+ for (my $j = length($tamount); $j > length($i + 1); $j--) {
+ $num = " " . $num;
+ }
+ }
+ Irssi::print($num . ". " . $topiclist{lc($tag)}{lc($channel)}{$i}, MSGLEVEL_CRAP);
+ } else {
+ last;
+ }
+ }
+ } else {
+ Irssi::print("No topic history for %W$channel%n", MSGLEVEL_CRAP);
+ }
+ } else {
+ Irssi::print("Usage: /thistory <channel>");
+ }
+}
+
+sub event_topic {
+ my ($server, $data, $nick, $address) = @_;
+ my ($channel, $topic) = split(/ :/, $data, 2);
+ my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);
+ my $tag = $server->{'tag'};
+ my $output = $format;
+
+ $topic =~ s/%/%%/g;
+ $topic .= '%n';
+
+ $val{'sec'} = $sec < 10 ? "0$sec" : $sec;
+ $val{'min'} = $min < 10 ? "0$min" : $min;
+ $val{'hour'} = $hour < 10 ? "0$hour" : $hour;
+ $val{'mday'} = $mday < 10 ? "0$mday" : $mday;
+ $val{'mon'} = $mon + 1 < 10 ? "0" . ($mon + 1) : $mon + 1;
+ $val{'year'} = $year + 1900;
+
+ $val{'nick'} = $nick;
+ $val{'address'} = $address;
+ $val{'channel'} = $channel;
+ $val{'topic'} = $topic;
+ $val{'tag'} = $tag;
+
+ $output =~ s/$fchar(\w+)/$val{$1}/g;
+
+ for (my $i = (&getamount($tag, $channel) - 1); $i >= 0; $i--) {
+ if ($topiclist{lc($tag)}{lc($channel)}{$i}) {
+ $topiclist{lc($tag)}{lc($channel)}{$i + 1} = $topiclist{lc($tag)}{lc($channel)}{$i};
+ }
+ }
+ $topiclist{lc($tag)}{lc($channel)}{0} = $output;
+}
+
+sub getamount {
+ my ($tag, $channel) = @_;
+ my $amount = 0;
+
+ for (my $i = 0; $i < $tamount; $i++) {
+ if ($topiclist{lc($tag)}{lc($channel)}{$i}) {
+ $amount++;
+ }
+ }
+ return $amount;
+}
+
+Irssi::command_bind("topichistory", "cmd_topichistory");
+Irssi::command_bind("thistory", "cmd_topichistory");
+Irssi::command_bind("topicinfo", "cmd_topicinfo");
+Irssi::command_bind("tinfo", "cmd_topicinfo");
+Irssi::signal_add("event topic", "event_topic");
+
+Irssi::print("Loaded thistory.pl v$VERSION");
diff --git a/irssi/scripts/trackbar.pl b/irssi/scripts/trackbar.pl
new file mode 100644
index 0000000..7123330
--- /dev/null
+++ b/irssi/scripts/trackbar.pl
@@ -0,0 +1,189 @@
+# 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.
+#
+# Usage:
+#
+# The script works right out of the box, but if you want you can change
+# the working by /set'ing the following variables:
+#
+# trackbar_string The characters to repeat to draw the bar
+# trackbar_style The style for the bar, %r is red for example
+# See formats.txt that came with irssi
+#
+# /mark is a command that will redraw the line at the bottom. However! This
+# requires irssi version after 20021228. otherwise you'll get the error
+# redraw: unknown command, and your screen is all goofed up :)
+#
+# /upgrade & buf.pl notice: This version tries to remove the trackbars before
+# the upgrade is done, so buf.pl does not restore them, as they are not removeable
+# afterwards by trackbar. Unfortiounatly, to make this work, trackbar and buf.pl
+# need to be loaded in a specific order. Please experiment to see which order works
+# for you (strangely, it differs from configuration to configuration, something I will
+# try to fix in a next version)
+#
+# 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
+#
+# Version history:
+# 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
+#
+#
+# Call for help!
+#
+# There is a trackbar version 2.0 that properly handles resizes and immediate config change
+# activation. However, there is/are some bug(s) in irssi's main buffer/window code that causes
+# irssi to 'forget' lines, which is ofcourse completly unaccepteable. I haven't found the time
+# nor do I know the irssi's internals enough to find and fix this bug, if you want to help, please
+# contact me, I'll give you a copy of the 2.0 version that will immediatly show you the problems.
+#
+# Known bugs:
+# - if you /clear a window, it will be uncleared when returning to the window
+# - UTF-8 characters in the trackbar_string doesnt work. This is an irssi bug.
+# - if you resize your irssi (in xterm or so) the bar is not resized
+# - changing the trackbar style is only visible after returning to a window
+# however, changing style/resize takes in effect after you left the window.
+#
+# Whishlist/todo:
+# - instead of drawing a line, just invert timestamp or something,
+# to save a line (but I don't think this is possible with current irssi)
+# - some pageup keybinding possibility, to scroll up upto the trackbar
+# - <@coekie> kinlo: if i switch to another window, in another split window, i
+# want the trackbar to go down in the previouswindow in that splitwindow :)
+# - < bob_2> anyway to clear the line once the window is read?
+# - < elho> kinlo: wishlist item: a string that gets prepended to the repeating pattern
+# - < elho> an option to still have the timestamp in front of the bar
+# - < elho> oh and an option to not draw it in the status window :P
+#
+# BTW: when you have feature requests, mailing a patch that works is the fastest way
+# to get it added :p
+
+use strict;
+use 5.6.1;
+use Irssi;
+use Irssi::TextUI;
+
+my $VERSION = "1.4";
+
+my %IRSSI = (
+ authors => "Peter 'kinlo' Leurs",
+ contact => "peter\@pfoe.be",
+ name => "trackbar",
+ description => "Shows a bar where you've last read a window",
+ license => "GPLv2",
+ url => "http://www.pfoe.be/~peter/trackbar/",
+ changed => "Thu Feb 20 16:18:08 2003",
+);
+
+my %config;
+
+Irssi::settings_add_str('trackbar', 'trackbar_string' => '-');
+$config{'trackbar_string'} = Irssi::settings_get_str('trackbar_string');
+
+Irssi::settings_add_str('trackbar', 'trackbar_style' => '%K');
+$config{'trackbar_style'} = Irssi::settings_get_str('trackbar_style');
+
+Irssi::signal_add(
+ 'setup changed' => sub {
+ $config{'trackbar_string'} = Irssi::settings_get_str('trackbar_string');
+ $config{'trackbar_style'} = Irssi::settings_get_str('trackbar_style');
+ if ($config{'trackbar_style'} =~ /(?<!%)[^%]|%%|%$/) {
+ Irssi::print(
+ "trackbar: %RWarning!%n 'trackbar_style' seems to contain "
+ . "printable characters. Only use format codes (read "
+ . "formats.txt).", MSGLEVEL_CLIENTERROR);
+ }
+ }
+);
+
+Irssi::signal_add(
+ 'window changed' => sub {
+ my (undef, $oldwindow) = @_;
+
+ if ($oldwindow) {
+ my $line = $oldwindow->view()->get_bookmark('trackbar');
+ $oldwindow->view()->remove_line($line) if defined $line;
+ $oldwindow->print(line($oldwindow->{'width'}), MSGLEVEL_NEVER);
+ $oldwindow->view()->set_bookmark_bottom('trackbar');
+ }
+ }
+);
+
+sub line {
+ my $width = shift;
+ my $string = $config{'trackbar_string'};
+ $string = '-' unless defined $string;
+
+ # There is a bug in irssi's utf-8 handling on config file settings, as you
+ # can reproduce/see yourself by the following code sniplet:
+ #
+ # my $quake = pack 'U*', 8364; # EUR symbol
+ # Irssi::settings_add_str 'temp', 'temp_foo' => $quake;
+ # Irssi::print length $quake;
+ # # prints 1
+ # Irssi::print length Irssi::settings_get_str 'temp_foo';
+ # # prints 3
+ #
+ #
+ # Trackbar used to have a workaround, but on recent versions of perl/irssi
+ # it does no longer work. Therefore, if you want your trackbar to contain
+ # unicode characters, uncomment the line below for a nice full line, or set
+ # the string to whatever char you want.
+
+ # $string = pack('U*', 0x2500);
+
+
+ my $length = length $string;
+
+ if ($length == 0) {
+ $string = '-';
+ $length = 1;
+ }
+
+ my $times = $width / $length;
+ $times = int(1 + $times) if $times != int($times);
+ $string =~ s/%/%%/g;
+ return $config{'trackbar_style'} . substr($string x $times, 0, $width);
+}
+
+# Remove trackbars on upgrade - but this doesn't really work if the scripts are not loaded in the correct order... watch out!
+
+Irssi::signal_add_first( 'session save' => sub {
+ for my $window (Irssi::windows) {
+ next unless defined $window;
+ my $line = $window->view()->get_bookmark('trackbar');
+ $window->view()->remove_line($line) if defined $line;
+ }
+ }
+);
+
+sub cmd_mark {
+ my $window = Irssi::active_win();
+# return unless defined $window;
+ my $line = $window->view()->get_bookmark('trackbar');
+ $window->view()->remove_line($line) if defined $line;
+ $window->print(line($window->{'width'}), MSGLEVEL_NEVER);
+ $window->view()->set_bookmark_bottom('trackbar');
+ Irssi::command("redraw");
+}
+
+Irssi::command_bind('mark', 'cmd_mark');