wlstat.pl 21 KB

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