]> git.99rst.org Git - irssi-scripts.irssi.org.git/commitdiff
some anames improvements
authorAilin Nemui <redacted>
Mon, 15 Aug 2016 16:01:45 +0000 (18:01 +0200)
committerAilin Nemui <redacted>
Mon, 15 Aug 2016 16:01:45 +0000 (18:01 +0200)
scripts/anames.pl

index 686323b481943f19b199abd0f7f5b22f4c02c310..e365a2a8150a0e3b17a667200ce7d9b8da558f3c 100644 (file)
@@ -6,7 +6,7 @@
 # evil code to sort the nicklist by the alphabet and rank in nicklist.pl
 #
 # 1.6   - optional support for unicode nicknames, realnames script,
-#         formattable summary line (Nei)
+#         formattable summary line (default away colour changed!) (Nei)
 #
 # 1.5   - Fixed halfop display bug (patch by epinephrine), 20100712
 #
 # 0.9   - Initial test release
 
 use strict;
-use Irssi;
+use Irssi 20140918;
 use POSIX;
-#use Data::Dumper;
+use List::Util 'max';
 
 use vars qw($VERSION %IRSSI);
 
-$VERSION = '1.6'; # d34833f077fa302
+$VERSION = '1.6'; # f200e871df81c77
 %IRSSI = (
   authors     => 'Matt "f0rked" Sparks, Miklos Vajna',
   contact     => 'ms+irssi@quadpoint.org',
   name        => 'anames',
-  description => 'a /names display with away nicks colored',
+  description => 'a /names display with away nicks coloured',
   license     => 'GPLv2',
   url         => 'http://quadpoint.org',
   changed     => '2010-07-12',
@@ -59,34 +59,12 @@ $VERSION = '1.6'; # d34833f077fa302
 my $tmp_server;
 my $tmp_chan;
 
+
 Irssi::theme_register([
-  'endofanames', '{channel $0}: Total of {hilight $1} nicks {comment {hilight $2} ops, {hilight $3} halfops, {hilight $4} voices, {hilight $5} normal, {hilight $6} away}',
+  'endofanames' => '{channel $0}: Total of {hilight $1} nicks {comment {hilight $2} ops, {hilight $3} halfops, {hilight $4} voices, {hilight $5} normal, {hilight $6} away}',
+  'names_awaynick' => '{channick $0}',
 ]);
 
-sub cmd_anames
-{
-  my($args, $server, $item) = @_;
-  my $channel = Irssi::active_win->{active};
-  $tmp_server = $server;
-  $tmp_chan = $channel->{"name"};
-
-  if ($args ne "") {
-    $server = $args;
-    $server =~ s/-([^ ]*) .*/\1/;
-    $tmp_server = Irssi::server_find_tag($server);
-    $tmp_chan = $args;
-    $tmp_chan =~ s/-[^ ]* (.*)/\1/;
-  }
-
-  # set up redirection
-  $tmp_server->redirect_event("who", 1, $tmp_chan, 0, undef,
-                              {
-                                "event 352" => "redir who_reply",
-                                "event 315" => "redir who_reply_end",
-                              });
-
-  $tmp_server->command("who $tmp_chan");
-}
 
 local $@;
 eval { require Text::CharWidth; };
@@ -96,30 +74,63 @@ unless ($@) {
     *screen_length = sub { length($_[0]); }
 }
 
+
 sub object_printformat_module {
     my ($object, $level, $module, $format, @args) = @_;
     {
-        # deeeeeeep black magic.
         local *CORE::GLOBAL::caller = sub { $module };
         $object->printformat($level, $format, @args);
     }
 }
 
+
 sub core_printformat_module {
     my ($level, $module, $format, @args) = @_;
     {
-        # deeeeeeep black magic.
         local *CORE::GLOBAL::caller = sub { $module };
         Irssi::printformat($level, $format, @args);
     }
 }
 
 
+sub cmd_anames
+{
+  my($args, $server, $item) = @_;
+  my $channel = $item;
+  $tmp_server = $server->{"tag"};
+  $tmp_chan = $channel->{"name"};
+
+  if ($args ne "") {
+    my @args = split ' ', $args;
+    if ($args[0] =~ /-(.*)/) {
+      $tmp_server = $1;
+      $server = Irssi::server_find_tag($tmp_server);
+      shift @args;
+    }
+    $tmp_chan = $args[0];
+  }
+
+  unless ($server) {
+    core_printformat_module(MSGLEVEL_CLIENTERROR, 'fe-common/core', 'not_connected');
+    return;
+  }
+
+  # set up redirection
+  $server->redirect_event("who", 1, $tmp_chan, 0, undef,
+                              {
+                                "event 352" => "silent event who",
+                                "event 315" => "redir who_reply_end",
+                              });
+
+  $server->command("who $tmp_chan");
+}
+
+
 sub print_anames
 {
-  my $server = $tmp_server;
+  my $server = Irssi::server_find_tag($tmp_server);
   my $chan = $tmp_chan;
-  my $channel = Irssi::Server::channel_find($server, $chan);
+  my $channel = $server ? $server->channel_find($chan) : undef;
   my $nick;
 
   if (!$channel) {
@@ -130,50 +141,80 @@ sub print_anames
     my @nicks;
     my($ops, $halfops, $voices, $normal, $away) = (0, 0, 0, 0, 0);
 
-    # sorting from nicklist.pl
     my $prefer_real;
     if (exists $Irssi::Script::{'realnames::'}) {
-       my $code = "Irssi::Script::realnames"->can('use_realnames');
-       $prefer_real = $code && $code->($channel);
+        my $code = "Irssi::Script::realnames"->can('use_realnames');
+        $prefer_real = $code && $code->($channel);
     }
     my $_real = sub {
-       my $nick = shift;
-       $prefer_real && length $nick->{'realname'} ? $nick->{'realname'} : $nick->{'nick'}
+        my $nick = shift;
+        $prefer_real && length $nick->{'realname'} ? $nick->{'realname'} : $nick->{'nick'}
     };
+    # sorting from nicklist.pl
     foreach my $nick (sort {($a->{'op'}?'1':$a->{'halfop'}?'2':$a->{'voice'}?'3':$a->{'other'}>32?'0':'4').lc($_real->($a))
         cmp ($b->{'op'}?'1':$b->{'halfop'}?'2':$b->{'voice'}?'3':$b->{'other'}>32?'0':'4').lc($_real->($b))} $channel->nicks()) {
       my $realnick = $_real->($nick);
       my $gone = $nick->{'gone'};
 
       my $prefix;
-      if ($nick->{'op'}) {
+      if ($nick->{'other'}) {
+        $prefix = chr $nick->{'other'};
+      } elsif ($nick->{'op'}) {
         $prefix = "@";
+      } elsif ($nick->{'halfop'}) {
+        $prefix = "%";
+      } elsif ($nick->{'voice'}) {
+        $prefix = "+";
+      } else {
+        $prefix = " ";
+      }
+
+      my $format;
+      if ($nick->{'op'}) {
         $ops++;
+        $format = 'names_nick_op';
       } elsif ($nick->{'halfop'}) {
-        $prefix = "%%";
         $halfops++;
+        $format = 'names_nick_halfop';
       } elsif ($nick->{'voice'}) {
-        $prefix = "+";
         $voices++;
+        $format = 'names_nick_voice';
       } else {
-        $prefix = " ";
         $normal++;
+        $format = 'names_nick';
       }
 
-      $prefix = "%W$prefix%n";
       if ($gone) {
-        $realnick = "%K$realnick%n";
+        $realnick = $channel->window->format_get_text(__PACKAGE__, $server, $chan, 'names_awaynick', $realnick);
         $away++;
       }
+      my $text = $channel->window->format_get_text('fe-common/core', $server, $chan, $format, $prefix, $realnick);
+      my $bleak = Irssi::strip_codes($text);
 
-      push @nicks, "$prefix" . $realnick;
+      push @nicks, [ $prefix, $realnick, $format, screen_length($bleak) ];
     }
 
     my $total = @nicks;
     object_printformat_module($channel, MSGLEVEL_CLIENTCRAP, 'fe-common/core', 'names', $chan);
     columnize_nicks($channel,@nicks);
     $channel->printformat(MSGLEVEL_CLIENTNOTICE, 'endofanames', $chan, $total, $ops,
-                         $halfops, $voices, $normal, $away);
+                          $halfops, $voices, $normal, $away);
+  }
+}
+
+
+{ my %strip_table = (
+    # fe-common::core::formats.c:format_expand_styles
+    #      delete                format_backs  format_fores bold_fores   other stuff
+    (map { $_ => '' } (split //, '04261537' .  'kbgcrmyw' . 'KBGCRMYW' . 'U9_8I:|FnN>#[' . 'pP')),
+    #      escape
+    (map { $_ => $_ } (split //, '{}%')),
+   );
+  sub ir_strip_codes { # strip %codes
+      my $o = shift;
+      $o =~ s/(%(%|Z.{6}|z.{6}|X..|x..|.))/exists $strip_table{$2} ? $strip_table{$2} :
+         $2 =~ m{x(?:0[a-f]|[1-6][0-9a-z]|7[a-x])|z[0-9a-f]{6}}i ? '' : $1/gex;
+      $o
   }
 }
 
@@ -188,7 +229,17 @@ sub columnize_nicks
   # determine max columns
   # FIXME: this could be more intelligent (i.e., read window size)
   my $cols = Irssi::settings_get_int("names_max_columns");
-  $cols = 6 if $cols == 0;
+  if ($cols == 0) {
+      my $width = $channel->window->{width};
+      my $ts_format = Irssi::settings_get_str('timestamp_format');
+      my $render_str = Irssi::current_theme->format_expand(
+        Irssi::current_theme->get_format('fe-common/core', 'timestamp'));
+      (my $ts_escaped = $ts_format) =~ s/([%\$])/$1$1/g;
+      $render_str =~ s/(?|\$(.)(?!\w)|\$\{(\w+)\})/$1 eq 'Z' ? $ts_escaped : $1/ge;
+      $render_str = ir_strip_codes($render_str);
+      $width -= screen_length($render_str);
+      $cols = max(1, int( $width / max(1, map { 1+ $_->[-1] } @nicks) ));
+  }
 
   # determine number of rows
   my $rows = round(ceil($total / $cols));
@@ -197,19 +248,21 @@ sub columnize_nicks
   my @r;
   for (my $i = 0; $i < $cols; $i++) {
     # peek at next $rows items, determine max length
-    my $max_length = find_max_length(@nicks[0 .. $rows - 1]);
+    my $max_length = max map { $_->[-1] } @nicks[0 .. $rows - 1];
 
     # fill rows
     for (my $j = 0; $j < $rows; $j++) {
       my $n = shift @nicks;  # single nick
-      if ($n ne "") {
-        $r[$j] .= "%K[%n$n" . fill_spaces($n,$max_length) . "%K]%n ";
+      if ($n->[-1]) {
+        $r[$j] .= $channel->window->format_get_text('fe-common/core', $channel->{server}, $channel->{visible_name},
+          $n->[2], $n->[0], $n->[1] . fill_spaces($n->[-1],$max_length) );
       }
     }
   }
 
   for (my $m = 0; $m < $rows; $m++) {
     chomp $r[$m];
+    $r[$m] =~ s/%/%%/g;
     $channel->print($r[$m], MSGLEVEL_CLIENTCRAP);
   }
 }
@@ -217,23 +270,8 @@ sub columnize_nicks
 
 sub fill_spaces
 {
-  my($text, $max_length) = @_;
-  $text =~ s/%[a-zA-Z]//g;
-  return " " x ($max_length - screen_length($text));
-}
-
-
-sub find_max_length
-{
-  my $max_length = 0;
-  for (my $i = 0; $i < @_; $i++) {
-    my $nick = $_[$i];
-    $nick =~ s/%[a-zA-Z]//g;
-    if (screen_length($nick) > $max_length) {
-      $max_length = screen_length($nick);
-    }
-  }
-  return $max_length;
+  my($length, $max_length) = @_;
+  return " " x max (0, $max_length - $length);
 }
 
 
@@ -244,20 +282,10 @@ sub round
 }
 
 
-sub who_reply
-{
-  my($server, $data) = @_;
-  my(undef, $c, $i, $h, $n, $s) = split / /, $data;
-  if ($tmp_chan ne $c) {
-    $tmp_chan = $c;
-    #print "Got who info for $c";
-  }
-}
-
-
 sub who_reply_end
 {
   print_anames();
+  Irssi::signal_emit('chanquery who end', @_);
   $tmp_chan = "";
 }
 
@@ -266,6 +294,7 @@ Irssi::Irc::Server::redirect_register("who", 0, 0,
                                       {"event 352" => 1},
                                       {"event 315" => 1},
                                       undef);
-Irssi::signal_add("redir who_reply", \&who_reply);
-Irssi::signal_add("redir who_reply_end", \&who_reply_end);
-Irssi::command_bind("anames", \&cmd_anames);
+Irssi::signal_register({'chanquery who end' => [qw[iobject string]]});
+Irssi::signal_add("redir who_reply", 'who_reply');
+Irssi::signal_add("redir who_reply_end", 'who_reply_end');
+Irssi::command_bind("anames", 'cmd_anames');
git clone https://git.99rst.org/PROJECT