--- /dev/null
+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);
--- /dev/null
+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
+#
+###
+################
--- /dev/null
+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');
+
--- /dev/null
+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
+#
+###
+################
--- /dev/null
+# 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);
--- /dev/null
+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');
--- /dev/null
+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);
+
--- /dev/null
+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');
--- /dev/null
+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();
--- /dev/null
+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');