]> git.madduck.net Git - code/irssi/scripts-bc-bd.git/commitdiff

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

All patches and comments are welcome. Please squash your changes to logical commits before using git-format-patch and git-send-email to patches@git.madduck.net. If you'd read over the Git project's submission guidelines and adhered to them, I'd be especially grateful.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

imported scripts master
authorbd <bd@bc-bd.org>
Tue, 31 Mar 2009 13:24:57 +0000 (13:24 +0000)
committerbd <bd@bc-bd.org>
Tue, 31 Mar 2009 13:24:57 +0000 (13:24 +0000)
.gitattributes [new file with mode: 0644]
ai.pl [new file with mode: 0644]
chanact.pl [new file with mode: 0644]
ircops.pl [new file with mode: 0644]
nact.pl [new file with mode: 0644]
niq.pl [new file with mode: 0644]
nm.pl [new file with mode: 0644]
repeat.pl [new file with mode: 0644]
reslap.pl [new file with mode: 0644]
rotator.pl [new file with mode: 0644]
thankop.pl [new file with mode: 0644]

diff --git a/.gitattributes b/.gitattributes
new file mode 100644 (file)
index 0000000..31884f8
--- /dev/null
@@ -0,0 +1 @@
+* ident
diff --git a/ai.pl b/ai.pl
new file mode 100644 (file)
index 0000000..69829e8
--- /dev/null
+++ b/ai.pl
@@ -0,0 +1,265 @@
+use Irssi;
+use Irssi::Irc;
+use strict;
+
+use vars qw($VERSION %IRSSI);
+
+$VERSION="0.3";
+%IRSSI = (
+       authors=> 'BC-bd',
+       contact=> 'bd@bc-bd.org',
+       name=> 'ai',
+       description=> 'Puts people on ignore if they do a public away. See source for options.',
+       license=> 'GPL v2',
+       url=> 'https://bc-bd.org/svn/repos/irssi/ai',
+);
+
+# $Id$
+# for irssi 0.8.4 by bd@bc-bd.org
+#
+#########
+# USAGE
+###
+#
+# Examples:
+#
+#      Ignore people saying "away"
+#              /set ai_words away
+#
+#      Ignore people saying "gone for good" or "back"
+#              /set ai_words gone for good,back
+#
+#      Ignore people for 500 seconds
+#              /set ai_time 500
+#
+#      Ignore people forever
+#              /set ai_time 0
+#
+#      Ignore people only on channels #foo,#bar
+#              /set ai_ignore_only_in ON
+#              /set ai_channels #foo,#bar
+#
+#      Ignore people on all channels BUT #foo,#bar
+#              /set ai_ignore_only_in OFF
+#              /set ai_channels #foo,#bar
+# 
+#      Ignore people on all channels
+#              /set ai_ignore_only_in OFF
+#              /set -clear ai_channels
+#
+#      Perform a command on ignore (e.g send them a message)
+#              /set ai_command ^msg -$C $N no "$W" in $T please
+#      
+#      would become on #foo on chatnet bar from nick dude with "dude is away"
+#              /msg -cbar dude no "away" in #foo please
+#
+#      look further down for details
+#
+#      Per channel command on #irssi:
+#              /ai #irssi ^say foobar
+#
+#      delete channel command in #irssi:
+#              /ai #irssi
+#
+#########
+# OPTIONS
+#########
+#
+# /set ai_words [expr[,]+]+
+#              * expr  : comma seperated list of expressions that should trigger an ignore
+#                e.g.  : away,foo,bar baz bat,bam
+#
+# /set ai_command [command]
+#              * command  : to be executed on a triggered ignore.
+#                /set -clear ai_command to disable. The following $'s are expanded
+#                ( see the default command for an example ):
+#                  $C : Chatnet (e.g. IRCnet, DALNet, ...)
+#                  $N : Nick (some dude)
+#                  $W : Word (the word(s) that triggered the ignore
+#                  $T : Target (e.g. the channel)
+#
+# /set ai_channels [#channel[ ]]+
+#              * #channel  : space seperated list of channels, see ai_ignore_only_in
+#
+# /set ai_time <seconds>
+#              * seconds  : number of seconds to wait before removing the ignore
+#
+# /set ai_ignore_only_in <ON|OFF>
+#              * ON  : only trigger ignores in ai_channels
+#              * OFF : trigger ignores in all channels EXCEPT ai_channels
+#
+# /set ai_display <ON|OFF>
+#              * ON  : log whole sentence
+#              * OFF : only log word that matched regex
+#
+###
+################
+###
+#
+# Changelog
+#
+# Version 0.4
+#      - added optional sentence output
+#
+# Version 0.3
+#      - added per channel command support
+#      - the command is now executed in the channel the event occured
+#      - changed the expand char from % to $
+#
+# Version 0.2
+#  - changed MSGLVL_ALL to MSGLVL_ACTIONS to avoid problems
+#        with channels with ignored Levels
+#
+# Version 0.1
+#  - initial release
+#
+###
+################
+
+sub expand {
+  my ($string, %format) = @_;
+  my ($exp, $repl);
+  $string =~ s/\$$exp/$repl/g while (($exp, $repl) = each(%format));
+  return $string;
+}
+
+sub combineSettings {
+       my ($setting,$string,$match) = @_;
+
+       $match =  quotemeta($match);
+
+       if ($setting) {
+               if ($string !~ /$match\b/i) {
+                       return 1;
+               }
+       } else {
+               if ($string =~ /$match\b/i) {
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
+sub sig_action() {
+       my ($server,$msg,$nick,$address,$target) = @_;
+       
+       my $command;
+
+       if ($server->ignore_check($nick, $address, $target, $msg, MSGLEVEL_ACTIONS)) {
+               return;
+       }
+
+       if (combineSettings(Irssi::settings_get_bool('ai_ignore_only_in'),
+               Irssi::settings_get_str('ai_channels'),$target)) {
+               return ;
+       }
+
+       my @words = split(',',Irssi::settings_get_str('ai_words'));
+
+       foreach (@words) {
+               if ($msg =~ /$_/i) {
+                       my $word = $_;
+
+                       my $sentence = $word;
+
+                       my $channel = $server->channel_find($target);
+                       my $n = $channel->nick_find($nick);
+
+                       my $type = Irssi::Irc::MASK_USER | Irssi::Irc::MASK_DOMAIN;
+                       my $mask = Irssi::Irc::get_mask($n->{nick}, $n->{host}, $type);
+                       
+                       my $time = Irssi::settings_get_int('ai_time');
+                       if ($time == 0) {
+                               $time = "";
+                       } else {
+                               $time = "-time ".$time;
+                       }
+                       Irssi::command("^ignore ".$time." $mask");
+
+                       if (Irssi::settings_get_bool('ai_display')) {
+                               $sentence = $msg
+                       }
+                       Irssi::print("Ignoring $nick$target\@$server->{chatnet} because of '$sentence'");
+
+                       my %commands = stringToHash('`',Irssi::settings_get_str('ai_commands'));
+                       if (defined $commands{$target}) {
+                               $command = $commands{$target};
+                       } else {
+                               $command = Irssi::settings_get_str('ai_command');
+                       }
+
+                       if ($command ne "") {
+                               $command = expand($command,"C",$server->{tag},"N",$nick,"T",$target,"W",$word);
+                               $server->window_item_find($target)->command($command);
+                               $server->window_item_find($target)->print($command);
+                       }
+
+                       return;
+               }
+       }
+}
+
+sub stringToHash {
+       my ($delim,$str) = @_;
+
+       return split($delim,$str);
+}
+
+sub hashToString {
+       my ($delim,%hash) = @_;
+
+       return join($delim,%hash);
+}
+
+sub colorCommand {
+       my ($com) = @_;
+
+       $com =~ s/\$(.)/%_\$$1%_/g;
+
+       return $com;
+}
+
+sub cmd_ai {
+       my ($data, $server, $channel) = @_;
+
+       my $chan = $data;
+       $chan =~ s/ .*//;
+       $data =~ s/^\Q$chan\E *//;
+
+       my %command = stringToHash('`',Irssi::settings_get_str('ai_commands'));
+
+       if ($chan eq "") {
+               foreach my $key (keys(%command)) {
+                       Irssi::print("AI: %_$key%_ = ".colorCommand($command{$key}));
+               }
+       
+               Irssi::print("AI: placeholders: %_\$C%_)hatnet %_\$N%_)ick %_\$W%_)ord %_\$T%_)arget");
+               Irssi::print("AI: not enough parameters: ai <channel> [command]");
+
+               return;
+       }
+
+       if ($data eq "") {
+               delete($command{$chan});
+       } else {
+               $command{$chan} = $data;
+       }
+
+       Irssi::settings_set_str('ai_commands',hashToString('`',%command));
+
+       Irssi::print("AI: command on %_$chan%_ now: '".colorCommand($data)."'");
+}
+
+Irssi::command_bind('ai', 'cmd_ai');
+
+# "message irc action", SERVER_REC, char *msg, char *nick, char *address, char *target
+Irssi::signal_add_first('message irc action', 'sig_action');
+
+Irssi::settings_add_str('misc', 'ai_commands', '');
+Irssi::settings_add_str('misc', 'ai_words', 'away,gone,ist auf');
+Irssi::settings_add_str('misc', 'ai_command', '^msg -$C $N no "$W" in $T please');
+Irssi::settings_add_str('misc', 'ai_channels', '');
+Irssi::settings_add_int('misc', 'ai_time', 500);
+Irssi::settings_add_bool('misc', 'ai_ignore_only_in', 0);
+Irssi::settings_add_bool('misc', 'ai_display', 0);
diff --git a/chanact.pl b/chanact.pl
new file mode 100644 (file)
index 0000000..d4e36b1
--- /dev/null
@@ -0,0 +1,571 @@
+use Irssi 20020101.0001 ();
+use strict;
+use Irssi::TextUI;
+
+use vars qw($VERSION %IRSSI);
+
+$VERSION = "0.5.10";
+%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         => 'https://bc-bd.org/svn/repos/irssi/chanact'
+);
+
+# 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
+# madduck@madduck.net Better channel aliasing (case-sensitive, cross-network)
+# Jan 'jast' Krueger <jast@heapsort.de>, 2004-06-22
+# Ivo Timmermans <ivo@o2w.nl>  win->{hilight} patch
+# 
+#########
+# USAGE
+###
+# 
+# copy the script to ~/.irssi/scripts/
+#
+# In irssi:
+#
+#              /script load chanact
+#              /statusbar window add -after act chanact
+#
+# 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_chop_status <ON|OFF>
+#               * ON  : shorten (Status) to S
+#               * OFF : don't do it
+#
+# /set chanact_show_mode <ON|OFF>
+#               * ON  : show channel modes
+#               * OFF : don't show channel modes
+#
+# /set chanact_sort_by_activity <ON|OFF>
+#               * ON  : sorts the list by last activity
+#               * OFF : sorts the list by window number
+#
+# /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_header <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.
+#
+# /set chanact_remove_hash <ON|OFF>
+#              * ON  : Remove &#+!= from channel names
+#              * OFF : Don't touch channel names
+#
+# /set chanact_remove_prefix <string>
+#              * <string> : Regular expression used to remove from the
+#                           beginning of the channel name.
+#              * example  :
+#                  To shorten a lot of debian channels:
+#                  
+#                      /set chanact_remove_prefix deb(ian.(devel-)?)?
+#
+# /set chanact_filter <int>
+#              * 0 : show all channels
+#              * 1 : hide channels without activity
+#              * 2 : hide channels with only join/part/etc messages
+#              * 3 : hide channels with text messages
+#              * 4 : hide all channels (now why would you want to do that)
+#
+#########
+# 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 %show = (
+       0 => "{%n ",                    # NOTHING
+       1 => "{sb_act_text ",           # TEXT
+       2 => "{sb_act_msg ",            # MSG
+       3 => "{sb_act_hilight ",        # HILIGHT
+);
+
+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,@windows);
+       my $separator = Irssi::settings_get_str('chanact_separator'); 
+       my $abbrev = Irssi::settings_get_int('chanact_abbreviate_names');
+       my $remove_prefix = Irssi::settings_get_str('chanact_remove_prefix');
+       my $remove_hash = Irssi::settings_get_bool('chanact_remove_hash');
+
+       if (Irssi::settings_get_bool('chanact_sort_by_activity')) {
+               @windows = sort { ($b->{last_line} <=> $a->{last_line}) }
+                       Irssi::windows;
+       } else {
+               @windows = sort { ($a->{refnum}) <=> ($b->{refnum}) }
+                       Irssi::windows;
+       }
+
+       $actString = "";
+       foreach my $win (@windows) {
+       
+               # since irssi is single threaded this shouldn't happen
+               !ref($win) && next;
+
+               my $active = $win->{active};
+               !ref($active) && next;
+
+               my $name = $win->get_active_name;
+
+               # (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 = "%";
+                       }
+               }
+
+               next if (Irssi::settings_get_int('chanact_filter') > $win->{data_level});
+
+               # in case we have a specific hilightcolor use it
+               if ($win->{hilight_color}) {
+                       $hilight = "{sb_act_hilight_color $win->{hilight_color} ";
+               } else {
+                       $hilight = $show{$win->{data_level}};
+               }
+
+               if ($remove_prefix) {
+                       $name =~ s/^([&#+!=]?)$remove_prefix/$1/;
+               }
+               if ($abbrev) {
+                       if ($name =~ /^[&#+!=]/) {
+                               $name = substr($name, 1, $abbrev + 1);
+                       } else {
+                               $name = substr($name, 0, $abbrev);
+                       }
+               }
+               if ($remove_hash) {
+                       $name =~ s/^[&#+!=]//;
+               }
+
+               if (Irssi::settings_get_bool('chanact_show_alias') == 1 && 
+                               $win->{name} =~ /^([a-zA-Z+]):(.+)$/) {
+                       $number = "$1";
+                       $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_int('chanact_filter')) {
+                       $actString = "{sb ".Irssi::settings_get_str('chanact_header').$actString."}";
+               } else {
+                       $actString = "{sb ".$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()
+{
+       # if needRemake is already set, no need to trigger a redraw as we will
+       # be redrawing the item anyway.
+       return if $needRemake;
+
+       $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");
+       }
+       
+       my $winname = $witem->{name};
+       my $winserver = $window->{active_server}->{tag};
+       my $winhandle = "$winserver/$winname";
+       $window->set_name("$data:$winhandle");
+       $server->command("/bind meta-$data change_window $data:$winhandle");
+       Irssi::print("Window $winhandle is now accessible with meta-$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_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_bool('chanact', 'chanact_remove_hash', 0);
+Irssi::settings_add_str('chanact', 'chanact_remove_prefix', "");
+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);
+Irssi::settings_add_bool('chanact', 'chanact_sort_by_activity', 1);
+Irssi::settings_add_int('chanact', 'chanact_filter', 0);
+
+# 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 changed', 'chanactHasChanged');
+Irssi::signal_add_last('window item changed', 'chanactHasChanged');
+Irssi::signal_add_last('window hilight', 'chanactHasChanged');
+Irssi::signal_add_last('window item hilight', 'chanactHasChanged');
+Irssi::signal_add("window created", "chanactHasChanged");
+Irssi::signal_add("window destroyed", "chanactHasChanged");
+Irssi::signal_add("window name changed", "chanactHasChanged");
+Irssi::signal_add("window activity", "chanactHasChanged");
+Irssi::signal_add("print text", "chanactHasChanged");
+Irssi::signal_add('nick mode changed', 'chanactHasChanged');
+
+Irssi::signal_add_last('window refnum changed', 'refnum_changed');
+
+###############
+###
+#
+# Changelog
+# 
+# 0.5.10
+#      - fixed irssi crash when using Irssi::print from within remake()
+#       - added option to filter out some data levels, based on a patch by
+#         Juergen Jung <juergen@Winterkaelte.de>, see
+#         https://bc-bd.org/trac/irssi/ticket/15
+#              + retired chanact_show_all in favour of chanact_filter
+#
+# 0.5.9
+#      - changes by stefan voelkel
+#              + sort channels by activity, see
+#                https://bc-bd.org/trac/irssi/ticket/5, based on a patch by jan
+#                krueger
+#              + fixed chrash on /exec -interactive, see
+#              https://bc-bd.org/trac/irssi/ticket/7
+#
+#      - changes by Jan 'jast' Krueger <jast@heapsort.de>, 2004-06-22
+#              + updated documentation in script's comments
+#
+#      - changes by Ivo Timmermans <ivo@o2w.nl>
+#              + honor actcolor /hilight setting if present
+#
+# 0.5.8
+# - made aliases case-sensitive and include network in channel names by madduck
+#
+# 0.5.7
+# - integrated remove patch by Christoph Berg <myon@debian.org>
+#
+# 0.5.6
+# - fixed a bug (#1) reported by Wouter Coekaert
+# 
+# 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/ircops.pl b/ircops.pl
new file mode 100644 (file)
index 0000000..1048691
--- /dev/null
+++ b/ircops.pl
@@ -0,0 +1,44 @@
+use Irssi;
+use strict;
+
+use vars qw($VERSION %IRSSI);
+
+$VERSION = "0.1";
+%IRSSI = (
+    authors     => 'BC-bd',
+    contact     => 'bd@bc-bd.org',
+    name        => 'ircops',
+    description => '/IRCOPS - Display IrcOps in current channel',
+    license     => 'GPL v2',
+    url         => 'https://bc-bd.org/svn/repos/irssi/ircpops',
+);
+
+sub cmd_ircops {
+       my ($data, $server, $channel) = @_;
+
+       my (@list,$text,$num);
+
+       if (!$channel || $channel->{type} ne 'CHANNEL') {
+               Irssi::print('No active channel in window');
+               return;
+       }
+
+       foreach my $nick ($channel->nicks()) {
+               if ($nick->{serverop}) {
+                       push(@list,$nick->{nick});
+               }
+       }
+
+       $num = scalar @list;
+
+       if ($num == 0) {
+               $text = "no IrcOps on this channel";
+       } else {
+               $text = "IrcOps (".$num."): ".join(" ",@list);
+       }
+
+       $channel->print($text);
+}
+
+Irssi::command_bind('ircops', 'cmd_ircops');
+
diff --git a/nact.pl b/nact.pl
new file mode 100644 (file)
index 0000000..8f4345e
--- /dev/null
+++ b/nact.pl
@@ -0,0 +1,334 @@
+use Irssi;
+use Irssi::TextUI;
+use strict;
+
+use vars qw($VERSION %IRSSI);
+
+$VERSION="0.2.6";
+%IRSSI = (
+       authors=> 'BC-bd',
+       contact=> 'bd@bc-bd.org',
+       name=> 'nact',
+       description=> 'Adds an item which displays the current network activity. Needs /proc/net/dev.',
+       license=> 'GPL v2 or later',
+       url=> 'https://bc-bd.org/svn/repos/irssi/nact',
+);
+
+#########
+# INFO
+###
+#
+#  Currently running on Linux, OpenBsd and FreeBsd.
+#
+#  Type this to add the item:
+#
+#    /statusbar window add nact
+#
+#  See
+#  
+#    /help statusbar
+#
+#  for more help on how to custimize your statusbar.
+#  Add something like this to your theme file to customize to look of the item
+#
+#    nact_display = "$0%R>%n%_$1%_%G>%n$2";
+#    
+#  where $0 is the input, $1 the device and $2 the output. To customize the
+#  outout of the /bw command add something like
+#
+#    nact_command = "$0)in:$1:out($2";
+#
+#  to your theme file.
+#
+##########
+# THEME
+####
+#
+# This is the complete list of parameters passed to the format:
+#
+#    $0: incomming rate
+#    $1: name of the device, eg. eth0
+#    $2: outgoing rate
+#    $3: total bytes received
+#    $4: total bytes sent
+#    $5: sum of $4 and $5
+#
+#########
+# TODO
+###
+#
+# Make this script work on other unices, For that i need some infos on where
+# to find the total amount of sent bytes on other systems. You may be so kind
+# as to send me the name of such a file and a sample output of it.
+#
+#   or
+#
+# you can be so kind as to send me a patch. Fort that _please_ check that you
+# do have the latest nact.pl and use these diff switches:
+#
+#   diff -uN nact.pl.new nact.pl.old 
+#
+############
+# OPTIONS
+######
+#
+# /set nact_command <command>
+#   command: command to execute on /bw. example:
+#
+#     /set nact_command /say
+#
+# /set nact_devices <devices>
+#   devices: space seperated list of devices to display
+#
+# /set nact_interval <n>
+#   n: number of mili-seconds to wait before an update of the item
+#
+# /set nact_format <format>
+#   format: a format string like the one with sprintf. examples: 
+#
+#     /set nact_format %d    no digits after the point at all
+#     /set nact_format %.3f  3 digits after the point
+#     /set nact_format %.5f  5 digits after the point
+# 
+# /set nact_unit <n>
+#   n: set the unit to KiB, MiB, or GiB. examples:
+#
+#     /set nact_unit 0 calculate dynamically
+#     /set nact_unit 1 set to KiB/s
+#     /set nact_unit 2 set to MiB/s
+#     /set nact_unit 3 set to GiB/s
+#   
+###
+################
+
+my $outString = "nact...";
+my $outCmd = "nact...";
+my (%in,%out,$timeout,$getBytes);
+
+sub getBytesLinux() {
+       my @list;
+       my $ignore = 2;
+       
+       open(FID, "/proc/net/dev");
+
+       while (<FID>) {
+               if ($ignore > 0) {
+                       $ignore--;
+                       next;
+               }
+
+               my $line = $_;
+               $line =~ s/[\s:]/ /g;
+               @list = split(" ", $line);
+               $in{$list[0]} = $list[1];
+               $out{$list[0]} = $list[9];
+       }
+
+       close (FID);
+}
+
+sub getBytesOBSD() {
+       my @list;
+       
+       open(FID, "/usr/bin/netstat -nib|");
+
+       while (<FID>) {
+               my $line = $_;
+               @list = split(" ", $line);
+               $in{$list[0]} = $list[4];
+               $out{$list[0]} = $list[5];
+       }
+
+       close (FID);
+}
+
+sub getBytesFBSD() {
+  my @list;
+  my $olddev="";
+
+  open(FID, "/usr/bin/netstat -nib|");
+  while (<FID>) {
+    my $line = $_;
+    @list = split(" ", $line);
+    next if $list[0] eq $olddev;
+    $in{$list[0]} = $list[6];
+    $out{$list[0]} = $list[9];
+    $olddev=$list[0];
+  }
+
+  close (FID);
+}
+
+sub make_kilo($$$) {
+       my ($what,$format,$unit) = @_;
+       my ($effective);
+
+       # determine the effective unit, either from forcing, or from dynamically
+       # checking the size of the value
+       if ($unit == 0) {
+               if ($what >= 1024*1024*1024) {
+                       $effective = 3
+               } elsif ($what >= 1024*1024) {
+                       $effective = 2
+               } elsif ($what >= 1024) {
+                       $effective = 1
+               } else {
+                       $effective = 0;
+               }
+       } else {
+               $effective = $unit;
+       }
+       
+       if ($effective >= 3) {
+                       return sprintf($format."%s", $what/(1024*1024*1024), "G");
+       } elsif ($effective == 2) {
+                       return sprintf($format."%s", $what/(1024*1024), "M");
+       } elsif ($effective == 1) {
+                       return sprintf($format."%s", $what/(1024), "K");
+       } else {
+               return sprintf($format, $what);
+       }
+}
+
+sub sb_nact() {
+       my ($item, $get_size_only) = @_;
+
+       $item->default_handler($get_size_only, "{sb $outString}", undef, 1);
+}
+
+sub timeout_nact() {
+       my ($out,$char);
+       my $slice = Irssi::settings_get_int('nact_interval');
+       my $format = Irssi::settings_get_str('nact_format');
+       my $unit = Irssi::settings_get_int('nact_unit');
+       my $theme = Irssi::current_theme();
+       my %oldIn = %in;
+       my %oldOut = %out;
+       
+       &$getBytes();
+               
+       $out = "";
+       $outCmd = "";
+               
+       foreach (split(" ", Irssi::settings_get_str('nact_devices'))) {
+               my $b_in = $in{$_};
+               my $b_out = $out{$_};
+               my $deltaIn = make_kilo(($b_in -$oldIn{$_})*1000/$slice,$format,$unit);
+               my $deltaOut = make_kilo(($b_out -$oldOut{$_})*1000/$slice,$format,$unit);
+               my $i = make_kilo($b_in,$format,$unit);
+               my $o = make_kilo($b_out,$format,$unit);
+               my $s = make_kilo($b_in +$b_out,$format,$unit);
+
+               $out .= Irssi::current_theme->format_expand(
+                       "{nact_display $deltaIn $_ $deltaOut $i $o $s}",Irssi::EXPAND_FLAG_IGNORE_REPLACES);
+               
+               $outCmd .= Irssi::current_theme->format_expand(
+                       "{nact_command $deltaIn $_ $deltaOut $i $o $s}",Irssi::EXPAND_FLAG_IGNORE_REPLACES);
+       }
+
+       # perhaps this usage of $out as temp variable does fix those nasty
+       # display errors
+       $outString = $out;
+       Irssi::statusbar_items_redraw('nact');
+}
+
+sub nact_setup() {
+       my $slice = Irssi::settings_get_int('nact_interval');
+       
+       Irssi::timeout_remove($timeout);
+
+       if ($slice < 10) {
+               Irssi::print("nact.pl, ERROR nact_interval must be greater than 10");
+               return;
+       }
+
+       $timeout = Irssi::timeout_add($slice, 'timeout_nact' , undef);
+}
+
+sub cmd_bw {
+       my ($data, $server, $witem) = @_;
+
+       if ($witem && ($witem->{type} eq "CHANNEL" || $witem->{type} eq "QUERY")) {
+               $witem->command(Irssi::settings_get_str('nact_command')." ".$outCmd);
+       } else {
+               Irssi::print("nact: command needs window of type channel or query.");
+       }
+}
+
+Irssi::command_bind('bw','cmd_bw');
+
+Irssi::signal_add('setup changed','nact_setup');
+
+# register our item
+Irssi::statusbar_item_register('nact', undef, 'sb_nact');
+
+# register our os independant settings
+Irssi::settings_add_int('misc', 'nact_interval', 10000);
+Irssi::settings_add_str('misc', 'nact_format', '%.0f');
+Irssi::settings_add_int('misc', 'nact_unit', 0);
+Irssi::settings_add_str('misc', 'nact_command', 'me looks at the gauges:');
+
+# os detection
+my $os = `uname`;
+if ($os =~ /Linux/) {
+       Irssi::print("nact.pl, running on Linux, using /proc/net/dev");
+       $getBytes = \&getBytesLinux;
+       Irssi::settings_add_str('misc', 'nact_devices', "eth0 lo");
+} elsif ($os =~ /OpenBSD/) {
+       Irssi::print("nact.pl, running on OpenBSD, using netstat -nbi");
+       $getBytes = \&getBytesOBSD;
+       Irssi::settings_add_str('misc', 'nact_devices', "tun0");
+} elsif ($os =~ /FreeBSD/) {
+  Irssi::print("nact.pl, running on FreeBSD, using netstat -nbi");
+  $getBytes = \&getBytesFBSD;
+  Irssi::settings_add_str('misc', 'nact_devices', "rl0");
+} else {
+       Irssi::print("nact.pl, sorry no support for OS:$os");
+       Irssi::print("nact.pl, If you know how to collect the needed data on your OS, mail me :)");
+       $os = "";
+}
+
+if ($os ne "") {
+       &$getBytes();
+       nact_setup();
+}
+
+################
+###
+# Changelog
+#
+# Version 0.2.5
+#  - added nact_command
+#  - added /bw
+#
+# Version 0.2.4
+#  - added FreeBSD support (by senneth)
+#
+# Version 0.2.3
+#  - stray ' ' in the item (reported by darix). Add a " " at the end of your
+#      nact_display if you have more than one interface listed.
+#
+# Version 0.2.2
+#  - added missing use Irssi::TextUI (reported by darix)
+#  - small parameter switch bug (reported by darix)
+#
+# Version 0.2.1
+#  - added total number of bytes sent/received
+#  
+# Version 0.2.0
+#  - runs now from autorun/ on openbsd
+#  - changed nact_interval to mili-seconds
+#  - added nact_format, nact_unit
+#
+# Version 0.1.2
+#  - small typo in the docs
+#
+# Version 0.1.1
+#  - introduced multiple os support
+#  - added a theme thingie to make sascha happy ;)
+#
+# Version 0.1.0
+#  - initial release
+#
+###
+################
diff --git a/niq.pl b/niq.pl
new file mode 100644 (file)
index 0000000..c601247
--- /dev/null
+++ b/niq.pl
@@ -0,0 +1,325 @@
+# BitchX TAB complete style
+# for irssi 0.7.99 by bd@bc-bd.org
+#
+# <tab> signal handling learned from dictcomplete by Timo Sirainen
+#
+# thx go out to fuchs, darix, dg, peder and all on #irssi who helped
+#
+#########
+# USAGE
+###
+# 
+# In a channel window type "ab<tab>" to see a list of nicks starting
+# with "ab".
+# If you now press <tab> again, irssi will default to its own nick
+# completion method.
+# If you enter more characters you can use <tab> again to see a list
+# of the matching nicks, or to complete the nick if there is only
+# one matching.
+#
+# The last completion is saved so if you press "<tab>" with an empty
+# input line, you get the last completed nick.
+#
+# Now there is a statusbar item where you can see the completing
+# nicks instead of in the channel window. There are two ways to 
+# use it:
+#
+#      1) Inside another statusbar
+#
+#              /set niq_show_in_statusbar ON
+#              /statusbar window add -before more niq
+#
+#      2) In an own statusbar
+#
+#              /set niq_show_in_statusbar ON
+#              /set niq_own_statusbar ON
+#
+# WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+#
+# THIS IS CURRENTLY BROKEN IN IRSSI 0.8.4 AND ONLY WORKS WITH 
+# THE ACTUAL CVS VERSION. USEING THIS ON AN VERSION 0.8.4 OR
+# OLDER WILL ERASE YOUR INPUT LINE
+#
+# With 2) you can also set
+#
+#              /set niq_hide_on_inactive ON
+#
+# which will only show the bar if you complete nicks.
+#
+# WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+#
+#########
+# OPTIONS
+#########
+#
+# /set niq_show_in_statusbar <ON|OFF>
+#              * ON  : show the completing nicks in a statusbar item
+#              * OFF : show the nicks in the channel window
+#
+# /set niq_own_statusbar <ON|OFF>
+#              * ON  : use an own statusbar for the nicks
+#              * OFF : just use an item
+#
+# /set niq_hide_on_inactive <ON|OFF>
+#              * ON  : hide the own statusbar on inactivity
+#              * OFF : dont hide it
+#
+# /set niq_color_char <ON|OFF>
+#              * ON  : colors the next unlikely character
+#              * OFF : boring no colors
+#
+###
+################
+###
+# Changelog
+#
+# Version 0.5.6
+# - work around an use problem
+#
+# Version 0.5.5
+# - fixed completion for nicks starting with special chars
+#
+# Version 0.5.4
+# - removed unneeded sort() of colored nicks
+# - moved colored nick generation to where it is needed
+# - the statusbar only worked with colorized nicks (duh!)
+# 
+# Version 0.5.3
+#      - stop nickcompleting if last char is the completion_char
+#        which is in most cases ':'
+#
+# Version 0.5.2
+#      - fixed vanishing statusbar. it wrongly was reset on any
+#        privmsg.
+#
+# Version 0.5.1
+#      - changed statusbar to be off by default since most people 
+#        dont use the latest fixed version.
+#
+# Version 0.5
+#      - added own statusbar option
+#  - added color char option
+#
+# Version 0.4
+#      - added an niq statusbar
+#
+# Version 0.3
+#  - added default to irssi method on <tab><tab>
+#
+# Version 0.2 
+#  - added lastcomp support
+#
+# Version 0.1
+#  - initial release
+###
+################
+
+use Irssi;
+use Irssi::TextUI;
+use strict;
+
+use vars qw($VERSION %IRSSI);
+
+$VERSION="0.5.6";
+%IRSSI = (
+       authors=> 'BC-bd',
+       contact=> 'bd@bc-bd.org',
+       name=> 'niq',
+       description=> 'BitchX like Nickcompletion at line start plus statusbar',
+       license=> 'GPL v2',
+       url=> 'https://bc-bd.org/svn/repos/irssi/niq',
+);
+
+my($lastword,$lastcomp,$niqString);
+
+$lastcomp = "";
+$lastword = "";
+
+# build our nick with completion_char, add to complist and stop the signal
+sub buildNickAndStop {
+       my ($complist,$nick) = @_;
+       my $push = $nick.Irssi::settings_get_str('completion_char');
+               
+       $lastcomp = $nick;
+       $lastword = "";
+       push (@{$complist}, $push);
+
+       if (Irssi::settings_get_bool('niq_show_in_statusbar') == 1) {
+               drawStatusbar("");
+       }
+
+       Irssi::signal_stop();
+}
+
+# the signal handler
+sub sig_complete {
+       my ($complist, $window, $word, $linestart, $want_space) = @_;
+
+       # still allow channel- #<tab>, /set n<tab>, etc completion.
+       if ($linestart ne "") {
+               return;
+       }
+
+       # also back out if nothing has been entered and lastcomp is ""
+       if ($word eq "") {
+               if ($lastcomp ne "") {
+                       buildNickAndStop($complist,$lastcomp);
+                       return;
+               } else {
+                       return;
+               }
+       }
+       if (rindex($word,Irssi::settings_get_str('completion_char')) == length($word) -1) {
+               chop($word);
+               buildNickAndStop($complist,$word,0);
+               return;
+       }
+
+       my $channel = $window->{active};
+
+       # the completion is ok if this is a channel
+       if ($channel->{type} ne "CHANNEL") 
+       {
+               return;
+       }
+
+       my (@nicks);
+
+       # get the matching nicks but quote this l33t special chars like ^
+       my $shortestNick = 999;
+       my $quoted = quotemeta $word;
+       foreach my $n ($channel->nicks()) {
+               if ($n->{nick} =~ /^$quoted/i && $window->{active_server}->{nick} ne $n->{nick}) {
+                       push(@nicks,$n->{nick});
+                       if (length($n->{nick}) < $shortestNick) {
+                               $shortestNick = length($n->{nick});
+                       }
+               }
+       }
+
+       @nicks = sort(@nicks);
+       
+       # if theres only one nick return it.
+       if (scalar @nicks eq 1)
+       {
+               buildNickAndStop($complist,$nicks[0]);
+       } elsif (scalar @nicks gt 1) {
+               # check if this is <tab> or <tab><tab>
+               if ($lastword eq $word) {
+                       # <tab><tab> so default to the irssi method
+                       sort(@nicks);
+                       for (@nicks) { $_ .= ':'; }
+                       push (@{$complist}, @nicks);
+
+                       # but delete lastword to be ready for the next <tab>
+                       $lastword = "";
+
+                       if (Irssi::settings_get_bool('niq_show_in_statusbar') == 1) {
+                               drawStatusbar("");
+                       }
+
+                       return;
+               } else {
+                       # <tab> only so just print
+               
+                       # TODO
+                       # TODO way too slow, need some ideas first!
+                       # TODO 
+                       # find the longest matching subword
+#                      Irssi::print(join(" ",@nicks));
+#                      Irssi::print($shortestNick);
+#                      my ($i,$n);
+#                      my $exit = 0;
+#                      for ($i = length($word); $exit == 0 && $i <$shortestNick; $i++) {
+#                        my $char = substr($nicks[0],$i,1);
+#                              Irssi::print($i." ".$char);
+#                              foreach $n (@nicks) {
+#                                      Irssi::print($n);
+#                                      if (substr($n,$i,1) ne $char) {
+#                                              $i--;
+#                                              $exit = 1;
+#                                              Irssi::print("exit: ".$i);
+#                                      }
+#                              }
+#                      }
+#                      Irssi::print($i);
+#                      $word = substr($nicks[0],0,$i);
+#                      Irssi::print($word);
+#      
+#                      @$complist = ();
+#                      $$complist[0] = $word;
+#                      $$want_space = 0;
+
+                       # build string w/o colored nicks
+                       if (Irssi::settings_get_bool('niq_color_char') == 1) {
+                               $niqString = "";
+                               foreach my $n (@nicks) {
+                                       my $coloredNick = $n;
+                                       $coloredNick =~ s/($quoted)(.)(.*)/$1%_$2%_$3/i;
+                                       $niqString .= "$coloredNick ";
+                               }
+                       } else {
+                               $niqString = join(" ",@nicks);
+                       }
+                       
+                       if (Irssi::settings_get_bool('niq_show_in_statusbar') == 1) {
+                               drawStatusbar($niqString);
+                       } else {
+                               $window->print($niqString);
+                       }
+
+                       Irssi::signal_stop();
+
+                       # remember last word
+                       $lastword = $word;
+
+                       return;
+               }
+       } 
+
+       # we have not found a nick, so someone used <tab> within another conttext
+       # and thus $lastword is no longer of interest
+#      $lastword = ""
+}
+
+sub emptyBar() {
+       $lastword = "";
+       
+       drawStatusbar("");
+}
+
+sub drawStatusbar() {
+       my ($word) = @_;
+
+       if (Irssi::settings_get_bool('niq_own_statusbar') == 1) {
+               if (Irssi::settings_get_bool('niq_hide_on_inactive') == 1) {
+                       if ($word eq "") {
+                               Irssi::command("statusbar niq disable");
+                       } else {
+                               Irssi::command("statusbar niq enable");
+                       }
+               }
+       }
+
+       $niqString = "{sb $word}";
+       Irssi::statusbar_items_redraw('niq');
+}
+
+sub niqStatusbar() {
+       my ($item, $get_size_only) = @_;
+
+       $item->default_handler($get_size_only, $niqString, undef, 1);
+}
+
+Irssi::signal_add_first('complete word', 'sig_complete');
+Irssi::signal_add_last('window changed', 'emptyBar');
+#Irssi::signal_add('event privmsg', 'emptyBar');
+Irssi::signal_add('message own_public', 'emptyBar');
+
+Irssi::statusbar_item_register('niq', '$0', 'niqStatusbar');
+Irssi::statusbars_recreate_items();
+
+Irssi::settings_add_bool('misc', 'niq_show_in_statusbar', 0);
+Irssi::settings_add_bool('misc', 'niq_own_statusbar', 0);
+Irssi::settings_add_bool('misc', 'niq_hide_on_inactive', 1);
+Irssi::settings_add_bool('misc', 'niq_color_char', 1);
diff --git a/nm.pl b/nm.pl
new file mode 100644 (file)
index 0000000..41eb39a
--- /dev/null
+++ b/nm.pl
@@ -0,0 +1,616 @@
+use Irssi;
+use strict;
+
+use vars qw($VERSION %IRSSI);
+
+$VERSION="0.3.6";
+%IRSSI = (
+       authors=> 'BC-bd',
+       contact=> 'bd@bc-bd.org',
+       name=> 'nm',
+       description=> 'right aligned nicks depending on longest nick',
+       license=> 'GPL v2',
+       url=> 'https://bc-bd.org/svn/repos/irssi/nm',
+);
+
+# $Id$
+# nm.pl
+# for irssi 0.8.4 by bd@bc-bd.org
+#
+# right aligned nicks depending on longest nick
+#
+# inspired by neatmsg.pl from kodgehopper <kodgehopper@netscape.net
+# formats taken from www.irssi.de
+# thanks to adrianel <adrinael@nuclearzone.org> for some hints
+# thanks to Eric Wald <eswald@gmail.com> for the left alignment patch
+# inspired by nickcolor.pl by Timo Sirainen and Ian Peters
+# thanks to And1 <and1@meinungsverstaerker.de> for a small patch
+# thanks to berber@tzi.de for the save/load patch
+#
+#########
+# USAGE
+###
+# 
+# use
+# 
+#      /neatcolor help
+#
+# for help on available commands
+#
+#########
+# OPTIONS
+#########
+
+my $help = "
+/set neat_colorize <ON|OFF>
+    * ON  : colorize nicks
+    * OFF : do not colorize nicks
+
+/set neat_colors <string>
+    Use these colors when colorizing nicks, eg:
+
+        /set neat_colors yYrR
+
+    See the file formats.txt on an explanation of what colors are
+    available.
+
+/set neat_left_actions <ON|OFF>
+    * ON  : print nicks left-aligned on actions
+    * OFF : print nicks right-aligned on actions
+
+/set neat_left_messages <ON|OFF>
+    * ON  : print nicks left-aligned on messages
+    * OFF : print nicks right-aligned on messages
+
+/set neat_right_mode <ON|OFF>
+    * ON  : print the mode of the nick e.g @%+ after the nick
+    * OFF : print it left of the nick 
+
+/set neat_maxlength <number>
+    * number : Maximum length of Nicks to display. Longer nicks are truncated.
+    * 0      : Do not truncate nicks.
+
+/set neat_melength <number>
+    * number : number of spaces to substract from /me padding
+
+/set neat_ignorechars <str>
+    * str : regular expression used to filter out unwanted characters in
+            nicks. this can be used to assign the same color for similar
+            nicks, e.g. foo and foo_:
+
+                /set neat_ignorechars [_]
+
+/set neat_allow_shrinking <ON|OFF>
+    * ON  : shrink padding when longest nick disappears
+    * OFF : do not shrink, only allow growing
+";
+
+#
+###
+################
+###
+#
+# Changelog
+#
+# Version 0.3.6
+#  - added option to ignore certain characters from color hash building, see
+#    https://bc-bd.org/trac/irssi/ticket/22
+#  - added option to save and specify colors for nicks, see
+#    https://bc-bd.org/trac/irssi/ticket/23
+#  - added option to disallow shrinking, see
+#    https://bc-bd.org/trac/irssi/ticket/12
+#
+# Version 0.3.5
+#  - now also aligning own messages in queries
+#
+# Version 0.3.4
+#  - fxed off by one error in nick_to_color, patch by jrib, see
+#  https://bc-bd.org/trac/irssi/ticket/24
+#
+# Version 0.3.3
+#  - added support for alignment in queries, see
+#    https://bc-bd.org/trac/irssi/ticket/21
+#
+# Version 0.3.2
+#  - integrated left alignment patch from Eric Wald <eswald@gmail.com>, see
+#    https://bc-bd.org/trac/irssi/ticket/18
+#
+# Version 0.3.1
+#  - /me padding, see https://bc-bd.org/trac/irssi/ticket/17
+#
+# Version 0.3.0
+#  - integrate nick coloring support
+#
+# Version 0.2.1
+#  - moved neat_maxlength check to reformat() (thx to Jerome De Greef <jdegreef@brutele.be>)
+#
+# Version 0.2.0
+#  - by adrianel <adrinael@nuclearzone.org>
+#     * reformat after setup reload
+#     * maximum length of nicks
+#
+# Version 0.1.0
+#  - got lost somewhere
+#
+# Version 0.0.2
+#  - ugly typo fixed
+#  
+# Version 0.0.1
+#  - initial release
+#
+###
+################
+###
+#
+# BUGS
+#
+# Empty nicks, eg "<> message"
+#      This seems to be triggered by some themes. As of now there is no known
+#      fix other than changing themes, see
+#      https://bc-bd.org/trac/irssi/ticket/19
+#
+# Well, it's a feature: due to the lacking support of extendable themes
+# from irssi it is not possible to just change some formats per window.
+# This means that right now all windows are aligned with the same nick
+# length, which can be somewhat annoying.
+# If irssi supports extendable themes, I will include per-server indenting
+# and a setting where you can specify servers you don't want to be indented
+#
+###
+################
+
+my ($longestNick, %saved_colors, @colors, $alignment, $sign, %commands);
+
+my $colorize = -1;
+
+sub reformat() {
+       my $max = Irssi::settings_get_int('neat_maxlength');
+       my $actsign = Irssi::settings_get_bool('neat_left_actions')? '': '-';
+       $sign = Irssi::settings_get_bool('neat_left_messages')? '': '-';
+
+       if ($max && $max < $longestNick) {
+               $longestNick = $max;
+       }
+
+       my $me = $longestNick - Irssi::settings_get_int('neat_melength');
+       $me = 0 if ($me < 0);
+
+       Irssi::command('^format own_action {ownaction $['.$actsign.$me.']0} $1');
+       Irssi::command('^format action_public {pubaction $['.$actsign.$me.']0}$1');
+       Irssi::command('^format action_private {pvtaction $['.$actsign.$me.']0}$1');
+       Irssi::command('^format action_private_query {pvtaction_query $['.$actsign.$me.']0} $2');
+
+       my $length = $sign . $longestNick;
+       if (Irssi::settings_get_bool('neat_right_mode') == 0) {
+               Irssi::command('^format own_msg {ownmsgnick $2 {ownnick $['.$length.']0}}$1');
+               Irssi::command('^format own_msg_channel {ownmsgnick $3 {ownnick $['.$length.']0}{msgchannel $1}}$2');
+               Irssi::command('^format pubmsg_me {pubmsgmenick $2 {menick $['.$length.']0}}$1');
+               Irssi::command('^format pubmsg_me_channel {pubmsgmenick $3 {menick $['.$length.']0}{msgchannel $1}}$2');
+               Irssi::command('^format pubmsg_hilight {pubmsghinick $0 $3 $['.$length.']1%n}$2');
+               Irssi::command('^format pubmsg_hilight_channel {pubmsghinick $0 $4 $['.$length.']1{msgchannel $2}}$3');
+               Irssi::command('^format pubmsg {pubmsgnick $2 {pubnick $['.$length.']0}}$1');
+               Irssi::command('^format pubmsg_channel {pubmsgnick $2 {pubnick $['.$length.']0}}$1');
+       } else {
+               Irssi::command('^format own_msg {ownmsgnick {ownnick $['.$length.']0$2}}$1');
+               Irssi::command('^format own_msg_channel {ownmsgnick {ownnick $['.$length.']0$3}{msgchannel $1}}$2');
+               Irssi::command('^format pubmsg_me {pubmsgmenick {menick $['.$length.']0}$2}$1');
+               Irssi::command('^format pubmsg_me_channel {pubmsgmenick {menick $['.$length.']0$3}{msgchannel $1}}$2');
+               Irssi::command('^format pubmsg_hilight {pubmsghinick $0 $0 $['.$length.']1$3%n}$2');
+               Irssi::command('^format pubmsg_hilight_channel {pubmsghinick $0 $['.$length.']1$4{msgchannel $2}}$3');
+               Irssi::command('^format pubmsg {pubmsgnick {pubnick $['.$length.']0$2}}$1');
+               Irssi::command('^format pubmsg_channel {pubmsgnick {pubnick $['.$length.']0$2}}$1');
+       }
+
+       # format queries
+       Irssi::command('^format own_msg_private_query {ownprivmsgnick {ownprivnick $['.$length.']2}}$1');
+       Irssi::command('^format msg_private_query {privmsgnick $['.$length.']0}$2');
+};
+
+sub findLongestNick {
+       $longestNick = 0;
+
+       # get own nick length
+       map {
+               my $len = length($_->{nick});
+
+               $longestNick = $len if ($len > $longestNick);
+       } Irssi::servers();
+
+       # find longest other nick
+       foreach (Irssi::channels()) {
+               foreach ($_->nicks()) {
+                       my $len = length($_->{nick});
+
+                       $longestNick = $len if ($len > $longestNick);
+               }
+       }
+
+       reformat();
+}
+
+# a new nick was created
+sub sig_newNick
+{
+       my ($channel, $nick) = @_;
+
+       my $len = length($nick->{nick});
+
+       if ($len > $longestNick) {
+               $longestNick = $len;
+               reformat();
+       }
+
+       return if (exists($saved_colors{$nick->{nick}}));
+
+       $saved_colors{$nick->{nick}} = "%".nick_to_color($nick->{nick});
+}
+
+# something changed
+sub sig_changeNick
+{
+       my ($channel, $nick, $old_nick) = @_;
+
+       # we only need to recalculate if this was the longest nick
+       if (length($old_nick) == $longestNick) {
+               my $len = length($nick->{nick});
+
+               # if the new nick is shorter we need to find the longest nick
+               # again, if it is longer, it is the new longest nick
+               if ($len < $longestNick) {
+                       # only look for a new longest nick if we are allowed to
+                       # shrink
+                       findLongestNick() if Irssi::settings_get_bool('neat_allow_shrinking');
+               } else {
+                       $longestNick = $len;
+               }
+
+               reformat();
+       }
+
+       $saved_colors{$nick->{nick}} = $saved_colors{$nick->{old_nick}};
+       delete $saved_colors{$nick->{old_nick}}
+}
+
+sub sig_removeNick
+{
+       my ($channel, $nick) = @_;
+
+       my $thisLen = length($nick->{nick});
+
+       # we only need to recalculate if this was the longest nick and we are
+       # allowed to shrink
+       if ($thisLen == $longestNick && Irssi::settings_get_bool('neat_allow_shrinking')) {
+               findLongestNick();
+               reformat();
+       }
+
+       # we do not remove a known color for a gone nick, as they may return
+}
+
+# based on simple_hash from nickcolor.pl
+sub nick_to_color($) {
+       my ($string) = @_;
+       chomp $string;
+
+       my $ignore = Irssi::settings_get_str("neat_ignorechars");
+       $string =~ s/$ignore//g;
+
+       my $counter;
+       foreach my $char (split(//, $string)) {
+               $counter += ord $char;
+       }
+
+       return $colors[$counter % ($#colors + 1)];
+}
+
+sub color_left($) {
+       Irssi::command('^format pubmsg {pubmsgnick $2 {pubnick '.$_[0].'$['.$sign.$longestNick.']0}}$1');
+       Irssi::command('^format pubmsg_channel {pubmsgnick $2 {pubnick '.$_[0].'$['.$sign.$longestNick.']0}}$1');
+}
+
+sub color_right($) {
+       Irssi::command('^format pubmsg {pubmsgnick {pubnick '.$_[0].'$['.$sign.$longestNick.']0}$2}$1');
+       Irssi::command('^format pubmsg_channel {pubmsgnick {pubnick '.$_[0].'$['.$sign.$longestNick.']0}$2}$1');
+}
+
+sub sig_public {
+       my ($server, $msg, $nick, $address, $target) = @_;
+
+       &$alignment($saved_colors{$nick});
+}
+
+sub sig_setup {
+       @colors = split(//, Irssi::settings_get_str('neat_colors'));
+
+       # check left or right alignment
+       if (Irssi::settings_get_bool('neat_right_mode') == 0) {
+               $alignment = \&color_left;
+       } else {
+               $alignment = \&color_right;
+       }
+       
+       # check if we switched coloring on or off
+       my $new = Irssi::settings_get_bool('neat_colorize');
+       if ($new != $colorize) {
+               if ($new) {
+                       Irssi::signal_add('message public', 'sig_public');
+               } else {
+                       if ($colorize >= 0) {
+                               Irssi::signal_remove('message public', 'sig_public');
+                       }
+               }
+       }
+       $colorize = $new;
+
+       reformat();
+       &$alignment('%w');
+}
+
+# make sure that every nick has an assigned color
+sub assert_colors() {
+       foreach (Irssi::channels()) {
+               foreach ($_->nicks()) {
+                       next if (exists($saved_colors{$_->{nick}}));
+
+                       $saved_colors{$_->{nick}} = "%".nick_to_color($_->{nick});
+               }
+       }
+}
+
+# load colors from file
+sub load_colors() {
+       open(FID, "<".$ENV{HOME}."/.irssi/saved_colors") || return;
+
+       while (<FID>) {
+               chomp;
+               my ($k, $v) = split(/:/);
+               $saved_colors{$k} = $v;
+       }
+
+       close(FID);
+}
+
+# save colors to file
+sub save_colors() {
+       open(FID, ">".$ENV{HOME}."/.irssi/saved_colors");
+
+       print FID $_.":".$saved_colors{$_}."\n" foreach (keys(%saved_colors));
+
+       close(FID);
+}
+
+# log a line to a window item
+sub neat_log($@) {
+       my ($witem, @text) = @_;
+
+       $witem->print("nm.pl: ".$_) foreach(@text);
+}
+
+# show available colors
+sub cmd_neatcolor_colors($) {
+       my ($witem, undef, undef) = @_;
+
+       neat_log($witem, "Available colors: ".join("", map { "%".$_.$_ } @colors));
+}
+
+# display the configured color for a nick
+sub cmd_neatcolor_get() {
+       my ($witem, $nick, undef) = @_;
+
+       if (!exists($saved_colors{$nick})) {
+               neat_log($witem, "Error: no such nick '$nick'");
+               return;
+       }
+
+       neat_log($witem, "Color for ".$saved_colors{$nick}.$nick);
+}
+
+# display help
+sub cmd_neatcolor_help() {
+       my ($witem, $cmd, undef) = @_;
+
+       if ($cmd) {
+               if (!exists($commands{$cmd})) {
+                       neat_log($witem, "Error: no such command '$cmd'");
+                       return;
+               }
+
+               if (!exists($commands{$cmd}{verbose})) {
+                       neat_log($witem, "No additional help for '$cmd' available");
+                       return;
+               }
+
+               neat_log($witem, ( "", "Help for ".uc($cmd), "" ) );
+               neat_log($witem, @{$commands{$cmd}{verbose}});
+               return;
+       }
+
+       neat_log($witem, split(/\n/, $help));
+       neat_log($witem, "Available options for /neatcolor");
+       neat_log($witem, "    ".$_.": ".$commands{$_}{text}) foreach(sort(keys(%commands)));
+
+       my @verbose;
+       foreach (sort(keys(%commands))) {
+               push(@verbose, $_) if exists($commands{$_}{verbose});
+       }
+
+       neat_log($witem, "Verbose help available for: '".join(", ", @verbose)."'");
+}
+
+# list configured nicks
+sub cmd_neatcolor_list() {
+       my ($witem, undef, undef) = @_;
+
+       neat_log($witem, "Configured nicks: ".join(", ", map { $saved_colors{$_}.$_ } sort(keys(%saved_colors))));
+}
+
+# reset a nick to its default color
+sub cmd_neatcolor_reset() {
+       my ($witem, $nick, undef) = @_;
+
+       if (!exists($saved_colors{$nick})) {
+               neat_log($witem, "Error: no such nick '$nick'");
+               return;
+       }
+
+       $saved_colors{$nick} = "%".nick_to_color($nick);
+       neat_log($witem, "Reset color for ".$saved_colors{$nick}.$nick);
+}
+
+# save configured colors to disk
+sub cmd_neatcolor_save() {
+       my ($witem, undef, undef) = @_;
+
+       save_colors();
+
+       neat_log($witem, "color information saved");
+}
+
+# set a color for a nick
+sub cmd_neatcolor_set() {
+       my ($witem, $nick, $color) = @_;
+
+       my @found = grep(/$color/, @colors);
+       if ($#found) {
+               neat_log($witem, "Error: trying to set unknown color '%$color$color%n'");
+               cmd_neatcolor_colors($witem);
+               return;
+       }
+
+       if ($witem->{type} ne "CHANNEL" && $witem->{type} ne "QUERY") {
+               neat_log($witem, "Warning: not a Channel/Query, can not check nick");
+       } else {
+               my @nicks = grep(/^$nick$/i, map { $_->{nick} } ($witem->nicks()));
+
+               if ($#nicks < 0) {
+                       neat_log($witem, "Warning: could not find nick '$nick' here");
+               } else {
+                       if ($nicks[0] ne $nick) {
+                               neat_log($witem, "Warning: using '$nicks[0]' instead of '$nick'");
+                               $nick = $nicks[0];
+                       }
+               }
+       }
+
+       $saved_colors{$nick} = "%".$color;
+       neat_log($witem, "Set color for $saved_colors{$nick}$nick");
+}
+
+%commands = (
+       colors => {
+               text => "show available colors",
+               verbose => [
+                       "COLORS",
+                       "",
+                       "displays all available colors",
+                       "",
+                       "You can restrict/define the list of available colors ".
+                       "with the help of the neat_colors setting"
+               ],
+               func => \&cmd_neatcolor_colors,
+       },
+       get => {
+               text => "retrieve color for a nick",
+               verbose => [
+                       "GET <nick>",
+                       "",
+                       "displays color used for <nick>"
+               ],
+               func => \&cmd_neatcolor_get,
+       },
+       help => {
+               text => "print this help message",
+               func => \&cmd_neatcolor_help,
+       },
+       list => {
+               text => "list configured nick/color pairs",
+               func => \&cmd_neatcolor_list,
+       },
+       reset => {
+               text => "reset color to default",
+               verbose => [
+                       "RESET <nick>",
+                       "",
+                       "resets the color used for <nick> to its internal default"
+               ],
+               func => \&cmd_neatcolor_reset,
+       },
+       save => {
+               text => "save color information to disk",
+               verbose => [
+                       "SAVE",
+                       "",
+                       "saves color information to disk, so that it survives ".
+                       "an irssi restart.",
+                       "",
+                       "Color information will be automatically saved on /quit",
+               ],
+               func => \&cmd_neatcolor_save,
+       },
+       set => {
+               text => "set a specific color for a nick",
+               verbose => [
+                       "SET <nick> <color>",
+                       "",
+                       "use <color> for <nick>",
+                       "",
+                       "This command will perform a couple of sanity checks, ".
+                       "when called from a CHANNEL/QUERY window",
+                       "",
+                       "EXAMPLE:",
+                       "  /neatcolor set bc-bd r",
+                       "",
+                       "use /neatcolor COLORS to see available colors"
+               ],
+               func => \&cmd_neatcolor_set,
+       },
+);
+
+# the main command callback that gets called for all neatcolor commands
+sub cmd_neatcolor() {
+       my ($data, $server, $witem) = @_;
+       my ($cmd, $nick, $color) = split (/ /, $data);
+
+       $cmd = lc($cmd);
+
+       # make sure we have a valid witem to print text to
+       $witem = Irssi::active_win() unless ($witem);
+
+       if (!exists($commands{$cmd})) {
+               neat_log($witem, "Error: unknown command '$cmd'");
+               &{$commands{"help"}{"func"}} if (exists($commands{"help"}));
+               return;
+       }
+
+       &{$commands{$cmd}{"func"}}($witem, $nick, $color);
+}
+
+Irssi::settings_add_bool('misc', 'neat_left_messages', 0);
+Irssi::settings_add_bool('misc', 'neat_left_actions', 0);
+Irssi::settings_add_bool('misc', 'neat_right_mode', 1);
+Irssi::settings_add_int('misc', 'neat_maxlength', 0);
+Irssi::settings_add_int('misc', 'neat_melength', 2);
+Irssi::settings_add_bool('misc', 'neat_colorize', 1);
+Irssi::settings_add_str('misc', 'neat_colors', 'rRgGyYbBmMcC');
+Irssi::settings_add_str('misc', 'neat_ignorechars', '');
+Irssi::settings_add_bool('misc', 'neat_allow_shrinking', 1);
+
+Irssi::command_bind('neatcolor', 'cmd_neatcolor');
+
+Irssi::signal_add('nicklist new', 'sig_newNick');
+Irssi::signal_add('nicklist changed', 'sig_changeNick');
+Irssi::signal_add('nicklist remove', 'sig_removeNick');
+
+Irssi::signal_add('setup changed', 'sig_setup');
+Irssi::signal_add_last('setup reread', 'sig_setup');
+
+findLongestNick();
+sig_setup;
+
+load_colors();
+assert_colors();
+
+# we need to add this signal _after_ the colors have been loaded, to make sure
+# no race condition exists wrt color saving
+Irssi::signal_add('gui exit', 'save_colors');
diff --git a/repeat.pl b/repeat.pl
new file mode 100644 (file)
index 0000000..0eb3fc3
--- /dev/null
+++ b/repeat.pl
@@ -0,0 +1,138 @@
+use Irssi;
+use strict;
+
+use vars qw($VERSION %IRSSI);
+
+$VERSION="0.1.3";
+%IRSSI = (
+       authors=> 'BC-bd',
+       contact=> 'bd@bc-bd.org',
+       name=> 'repeat',
+       description=> 'Hide duplicate lines',
+       license=> 'GPL v2',
+       url=> 'https://bc-bd.org/svn/repos/irssi/repeat',
+);
+
+# repeal.pl: ignore repeated messages
+# 
+# for irssi 0.8.5 by bd@bc-bd.org
+#
+#########
+# USAGE
+###
+# 
+# This script hides repeated lines from:
+#
+#   dude> Plz Help me!!!
+#   dude> Plz Help me!!!
+#   dude> Plz Help me!!!
+#   guy> foo
+#
+# Becomes:
+#
+#   dude> Plz Help me!!!
+#   guy> foo
+#
+# Or with 'repeat_show' set to ON:
+#
+#   dude> Plz Help me!!!
+# Irssi: Message repeated 3 times
+#   guy> foo
+#
+#########
+# OPTIONS
+#########
+#
+# /set repeat_show <ON|OFF>
+#   * ON  : show info line: 'Message repeated N times'
+#   * OFF : don't show it.
+#
+# /set repeat_count <N>
+#   N : Display a message N times, then ignore it.
+#
+###
+################
+###
+# Changelog
+#
+# Version 0.1.3
+# - fix: also check before own message (by Wouter Coekaerts)
+#
+# Version 0.1.2
+# - removed stray debug message (duh!)
+#
+# Version 0.1.1
+# - off by one fixed
+# - fixed missing '$'
+#
+# Version 0.1.0
+# - initial release
+#
+my %said;
+my %count;
+
+sub sig_public {
+  my ($server, $msg, $nick, $address, $target) = @_;
+
+       my $maxcount = Irssi::settings_get_int('repeat_count');
+
+       my $window = $server->window_find_item($target);
+       my $refnum = $window->{refnum};
+
+       my $this = $refnum.$nick.$msg;
+
+       my $last = $said{$refnum};
+       my $i = $count{$refnum};
+
+#      $window->print("'$this' '$last' $i");
+       if ($last eq $this and not $nick eq $server->{nick}) {
+               $count{$refnum} = $i +1;
+       
+               if ($i >= $maxcount) {
+                       Irssi::signal_stop();
+               }
+       } else {
+               if ($i > $maxcount && Irssi::settings_get_bool('repeat_show')) {
+                       $window->print("Message repeated ".($i-1)." times");
+               }
+
+               $count{$refnum} = 1;
+               $said{$refnum} = $this;
+       }
+}
+
+sub sig_own_public {
+       my ($server, $msg, $target) = @_;       
+       sig_public ($server, $msg, $server->{nick}, "", $target);
+}
+
+sub remove_window {
+       my ($num) = @_;
+
+       delete($count{$num});
+       delete($said{$num});
+}
+
+sub sig_refnum {
+       my ($window,$old) = @_;
+       my $refnum = $window->{refnum};
+       
+       $count{$refnum} = $count{old};
+       $said{$refnum} = $count{old};
+
+       remove_window($old);
+}
+
+sub sig_destroyed {
+       my ($window) = @_;
+       remove_window($window->{refnum});
+}
+
+Irssi::signal_add('message public', 'sig_public');
+Irssi::signal_add('message own_public', 'sig_own_public');
+Irssi::signal_add_last('window refnum changed', 'sig_refnum');
+Irssi::signal_add_last('window destroyed', 'sig_destroyed');
+
+Irssi::settings_add_int('misc', 'repeat_count', 1);
+Irssi::settings_add_bool('misc', 'repeat_show', 1);
+
diff --git a/reslap.pl b/reslap.pl
new file mode 100644 (file)
index 0000000..49bea13
--- /dev/null
+++ b/reslap.pl
@@ -0,0 +1,66 @@
+use Irssi;
+use Irssi::Irc;
+use strict;
+
+use vars qw($VERSION %IRSSI);
+
+$VERSION="0.1.0";
+%IRSSI = (
+       authors=> 'BC-bd',
+       contact=> 'bd@bc-bd.org',
+       name=> 'reslap',
+       description=> 'Autoreslaps people',
+       license=> 'GPL v2',
+       url=> 'https://bc-bd.org/svn/repos/irssi/reslap',
+);
+
+# $Id$
+# for irssi 0.8.5 by bd@bc-bd.org
+#
+#########
+# USAGE
+###
+#
+#########
+# OPTIONS
+#########
+#
+###
+################
+###
+#
+# Changelog
+#
+# Version 0.1.0
+#  - initial release
+#
+###
+################
+
+sub sig_action() {
+       my ($server,$msg,$nick,$address,$target) = @_;
+
+       my $window = $server->window_find_item($target);
+       my $match = "slaps $server->{nick} around a bit with a ";
+       my $fish = $msg;
+       
+       $fish =~ s/\Q$match\E//e;
+
+       if ($fish ne $msg) {
+               $window->command("/me slaps $nick around a bit with a ".$fish." (autoreslap successfull)");
+               return 0;
+       }
+
+       $match = "drives over $server->{nick}";
+       my $jump = $msg;
+
+       $jump =~ s/\Q$match\E//e;
+
+       if ($jump ne $msg) {
+               $window->command("/me jumps away (autoavoidance successfull)");
+               return 0;
+       }
+}
+
+# "message irc action", SERVER_REC, char *msg, char *nick, char *address, char *target
+Irssi::signal_add_last('message irc action', 'sig_action');
diff --git a/rotator.pl b/rotator.pl
new file mode 100644 (file)
index 0000000..70158f8
--- /dev/null
@@ -0,0 +1,137 @@
+use Irssi;
+use Irssi::TextUI;
+use strict;
+
+use vars qw($VERSION %IRSSI);
+
+$VERSION="0.2.1";
+%IRSSI = (
+       authors=> 'BC-bd',
+       contact=> 'bd@bc-bd.org',
+       name=> 'rotator',
+       description=> 'Displaye a small, changeing statusbar item to show irssi is still running',
+       license=> 'GPL v2',
+       url=> 'https://bc-bd.org/svn/repos/irssi/rotator',
+);
+
+# rotator Displaye a small, changeing statusbar item to show irssi is still running
+# for irssi 0.8.4 by bd@bc-bd.org
+#
+#########
+# USAGE
+###
+# 
+# To use this script type f.e.:
+#
+#              /statusbar window add -after more -alignment right rotator
+#
+# For more info on statusbars read the docs for /statusbar
+#
+#########
+# OPTIONS
+#########
+#
+# /set rotator_seperator <char>
+#      The character that is used to split the string in elements.
+#
+# /set rotator_chars <string>
+#      The string to display. Examples are:
+#
+#              /set rotator_chars . o 0 O
+#              /set rotator_chars _ ­ ¯
+#              /set rotator_chars %r­ %Y- %g-
+#
+# /set rotator_speed <int>
+#      The number of milliseconds to display every char.
+#      1 second = 1000 milliseconds.
+#
+# /set rotator_bounce <ON|OFF>
+#              * ON  : reverse direction at the end of rotator_chars
+#              * OFF : start from the beginning
+#
+###
+################
+###
+# Changelog
+#
+# Version 0.2.1
+#  - checking rotator_speed to be > 10
+#
+# Version 0.2
+#  - added rotator_bounce
+#  - added rotator_seperator
+#  - added support for elements longer than one char
+#  - fixed displaying of special chars (thx to peder for pointing this one out)
+#
+# Version 0.1
+#  - initial release
+#
+###
+################
+
+my ($pos,$char,$timeout,$boundary,$direction);
+
+$char = '';
+
+sub rotatorTimeout {
+       my @rot = split(Irssi::settings_get_str('rotator_seperator'), Irssi::settings_get_str('rotator_chars'));
+       my $len = scalar @rot;
+
+       $char = quotemeta($rot[$pos]);
+
+       if ($pos == $boundary) {
+               if (Irssi::settings_get_bool('rotator_bounce')) {
+                       if ($direction < 0) {
+                               $boundary = $len -1;
+                       } else {
+                               $boundary = 0;
+                       }
+                       $direction *= -1;
+               } else {
+                       $pos = -1;
+               }
+       }
+
+       $pos += $direction;
+
+       Irssi::statusbar_items_redraw('rotator');
+}
+
+sub rotatorStatusbar() {
+       my ($item, $get_size_only) = @_;
+
+       $item->default_handler($get_size_only, "{sb ".$char."}", undef, 1);
+}
+
+sub rotatorSetup() {
+       my $time = Irssi::settings_get_int('rotator_speed');
+
+       Irssi::timeout_remove($timeout);
+
+       $boundary = scalar split(Irssi::settings_get_str('rotator_seperator'), Irssi::settings_get_str('rotator_chars')) -1;
+       $direction = +1;
+       $pos = 0;
+
+       if ($time < 10) {
+               Irssi::print("rotator: rotator_speed must be > 10");
+       } else {
+               $timeout = Irssi::timeout_add($time, 'rotatorTimeout' , undef);
+       }
+}
+
+Irssi::signal_add('setup changed', 'rotatorSetup');
+
+Irssi::statusbar_item_register('rotator', '$0', 'rotatorStatusbar');
+
+Irssi::settings_add_str('misc', 'rotator_chars', '. o 0 O 0 o');
+Irssi::settings_add_str('misc', 'rotator_seperator', ' ');
+Irssi::settings_add_int('misc', 'rotator_speed', 2000);
+Irssi::settings_add_bool('misc', 'rotator_bounce', 1);
+
+if (Irssi::settings_get_int('rotator_speed') < 10) {
+       Irssi::print("rotator: rotator_speed must be > 10");
+} else {
+       $timeout = Irssi::timeout_add(Irssi::settings_get_int('rotator_speed'), 'rotatorTimeout' , undef);
+}
+
+rotatorSetup();
diff --git a/thankop.pl b/thankop.pl
new file mode 100644 (file)
index 0000000..bb87c3d
--- /dev/null
@@ -0,0 +1,134 @@
+use Irssi 0.8.10 ();
+use strict;
+
+use vars qw($VERSION %IRSSI);
+
+$VERSION="0.1.7";
+%IRSSI = (
+       authors=> 'BC-bd',
+       contact=> 'bd@bc-bd.org',
+       name=> 'thankop',
+       description=> 'Remembers the last person oping you on a channel',
+       license=> 'GPL v2',
+       url=> 'https://bc-bd.org/svn/repos/irssi/thankop',
+);
+
+# $Id$ #
+# 
+#########
+# USAGE
+###
+#
+# Type '/thankop' in a channel window to thank the person opping you
+#
+##########
+# OPTIONS
+####
+#
+# /set thankop_command [command]
+#              * command  : to be executed. The following $'s are expanded
+#                  $N : Nick (some dude)
+#                  
+#              eg:
+#              
+#                /set thankop_command say $N: w00t!
+#
+#              Would say
+#
+#                <nick>: w00t!
+#
+#              To the channel you got op in, with <nick> beeing the nick who
+#              opped you
+#
+################
+###
+# Changelog
+#
+# Version 0.1.7
+#  - fix crash if used in a window != CHANNEL
+#  - do not thank someone who has already left
+#
+# Version 0.1.6
+#  - added support for multiple networks, thanks to senneth
+#  - adapted to signal changes in 0.8.10
+#
+# Version 0.1.5
+#  - change back to setting instead of theme item
+#
+# Version 0.1.4
+#  - added theme item to customize the message (idea from mordeth)
+#
+# Version 0.1.3
+#  - removed '/' from the ->command (thx to mordeth)
+#  - removed debug messages (where commented out)
+#  
+# Version 0.1.2
+#  - added version dependency, since some 0.8.4 users complained about a not
+#      working script
+#  
+# Version 0.1.1
+#  - unsetting of hash values is done with delete not unset.
+#
+# Version 0.1.0
+#  - initial release
+#  
+###
+################
+
+my %op;
+
+sub cmd_thankop {
+       my ($data, $server, $witem) = @_;
+
+       if (!$witem || ($witem->{type} =! "CHANNEL")) {
+               Irssi::print("thankop: Window not of type CHANNEL");
+               return;
+       }
+
+       my $tag = $witem->{server}->{tag}.'/'.$witem->{name};
+
+       # did we record who opped us here
+       if (!exists($op{$tag})) {
+               $witem->print("thankop: I don't know who op'ed you in here");
+               return;
+       }
+
+       my $by = $op{$tag};
+
+       # still here?
+       if (!$witem->nick_find($by)) {
+               $witem->print("thankop: $by already left");
+               return;
+       }
+
+       my $cmd = Irssi::settings_get_str('thankop_command');
+                               
+       $cmd =~ s/\$N/$by/;
+       $witem->command($cmd);
+}
+
+sub mode_changed {
+       my ($channel, $nick, $by, undef, undef) = @_;
+
+       return if ($channel->{server}->{nick} ne $nick->{nick});
+
+       # since 0.8.10 this is set after signals have been processed
+       return if ($channel->{chanop});
+
+       my $tag = $channel->{server}->{tag}.'/'.$channel->{name};
+
+       $op{$tag} = $by;
+}
+
+sub channel_destroyed {
+       my ($channel) = @_;
+
+       my $tag = $channel->{server}->{tag}.'/'.$channel->{name};
+
+       delete($op{$tag});
+}
+
+Irssi::command_bind('thankop','cmd_thankop');
+Irssi::signal_add_last('nick mode changed', 'mode_changed');
+
+Irssi::settings_add_str('thankop', 'thankop_command', 'say $N: opthx');