/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);