]> git.madduck.net Git - code/irssi/scripts-bc-bd.git/blob - niq.pl

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

All patches and comments are welcome. Please squash your changes to logical commits before using git-format-patch and git-send-email to patches@git.madduck.net. If you'd read over the Git project's submission guidelines and adhered to them, I'd be especially grateful.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

simplify level assignment
[code/irssi/scripts-bc-bd.git] / 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/niq',
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);