File: niq.pl

package info (click to toggle)
irssi-scripts 20070925
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 3,708 kB
  • ctags: 2,415
  • sloc: perl: 54,737; makefile: 43; sh: 20
file content (324 lines) | stat: -rw-r--r-- 7,806 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
# BitchX TAB complete style
# for irssi 0.7.99 by bd@bc-bd.org
#
# <tab> 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<tab>" to see a list of nicks starting
# with "ab".
# If you now press <tab> again, irssi will default to its own nick
# completion method.
# If you enter more characters you can use <tab> 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 "<tab>" 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|OFF>
#		* ON  : show the completing nicks in a statusbar item
#		* OFF : show the nicks in the channel window
#
# /set niq_own_statusbar <ON|OFF>
#		* ON  : use an own statusbar for the nicks
#		* OFF : just use an item
#
# /set niq_hide_on_inactive <ON|OFF>
#		* ON  : hide the own statusbar on inactivity
#		* OFF : dont hide it
#
# /set niq_color_char <ON|OFF>
#		* ON  : colors the next unlikely character
#		* OFF : boring no colors
#
###
################
###
# Changelog
#
# Version 0.6.0-INWORK
# - complete the entered string up to the first not-mathing character
#
# 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 <tab><tab>
#
# Version 0.2 
#  - added lastcomp support
#
# Version 0.1
#  - initial release
###
################

use Irssi;
use strict;

use vars qw($VERSION %IRSSI);

$VERSION="0.5.5";
%IRSSI = (
	authors=> 'BC-bd',
	contact=> 'bd@bc-bd.org',
	name=> 'niq',
	description=> 'BitchX like Nickcompletion at line start plus statusbar',
	license=> 'GPL v2',
	url=> 'http://bc-bd.org/software.php3#irssi',
);

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- #<tab>, /set n<tab>, 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 <tab> or <tab><tab>
		if ($lastword eq $word) {
			# <tab><tab> so default to the irssi method
			sort(@nicks);
			for (@nicks) { $_ .= ':'; }
			push (@{$complist}, @nicks);

			# but delete lastword to be ready for the next <tab>
			$lastword = "";

			if (Irssi::settings_get_bool('niq_show_in_statusbar') == 1) {
				drawStatusbar("");
			}

			return;
		} else {
			# <tab> 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 <tab> 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);