diff options
author | jluehrs2 <jluehrs2@uiuc.edu> | 2008-11-13 13:21:04 -0500 |
---|---|---|
committer | jluehrs2 <jluehrs2@uiuc.edu> | 2008-11-13 13:21:04 -0500 |
commit | ead7fb900518ba6e11676268ce6bc37495adf5a6 (patch) | |
tree | 1a64b21b70a2ff961b5b3fad68a3e594cedf476c /irssi | |
parent | 4a9f06a419bd1fbd1c5216d3c6268f6b9938a075 (diff) | |
download | conf-ead7fb900518ba6e11676268ce6bc37495adf5a6.tar.gz conf-ead7fb900518ba6e11676268ce6bc37495adf5a6.zip |
add my irssi configuration
Diffstat (limited to 'irssi')
-rw-r--r-- | irssi/config | 353 | ||||
-rw-r--r-- | irssi/scripts/all.pl | 30 | ||||
-rw-r--r-- | irssi/scripts/autowrap.pl | 38 | ||||
-rw-r--r-- | irssi/scripts/bitlbee_join_notice.pl | 94 | ||||
-rw-r--r-- | irssi/scripts/bitlbee_status_notice.pl | 172 | ||||
-rw-r--r-- | irssi/scripts/bitlbee_typing_notice.pl | 320 | ||||
-rw-r--r-- | irssi/scripts/chanact.pl | 481 | ||||
-rw-r--r-- | irssi/scripts/gobots.pl | 37 | ||||
-rw-r--r-- | irssi/scripts/hilightwin.pl | 44 | ||||
-rw-r--r-- | irssi/scripts/nickcolor.pl | 156 | ||||
-rw-r--r-- | irssi/scripts/nicklist.pl | 611 | ||||
-rw-r--r-- | irssi/scripts/thistory.pl | 159 | ||||
-rw-r--r-- | irssi/scripts/trackbar.pl | 189 |
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'); |