aboutsummaryrefslogtreecommitdiffstats
path: root/fixery
diff options
context:
space:
mode:
authorTom Feist <shabble@metavore.org>2011-10-10 15:07:27 +0000
committerTom Feist <shabble@metavore.org>2011-10-10 15:07:27 +0000
commit0ec4aeed1efc121a2270f3a9a03cecf09161b4fd (patch)
tree7181f85ffb713be901444dd113f71d7f0fde963f /fixery
parentawayproxy: more formatting cleanup, some constants for script modes, and a (diff)
downloadirssi-scripts-0ec4aeed1efc121a2270f3a9a03cecf09161b4fd.tar.gz
irssi-scripts-0ec4aeed1efc121a2270f3a9a03cecf09161b4fd.zip
adding nicklist, with some minor cosmetic cleanup so far.
Also a readme that explains what the stuff in this dir does.
Diffstat (limited to 'fixery')
-rw-r--r--fixery/README.md19
-rw-r--r--fixery/nicklist.pl647
2 files changed, 666 insertions, 0 deletions
diff --git a/fixery/README.md b/fixery/README.md
new file mode 100644
index 0000000..a429748
--- /dev/null
+++ b/fixery/README.md
@@ -0,0 +1,19 @@
+# The Fixery
+
+This is a dumping ground for toxic scripts that have been washed in totally
+pure and healthy dispersant solution, thus removing all oil, greasiness, and
+probably heartbeat.
+
+Actually, it's just me rewriting or refactoring existing scripts from
+http://scripts.irssi.org because I spot some bug with them, or decide
+they need extra features.
+
+When there are some here, this will be a shiney exciting list:
+
+* `awayproxy` - Auto-sets /away when all your clients disconnect from a proxying
+ irssi instance. It can also collect up messages during your absence, and
+ either /notice them to you when you rejoin, or batch them up and send
+ periodically in an email.
+
+ * **TODO** Add proper settings support
+ * **TODO**
diff --git a/fixery/nicklist.pl b/fixery/nicklist.pl
new file mode 100644
index 0000000..10c815b
--- /dev/null
+++ b/fixery/nicklist.pl
@@ -0,0 +1,647 @@
+# for documentation: see http://wouter.coekaerts.be/site/irssi/nicklist
+
+use Irssi;
+use strict;
+use IO::Handle; # for (auto)flush
+use Fcntl; # for sysopen
+use vars qw($VERSION %IRSSI);
+$VERSION = '0.4.6';
+%IRSSI = (
+ authors => 'Wouter Coekaerts',
+ contact => 'coekie@irssi.org',
+ name => 'nicklist',
+ description => 'draws a nicklist to another terminal, or at the right of your irssi in the same terminal',
+ license => 'GPLv2',
+ url => 'http://wouter.coekaerts.be/irssi',
+ changed => '29/06/2004'
+ );
+
+sub cmd_help {
+ print ( <<EOF
+Commands:
+NICKLIST HELP
+NICKLIST SCROLL <nr of lines>
+NICKLIST SCREEN
+NICKLIST FIFO
+NICKLIST OFF
+NICKLIST UPDATE
+
+For help see: http://wouter.coekaerts.be/site/irssi/nicklist
+
+in short:
+
+1. FIFO MODE
+- in irssi: /NICKLIST FIFO (only the first time, to create the fifo)
+- in a shell, in a window where you want the nicklist: cat ~/.irssi/nicklistfifo
+- back in irssi:
+ /SET nicklist_heigth <height of nicklist>
+ /SET nicklist_width <width of nicklist>
+ /NICKLIST FIFO
+
+2. SCREEN MODE
+- start irssi inside screen ("screen irssi")
+- /NICKLIST SCREEN
+EOF
+ );
+}
+
+my $prev_lines = 0; # number of lines in previous written nicklist
+my $scroll_pos = 0; # scrolling position
+my $cursor_line; # line the cursor is currently on
+my ($OFF, $SCREEN, $FIFO) = (0,1,2); # modes
+my $mode = $OFF; # current mode
+my $need_redraw = 0; # nicklist needs redrawing
+my $screen_resizing = 0; # terminal is being resized
+my $active_channel; # (REC)
+
+# array of hashes, containing the internal nicklist of the active channel
+my @nicklist=();
+# nick => realnick
+# mode =>
+my ($MODE_OP, $MODE_HALFOP, $MODE_VOICE, $MODE_NORMAL) = (0,1,2,3);
+# status =>
+my ($STATUS_NORMAL, $STATUS_JOINING, $STATUS_PARTING,
+ $STATUS_QUITING, $STATUS_KICKED, $STATUS_SPLIT) = (0,1,2,3,4,5);
+# text => text to be printed
+# cmp => text used to compare (sort) nicks
+
+
+# 'cached' settings
+my ($screen_prefix, $irssi_width,
+ @prefix_mode, @prefix_status, $height, $nicklist_width);
+
+sub read_settings {
+ ($screen_prefix = Irssi::settings_get_str('nicklist_screen_prefix')) =~ s/\\e/\033/g;
+
+ ($prefix_mode[$MODE_OP] = Irssi::settings_get_str('nicklist_prefix_mode_op')) =~ s/\\e/\033/g;
+ ($prefix_mode[$MODE_HALFOP] = Irssi::settings_get_str('nicklist_prefix_mode_halfop')) =~ s/\\e/\033/g;
+ ($prefix_mode[$MODE_VOICE] = Irssi::settings_get_str('nicklist_prefix_mode_voice')) =~ s/\\e/\033/g;
+ ($prefix_mode[$MODE_NORMAL] = Irssi::settings_get_str('nicklist_prefix_mode_normal')) =~ s/\\e/\033/g;
+
+ if ($mode != $SCREEN) {
+ $height = Irssi::settings_get_int('nicklist_height');
+ }
+ my $new_nicklist_width = Irssi::settings_get_int('nicklist_width');
+ if ($new_nicklist_width != $nicklist_width && $mode == $SCREEN) {
+ sig_terminal_resized();
+ }
+ $nicklist_width = $new_nicklist_width;
+}
+
+sub update {
+ read_settings();
+ make_nicklist();
+}
+
+##################
+##### OUTPUT #####
+##################
+
+### off ###
+
+sub cmd_off {
+ if ($mode == $SCREEN) {
+ screen_stop();
+ } elsif ($mode == $FIFO) {
+ fifo_stop();
+ }
+}
+
+### fifo ###
+
+sub cmd_fifo_start {
+ read_settings();
+ my $path = Irssi::settings_get_str('nicklist_fifo_path');
+ unless (-p $path) { # not a pipe
+ if (-e _) { # but a something else
+ die "$0: $path exists and is not a pipe, please remove it\n";
+ } else {
+ require POSIX;
+ POSIX::mkfifo($path, 0666) or die "can\'t mkfifo $path: $!";
+ Irssi::print("Fifo created. Start reading it (\"cat $path\") and try again.");
+ return;
+ }
+ }
+ if (!sysopen(FIFO, $path, O_WRONLY | O_NONBLOCK)) { # or die "can't write $path: $!";
+ Irssi::print("Couldn\'t write to the fifo ($!). Please start reading the fifo (\"cat $path\") and try again.");
+ return;
+ }
+ FIFO->autoflush(1);
+ print FIFO "\033[2J\033[1;1H"; # erase screen & jump to 0,0
+ $cursor_line = 0;
+ if ($mode == $SCREEN) {
+ screen_stop();
+ }
+ $mode = $FIFO;
+ make_nicklist();
+}
+
+sub fifo_stop {
+ close FIFO;
+ $mode = $OFF;
+ Irssi::print("Fifo closed.");
+}
+
+### screen ###
+
+sub cmd_screen_start {
+ if (!defined($ENV{'STY'})) {
+ Irssi::print 'screen not detected, screen mode only works inside screen';
+ return;
+ }
+ read_settings();
+ if ($mode == $SCREEN) {
+ return;
+ }
+ if ($mode == $FIFO) {
+ fifo_stop();
+ }
+ $mode = $SCREEN;
+ Irssi::signal_add_last('gui print text finished', \&sig_gui_print_text_finished);
+ Irssi::signal_add_last('gui page scrolled', \&sig_page_scrolled);
+ Irssi::signal_add('terminal resized', \&sig_terminal_resized);
+ screen_size();
+ make_nicklist();
+}
+
+sub screen_stop {
+ $mode = $OFF;
+ Irssi::signal_remove('gui print text finished', \&sig_gui_print_text_finished);
+ Irssi::signal_remove('gui page scrolled', \&sig_page_scrolled);
+ Irssi::signal_remove('terminal resized', \&sig_terminal_resized);
+ system 'screen -x '.$ENV{'STY'}.' -X fit';
+}
+
+sub screen_size {
+ if ($mode != $SCREEN) {
+ return;
+ }
+ $screen_resizing = 1;
+ # fit screen
+ system 'screen -x '.$ENV{'STY'}.' -X fit';
+ # get size (from perldoc -q size)
+ my ($winsize, $row, $col, $xpixel, $ypixel);
+ eval 'use Term::ReadKey; ($col, $row, $xpixel, $ypixel) = GetTerminalSize';
+ # require Term::ReadKey 'GetTerminalSize';
+ # ($col, $row, $xpixel, $ypixel) = Term::ReadKey::GetTerminalSize;
+ #};
+ if ($@) { # no Term::ReadKey, try the ugly way
+ eval {
+ require 'sys/ioctl.ph';
+ # without this reloading doesn't work. workaround for some unknown bug
+ do 'asm/ioctls.ph';
+ };
+
+ # ugly way not working, let's try something uglier, the dg-hack(tm) (constant for linux only?)
+ if ($@) {
+ no strict 'refs'; *TIOCGWINSZ = sub { return 0x5413 };
+ }
+
+ unless (defined &TIOCGWINSZ) {
+ die "Term::ReadKey not found, and ioctl 'workaround' failed. Install the Term::ReadKey perl module to use screen mode.\n";
+ }
+ open(TTY, "+</dev/tty") or die "No tty: $!";
+ unless (ioctl(TTY, &TIOCGWINSZ, $winsize='')) {
+ die "Term::ReadKey not found, and ioctl 'workaround' failed ($!). Install the Term::ReadKey perl module to use screen mode.\n";
+ }
+ close(TTY);
+ ($row, $col, $xpixel, $ypixel) = unpack('S4', $winsize);
+ }
+
+ # set screen width
+ $irssi_width = $col-$nicklist_width-1;
+ $height = $row-1;
+
+ # on some recent systems, "screen -X fit; screen -X width -w 50" doesn't work, needs a sleep in between the 2 commands
+ # so we wait a second before setting the width
+ Irssi::timeout_add_once(1000, sub {
+ my ($new_irssi_width) = @_;
+ system 'screen -x '.$ENV{'STY'}.' -X width -w ' . $new_irssi_width;
+ # and then we wait another second for the resizing, and then redraw.
+ Irssi::timeout_add_once(1000,sub {$screen_resizing = 0; redraw()}, []);
+ }, $irssi_width);
+}
+
+sub sig_terminal_resized {
+ if ($screen_resizing) {
+ return;
+ }
+ $screen_resizing = 1;
+ Irssi::timeout_add_once(1000,\&screen_size,[]);
+}
+
+
+### both ###
+
+sub nicklist_write_start {
+ if ($mode == $SCREEN) {
+ print STDERR "\033P\033[s\033\\"; # save cursor
+ }
+}
+
+sub nicklist_write_end {
+ if ($mode == $SCREEN) {
+ print STDERR "\033P\033[u\033\\"; # restore cursor
+ }
+}
+
+sub nicklist_write_line {
+ my ($line, $data) = @_;
+ if ($mode == $SCREEN) {
+ print STDERR "\033P\033[" . ($line+1) . ';'. ($irssi_width+1) .'H'. $screen_prefix . $data . "\033\\";
+ } elsif ($mode == $FIFO) {
+ $data = "\033[m$data"; # reset color
+ if ($line == $cursor_line+1) {
+ $data = "\n$data"; # next line
+ } elsif ($line == $cursor_line) {
+ $data = "\033[1G".$data; # back to beginning of line
+ } else {
+ $data = "\033[".($line+1).";0H".$data; # jump
+ }
+ $cursor_line=$line;
+ print(FIFO $data) or fifo_stop();
+ }
+}
+
+# recalc the text of the nicklist item
+sub calc_text {
+ my ($nick) = @_;
+ my $tmp = $nicklist_width-3;
+ (my $text = $nick->{'nick'}) =~ s/^(.{$tmp})..+$/$1\033[34m~\033[m/;
+ $nick->{'text'} = $prefix_mode[$nick->{'mode'}] . $text . (' ' x ($nicklist_width-length($nick->{'nick'})-1));
+ $nick->{'cmp'} = $nick->{'mode'}.lc($nick->{'nick'});
+}
+
+# redraw the given nick (nr) if it is visible
+sub redraw_nick_nr {
+ my ($nr) = @_;
+ my $line = $nr - $scroll_pos;
+ if ($line >= 0 && $line < $height) {
+ nicklist_write_line($line, $nicklist[$nr]->{'text'});
+ }
+}
+
+# nick was inserted, redraw area if necessary
+sub draw_insert_nick_nr {
+ my ($nr) = @_;
+ my $line = $nr - $scroll_pos;
+ if ($line < 0) { # nick is inserted above visible area
+ $scroll_pos++; # 'scroll' down :)
+ } elsif ($line < $height) { # line is visible
+ if ($mode == $SCREEN) {
+ need_redraw();
+ } elsif ($mode == $FIFO) {
+ my $data = "\033[m\033[L". $nicklist[$nr]->{'text'}; # reset color & insert line & write nick
+ if ($line == $cursor_line) {
+ $data = "\033[1G".$data; # back to beginning of line
+ } else {
+ $data = "\033[".($line+1).";1H".$data; # jump
+ }
+ $cursor_line=$line;
+ print(FIFO $data) or fifo_stop();
+ if ($prev_lines < $height) {
+ $prev_lines++; # the nicklist has one line more
+ }
+ }
+ }
+}
+
+sub draw_remove_nick_nr {
+ my ($nr) = @_;
+ my $line = $nr - $scroll_pos;
+ if ($line < 0) { # nick removed above visible area
+ $scroll_pos--; # 'scroll' up :)
+ } elsif ($line < $height) { # line is visible
+ if ($mode == $SCREEN) {
+ need_redraw();
+ } elsif ($mode == $FIFO) {
+ #my $data = "\033[m\033[L[i$line]". $nicklist[$nr]->{'text'}; # reset color & insert line & write nick
+ my $data = "\033[M"; # delete line
+ if ($line != $cursor_line) {
+ $data = "\033[".($line+1)."d".$data; # jump
+ }
+ $cursor_line=$line;
+ print(FIFO $data) or fifo_stop();
+ if (@nicklist-$scroll_pos >= $height) {
+ redraw_nick_nr($scroll_pos+$height-1);
+ }
+ }
+ }
+}
+
+# redraw the whole nicklist
+sub redraw {
+ $need_redraw = 0;
+ #make_nicklist();
+ nicklist_write_start();
+ my $line = 0;
+ ### draw nicklist ###
+ for (my $i=$scroll_pos;$line < $height && $i < @nicklist; $i++) {
+ nicklist_write_line($line++, $nicklist[$i]->{'text'});
+ }
+
+ ### clean up other lines ###
+ my $real_lines = $line;
+ while ($line < $prev_lines) {
+ nicklist_write_line($line++,' ' x $nicklist_width);
+ }
+ $prev_lines = $real_lines;
+ nicklist_write_end();
+}
+
+# redraw (with little delay to avoid redrawing to much)
+sub need_redraw {
+ if (!$need_redraw) {
+ $need_redraw = 1;
+ Irssi::timeout_add_once(10,\&redraw,[]);
+ }
+}
+
+sub sig_page_scrolled {
+ $prev_lines = $height; # we'll need to redraw everything if he scrolled up
+ need_redraw;
+}
+
+# redraw (with delay) if the window is visible (only in screen mode)
+sub sig_gui_print_text_finished {
+ if ($need_redraw) { # there's already a redraw 'queued'
+ return;
+ }
+ my $window = @_[0];
+ if ($window->{'refnum'} == Irssi::active_win->{'refnum'} || Irssi::settings_get_str('nicklist_screen_split_windows') eq '*') {
+ need_redraw;
+ return;
+ }
+ foreach my $win (split(/[ ,]/, Irssi::settings_get_str('nicklist_screen_split_windows'))) {
+ if ($window->{'refnum'} == $win || $window->{'name'} eq $win) {
+ need_redraw;
+ return;
+ }
+ }
+}
+
+####################
+##### NICKLIST #####
+####################
+
+# returns the position of the given nick(as string) in the (internal) nicklist
+sub find_nick {
+ my ($nick) = @_;
+ for (my $i=0;$i < @nicklist; $i++) {
+ if ($nicklist[$i]->{'nick'} eq $nick) {
+ return $i;
+ }
+ }
+ return -1;
+}
+
+# find position where nick should be inserted into the list
+sub find_insert_pos {
+ my ($cmp)= @_;
+ for (my $i=0;$i < @nicklist; $i++) {
+ if ($nicklist[$i]->{'cmp'} gt $cmp) {
+ return $i;
+ }
+ }
+ return scalar(@nicklist); #last
+}
+
+# make the (internal) nicklist (@nicklist)
+sub make_nicklist {
+ @nicklist = ();
+ $scroll_pos = 0;
+
+ ### get & check channel ###
+ my $channel = Irssi::active_win->{active};
+
+ 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'}) ) {
+ $active_channel = undef;
+ # no nicklist
+ } else {
+ $active_channel = $channel;
+ ### make nicklist ###
+ my $thisnick;
+ my @sorted_nicks = sort nicksort $channel->nicks();
+
+ foreach my $nick (@sorted_nicks) {
+ $thisnick = {'nick' => $nick->{'nick'},
+ 'mode' => ($nick->{'op'}
+ ? $MODE_OP
+ :$nick->{'halfop'}
+ ? $MODE_HALFOP
+ :$nick->{'voice'}
+ ? $MODE_VOICE:$MODE_NORMAL)
+ };
+ calc_text($thisnick);
+ push @nicklist, $thisnick;
+ }
+ }
+ need_redraw();
+}
+
+sub nicksort {
+ (
+ ($a->{'op'}
+ ? '1'
+ : $a->{'halfop'}
+ ? '2'
+ : $a->{'voice'}
+ ? '3'
+ : '4') .
+ lc($a->{'nick'})
+ ) cmp (
+ ($b->{'op'}
+ ?'1'
+ :$b->{'halfop'}
+ ?'2'
+ :$b->{'voice'}
+ ?'3'
+ :'4') .
+ lc($b->{'nick'})
+ )
+}
+# insert nick(as hash) into nicklist
+# pre: cmp has to be calculated
+sub insert_nick {
+ my ($nick) = @_;
+ my $nr = find_insert_pos($nick->{'cmp'});
+ splice @nicklist, $nr, 0, $nick;
+ draw_insert_nick_nr($nr);
+}
+
+# remove nick(as nr) from nicklist
+sub remove_nick {
+ my ($nr) = @_;
+ splice @nicklist, $nr, 1;
+ draw_remove_nick_nr($nr);
+}
+
+###################
+##### ACTIONS #####
+###################
+
+# scroll the nicklist, arg = number of lines to scroll, positive = down, negative = up
+sub cmd_scroll {
+ if (!$active_channel) { # not a channel active
+ return;
+ }
+ my @nicks=Irssi::active_win->{active}->nicks;
+ my $nick_count = scalar(@nicks)+0;
+ my $channel = Irssi::active_win->{active};
+ if (!$channel || $channel->{type} ne 'CHANNEL' || !$channel->{names_got} || $nick_count <= Irssi::settings_get_int('nicklist_height')) {
+ return;
+ }
+ $scroll_pos += @_[0];
+
+ if ($scroll_pos > $nick_count - $height) {
+ $scroll_pos = $nick_count - $height;
+ }
+ if ($scroll_pos <= 0) {
+ $scroll_pos = 0;
+ }
+ need_redraw();
+}
+
+sub is_active_channel {
+ my ($server,$channel) = @_; # (channel as string)
+ return ($server && $server->{'tag'} eq $active_channel->{'server'}->{'tag'} && $server->channel_find($channel) && $active_channel && $server->channel_find($channel)->{'name'} eq $active_channel->{'name'});
+}
+
+sub sig_channel_wholist { # this is actualy a little late, when the names are received would be better
+ my ($channel) = @_;
+ if (Irssi::active_win->{'active'} && Irssi::active_win->{'active'}->{'name'} eq $channel->{'name'}) { # the channel joined is active
+ make_nicklist
+ }
+}
+
+sub sig_join {
+ my ($server,$channel,$nick,$address) = @_;
+ if (!is_active_channel($server,$channel)) {
+ return;
+ }
+ my $newnick = {'nick' => $nick, 'mode' => $MODE_NORMAL};
+ calc_text($newnick);
+ insert_nick($newnick);
+}
+
+sub sig_kick {
+ my ($server, $channel, $nick, $kicker, $address, $reason) = @_;
+ if (!is_active_channel($server,$channel)) {
+ return;
+ }
+ my $nr = find_nick($nick);
+ if ($nr == -1) {
+ Irssi::print("nicklist warning: $nick was kicked from $channel, but not found in nicklist");
+ } else {
+ remove_nick($nr);
+ }
+}
+
+sub sig_part {
+ my ($server,$channel,$nick,$address, $reason) = @_;
+ if (!is_active_channel($server,$channel)) {
+ return;
+ }
+ my $nr = find_nick($nick);
+ if ($nr == -1) {
+ Irssi::print("nicklist warning: $nick has parted $channel, but was not found in nicklist");
+ } else {
+ remove_nick($nr);
+ }
+
+}
+
+sub sig_quit {
+ my ($server,$nick,$address, $reason) = @_;
+ if ($server->{'tag'} ne $active_channel->{'server'}->{'tag'}) {
+ return;
+ }
+ my $nr = find_nick($nick);
+ if ($nr != -1) {
+ remove_nick($nr);
+ }
+}
+
+sub sig_nick {
+ my ($server, $newnick, $oldnick, $address) = @_;
+ if ($server->{'tag'} ne $active_channel->{'server'}->{'tag'}) {
+ return;
+ }
+ my $nr = find_nick($oldnick);
+ if ($nr != -1) { # if nick was found (nickchange is in current channel)
+ my $nick = $nicklist[$nr];
+ remove_nick($nr);
+ $nick->{'nick'} = $newnick;
+ calc_text($nick);
+ insert_nick($nick);
+ }
+}
+
+sub sig_mode {
+ my ($channel, $nick, $setby, $mode, $type) = @_; # (nick and channel as rec)
+ if ($channel->{'server'}->{'tag'} ne $active_channel->{'server'}->{'tag'} || $channel->{'name'} ne $active_channel->{'name'}) {
+ return;
+ }
+ my $nr = find_nick($nick->{'nick'});
+ if ($nr == -1) {
+ Irssi::print("nicklist warning: $nick->{'nick'} had mode set on $channel->{'name'}, but was not found in nicklist");
+ } else {
+ my $nicklist_item = $nicklist[$nr];
+ remove_nick($nr);
+ $nicklist_item->{'mode'} = ($nick->{'op'}?$MODE_OP:$nick->{'halfop'}?$MODE_HALFOP:$nick->{'voice'}?$MODE_VOICE:$MODE_NORMAL);
+ calc_text($nicklist_item);
+ insert_nick($nicklist_item);
+ }
+}
+
+##### command binds #####
+Irssi::command_bind 'nicklist' => sub {
+ my ( $data, $server, $item ) = @_;
+ $data =~ s/\s+$//g;
+ Irssi::command_runsub ('nicklist', $data, $server, $item ) ;
+};
+Irssi::signal_add_first 'default command nicklist' => sub {
+ # gets triggered if called with unknown subcommand
+ cmd_help();
+};
+Irssi::command_bind('nicklist update',\&update);
+Irssi::command_bind('nicklist help',\&cmd_help);
+Irssi::command_bind('nicklist scroll',\&cmd_scroll);
+Irssi::command_bind('nicklist fifo',\&cmd_fifo_start);
+Irssi::command_bind('nicklist screen',\&cmd_screen_start);
+Irssi::command_bind('nicklist screensize',\&screen_size);
+Irssi::command_bind('nicklist off',\&cmd_off);
+
+##### signals #####
+Irssi::signal_add_last('window item changed', \&make_nicklist);
+Irssi::signal_add_last('window changed', \&make_nicklist);
+Irssi::signal_add_last('channel wholist', \&sig_channel_wholist);
+Irssi::signal_add_first('message join', \&sig_join); # first, to be before ignores
+Irssi::signal_add_first('message part', \&sig_part);
+Irssi::signal_add_first('message kick', \&sig_kick);
+Irssi::signal_add_first('message quit', \&sig_quit);
+Irssi::signal_add_first('message nick', \&sig_nick);
+Irssi::signal_add_first('message own_nick', \&sig_nick);
+Irssi::signal_add_first('nick mode changed', \&sig_mode);
+
+Irssi::signal_add('setup changed', \&read_settings);
+
+##### settings #####
+Irssi::settings_add_str('nicklist', 'nicklist_screen_prefix', '\e[m ');
+Irssi::settings_add_str('nicklist', 'nicklist_prefix_mode_op', '\e[32m@\e[39m');
+Irssi::settings_add_str('nicklist', 'nicklist_prefix_mode_halfop', '\e[34m%\e[39m');
+Irssi::settings_add_str('nicklist', 'nicklist_prefix_mode_voice', '\e[33m+\e[39m');
+Irssi::settings_add_str('nicklist', 'nicklist_prefix_mode_normal', ' ');
+
+Irssi::settings_add_int('nicklist', 'nicklist_width',11);
+Irssi::settings_add_int('nicklist', 'nicklist_height',24);
+Irssi::settings_add_str('nicklist', 'nicklist_fifo_path', Irssi::get_irssi_dir . '/nicklistfifo');
+Irssi::settings_add_str('nicklist', 'nicklist_screen_split_windows', '');
+Irssi::settings_add_str('nicklist', 'nicklist_automode', '');
+
+read_settings();
+if (uc(Irssi::settings_get_str('nicklist_automode')) eq 'SCREEN') {
+ cmd_screen_start();
+} elsif (uc(Irssi::settings_get_str('nicklist_automode')) eq 'FIFO') {
+ cmd_fifo_start();
+}