1# BitchX TAB complete style 2# for irssi 0.7.99 by bd@bc-bd.org 3# 4# <tab> signal handling learned from dictcomplete by Timo Sirainen 5# 6# thx go out to fuchs, darix, dg, peder and all on #irssi who helped 7# 8######### 9# USAGE 10### 11# 12# In a channel window type "ab<tab>" to see a list of nicks starting 13# with "ab". 14# If you now press <tab> again, irssi will default to its own nick 15# completion method. 16# If you enter more characters you can use <tab> again to see a list 17# of the matching nicks, or to complete the nick if there is only 18# one matching. 19# 20# The last completion is saved so if you press "<tab>" with an empty 21# input line, you get the last completed nick. 22# 23# Now there is a statusbar item where you can see the completing 24# nicks instead of in the channel window. There are two ways to 25# use it: 26# 27# 1) Inside another statusbar 28# 29# /set niq_show_in_statusbar ON 30# /statusbar window add -before more niq 31# 32# 2) In an own statusbar 33# 34# /statusbar niq enable 35# /statusbar niq add niq 36# /statusbar niq disable 37# /set niq_show_in_statusbar ON 38# /set niq_own_statusbar ON 39# 40# You can also hide the bar when not completing nicks by using 41# 42# /set niq_hide_on_inactive ON 43# 44######### 45# OPTIONS 46######### 47# 48# /set niq_show_in_statusbar <ON|OFF> 49# * ON : show the completing nicks in a statusbar item 50# * OFF : show the nicks in the channel window 51# 52# /set niq_own_statusbar <ON|OFF> 53# * ON : use an own statusbar for the nicks 54# * OFF : just use an item 55# 56# /set niq_hide_on_inactive <ON|OFF> 57# * ON : hide the own statusbar on inactivity 58# * OFF : dont hide it 59# 60# /set niq_color_char <ON|OFF> 61# * ON : colors the next unlikely character 62# * OFF : boring no colors 63# 64### 65################ 66### 67# Changelog 68# 69# Version 0.5.7 70# - use configured completion_char instead of a colon 71# - removed old, unused code 72# - fixed url 73# - fixed documentation leading to emtpy statusbar 74# - removed warning about a problem with irssi version 0.8.4 75# 76# Version 0.5.6 77# - work around an use problem 78# 79# Version 0.5.5 80# - fixed completion for nicks starting with special chars 81# 82# Version 0.5.4 83# - removed unneeded sort() of colored nicks 84# - moved colored nick generation to where it is needed 85# - the statusbar only worked with colorized nicks (duh!) 86# 87# Version 0.5.3 88# - stop nickcompleting if last char is the completion_char 89# which is in most cases ':' 90# 91# Version 0.5.2 92# - fixed vanishing statusbar. it wrongly was reset on any 93# privmsg. 94# 95# Version 0.5.1 96# - changed statusbar to be off by default since most people 97# dont use the latest fixed version. 98# 99# Version 0.5 100# - added own statusbar option 101# - added color char option 102# 103# Version 0.4 104# - added an niq statusbar 105# 106# Version 0.3 107# - added default to irssi method on <tab><tab> 108# 109# Version 0.2 110# - added lastcomp support 111# 112# Version 0.1 113# - initial release 114### 115################ 116 117use Irssi; 118use Irssi::TextUI; 119use strict; 120 121use vars qw($VERSION %IRSSI); 122 123$VERSION="0.5.7"; 124%IRSSI = ( 125 authors=> 'BC-bd', 126 contact=> 'bd@bc-bd.org', 127 name=> 'niq', 128 description=> 'BitchX like Nickcompletion at line start plus statusbar', 129 sbitems=> 'niq', 130 license=> 'GPL v2', 131 url=> 'https://bc-bd.org/cgi-bin/gitweb.cgi?p=irssi.git;a=summary', 132); 133 134my($lastword,$lastcomp,$niqString); 135 136$lastcomp = ""; 137$lastword = ""; 138 139# build our nick with completion_char, add to complist and stop the signal 140sub buildNickAndStop { 141 my ($complist,$nick) = @_; 142 my $push = $nick.Irssi::settings_get_str('completion_char'); 143 144 $lastcomp = $nick; 145 $lastword = ""; 146 push (@{$complist}, $push); 147 148 if (Irssi::settings_get_bool('niq_show_in_statusbar') == 1) { 149 drawStatusbar(""); 150 } 151 152 Irssi::signal_stop(); 153} 154 155# the signal handler 156sub sig_complete { 157 my ($complist, $window, $word, $linestart, $want_space) = @_; 158 159 # still allow channel- #<tab>, /set n<tab>, etc completion. 160 if ($linestart ne "") { 161 return; 162 } 163 164 # also back out if nothing has been entered and lastcomp is "" 165 if ($word eq "") { 166 if ($lastcomp ne "") { 167 buildNickAndStop($complist,$lastcomp); 168 return; 169 } else { 170 return; 171 } 172 } 173 if (rindex($word,Irssi::settings_get_str('completion_char')) == length($word) -1) { 174 chop($word); 175 buildNickAndStop($complist,$word,0); 176 return; 177 } 178 179 my $channel = $window->{active}; 180 181 # the completion is ok if this is a channel 182 if ($channel->{type} ne "CHANNEL") 183 { 184 return; 185 } 186 187 my (@nicks); 188 189 # get the matching nicks but quote this l33t special chars like ^ 190 my $shortestNick = 999; 191 my $quoted = quotemeta $word; 192 foreach my $n ($channel->nicks()) { 193 if ($n->{nick} =~ /^$quoted/i && $window->{active_server}->{nick} ne $n->{nick}) { 194 push(@nicks,$n->{nick}); 195 if (length($n->{nick}) < $shortestNick) { 196 $shortestNick = length($n->{nick}); 197 } 198 } 199 } 200 201 @nicks = sort(@nicks); 202 203 # if theres only one nick return it. 204 if (scalar @nicks eq 1) 205 { 206 buildNickAndStop($complist,$nicks[0]); 207 } elsif (scalar @nicks gt 1) { 208 # check if this is <tab> or <tab><tab> 209 if ($lastword eq $word) { 210 # <tab><tab> so default to the irssi method 211 sort(@nicks); 212 for (@nicks) { 213 $_ .= Irssi::settings_get_str ('completion_char'); 214 } 215 216 push (@{$complist}, @nicks); 217 218 # but delete lastword to be ready for the next <tab> 219 $lastword = ""; 220 221 if (Irssi::settings_get_bool('niq_show_in_statusbar') == 1) { 222 drawStatusbar(""); 223 } 224 225 return; 226 } else { 227 # <tab> only so just print 228 229 # build string w/o colored nicks 230 if (Irssi::settings_get_bool('niq_color_char') == 1) { 231 $niqString = ""; 232 foreach my $n (@nicks) { 233 my $coloredNick = $n; 234 $coloredNick =~ s/($quoted)(.)(.*)/$1%_$2%_$3/i; 235 $niqString .= "$coloredNick "; 236 } 237 } else { 238 $niqString = join(" ",@nicks); 239 } 240 241 if (Irssi::settings_get_bool('niq_show_in_statusbar') == 1) { 242 drawStatusbar($niqString); 243 } else { 244 $window->print($niqString); 245 } 246 247 Irssi::signal_stop(); 248 249 # remember last word 250 $lastword = $word; 251 252 return; 253 } 254 } 255} 256 257sub emptyBar() { 258 $lastword = ""; 259 260 drawStatusbar(""); 261} 262 263sub drawStatusbar() { 264 my ($word) = @_; 265 266 if (Irssi::settings_get_bool('niq_own_statusbar') == 1) { 267 if (Irssi::settings_get_bool('niq_hide_on_inactive') == 1) { 268 if ($word eq "") { 269 Irssi::command("statusbar niq disable"); 270 } else { 271 Irssi::command("statusbar niq enable"); 272 } 273 } 274 } 275 276 $niqString = "{sb $word}"; 277 Irssi::statusbar_items_redraw('niq'); 278} 279 280sub niqStatusbar() { 281 my ($item, $get_size_only) = @_; 282 283 $item->default_handler($get_size_only, $niqString, undef, 1); 284} 285 286Irssi::signal_add_first('complete word', 'sig_complete'); 287Irssi::signal_add_last('window changed', 'emptyBar'); 288Irssi::signal_add('message own_public', 'emptyBar'); 289 290Irssi::statusbar_item_register('niq', '$0', 'niqStatusbar'); 291Irssi::statusbars_recreate_items(); 292 293Irssi::settings_add_bool('misc', 'niq_show_in_statusbar', 0); 294Irssi::settings_add_bool('misc', 'niq_own_statusbar', 0); 295Irssi::settings_add_bool('misc', 'niq_hide_on_inactive', 1); 296Irssi::settings_add_bool('misc', 'niq_color_char', 1); 297