use strict; use Irssi 20020101.0250 (); use vars qw($VERSION %IRSSI); $VERSION = "2.1"; %IRSSI = ( authors => "Timo Sirainen, Ian Peters, David Leadbeater, Bruno Cattáneo", contact => "tss\@iki.fi", name => "Nick Color", description => "assign a different color for each nick", license => "Public Domain", url => "http://irssi.org/", changed => "Mon 08 Jan 21:28:53 BST 2018", ); # Settings: # nickcolor_colors: List of color codes to use. # e.g. /set nickcolor_colors 2 3 4 5 6 7 9 10 11 12 13 # (avoid 8, as used for hilights in the default theme). # # nickcolor_enable_prefix: Enables prefix for same nick. # # nickcolor_enable_truncate: Enables nick truncation. # # nickcolor_prefix_text: Prefix text for succesive messages. # e.g. /set nickcolor_prefix_text - # # nickcolor_truncate_value: Truncate nick value. # e.g. /set nickcolor_truncate_value -7 # This will truncate nicknames at 7 characters and make them right aligned my %saved_colors; my %session_colors = {}; my %saved_nicks; # To store each channel's last nickname sub load_colors { open my $color_fh, "<", "$ENV{HOME}/.irssi/saved_colors"; while (<$color_fh>) { chomp; my($nick, $color) = split ":"; $saved_colors{$nick} = $color; } } sub save_colors { open COLORS, ">", "$ENV{HOME}/.irssi/saved_colors"; foreach my $nick (keys %saved_colors) { print COLORS "$nick:$saved_colors{$nick}\n"; } close COLORS; } # If someone we've colored (either through the saved colors, or the hash # function) changes their nick, we'd like to keep the same color associated # with them (but only in the session_colors, ie a temporary mapping). sub sig_nick { my ($server, $newnick, $nick, $address) = @_; my $color; $newnick = substr ($newnick, 1) if ($newnick =~ /^:/); if ($color = $saved_colors{$nick}) { $session_colors{$newnick} = $color; } elsif ($color = $session_colors{$nick}) { $session_colors{$newnick} = $color; } } # This gave reasonable distribution values when run across # /usr/share/dict/words sub simple_hash { my ($string) = @_; chomp $string; my @chars = split //, $string; my $counter; foreach my $char (@chars) { $counter += ord $char; } my @colors = split / /, Irssi::settings_get_str('nickcolor_colors'); $counter = $colors[$counter % @colors]; return $counter; } # process public (others) messages sub sig_public { my ($server, $msg, $nick, $address, $target) = @_; my $enable_prefix = Irssi::settings_get_bool('nickcolor_enable_prefix'); my $enable_truncate = Irssi::settings_get_bool('nickcolor_enable_truncate'); my $prefix_text = Irssi::settings_get_str('nickcolor_prefix_text'); my $truncate_value = Irssi::settings_get_int('nickcolor_truncate_value'); # Reference for server/channel my $tagtarget = "$server->{tag}/$target"; # Set default nick truncate value to 0 if option is disabled $truncate_value = 0 if (!$enable_truncate); # Has the user assigned this nick a color? my $color = $saved_colors{$nick}; # Have -we- already assigned this nick a color? if (!$color) { $color = $session_colors{$nick}; } # Let's assign this nick a color if (!$color) { $color = simple_hash $nick; $session_colors{$nick} = $color; } $color = sprintf "\003%02d", $color; # Optional: We check if it's the same nickname for current target if ($saved_nicks{$tagtarget} eq $nick && $enable_prefix) { # Grouped message Irssi::command('/^format pubmsg ' . $prefix_text . '$1'); } else { # Normal message Irssi::command('/^format pubmsg {pubmsgnick $2 {pubnick ' . $color . '$[' . $truncate_value . ']0}}$1'); # Save nickname for next message $saved_nicks{$tagtarget} = $nick; } } # process public (me) messages sub sig_me { my ($server, $msg, $target) = @_; my $nick = $server->{nick}; my $enable_prefix = Irssi::settings_get_bool('nickcolor_enable_prefix'); my $enable_truncate = Irssi::settings_get_bool('nickcolor_enable_truncate'); my $prefix_text = Irssi::settings_get_str('nickcolor_prefix_text'); my $truncate_value = Irssi::settings_get_int('nickcolor_truncate_value'); # Reference for server/channel my $tagtarget = "$server->{tag}/$target"; # Set default nick truncate value to 0 if option is disabled $truncate_value = 0 if (!$enable_truncate); # Optional: We check if it's the same nickname for current target if ($saved_nicks{$tagtarget} eq $nick && $enable_prefix) { # Grouped message Irssi::command('/^format own_msg ' . $prefix_text . '$1'); } else { # Normal message Irssi::command('/^format own_msg {ownmsgnick $2 {ownnick $[' . $truncate_value . ']0}}$1'); # Save nickname for next message $saved_nicks{$tagtarget} = $nick; } } # process public (others) actions sub sig_action_public { my ($server, $msg, $nick, $address, $target) = @_; my $enable_prefix = Irssi::settings_get_bool('nickcolor_enable_prefix'); # Reference for server/channel my $tagtarget = "$server->{tag}/$target"; # Empty current target nick if prefix option is enabled $saved_nicks{$tagtarget} = '' if ($enable_prefix); } # process public (me) actions sub sig_action_me { my ($server, $msg, $target) = @_; my $nick = $server->{nick}; my $enable_prefix = Irssi::settings_get_bool('nickcolor_enable_prefix'); # Reference for server/channel my $tagtarget = "$server->{tag}/$target"; # Empty current target nick if prefix option is enabled $saved_nicks{$tagtarget} = '' if ($enable_prefix); } sub cmd_color { my ($data, $server, $witem) = @_; my ($op, $nick, $color) = split " ", $data; $op = lc $op; if (!$op) { Irssi::print ("No operation given (save/set/clear/list/preview)"); } elsif ($op eq "save") { save_colors; } elsif ($op eq "set") { if (!$nick) { Irssi::print ("Nick not given"); } elsif (!$color) { Irssi::print ("Color not given"); } elsif ($color < 2 || $color > 14) { Irssi::print ("Color must be between 2 and 14 inclusive"); } else { $saved_colors{$nick} = $color; } } elsif ($op eq "clear") { if (!$nick) { Irssi::print ("Nick not given"); } else { delete ($saved_colors{$nick}); } } elsif ($op eq "list") { Irssi::print ("\nSaved Colors:"); foreach my $nick (keys %saved_colors) { Irssi::print (chr (3) . sprintf("%02d", $saved_colors{$nick}) . "$nick" . chr (3) . "1 ($saved_colors{$nick})"); } } elsif ($op eq "preview") { Irssi::print ("\nAvailable colors:"); foreach my $i (2..14) { Irssi::print (chr (3) . "$i" . "Color #$i"); } } } load_colors; Irssi::settings_add_str('misc', 'nickcolor_colors', '2 3 4 5 6 7 9 10 11 12 13'); Irssi::settings_add_bool('misc', 'nickcolor_enable_prefix', 0); Irssi::settings_add_bool('misc', 'nickcolor_enable_truncate', 0); Irssi::settings_add_str('misc', 'nickcolor_prefix_text' => '- '); Irssi::settings_add_int('misc', 'nickcolor_truncate_value' => 0); Irssi::command_bind('color', 'cmd_color'); Irssi::signal_add('message public', 'sig_public'); Irssi::signal_add('message own_public', 'sig_me'); Irssi::signal_add('message irc action', 'sig_action_public'); Irssi::signal_add('message irc own_action', 'sig_action_me'); Irssi::signal_add('event nick', 'sig_nick');