# BitchX TAB complete style # for irssi 0.7.99 by bd@bc-bd.org # # signal handling learned from dictcomplete by Timo Sirainen # # thx go out to fuchs, darix, dg, peder and all on #irssi who helped # ######### # USAGE ### # # In a channel window type "ab" to see a list of nicks starting # with "ab". # If you now press again, irssi will default to its own nick # completion method. # If you enter more characters you can use again to see a list # of the matching nicks, or to complete the nick if there is only # one matching. # # The last completion is saved so if you press "" with an empty # input line, you get the last completed nick. # # Now there is a statusbar item where you can see the completing # nicks instead of in the channel window. There are two ways to # use it: # # 1) Inside another statusbar # # /set niq_show_in_statusbar ON # /statusbar window add -before more niq # # 2) In an own statusbar # # /set niq_show_in_statusbar ON # /set niq_own_statusbar ON # # WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING # # THIS IS CURRENTLY BROKEN IN IRSSI 0.8.4 AND ONLY WORKS WITH # THE ACTUAL CVS VERSION. USEING THIS ON AN VERSION 0.8.4 OR # OLDER WILL ERASE YOUR INPUT LINE # # With 2) you can also set # # /set niq_hide_on_inactive ON # # which will only show the bar if you complete nicks. # # WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING # ######### # OPTIONS ######### # # /set niq_show_in_statusbar # * ON : show the completing nicks in a statusbar item # * OFF : show the nicks in the channel window # # /set niq_own_statusbar # * ON : use an own statusbar for the nicks # * OFF : just use an item # # /set niq_hide_on_inactive # * ON : hide the own statusbar on inactivity # * OFF : dont hide it # # /set niq_color_char # * ON : colors the next unlikely character # * OFF : boring no colors # ### ################ ### # Changelog # # Version 0.5.6 # - work around an use problem # # Version 0.5.5 # - fixed completion for nicks starting with special chars # # Version 0.5.4 # - removed unneeded sort() of colored nicks # - moved colored nick generation to where it is needed # - the statusbar only worked with colorized nicks (duh!) # # Version 0.5.3 # - stop nickcompleting if last char is the completion_char # which is in most cases ':' # # Version 0.5.2 # - fixed vanishing statusbar. it wrongly was reset on any # privmsg. # # Version 0.5.1 # - changed statusbar to be off by default since most people # dont use the latest fixed version. # # Version 0.5 # - added own statusbar option # - added color char option # # Version 0.4 # - added an niq statusbar # # Version 0.3 # - added default to irssi method on # # Version 0.2 # - added lastcomp support # # Version 0.1 # - initial release ### ################ use Irssi; use Irssi::TextUI; use strict; use vars qw($VERSION %IRSSI); $VERSION="0.5.6"; %IRSSI = ( authors=> 'BC-bd', contact=> 'bd@bc-bd.org', name=> 'niq', description=> 'BitchX like Nickcompletion at line start plus statusbar', license=> 'GPL v2', url=> 'https://bc-bd.org/svn/repos/irssi/niq', ); my($lastword,$lastcomp,$niqString); $lastcomp = ""; $lastword = ""; # build our nick with completion_char, add to complist and stop the signal sub buildNickAndStop { my ($complist,$nick) = @_; my $push = $nick.Irssi::settings_get_str('completion_char'); $lastcomp = $nick; $lastword = ""; push (@{$complist}, $push); if (Irssi::settings_get_bool('niq_show_in_statusbar') == 1) { drawStatusbar(""); } Irssi::signal_stop(); } # the signal handler sub sig_complete { my ($complist, $window, $word, $linestart, $want_space) = @_; # still allow channel- #, /set n, etc completion. if ($linestart ne "") { return; } # also back out if nothing has been entered and lastcomp is "" if ($word eq "") { if ($lastcomp ne "") { buildNickAndStop($complist,$lastcomp); return; } else { return; } } if (rindex($word,Irssi::settings_get_str('completion_char')) == length($word) -1) { chop($word); buildNickAndStop($complist,$word,0); return; } my $channel = $window->{active}; # the completion is ok if this is a channel if ($channel->{type} ne "CHANNEL") { return; } my (@nicks); # get the matching nicks but quote this l33t special chars like ^ my $shortestNick = 999; my $quoted = quotemeta $word; foreach my $n ($channel->nicks()) { if ($n->{nick} =~ /^$quoted/i && $window->{active_server}->{nick} ne $n->{nick}) { push(@nicks,$n->{nick}); if (length($n->{nick}) < $shortestNick) { $shortestNick = length($n->{nick}); } } } @nicks = sort(@nicks); # if theres only one nick return it. if (scalar @nicks eq 1) { buildNickAndStop($complist,$nicks[0]); } elsif (scalar @nicks gt 1) { # check if this is or if ($lastword eq $word) { # so default to the irssi method sort(@nicks); for (@nicks) { $_ .= ':'; } push (@{$complist}, @nicks); # but delete lastword to be ready for the next $lastword = ""; if (Irssi::settings_get_bool('niq_show_in_statusbar') == 1) { drawStatusbar(""); } return; } else { # only so just print # TODO # TODO way too slow, need some ideas first! # TODO # find the longest matching subword # Irssi::print(join(" ",@nicks)); # Irssi::print($shortestNick); # my ($i,$n); # my $exit = 0; # for ($i = length($word); $exit == 0 && $i <$shortestNick; $i++) { # my $char = substr($nicks[0],$i,1); # Irssi::print($i." ".$char); # foreach $n (@nicks) { # Irssi::print($n); # if (substr($n,$i,1) ne $char) { # $i--; # $exit = 1; # Irssi::print("exit: ".$i); # } # } # } # Irssi::print($i); # $word = substr($nicks[0],0,$i); # Irssi::print($word); # # @$complist = (); # $$complist[0] = $word; # $$want_space = 0; # build string w/o colored nicks if (Irssi::settings_get_bool('niq_color_char') == 1) { $niqString = ""; foreach my $n (@nicks) { my $coloredNick = $n; $coloredNick =~ s/($quoted)(.)(.*)/$1%_$2%_$3/i; $niqString .= "$coloredNick "; } } else { $niqString = join(" ",@nicks); } if (Irssi::settings_get_bool('niq_show_in_statusbar') == 1) { drawStatusbar($niqString); } else { $window->print($niqString); } Irssi::signal_stop(); # remember last word $lastword = $word; return; } } # we have not found a nick, so someone used within another conttext # and thus $lastword is no longer of interest # $lastword = "" } sub emptyBar() { $lastword = ""; drawStatusbar(""); } sub drawStatusbar() { my ($word) = @_; if (Irssi::settings_get_bool('niq_own_statusbar') == 1) { if (Irssi::settings_get_bool('niq_hide_on_inactive') == 1) { if ($word eq "") { Irssi::command("statusbar niq disable"); } else { Irssi::command("statusbar niq enable"); } } } $niqString = "{sb $word}"; Irssi::statusbar_items_redraw('niq'); } sub niqStatusbar() { my ($item, $get_size_only) = @_; $item->default_handler($get_size_only, $niqString, undef, 1); } Irssi::signal_add_first('complete word', 'sig_complete'); Irssi::signal_add_last('window changed', 'emptyBar'); #Irssi::signal_add('event privmsg', 'emptyBar'); Irssi::signal_add('message own_public', 'emptyBar'); Irssi::statusbar_item_register('niq', '$0', 'niqStatusbar'); Irssi::statusbars_recreate_items(); Irssi::settings_add_bool('misc', 'niq_show_in_statusbar', 0); Irssi::settings_add_bool('misc', 'niq_own_statusbar', 0); Irssi::settings_add_bool('misc', 'niq_hide_on_inactive', 1); Irssi::settings_add_bool('misc', 'niq_color_char', 1);