nicklist.pl 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612
  1. # for documentation: see http://wouter.coekaerts.be/site/irssi/nicklist
  2. use Irssi;
  3. use strict;
  4. use IO::Handle; # for (auto)flush
  5. use Fcntl; # for sysopen
  6. use vars qw($VERSION %IRSSI);
  7. $VERSION = '0.4.6';
  8. %IRSSI = (
  9. authors => 'Wouter Coekaerts',
  10. contact => 'coekie@irssi.org',
  11. name => 'nicklist',
  12. description => 'draws a nicklist to another terminal, or at the right of your irssi in the same terminal',
  13. license => 'GPLv2',
  14. url => 'http://wouter.coekaerts.be/irssi',
  15. changed => '29/06/2004'
  16. );
  17. sub cmd_help {
  18. print ( <<EOF
  19. Commands:
  20. NICKLIST HELP
  21. NICKLIST SCROLL <nr of lines>
  22. NICKLIST SCREEN
  23. NICKLIST FIFO
  24. NICKLIST OFF
  25. NICKLIST UPDATE
  26. For help see: http://wouter.coekaerts.be/site/irssi/nicklist
  27. in short:
  28. 1. FIFO MODE
  29. - in irssi: /NICKLIST FIFO (only the first time, to create the fifo)
  30. - in a shell, in a window where you want the nicklist: cat ~/.irssi/nicklistfifo
  31. - back in irssi:
  32. /SET nicklist_heigth <height of nicklist>
  33. /SET nicklist_width <width of nicklist>
  34. /NICKLIST FIFO
  35. 2. SCREEN MODE
  36. - start irssi inside screen ("screen irssi")
  37. - /NICKLIST SCREEN
  38. EOF
  39. );
  40. }
  41. my $prev_lines = 0; # number of lines in previous written nicklist
  42. my $scroll_pos = 0; # scrolling position
  43. my $cursor_line; # line the cursor is currently on
  44. my ($OFF, $SCREEN, $FIFO) = (0,1,2); # modes
  45. my $mode = $OFF; # current mode
  46. my $need_redraw = 0; # nicklist needs redrawing
  47. my $screen_resizing = 0; # terminal is being resized
  48. my $active_channel; # (REC)
  49. my @nicklist=(); # array of hashes, containing the internal nicklist of the active channel
  50. # nick => realnick
  51. # mode =>
  52. my ($MODE_OP, $MODE_HALFOP, $MODE_VOICE, $MODE_NORMAL) = (0,1,2,3);
  53. # status =>
  54. my ($STATUS_NORMAL, $STATUS_JOINING, $STATUS_PARTING, $STATUS_QUITING, $STATUS_KICKED, $STATUS_SPLIT) = (0,1,2,3,4,5);
  55. # text => text to be printed
  56. # cmp => text used to compare (sort) nicks
  57. # 'cached' settings
  58. my ($screen_prefix, $irssi_width, @prefix_mode, @prefix_status, $height, $nicklist_width);
  59. sub read_settings {
  60. ($screen_prefix = Irssi::settings_get_str('nicklist_screen_prefix')) =~ s/\\e/\033/g;
  61. ($prefix_mode[$MODE_OP] = Irssi::settings_get_str('nicklist_prefix_mode_op')) =~ s/\\e/\033/g;
  62. ($prefix_mode[$MODE_HALFOP] = Irssi::settings_get_str('nicklist_prefix_mode_halfop')) =~ s/\\e/\033/g;
  63. ($prefix_mode[$MODE_VOICE] = Irssi::settings_get_str('nicklist_prefix_mode_voice')) =~ s/\\e/\033/g;
  64. ($prefix_mode[$MODE_NORMAL] = Irssi::settings_get_str('nicklist_prefix_mode_normal')) =~ s/\\e/\033/g;
  65. if ($mode != $SCREEN) {
  66. $height = Irssi::settings_get_int('nicklist_height');
  67. }
  68. my $new_nicklist_width = Irssi::settings_get_int('nicklist_width');
  69. if ($new_nicklist_width != $nicklist_width && $mode == $SCREEN) {
  70. sig_terminal_resized();
  71. }
  72. $nicklist_width = $new_nicklist_width;
  73. }
  74. sub update {
  75. read_settings();
  76. make_nicklist();
  77. }
  78. ##################
  79. ##### OUTPUT #####
  80. ##################
  81. ### off ###
  82. sub cmd_off {
  83. if ($mode == $SCREEN) {
  84. screen_stop();
  85. } elsif ($mode == $FIFO) {
  86. fifo_stop();
  87. }
  88. }
  89. ### fifo ###
  90. sub cmd_fifo_start {
  91. read_settings();
  92. my $path = Irssi::settings_get_str('nicklist_fifo_path');
  93. unless (-p $path) { # not a pipe
  94. if (-e _) { # but a something else
  95. die "$0: $path exists and is not a pipe, please remove it\n";
  96. } else {
  97. require POSIX;
  98. POSIX::mkfifo($path, 0666) or die "can\'t mkfifo $path: $!";
  99. Irssi::print("Fifo created. Start reading it (\"cat $path\") and try again.");
  100. return;
  101. }
  102. }
  103. if (!sysopen(FIFO, $path, O_WRONLY | O_NONBLOCK)) { # or die "can't write $path: $!";
  104. Irssi::print("Couldn\'t write to the fifo ($!). Please start reading the fifo (\"cat $path\") and try again.");
  105. return;
  106. }
  107. FIFO->autoflush(1);
  108. print FIFO "\033[2J\033[1;1H"; # erase screen & jump to 0,0
  109. $cursor_line = 0;
  110. if ($mode == $SCREEN) {
  111. screen_stop();
  112. }
  113. $mode = $FIFO;
  114. make_nicklist();
  115. }
  116. sub fifo_stop {
  117. close FIFO;
  118. $mode = $OFF;
  119. Irssi::print("Fifo closed.");
  120. }
  121. ### screen ###
  122. sub cmd_screen_start {
  123. if (!defined($ENV{'STY'})) {
  124. Irssi::print 'screen not detected, screen mode only works inside screen';
  125. return;
  126. }
  127. read_settings();
  128. if ($mode == $SCREEN) {return;}
  129. if ($mode == $FIFO) {
  130. fifo_stop();
  131. }
  132. $mode = $SCREEN;
  133. Irssi::signal_add_last('gui print text finished', \&sig_gui_print_text_finished);
  134. Irssi::signal_add_last('gui page scrolled', \&sig_page_scrolled);
  135. Irssi::signal_add('terminal resized', \&sig_terminal_resized);
  136. screen_size();
  137. make_nicklist();
  138. }
  139. sub screen_stop {
  140. $mode = $OFF;
  141. Irssi::signal_remove('gui print text finished', \&sig_gui_print_text_finished);
  142. Irssi::signal_remove('gui page scrolled', \&sig_page_scrolled);
  143. Irssi::signal_remove('terminal resized', \&sig_terminal_resized);
  144. system 'screen -x '.$ENV{'STY'}.' -X fit';
  145. }
  146. sub screen_size {
  147. if ($mode != $SCREEN) {
  148. return;
  149. }
  150. $screen_resizing = 1;
  151. # fit screen
  152. system 'screen -x '.$ENV{'STY'}.' -X fit';
  153. # get size (from perldoc -q size)
  154. my ($winsize, $row, $col, $xpixel, $ypixel);
  155. eval 'use Term::ReadKey; ($col, $row, $xpixel, $ypixel) = GetTerminalSize';
  156. # require Term::ReadKey 'GetTerminalSize';
  157. # ($col, $row, $xpixel, $ypixel) = Term::ReadKey::GetTerminalSize;
  158. #};
  159. if ($@) { # no Term::ReadKey, try the ugly way
  160. eval {
  161. require 'sys/ioctl.ph';
  162. # without this reloading doesn't work. workaround for some unknown bug
  163. do 'asm/ioctls.ph';
  164. };
  165. # ugly way not working, let's try something uglier, the dg-hack(tm) (constant for linux only?)
  166. if($@) { no strict 'refs'; *TIOCGWINSZ = sub { return 0x5413 } }
  167. unless (defined &TIOCGWINSZ) {
  168. die "Term::ReadKey not found, and ioctl 'workaround' failed. Install the Term::ReadKey perl module to use screen mode.\n";
  169. }
  170. open(TTY, "+</dev/tty") or die "No tty: $!";
  171. unless (ioctl(TTY, &TIOCGWINSZ, $winsize='')) {
  172. die "Term::ReadKey not found, and ioctl 'workaround' failed ($!). Install the Term::ReadKey perl module to use screen mode.\n";
  173. }
  174. close(TTY);
  175. ($row, $col, $xpixel, $ypixel) = unpack('S4', $winsize);
  176. }
  177. # set screen width
  178. $irssi_width = $col-$nicklist_width-1;
  179. $height = $row-1;
  180. # on some recent systems, "screen -X fit; screen -X width -w 50" doesn't work, needs a sleep in between the 2 commands
  181. # so we wait a second before setting the width
  182. Irssi::timeout_add_once(1000, sub {
  183. my ($new_irssi_width) = @_;
  184. system 'screen -x '.$ENV{'STY'}.' -X width -w ' . $new_irssi_width;
  185. # and then we wait another second for the resizing, and then redraw.
  186. Irssi::timeout_add_once(1000,sub {$screen_resizing = 0; redraw()}, []);
  187. }, $irssi_width);
  188. }
  189. sub sig_terminal_resized {
  190. if ($screen_resizing) {
  191. return;
  192. }
  193. $screen_resizing = 1;
  194. Irssi::timeout_add_once(1000,\&screen_size,[]);
  195. }
  196. ### both ###
  197. sub nicklist_write_start {
  198. if ($mode == $SCREEN) {
  199. print STDERR "\033P\033[s\033\\"; # save cursor
  200. }
  201. }
  202. sub nicklist_write_end {
  203. if ($mode == $SCREEN) {
  204. print STDERR "\033P\033[u\033\\"; # restore cursor
  205. }
  206. }
  207. sub nicklist_write_line {
  208. my ($line, $data) = @_;
  209. if ($mode == $SCREEN) {
  210. print STDERR "\033P\033[" . ($line+1) . ';'. ($irssi_width+1) .'H'. $screen_prefix . $data . "\033\\";
  211. } elsif ($mode == $FIFO) {
  212. $data = "\033[m$data"; # reset color
  213. if ($line == $cursor_line+1) {
  214. $data = "\n$data"; # next line
  215. } elsif ($line == $cursor_line) {
  216. $data = "\033[1G".$data; # back to beginning of line
  217. } else {
  218. $data = "\033[".($line+1).";0H".$data; # jump
  219. }
  220. $cursor_line=$line;
  221. print(FIFO $data) or fifo_stop();
  222. }
  223. }
  224. # recalc the text of the nicklist item
  225. sub calc_text {
  226. my ($nick) = @_;
  227. my $tmp = $nicklist_width-3;
  228. (my $text = $nick->{'nick'}) =~ s/^(.{$tmp})..+$/$1\033[34m~\033[m/;
  229. $nick->{'text'} = $prefix_mode[$nick->{'mode'}] . $text . (' ' x ($nicklist_width-length($nick->{'nick'})-1));
  230. $nick->{'cmp'} = $nick->{'mode'}.lc($nick->{'nick'});
  231. }
  232. # redraw the given nick (nr) if it is visible
  233. sub redraw_nick_nr {
  234. my ($nr) = @_;
  235. my $line = $nr - $scroll_pos;
  236. if ($line >= 0 && $line < $height) {
  237. nicklist_write_line($line, $nicklist[$nr]->{'text'});
  238. }
  239. }
  240. # nick was inserted, redraw area if necessary
  241. sub draw_insert_nick_nr {
  242. my ($nr) = @_;
  243. my $line = $nr - $scroll_pos;
  244. if ($line < 0) { # nick is inserted above visible area
  245. $scroll_pos++; # 'scroll' down :)
  246. } elsif ($line < $height) { # line is visible
  247. if ($mode == $SCREEN) {
  248. need_redraw();
  249. } elsif ($mode == $FIFO) {
  250. my $data = "\033[m\033[L". $nicklist[$nr]->{'text'}; # reset color & insert line & write nick
  251. if ($line == $cursor_line) {
  252. $data = "\033[1G".$data; # back to beginning of line
  253. } else {
  254. $data = "\033[".($line+1).";1H".$data; # jump
  255. }
  256. $cursor_line=$line;
  257. print(FIFO $data) or fifo_stop();
  258. if ($prev_lines < $height) {
  259. $prev_lines++; # the nicklist has one line more
  260. }
  261. }
  262. }
  263. }
  264. sub draw_remove_nick_nr {
  265. my ($nr) = @_;
  266. my $line = $nr - $scroll_pos;
  267. if ($line < 0) { # nick removed above visible area
  268. $scroll_pos--; # 'scroll' up :)
  269. } elsif ($line < $height) { # line is visible
  270. if ($mode == $SCREEN) {
  271. need_redraw();
  272. } elsif ($mode == $FIFO) {
  273. #my $data = "\033[m\033[L[i$line]". $nicklist[$nr]->{'text'}; # reset color & insert line & write nick
  274. my $data = "\033[M"; # delete line
  275. if ($line != $cursor_line) {
  276. $data = "\033[".($line+1)."d".$data; # jump
  277. }
  278. $cursor_line=$line;
  279. print(FIFO $data) or fifo_stop();
  280. if (@nicklist-$scroll_pos >= $height) {
  281. redraw_nick_nr($scroll_pos+$height-1);
  282. }
  283. }
  284. }
  285. }
  286. # redraw the whole nicklist
  287. sub redraw {
  288. $need_redraw = 0;
  289. #make_nicklist();
  290. nicklist_write_start();
  291. my $line = 0;
  292. ### draw nicklist ###
  293. for (my $i=$scroll_pos;$line < $height && $i < @nicklist; $i++) {
  294. nicklist_write_line($line++, $nicklist[$i]->{'text'});
  295. }
  296. ### clean up other lines ###
  297. my $real_lines = $line;
  298. while($line < $prev_lines) {
  299. nicklist_write_line($line++,' ' x $nicklist_width);
  300. }
  301. $prev_lines = $real_lines;
  302. nicklist_write_end();
  303. }
  304. # redraw (with little delay to avoid redrawing to much)
  305. sub need_redraw {
  306. if(!$need_redraw) {
  307. $need_redraw = 1;
  308. Irssi::timeout_add_once(10,\&redraw,[]);
  309. }
  310. }
  311. sub sig_page_scrolled {
  312. $prev_lines = $height; # we'll need to redraw everything if he scrolled up
  313. need_redraw;
  314. }
  315. # redraw (with delay) if the window is visible (only in screen mode)
  316. sub sig_gui_print_text_finished {
  317. if ($need_redraw) { # there's already a redraw 'queued'
  318. return;
  319. }
  320. my $window = @_[0];
  321. if ($window->{'refnum'} == Irssi::active_win->{'refnum'} || Irssi::settings_get_str('nicklist_screen_split_windows') eq '*') {
  322. need_redraw;
  323. return;
  324. }
  325. foreach my $win (split(/[ ,]/, Irssi::settings_get_str('nicklist_screen_split_windows'))) {
  326. if ($window->{'refnum'} == $win || $window->{'name'} eq $win) {
  327. need_redraw;
  328. return;
  329. }
  330. }
  331. }
  332. ####################
  333. ##### NICKLIST #####
  334. ####################
  335. # returns the position of the given nick(as string) in the (internal) nicklist
  336. sub find_nick {
  337. my ($nick) = @_;
  338. for (my $i=0;$i < @nicklist; $i++) {
  339. if ($nicklist[$i]->{'nick'} eq $nick) {
  340. return $i;
  341. }
  342. }
  343. return -1;
  344. }
  345. # find position where nick should be inserted into the list
  346. sub find_insert_pos {
  347. my ($cmp)= @_;
  348. for (my $i=0;$i < @nicklist; $i++) {
  349. if ($nicklist[$i]->{'cmp'} gt $cmp) {
  350. return $i;
  351. }
  352. }
  353. return scalar(@nicklist); #last
  354. }
  355. # make the (internal) nicklist (@nicklist)
  356. sub make_nicklist {
  357. @nicklist = ();
  358. $scroll_pos = 0;
  359. ### get & check channel ###
  360. my $channel = Irssi::active_win->{active};
  361. if (!$channel || (ref($channel) ne 'Irssi::Irc::Channel' && ref($channel) ne 'Irssi::Silc::Channel') || $channel->{'type'} ne 'CHANNEL' || ($channel->{chat_type} ne 'SILC' && !$channel->{'names_got'}) ) {
  362. $active_channel = undef;
  363. # no nicklist
  364. } else {
  365. $active_channel = $channel;
  366. ### make nicklist ###
  367. my $thisnick;
  368. foreach my $nick (sort {(($a->{'op'}?'1':$a->{'halfop'}?'2':$a->{'voice'}?'3':'4').lc($a->{'nick'}))
  369. cmp (($b->{'op'}?'1':$b->{'halfop'}?'2':$b->{'voice'}?'3':'4').lc($b->{'nick'}))} $channel->nicks()) {
  370. $thisnick = {'nick' => $nick->{'nick'}, 'mode' => ($nick->{'op'}?$MODE_OP:$nick->{'halfop'}?$MODE_HALFOP:$nick->{'voice'}?$MODE_VOICE:$MODE_NORMAL)};
  371. calc_text($thisnick);
  372. push @nicklist, $thisnick;
  373. }
  374. }
  375. need_redraw();
  376. }
  377. # insert nick(as hash) into nicklist
  378. # pre: cmp has to be calculated
  379. sub insert_nick {
  380. my ($nick) = @_;
  381. my $nr = find_insert_pos($nick->{'cmp'});
  382. splice @nicklist, $nr, 0, $nick;
  383. draw_insert_nick_nr($nr);
  384. }
  385. # remove nick(as nr) from nicklist
  386. sub remove_nick {
  387. my ($nr) = @_;
  388. splice @nicklist, $nr, 1;
  389. draw_remove_nick_nr($nr);
  390. }
  391. ###################
  392. ##### ACTIONS #####
  393. ###################
  394. # scroll the nicklist, arg = number of lines to scroll, positive = down, negative = up
  395. sub cmd_scroll {
  396. if (!$active_channel) { # not a channel active
  397. return;
  398. }
  399. my @nicks=Irssi::active_win->{active}->nicks;
  400. my $nick_count = scalar(@nicks)+0;
  401. my $channel = Irssi::active_win->{active};
  402. if (!$channel || $channel->{type} ne 'CHANNEL' || !$channel->{names_got} || $nick_count <= Irssi::settings_get_int('nicklist_height')) {
  403. return;
  404. }
  405. $scroll_pos += @_[0];
  406. if ($scroll_pos > $nick_count - $height) {
  407. $scroll_pos = $nick_count - $height;
  408. }
  409. if ($scroll_pos <= 0) {
  410. $scroll_pos = 0;
  411. }
  412. need_redraw();
  413. }
  414. sub is_active_channel {
  415. my ($server,$channel) = @_; # (channel as string)
  416. return ($server && $server->{'tag'} eq $active_channel->{'server'}->{'tag'} && $server->channel_find($channel) && $active_channel && $server->channel_find($channel)->{'name'} eq $active_channel->{'name'});
  417. }
  418. sub sig_channel_wholist { # this is actualy a little late, when the names are received would be better
  419. my ($channel) = @_;
  420. if (Irssi::active_win->{'active'} && Irssi::active_win->{'active'}->{'name'} eq $channel->{'name'}) { # the channel joined is active
  421. make_nicklist
  422. }
  423. }
  424. sub sig_join {
  425. my ($server,$channel,$nick,$address) = @_;
  426. if (!is_active_channel($server,$channel)) {
  427. return;
  428. }
  429. my $newnick = {'nick' => $nick, 'mode' => $MODE_NORMAL};
  430. calc_text($newnick);
  431. insert_nick($newnick);
  432. }
  433. sub sig_kick {
  434. my ($server, $channel, $nick, $kicker, $address, $reason) = @_;
  435. if (!is_active_channel($server,$channel)) {
  436. return;
  437. }
  438. my $nr = find_nick($nick);
  439. if ($nr == -1) {
  440. Irssi::print("nicklist warning: $nick was kicked from $channel, but not found in nicklist");
  441. } else {
  442. remove_nick($nr);
  443. }
  444. }
  445. sub sig_part {
  446. my ($server,$channel,$nick,$address, $reason) = @_;
  447. if (!is_active_channel($server,$channel)) {
  448. return;
  449. }
  450. my $nr = find_nick($nick);
  451. if ($nr == -1) {
  452. Irssi::print("nicklist warning: $nick has parted $channel, but was not found in nicklist");
  453. } else {
  454. remove_nick($nr);
  455. }
  456. }
  457. sub sig_quit {
  458. my ($server,$nick,$address, $reason) = @_;
  459. if ($server->{'tag'} ne $active_channel->{'server'}->{'tag'}) {
  460. return;
  461. }
  462. my $nr = find_nick($nick);
  463. if ($nr != -1) {
  464. remove_nick($nr);
  465. }
  466. }
  467. sub sig_nick {
  468. my ($server, $newnick, $oldnick, $address) = @_;
  469. if ($server->{'tag'} ne $active_channel->{'server'}->{'tag'}) {
  470. return;
  471. }
  472. my $nr = find_nick($oldnick);
  473. if ($nr != -1) { # if nick was found (nickchange is in current channel)
  474. my $nick = $nicklist[$nr];
  475. remove_nick($nr);
  476. $nick->{'nick'} = $newnick;
  477. calc_text($nick);
  478. insert_nick($nick);
  479. }
  480. }
  481. sub sig_mode {
  482. my ($channel, $nick, $setby, $mode, $type) = @_; # (nick and channel as rec)
  483. if ($channel->{'server'}->{'tag'} ne $active_channel->{'server'}->{'tag'} || $channel->{'name'} ne $active_channel->{'name'}) {
  484. return;
  485. }
  486. my $nr = find_nick($nick->{'nick'});
  487. if ($nr == -1) {
  488. Irssi::print("nicklist warning: $nick->{'nick'} had mode set on $channel->{'name'}, but was not found in nicklist");
  489. } else {
  490. my $nicklist_item = $nicklist[$nr];
  491. remove_nick($nr);
  492. $nicklist_item->{'mode'} = ($nick->{'op'}?$MODE_OP:$nick->{'halfop'}?$MODE_HALFOP:$nick->{'voice'}?$MODE_VOICE:$MODE_NORMAL);
  493. calc_text($nicklist_item);
  494. insert_nick($nicklist_item);
  495. }
  496. }
  497. ##### command binds #####
  498. Irssi::command_bind 'nicklist' => sub {
  499. my ( $data, $server, $item ) = @_;
  500. $data =~ s/\s+$//g;
  501. Irssi::command_runsub ('nicklist', $data, $server, $item ) ;
  502. };
  503. Irssi::signal_add_first 'default command nicklist' => sub {
  504. # gets triggered if called with unknown subcommand
  505. cmd_help();
  506. };
  507. Irssi::command_bind('nicklist update',\&update);
  508. Irssi::command_bind('nicklist help',\&cmd_help);
  509. Irssi::command_bind('nicklist scroll',\&cmd_scroll);
  510. Irssi::command_bind('nicklist fifo',\&cmd_fifo_start);
  511. Irssi::command_bind('nicklist screen',\&cmd_screen_start);
  512. Irssi::command_bind('nicklist screensize',\&screen_size);
  513. Irssi::command_bind('nicklist off',\&cmd_off);
  514. ##### signals #####
  515. Irssi::signal_add_last('window item changed', \&make_nicklist);
  516. Irssi::signal_add_last('window changed', \&make_nicklist);
  517. Irssi::signal_add_last('channel wholist', \&sig_channel_wholist);
  518. Irssi::signal_add_first('message join', \&sig_join); # first, to be before ignores
  519. Irssi::signal_add_first('message part', \&sig_part);
  520. Irssi::signal_add_first('message kick', \&sig_kick);
  521. Irssi::signal_add_first('message quit', \&sig_quit);
  522. Irssi::signal_add_first('message nick', \&sig_nick);
  523. Irssi::signal_add_first('message own_nick', \&sig_nick);
  524. Irssi::signal_add_first('nick mode changed', \&sig_mode);
  525. Irssi::signal_add('setup changed', \&read_settings);
  526. ##### settings #####
  527. Irssi::settings_add_str('nicklist', 'nicklist_screen_prefix', '\e[m ');
  528. Irssi::settings_add_str('nicklist', 'nicklist_prefix_mode_op', '\e[32m@\e[39m');
  529. Irssi::settings_add_str('nicklist', 'nicklist_prefix_mode_halfop', '\e[34m%\e[39m');
  530. Irssi::settings_add_str('nicklist', 'nicklist_prefix_mode_voice', '\e[33m+\e[39m');
  531. Irssi::settings_add_str('nicklist', 'nicklist_prefix_mode_normal', ' ');
  532. Irssi::settings_add_int('nicklist', 'nicklist_width',11);
  533. Irssi::settings_add_int('nicklist', 'nicklist_height',24);
  534. Irssi::settings_add_str('nicklist', 'nicklist_fifo_path', Irssi::get_irssi_dir . '/nicklistfifo');
  535. Irssi::settings_add_str('nicklist', 'nicklist_screen_split_windows', '');
  536. Irssi::settings_add_str('nicklist', 'nicklist_automode', '');
  537. read_settings();
  538. if (uc(Irssi::settings_get_str('nicklist_automode')) eq 'SCREEN') {
  539. cmd_screen_start();
  540. } elsif (uc(Irssi::settings_get_str('nicklist_automode')) eq 'FIFO') {
  541. cmd_fifo_start();
  542. }