html/wlstat.pl


   1 use strict; # use warnings;
   2 
   3 # FIXME COULD SOMEONE PLEASE TELL ME HOW TO SHUT UP
   4 #
   5 # ...
   6 # Variable "*" will not stay shared at (eval *) line *.
   7 # Variable "*" will not stay shared at (eval *) line *.
   8 # ...
   9 # Can't locate package Irssi::Nick for @Irssi::Irc::Nick::ISA at (eval *) line *.
  10 # ...
  11 #
  12 # THANKS
  13 
  14 use Irssi (); # which is the minimum required version of Irssi ?
  15 use Irssi::TextUI;
  16 
  17 use vars qw($VERSION %IRSSI);
  18 
  19 $VERSION = '0.5';
  20 %IRSSI = (
  21     authors     => 'BC-bd, Veli, Timo \'cras\' Sirainen, Wouter Coekaerts, Nei',
  22     contact     => 'bd@bc-bd.org, veli@piipiip.net, tss@iki.fi, wouter@coekaerts.be, Nei@QuakeNet',
  23     name        => 'wlstat',
  24     description => 'Adds a window list in the status area. Based on chanact.pl by above authors.',
  25     license     => 'GNU GPLv2 or later',
  26 );
  27 
  28 # adapted by Nei
  29 
  30 ###############
  31 # original comment
  32 # ###########
  33 # # Adds new powerful and customizable [Act: ...] item (chanelnames,modes,alias).
  34 # # Lets you give alias characters to windows so that you can select those with
  35 # # meta-<char>.
  36 # #
  37 # # for irssi 0.8.2 by bd@bc-bd.org
  38 # #
  39 # # inspired by chanlist.pl by 'cumol@hammerhart.de'
  40 # #
  41 # #########
  42 # # Contributors
  43 # #########
  44 # #
  45 # # veli@piipiip.net   /window_alias code
  46 # # qrczak@knm.org.pl  chanact_abbreviate_names
  47 # # qerub@home.se      Extra chanact_show_mode and chanact_chop_status
  48 # #
  49 #
  50 # FURTHER THANKS TO
  51 # ############
  52 # # buu, fxn, Somni, Khisanth, integral, tybalt89   for much support in any aspect perl
  53 # # and the channel in general ( #perl @ freenode ) and especially the ir_* functions
  54 # #
  55 # # Valentin 'senneth' Batz ( vb@g-23.org ) for the pointer to grep.pl, continuous support
  56 # #                                         and help in digging up ir_strip_codes
  57 # #
  58 # # OnetrixNET technology networks for the debian environment
  59 # #
  60 # # Monkey-Pirate.com / Spaceman Spiff for the webspace
  61 # #
  62 #
  63 
  64 ######
  65 # M A I N    P R O B L E M
  66 #####
  67 #
  68 # It is impossible to place the wlstat on a statusbar together with other items, because I
  69 # do not know how to calculate the size that it is going to get granted, and therefore I
  70 # cannot do the linebreaks properly.
  71 # This is what is missing to make a nice script out of wlstat.
  72 # If you have any ideas, please contact me ASAP :).
  73 #
  74 ######
  75 
  76 ######
  77 # UTF-8 PROBLEM
  78 #####
  79 #
  80 # Please help me find a solution to this:
  81 # this be your statusbar, it is using up the maximum term size
  82 # [[1=1]#abc [2=2]#defghi]
  83 # 
  84 # now consider this example: "ascii" characters are marked with ., utf-8 characters with *
  85 # [[1=1]#... [2=2]#...***]
  86 #
  87 # you should think that this is how it would be displayed? WRONG!
  88 # [[1=1]#... [2=2]#...***   ]
  89 #
  90 # this is what Irssi does.. I believe my length calculating code to be correct, however, I'd
  91 # love to be proven wrong (or receive any other fix, too, of course!)
  92 #
  93 ######
  94 
  95 #########
  96 # USAGE
  97 ###
  98 #
  99 # copy the script to ~/.irssi/scripts/
 100 #
 101 # In irssi:
 102 #
 103 #		/script load wlstat
 104 #
 105 #
 106 # Hint: to get rid of the old [Act:] display
 107 #     /statusbar window remove act
 108 #
 109 # to get it back:
 110 #     /statusbar window add -after lag -priority 10 act
 111 #
 112 ##########
 113 # OPTIONS
 114 ########
 115 #
 116 # /set wlstat_display_nokey <string>
 117 # /set wlstat_display_key <string>
 118 #		* string : Format String for one window. The following $'s are expanded:
 119 #		    $C : Name
 120 #		    $N : Number of the Window
 121 #		    $Q : meta-Keymap
 122 #		    $H : Start highlighting
 123 #		    $S : Stop highlighting
 124 #     IMPORTANT: don't forget to use $S if you used $H before!
 125 #
 126 # /set wlstat_separator <string>
 127 #     * string : Charater to use between the channel entries
 128 #     you'll need to escape " " space and "$" like this:
 129 #     "/set wlstat_separator \ "
 130 #     "/set wlstat_separator \$"
 131 #     and {}% like this:
 132 #     "/set wlstat_separator %{"
 133 #     "/set wlstat_separator %}"
 134 #     "/set wlstat_separator %%"
 135 #     (reason being, that the separator is used inside a {format })
 136 #
 137 # /set wlstat_hide_data <num>
 138 #     * num : hide the window if its data_level is below num
 139 #     set it to 0 to basically disable this feature,
 140 #               1 if you don't want windows without activity to be shown
 141 #               2 to show only those windows with channel text or hilight
 142 #               3 to show only windows with hilight
 143 #
 144 # /set wlstat_maxlines <num>
 145 #     * num : number of lines to use for the window list (0 to disable)
 146 #
 147 # /set wlstat_sort <-data_level|-last_line|refnum>
 148 #     * you can change the window sort order with this variable
 149 #         -data_level : sort windows with hilight first
 150 #         -last_line  : sort windows in order of activity
 151 #         refnum      : sort windows by window number
 152 #
 153 # /set wlstat_placement <top|bottom>
 154 # /set wlstat_position <num>
 155 #     * these settings correspond to /statusbar because wlstat will create
 156 #       statusbars for you
 157 #     (see /help statusbar to learn more)
 158 #
 159 # /set wlstat_all_disable <ON|OFF>
 160 #     * if you set wlstat_all_disable to ON, wlstat will also remove the
 161 #       last statusbar it created if it is empty.
 162 #       As you might guess, this only makes sense with wlstat_hide_data > 0 ;)
 163 #
 164 ###
 165 # WISHES
 166 ####
 167 #
 168 # if you fiddle with my mess, provide me with your fixes so I can benefit as well
 169 #
 170 # Nei =^.^= ( QuakeNet accountname: ailin )
 171 #
 172 
 173 my $actString = [];   # statusbar texts
 174 my $currentLines = 0;
 175 my $resetNeeded;      # layout/screen has changed, redo everything
 176 my $needRemake;       # "normal" changes
 177 #my $callcount = 0;
 178 my $globTime = undef; # timer to limit remake() calls
 179 
 180 my %statusbars;       # currently active statusbars
 181 
 182 # maybe I should just tie the array ?
 183 sub add_statusbar {
 184 	for (@_) {
 185 		# add subs
 186 		for my $l ($_) { eval {
 187 			no strict 'refs'; # :P
 188 			*{"wlstat$l"} = sub { wlstat($l, @_) };
 189 		}; }
 190 		Irssi::command("statusbar wl$_ reset");
 191 		Irssi::command("statusbar wl$_ enable");
 192 		if (lc Irssi::settings_get_str('wlstat_placement') eq 'top') {
 193 			Irssi::command("statusbar wl$_ placement top");
 194 		}
 195 		if ((my $x = int Irssi::settings_get_int('wlstat_position')) != 0) {
 196 			Irssi::command("statusbar wl$_ position $x");
 197 		}
 198 		Irssi::command("statusbar wl$_ add -priority 100 -alignment left barstar");
 199 		Irssi::command("statusbar wl$_ add wlstat$_");
 200 		Irssi::command("statusbar wl$_ add -priority 100 -alignment right barend");
 201 		Irssi::command("statusbar wl$_ disable");
 202 		Irssi::statusbar_item_register("wlstat$_", '$0', "wlstat$_");
 203 		$statusbars{$_} = {};
 204 	}
 205 }
 206 
 207 sub remove_statusbar {
 208 	for (@_) {
 209 		Irssi::command("statusbar wl$_ reset");
 210 		Irssi::statusbar_item_unregister("wlstat$_"); # XXX does this actually work ?
 211 		# DO NOT REMOVE the sub before you have unregistered it :))
 212 		for my $l ($_) { eval {
 213 			no strict 'refs';
 214 			undef &{"wlstat$l"};
 215 		}; }
 216 		delete $statusbars{$_};
 217 	}
 218 }
 219 
 220 sub syncLines {
 221 	my $temp = $currentLines;
 222 	$currentLines = @$actString;
 223 	#Irssi::print("current lines: $temp new lines: $currentLines");
 224 	my $currMaxLines = Irssi::settings_get_int('wlstat_maxlines');
 225 	if ($currMaxLines > 0 and @$actString > $currMaxLines) {
 226 		$currentLines = $currMaxLines;
 227 	}
 228 	return if ($temp == $currentLines);
 229 	if ($currentLines > $temp) {
 230 		for ($temp .. ($currentLines - 1)) {
 231 			add_statusbar($_);
 232 			Irssi::command("statusbar wl$_ enable");
 233 		}
 234 	}
 235 	else {
 236 		for ($_ = ($temp - 1); $_ >= $currentLines; $_--) {
 237 			Irssi::command("statusbar wl$_ disable");
 238 			remove_statusbar($_);
 239 		}
 240 	}
 241 }
 242 
 243 my %keymap;
 244 
 245 sub get_keymap {
 246 	my ($textDest, undef, $cont_stripped) = @_;
 247 	if ($textDest->{'level'} == 524288 and $textDest->{'target'} eq '' and !defined($textDest->{'server'})) {
 248 		if ($cont_stripped =~ m/meta-(.)\s+change_window (\d+)/) { $keymap{$2} = "$1"; }
 249 		Irssi::signal_stop();
 250 	}
 251 }
 252 
 253 sub update_keymap {
 254 	%keymap = ();
 255 	Irssi::signal_remove('command bind' => 'watch_keymap');
 256 	Irssi::signal_add_first('print text' => 'get_keymap');
 257 	Irssi::command('bind'); # stolen from grep
 258 	Irssi::signal_remove('print text' => 'get_keymap');
 259 	Irssi::signal_add('command bind' => 'watch_keymap');
 260 	Irssi::timeout_add_once(100, 'eventChanged', undef);
 261 }
 262 
 263 # watch keymap changes
 264 sub watch_keymap {
 265 	Irssi::timeout_add_once(1000, 'update_keymap', undef);
 266 }
 267 
 268 update_keymap();
 269 
 270 sub expand {
 271 	my ($string, %format) = @_;
 272 	my ($exp, $repl);
 273 	$string =~ s/\$$exp/$repl/g while (($exp, $repl) = each(%format));
 274 	return $string;
 275 }
 276 
 277 # FIXME implement $get_size_only check, and user $item->{min|max-size} ??
 278 sub wlstat {
 279 	my ($line, $item, $get_size_only) = @_;
 280 
 281 	if ($needRemake) {
 282 		$needRemake = undef;
 283 		remake();
 284 	}
 285 
 286 	my $text = $actString->[$line];  # DO NOT set the actual $actString->[$line] to '' here or
 287 	$text = '' unless defined $text; # you'll screw up the statusbar counter ($currentLines)
 288 	$item->default_handler($get_size_only, $text, '', 1);
 289 }
 290 
 291 my %strip_table = (
 292 	# fe-common::core::formats.c:format_expand_styles
 293 	#      delete                format_backs  format_fores bold_fores   other stuff
 294 	(map { $_ => '' } (split //, '04261537' .  'kbgcrmyw' . 'KBGCRMYW' . 'U9_8:|FnN>#[')),
 295 	#      escape
 296 	(map { $_ => $_ } (split //, '{}%')),
 297 );
 298 sub ir_strip_codes { # strip %codes
 299 	my $o = shift;
 300 	$o =~ s/(%(.))/exists $strip_table{$2} ? $strip_table{$2} : $1/gex;
 301 	$o
 302 }
 303 
 304 sub ir_parse_special {
 305 	my $o; my $i = shift;
 306 	my $win = Irssi::active_win();
 307 	my $server = Irssi::active_server();
 308 	if (ref $win and ref $win->{'active'}) {
 309 		$o = $win->{'active'}->parse_special($i);
 310 	}
 311 	elsif (ref $win and ref $win->{'active_server'}) {
 312 		$o = $win->{'active_server'}->parse_special($i);
 313 	}
 314 	elsif (ref $server) {
 315 		$o =  $server->parse_special($i);
 316 	}
 317 	else {
 318 		$o = Irssi::parse_special($i);
 319 	}
 320 	$o
 321 }
 322 
 323 sub sb_expand { # expand {format }s (and apply parse_special for $vars)
 324 	ir_parse_special(
 325 		Irssi::current_theme->format_expand(
 326 			shift,
 327 			(
 328 				Irssi::EXPAND_FLAG_IGNORE_REPLACES
 329 					|
 330 				Irssi::EXPAND_FLAG_IGNORE_EMPTY
 331 			)
 332 		)
 333 	)
 334 }
 335 sub sb_strip {
 336 	ir_strip_codes(
 337 		sb_expand(shift)
 338 	); # does this get us the actual length of that s*ty bar :P ?
 339 }
 340 sub sb_length {
 341 	# unicode cludge, d*mn broken Irssi
 342 	# screw it, this will fail from broken joining anyway (and cause warnings)
 343 	if (lc Irssi::settings_get_str('term_type') eq 'utf-8') {
 344 		my $temp = sb_strip(shift);
 345 		# try to switch on utf8
 346 		eval {
 347 			no warnings;
 348 			require Encode;
 349 			#$temp = Encode::decode_utf8($temp); # thanks for the hint, but I have my reasons for _utf8_on
 350 			Encode::_utf8_on($temp);
 351 		};
 352 		length($temp)
 353 	}
 354 	else {
 355 		length(sb_strip(shift))
 356 	}
 357 }
 358 
 359 # !!! G*DD*MN Irssi is adding an additional layer of backslashitis per { } layer
 360 # !!! AND I still don't know what I need to escape.
 361 # !!! and NOONE else seems to know or care either.
 362 # !!! f*ck open source. I mean it.
 363 # XXX any Irssi::print debug statement leads to SEGFAULT - why ?
 364 
 365 # major parts of the idea by buu (#perl @ freenode)
 366 # thanks to fxn and Somni for debugging
 367 #	while ($_[0] =~ /(.)/g) {
 368 #		my $c = $1; # XXX sooo... goto kills $1
 369 #		if ($q eq '%') { goto ESC; }
 370 
 371 ## <freenode:#perl:tybalt89> s/%(.)|(\{)|(\})|(\\|\$)/$1?$1:$2?($level++,$2):$3?($level>$min_level&&$level--,$3):'\\'x(2**$level-1).$4/ge;  # untested...
 372 sub ir_escape {
 373 	my $min_level = $_[1] || 0; my $level = $min_level;
 374 	my $o = shift;
 375 	$o =~ s/
 376 				(	%.	)	| # $1
 377 				(	\{	)	| # $2
 378 				(	\}	)	| # $3
 379 				(	\\	)	| # $4
 380 				(	\$(?=.)	)	| # $5
 381 				(	\$	) # $6
 382 		/
 383 				if ($1) { $1 } # %. escape
 384 				elsif ($2) { $level++; $2 } # { nesting start
 385 				elsif ($3) { if ($level > $min_level) { $level--; } $3 } # } nesting end
 386 				elsif ($4) { '\\'x(2**$level) } # \ needs \\escaping
 387 				elsif ($5) { '\\'x(2**$level-1) . '$' . '\\'x(2**$level-1) } # and $ needs even more because of "parse_special"
 388 				else { '\\'x(2**$level-1) . '$' } # $ needs \$ escaping
 389 		/gex;
 390 	$o
 391 }
 392 #sub ir_escape {
 393 #	my $min_level = $_[1] || 0; my $level = $min_level;
 394 #	my $o = shift;
 395 #	$o =~ s/
 396 #		(	%.	)	| # $1
 397 #		(	\{	)	| # $2
 398 #		(	\}	)	| # $3
 399 #		(	\\	|	\$	)	# $4
 400 #	/
 401 #		if ($1) { $1 } # %. escape
 402 #		elsif ($2) { $level++; $2 } # { nesting start
 403 #		elsif ($3) { if ($level > $min_level) { $level--; } $3 } # } nesting end
 404 #		else { '\\'x(2**($level-1)-1) . $4 } # \ or $ needs \\escaping
 405 #	/gex;
 406 #	$o
 407 #}
 408 
 409 sub ir_fe { # try to fix format stuff
 410 	my $x = shift;
 411 	# XXX why do I have to use two/four % here instead of one/two ?? answer: you screwed up in ir_escape
 412 	$x =~ s/([%{}])/%$1/g;
 413 	$x =~ s/(\\|\$)/\\$1/g;
 414 	#$x =~ s/(\$(?=.))|(\$)/$1?"\\\$\\":"\\\$"/ge; # I think this should be here (logic), but it doesn't work that way :P
 415 	#$x =~ s/\\/\\\\/g; # that's right, escape escapes
 416 	$x
 417 }
 418 
 419 sub remake () {
 420 	#$callcount++;
 421 	#my $xx = $callcount; Irssi::print("starting remake [ $xx ]");
 422 	my ($hilight, $number, $display);
 423 	my $separator = '{sb_act_sep ' . Irssi::settings_get_str('wlstat_separator') . '}';
 424 	my $custSort = Irssi::settings_get_str('wlstat_sort');
 425 	my $custSortDir = 1;
 426 	if ($custSort =~ /^[-!](.*)/) {
 427 		$custSortDir = -1;
 428 		$custSort = $1;
 429 	}
 430 
 431 	$actString = [];
 432 	my ($line, $width) = (0, [Irssi::windows]->[0]{'width'} - sb_length('{sb x}'));
 433 	foreach my $win (
 434 		sort {
 435 			(
 436 				( (int($a->{$custSort}) <=> int($b->{$custSort})) * $custSortDir )
 437 					||
 438 				($a->{'refnum'} <=> $b->{'refnum'})
 439 			)
 440 		} Irssi::windows
 441 	) {
 442 		$actString->[$line] = '' unless defined $actString->[$line] or Irssi::settings_get_bool('wlstat_all_disable');
 443 
 444 		# all stolen from chanact, what does this code do and why do we need it ?
 445 		!ref($win) && next;
 446 
 447 		my $name = $win->get_active_name;
 448 		my $active = $win->{'active'};
 449 		my $colour = $win->{'hilight_color'};
 450 		if (!defined $colour) { $colour = ''; }
 451 
 452 		if ($win->{'data_level'} < Irssi::settings_get_int('wlstat_hide_data')) { next; } # for Geert
 453 		if    ($win->{'data_level'} == 0) { $hilight = '{sb_act_none '; }
 454 		elsif ($win->{'data_level'} == 1) { $hilight = '{sb_act_text '; }
 455 		elsif ($win->{'data_level'} == 2) { $hilight = '{sb_act_msg '; }
 456 		elsif ($colour             ne '') { $hilight = "{sb_act_hilight_color $colour "; }
 457 		elsif ($win->{'data_level'} == 3) { $hilight = '{sb_act_hilight '; }
 458 		else                              { $hilight = '{sb_act_special '; }
 459 
 460 		$number = $win->{'refnum'};
 461 		$display = (defined $keymap{$number} and $keymap{$number} ne '')
 462 				?
 463 			(
 464 				Irssi::settings_get_str('wlstat_display_key')
 465 					||
 466 				Irssi::settings_get_str('wlstat_display_nokey')
 467 			)
 468 				:
 469 			Irssi::settings_get_str('wlstat_display_nokey')
 470 		;
 471 
 472 		my $add = expand($display,
 473 			C => ir_fe($name),
 474 			N => $number,
 475 			Q => ir_fe($keymap{$number}),
 476 			H => $hilight,
 477 			S => '}{sb_background}'
 478 		);
 479 		#$temp =~ s/\{\S+?(?:\s(.*?))?\}/$1/g;
 480 		#$temp =~ s/\\\\\\\\/\\/g; # XXX I'm actually guessing here, someone point me to docs please
 481 		$actString->[$line] = '' unless defined $actString->[$line];
 482 
 483 		# XXX how can I check whether the content still fits in the bar? this would allow
 484 		# XXX wlstatus to reside on a statusbar together with other items...
 485 		if (sb_length(ir_escape($actString->[$line] . $add)) >= $width) { # XXX doesn't correctly handle utf-8 multibyte ... help !!?
 486 			$actString->[$line] .= ' ' x ($width - sb_length(ir_escape($actString->[$line])));
 487 			$line++;
 488 		}
 489 		$actString->[$line] .= $add . $separator;
 490 		# XXX if I use these prints, output layout gets screwed up... why ?
 491 		#Irssi::print("line $line: ".$actString->[$line]);
 492 		#Irssi::print("temp $line: ".$temp);
 493 	}
 494 
 495 	# XXX the Irssi::print statements lead to the MOST WEIRD results
 496 	# e.g.: the loop gets executed TWICE for p > 0 ?!?
 497 	for (my $p = 0; $p < @$actString; $p++) { # wrap each line in {sb }, escape it properly, etc.
 498 		my $x = $actString->[$p];
 499 		$x =~ s/\Q$separator\E([ ]*)$/$1/;
 500 		#Irssi::print("[$p]".'current:'.join'.',split//,sb_strip(ir_escape($x,0)));
 501 		#Irssi::print("assumed length before:".sb_length(ir_escape($x,0)));
 502 		$x = "{sb $x}";
 503 		#Irssi::print("[$p]".'new:'.join'.',split//,sb_expand(ir_escape($x,0)));
 504 		#Irssi::print("[$p]".'new:'.join'.',split//,ir_escape($x,0));
 505 		#Irssi::print("assumed length after:".sb_length(ir_escape($x,0)));
 506 		$x = ir_escape($x);
 507 		#Irssi::print("[$p]".'REALnew:'.join'.',split//,sb_strip($x));
 508 		$actString->[$p] = $x;
 509 		# XXX any Irssi::print debug statement leads to SEGFAULT (sometimes) - why ?
 510 	}
 511 	#Irssi::print("remake [ $xx ] finished");
 512 }
 513 
 514 sub wlstatHasChanged () {
 515 	$globTime = undef;
 516 	my $temp = Irssi::settings_get_str('wlstat_placement').Irssi::settings_get_int('wlstat_position');
 517 	if ($temp ne $resetNeeded) { wlreset(); return; }
 518 	#Irssi::print("wlstat has changed, calls to remake so far: $callcount");
 519 	$needRemake = 1;
 520 
 521 	#remake();
 522 	if (
 523 		($needRemake and Irssi::settings_get_bool('wlstat_all_disable'))
 524 			or
 525 		(!Irssi::settings_get_bool('wlstat_all_disable') and $currentLines < 1)
 526 	) {
 527 		$needRemake = undef;
 528 		remake();
 529 	}
 530 	# XXX Irssi crashes if I try to do this without timer, why ? What's the minimum delay I need to use in the timer ?
 531 	Irssi::timeout_add_once(100, 'syncLines', undef);
 532 
 533 	for (keys %statusbars) {
 534 		Irssi::statusbar_items_redraw("wlstat$_");
 535 	}
 536 }
 537 
 538 sub eventChanged () { # Implement a change queue/blocker -.-)
 539 	if (defined $globTime) {
 540 		Irssi::timeout_remove($globTime);
 541 	} # delay the update further
 542 	$globTime = Irssi::timeout_add_once(10, 'wlstatHasChanged', undef);
 543 }
 544 
 545 #$needRemake = 1;
 546 sub resizeTerm () {
 547 	Irssi::timeout_add_once(100, 'eventChanged', undef);
 548 }
 549 
 550 Irssi::settings_add_str('wlstat', 'wlstat_display_nokey', '[$N]$H$C$S');
 551 Irssi::settings_add_str('wlstat', 'wlstat_display_key', '[$Q=$N]$H$C$S');
 552 Irssi::settings_add_str('wlstat', 'wlstat_separator', "\\ ");
 553 Irssi::settings_add_int('wlstat', 'wlstat_hide_data', 0);
 554 Irssi::settings_add_int('wlstat', 'wlstat_maxlines', 9);
 555 Irssi::settings_add_str('wlstat', 'wlstat_sort', 'refnum');
 556 Irssi::settings_add_str('wlstat', 'wlstat_placement', 'bottom');
 557 Irssi::settings_add_int('wlstat', 'wlstat_position', 0);
 558 Irssi::settings_add_bool('wlstat', 'wlstat_all_disable', 0);
 559 
 560 # remove old statusbars
 561 my %killBar;
 562 sub get_old_status {
 563 	my ($textDest, $cont, $cont_stripped) = @_;
 564 	if ($textDest->{'level'} == 524288 and $textDest->{'target'} eq '' and !defined($textDest->{'server'})) {
 565 		if ($cont_stripped =~ m/^wl(\d+)\s/) { $killBar{$1} = {}; }
 566 		Irssi::signal_stop();
 567 	}
 568 }
 569 sub killOldStatus {
 570 	%killBar = ();
 571 	Irssi::signal_add_first('print text' => 'get_old_status');
 572 	Irssi::command('statusbar');
 573 	Irssi::signal_remove('print text' => 'get_old_status');
 574 	remove_statusbar(keys %killBar);
 575 }
 576 #killOldStatus();
 577 
 578 sub wlreset {
 579 	$actString = [];
 580 	$currentLines = 0; # 1; # mhmmmm .. we actually enable one line down there so let's try this.
 581 	$resetNeeded = Irssi::settings_get_str('wlstat_placement').Irssi::settings_get_int('wlstat_position');
 582 	#update_keymap();
 583 	killOldStatus();
 584 	# Register statusbar
 585 	#add_statusbar(0);
 586 	#Irssi::command('statusbar wl0 enable');
 587 	resizeTerm();
 588 }
 589 
 590 wlreset();
 591 
 592 my $Unload;
 593 sub unload ($$$) {
 594 	$Unload = 1;
 595 	Irssi::timeout_add_once(10, sub { $Unload = undef; }, undef); # pretend we didn't do anything ASAP
 596 }
 597 Irssi::signal_add_first('gui exit' => sub { $Unload = undef; }); # last try to catch a sigsegv
 598 sub UNLOAD {
 599 	if ($Unload) { # this might well crash Irssi... try /eval /script unload someotherscript ; /quit (= SEGFAULT !)
 600 		$actString = ['']; # syncLines(); # XXX Irssi crashes when trying to disable all statusbars ?
 601 		killOldStatus();
 602 	}
 603 }
 604 
 605 sub addPrintTextHook { # update on print text
 606 	return if $_[0]->{'level'} == 262144 and $_[0]->{'target'} eq '' and !defined($_[0]->{'server'});
 607 	if (Irssi::settings_get_str('wlstat_sort') =~ /^[-!]?last_line$/) {
 608 		Irssi::timeout_add_once(100, 'eventChanged', undef);
 609 	}
 610 }
 611 
 612 #sub _x { my ($x, $y) = @_; ($x, sub { Irssi::print('-->signal '.$x); eval "$y();"; }) }
 613 #sub _x { @_ }
 614 Irssi::signal_add_first(
 615 	'command script unload' => 'unload'
 616 );
 617 Irssi::signal_add_last({
 618 	'setup changed' => 'eventChanged',
 619 	'print text' => 'addPrintTextHook',
 620 	'terminal resized' => 'resizeTerm',
 621 	'setup reread' => 'wlreset',
 622 	'window hilight' => 'eventChanged',
 623 });
 624 Irssi::signal_add({
 625 	'window created' => 'eventChanged',
 626 	'window destroyed' => 'eventChanged',
 627 	'window name changed' => 'eventChanged',
 628 	'window refnum changed' => 'eventChanged',
 629 	'window changed' => 'eventChanged',
 630 	'window changed automatic' => 'eventChanged',
 631 });
 632 
 633 #Irssi::signal_add('nick mode changed', 'chanactHasChanged'); # relicts
 634 
 635 ###############
 636 ###
 637 #
 638 # Changelog
 639 #
 640 # 0.5a
 641 # - add setting to also hide the last statusbar if empty (wlstat_all_disable)
 642 # - reverted to old utf8 code to also calculate broken utf8 length correctly
 643 # - simplified dealing with statusbars in wlreset
 644 # 
 645 # 0.4d
 646 # - fixed order of disabling statusbars
 647 # - several attempts at special chars, without any real success
 648 #   and much more weird new bugs caused by this
 649 # - setting to specify sort order
 650 # - reduced timeout values
 651 # - added wlstat_hide_data for Geert Hauwaerts ( geert@irssi.org ) :)
 652 # - make it so the dynamic sub is actually deleted
 653 # - fix a bug with removing of the last separator
 654 # - take into consideration parse_special
 655 # 
 656 # 0.3b
 657 # - automatically kill old statusbars
 658 # - reset on /reload
 659 # - position/placement settings
 660 #
 661 # 0.2
 662 # - automated retrieval of key bindings (thanks grep.pl authors)
 663 # - improved removing of statusbars
 664 # - got rid of status chop
 665 #
 666 # 0.1
 667 # - rewritten to suit my needs
 668 # - based on chanact 0.5.5
 669