/var/www/www.irssi.org-old/scripts/html/niq.pl


   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 #		/set niq_show_in_statusbar ON
  35 #		/set niq_own_statusbar ON
  36 #
  37 # WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
  38 #
  39 # THIS IS CURRENTLY BROKEN IN IRSSI 0.8.4 AND ONLY WORKS WITH 
  40 # THE ACTUAL CVS VERSION. USEING THIS ON AN VERSION 0.8.4 OR
  41 # OLDER WILL ERASE YOUR INPUT LINE
  42 #
  43 # With 2) you can also set
  44 #
  45 #		/set niq_hide_on_inactive ON
  46 #
  47 # which will only show the bar if you complete nicks.
  48 #
  49 # WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
  50 #
  51 #########
  52 # OPTIONS
  53 #########
  54 #
  55 # /set niq_show_in_statusbar <ON|OFF>
  56 #		* ON  : show the completing nicks in a statusbar item
  57 #		* OFF : show the nicks in the channel window
  58 #
  59 # /set niq_own_statusbar <ON|OFF>
  60 #		* ON  : use an own statusbar for the nicks
  61 #		* OFF : just use an item
  62 #
  63 # /set niq_hide_on_inactive <ON|OFF>
  64 #		* ON  : hide the own statusbar on inactivity
  65 #		* OFF : dont hide it
  66 #
  67 # /set niq_color_char <ON|OFF>
  68 #		* ON  : colors the next unlikely character
  69 #		* OFF : boring no colors
  70 #
  71 ###
  72 ################
  73 ###
  74 # Changelog
  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 
 117 use Irssi;
 118 use Irssi::TextUI;
 119 use strict;
 120 
 121 use vars qw($VERSION %IRSSI);
 122 
 123 $VERSION="0.5.6";
 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 	license=> 'GPL v2',
 130 	url=> 'https://bc-bd.org/svn/repos/irssi/trunk/',
 131 );
 132 
 133 my($lastword,$lastcomp,$niqString);
 134 
 135 $lastcomp = "";
 136 $lastword = "";
 137 
 138 # build our nick with completion_char, add to complist and stop the signal
 139 sub buildNickAndStop {
 140 	my ($complist,$nick) = @_;
 141 	my $push = $nick.Irssi::settings_get_str('completion_char');
 142 		
 143 	$lastcomp = $nick;
 144 	$lastword = "";
 145 	push (@{$complist}, $push);
 146 
 147 	if (Irssi::settings_get_bool('niq_show_in_statusbar') == 1) {
 148 		drawStatusbar("");
 149 	}
 150 
 151 	Irssi::signal_stop();
 152 }
 153 
 154 # the signal handler
 155 sub sig_complete {
 156 	my ($complist, $window, $word, $linestart, $want_space) = @_;
 157 
 158 	# still allow channel- #<tab>, /set n<tab>, etc completion.
 159 	if ($linestart ne "") {
 160 		return;
 161 	}
 162 
 163 	# also back out if nothing has been entered and lastcomp is ""
 164 	if ($word eq "") {
 165 		if ($lastcomp ne "") {
 166 			buildNickAndStop($complist,$lastcomp);
 167 			return;
 168 		} else {
 169 			return;
 170 		}
 171 	}
 172 	if (rindex($word,Irssi::settings_get_str('completion_char')) == length($word) -1) {
 173 		chop($word);
 174 		buildNickAndStop($complist,$word,0);
 175 		return;
 176 	}
 177 
 178 	my $channel = $window->{active};
 179 
 180 	# the completion is ok if this is a channel
 181 	if ($channel->{type} ne "CHANNEL") 
 182 	{
 183 		return;
 184 	}
 185 
 186 	my (@nicks);
 187 
 188 	# get the matching nicks but quote this l33t special chars like ^
 189 	my $shortestNick = 999;
 190 	my $quoted = quotemeta $word;
 191 	foreach my $n ($channel->nicks()) {
 192 		if ($n->{nick} =~ /^$quoted/i && $window->{active_server}->{nick} ne $n->{nick}) {
 193 			push(@nicks,$n->{nick});
 194 			if (length($n->{nick}) < $shortestNick) {
 195 				$shortestNick = length($n->{nick});
 196 			}
 197 		}
 198 	}
 199 
 200 	@nicks = sort(@nicks);
 201 	
 202 	# if theres only one nick return it.
 203 	if (scalar @nicks eq 1)
 204 	{
 205 		buildNickAndStop($complist,$nicks[0]);
 206 	} elsif (scalar @nicks gt 1) {
 207 		# check if this is <tab> or <tab><tab>
 208 		if ($lastword eq $word) {
 209 			# <tab><tab> so default to the irssi method
 210 			sort(@nicks);
 211 			for (@nicks) { $_ .= ':'; }
 212 			push (@{$complist}, @nicks);
 213 
 214 			# but delete lastword to be ready for the next <tab>
 215 			$lastword = "";
 216 
 217 			if (Irssi::settings_get_bool('niq_show_in_statusbar') == 1) {
 218 				drawStatusbar("");
 219 			}
 220 
 221 			return;
 222 		} else {
 223 			# <tab> only so just print
 224 		
 225 			# TODO
 226 			# TODO way too slow, need some ideas first!
 227 			# TODO 
 228 			# find the longest matching subword
 229 #			Irssi::print(join(" ",@nicks));
 230 #			Irssi::print($shortestNick);
 231 #			my ($i,$n);
 232 #			my $exit = 0;
 233 #			for ($i = length($word); $exit == 0 && $i <$shortestNick; $i++) {
 234 #			  my $char = substr($nicks[0],$i,1);
 235 #				Irssi::print($i." ".$char);
 236 #				foreach $n (@nicks) {
 237 #					Irssi::print($n);
 238 #					if (substr($n,$i,1) ne $char) {
 239 #						$i--;
 240 #				 		$exit = 1;
 241 #						Irssi::print("exit: ".$i);
 242 #					}
 243 #				}
 244 #			}
 245 #			Irssi::print($i);
 246 #			$word = substr($nicks[0],0,$i);
 247 #			Irssi::print($word);
 248 #	
 249 #			@$complist = ();
 250 #			$$complist[0] = $word;
 251 #			$$want_space = 0;
 252 
 253 			# build string w/o colored nicks
 254 			if (Irssi::settings_get_bool('niq_color_char') == 1) {
 255 				$niqString = "";
 256 				foreach my $n (@nicks) {
 257 					my $coloredNick = $n;
 258 					$coloredNick =~ s/($quoted)(.)(.*)/$1%_$2%_$3/i;
 259 					$niqString .= "$coloredNick ";
 260 				}
 261 			} else {
 262 				$niqString = join(" ",@nicks);
 263 			}
 264 			
 265 			if (Irssi::settings_get_bool('niq_show_in_statusbar') == 1) {
 266 				drawStatusbar($niqString);
 267 			} else {
 268 				$window->print($niqString);
 269 			}
 270 
 271 			Irssi::signal_stop();
 272 
 273 			# remember last word
 274 			$lastword = $word;
 275 
 276 			return;
 277 		}
 278 	} 
 279 
 280 	# we have not found a nick, so someone used <tab> within another conttext
 281 	# and thus $lastword is no longer of interest
 282 #	$lastword = ""
 283 }
 284 
 285 sub emptyBar() {
 286 	$lastword = "";
 287 	
 288 	drawStatusbar("");
 289 }
 290 
 291 sub drawStatusbar() {
 292 	my ($word) = @_;
 293 
 294 	if (Irssi::settings_get_bool('niq_own_statusbar') == 1) {
 295 		if (Irssi::settings_get_bool('niq_hide_on_inactive') == 1) {
 296 			if ($word eq "") {
 297 				Irssi::command("statusbar niq disable");
 298 			} else {
 299 				Irssi::command("statusbar niq enable");
 300 			}
 301 		}
 302 	}
 303 
 304 	$niqString = "{sb $word}";
 305 	Irssi::statusbar_items_redraw('niq');
 306 }
 307 
 308 sub niqStatusbar() {
 309 	my ($item, $get_size_only) = @_;
 310 
 311 	$item->default_handler($get_size_only, $niqString, undef, 1);
 312 }
 313 
 314 Irssi::signal_add_first('complete word', 'sig_complete');
 315 Irssi::signal_add_last('window changed', 'emptyBar');
 316 #Irssi::signal_add('event privmsg', 'emptyBar');
 317 Irssi::signal_add('message own_public', 'emptyBar');
 318 
 319 Irssi::statusbar_item_register('niq', '$0', 'niqStatusbar');
 320 Irssi::statusbars_recreate_items();
 321 
 322 Irssi::settings_add_bool('misc', 'niq_show_in_statusbar', 0);
 323 Irssi::settings_add_bool('misc', 'niq_own_statusbar', 0);
 324 Irssi::settings_add_bool('misc', 'niq_hide_on_inactive', 1);
 325 Irssi::settings_add_bool('misc', 'niq_color_char', 1);