1use Irssi 20020101.0001 ();
2
3use strict;
4use warnings;
5
6use Irssi::TextUI;
7
8use vars qw($VERSION %IRSSI);
9
10$VERSION = "0.6.0";
11%IRSSI = (
12    authors     => 'BC-bd',
13    contact     => 'bd@bc-bd.org',
14    name        => 'chanact',
15    description => 'Adds new powerful and customizable [Act: ...] item (chanelnames,modes,alias). Lets you give alias characters to windows so that you can select those with meta-<char>',
16    license     => 'GNU GPLv2 or later',
17    url         => 'http://bc-bd.org/blog/irssi/'
18);
19
20# Please send patches / pull requests to the email listed unter contact above
21# and not to the irssi/scripts.irssi.org repository on github.
22
23# Adds new powerful and customizable [Act: ...] item (chanelnames,modes,alias).
24# Lets you give alias characters to windows so that you can select those with
25# meta-<char>.
26#
27# for irssi 0.8.2 by bd@bc-bd.org
28#
29# inspired by chanlist.pl by 'cumol@hammerhart.de'
30#
31#########
32# Contributors
33#########
34#
35# veli@piipiip.net    original /window_alias code
36# qrczak@knm.org.pl   chanact_abbreviate_names
37# qerub@home.se       Extra chanact_show_mode and chanact_chop_status
38# madduck@madduck.net Better channel aliasing (case-sensitive, cross-network)
39#                     chanact_filter_windowlist basis
40# jast@heapsort.de    Updated documentation
41# ivo@o2w.nl          win->{hilight} patch
42# Bazerka             base patch for sorting by level change
43#                     updated documentation
44# mrtnpaolo@gmail.com rename commands
45# tslocum@gmail.com   Case-insensitive aliases
46#
47#########
48# USAGE
49###
50#
51# copy the script to ~/.irssi/scripts/
52#
53# In irssi:
54#
55#		/script load chanact
56#		/statusbar window add -after act chanact
57#
58# If you want the item to appear on another position read the help
59# for /statusbar.
60# To remove the [Act: 1,2,3] item type:
61#
62#		/statusbar window remove act
63#
64# To see all chanact options type:
65#
66# 	/ set chanact_
67#
68# After these steps you have your new statusbar item and you can start giving
69# aliases to your windows. Go to the window you want to give the alias to
70# and say:
71#
72#		/chanact_window_alias <alias char>
73#
74# You can remove the aliases with from an aliased window:
75#
76#		/chanact_window_unalias
77#
78# To see a list of your windows use:
79#
80#		/window list
81#
82# To make your bindings permanent you will need to save the config and layout
83# before quiting irssi:
84#
85# 		/save
86# 		/layout save
87#
88#########
89# OPTIONS
90#########
91#
92# /set chanact_chop_status <ON|OFF>
93#               * ON  : shorten (Status) to S
94#               * OFF : don't do it
95#
96# /set chanact_sort <refnum|activity|level+refnum|level+activity>
97#  	sort by ...
98#		refnum		: refnum
99#		activity	: last active window
100#		level+refnum	: data_level of window, then refnum
101#		level+activity	: data_level then activity
102#
103# /set chanact_display <string>
104#		* string : Format String for one Channel. The following $'s are expanded:
105#		    $C : Channel
106#		    $N : Number of the Window
107#		    $M : Mode in that channel
108#		    $H : Start highlightning
109#		    $S : Stop highlightning
110#		* example:
111#
112#		      /set chanact_display $H$N:$M.$S$C
113#
114#		    will give you on #irssi.de if you have voice
115#
116#		      [3:+.#irssi.de]
117#
118#		    with '3:+.' highlighted and the channel name printed in regular color
119#
120# /set chanact_case_sensitive <ON|OFF>
121# 		* ON  : Aliases are case-sensitive
122# 		* OFF : Aliases are case-insensitive
123#
124#		Existing aliases must be reapplied after changing this option
125#
126#		Switching from OFF to ON _after_ aliases have been defined, and
127#		then redefining or changing an existing alias will leave some
128#		bindings behind, e.g.
129#
130#			/set chanact_case_sensitive OFF
131#			/chanact_window_alias x
132#
133#				-> window reachable with meta-x/meta-X
134#
135#			/set chanact_case_sensitive ON
136#			/chanact_window_alias y
137#
138#				-> window reachable with meta-y/meta-X
139#
140# /set chanact_display_alias <string>
141#   as 'chanact_display' but is used if the window has an alias and
142#   'chanact_show_alias' is set to on.
143#
144# /set chanact_show_names <ON|OFF>
145#		* ON  : show the channelnames after the number/alias
146#		* OFF : don't show the names
147#
148# /set chanact_abbreviate_names <int>
149#               * 0     : don't abbreviate
150#               * <int> : strip channel name prefix character and leave only
151#                         that many characters of the proper name
152#
153# /set chanact_show_alias <ON|OFF>
154#		* ON  : show the aliase instead of the refnum
155#		* OFF : shot the refnum
156#
157# /set chanact_header <str>
158# 	* <str> : Characters to be displayed at the start of the item.
159# 	          Defaults to: "Act: "
160#
161# /set chanact_separator <str>
162#		* <str> : Charater to use between the channel entries
163#
164# /set chanact_autorenumber <ON|OFF>
165#		* ON  : Move the window automatically to first available slot
166#		        starting from "chanact_renumber_start" when assigning
167#		        an alias to window. Also moves the window back to a
168#		        first available slot from refnum 1 when the window
169#		        loses it's alias.
170#		* OFF : Don't move the windows automatically
171#
172# /set chanact_renumber_start <int>
173# 		* <int> : Move the window to first available slot after this
174# 		          num when "chanact_autorenumber" is ON.
175#
176# /set chanact_remove_hash <ON|OFF>
177# 		* ON  : Remove &#+!= from channel names
178# 		* OFF : Don't touch channel names
179#
180# /set chanact_remove_prefix <string>
181# 		* <string> : Regular expression used to remove from the
182# 		             beginning of the channel name.
183# 		* example  :
184# 		    To shorten a lot of debian channels:
185#
186# 			/set chanact_remove_prefix deb(ian.(devel-)?)?
187#
188# /set chanact_filter <int>
189# 		* 0 : show all channels
190# 		* 1 : hide channels without activity
191# 		* 2 : hide channels with only join/part/etc messages
192# 		* 3 : hide channels with text messages
193# 		* 4 : hide all channels (now why would you want to do that)
194#
195# /set chanact_filter_windowlist <string>
196#		* <string> : space-separated list of windows for which to use
197#			     chanact_filter_windowlist_level instead of
198#			     chanact_filter.
199#
200#			     Alternatively, an entry can be postfixed with
201#			     a comma (',') and the level to use for that
202#			     window.
203#
204#			     The special string @QUERIES matches all queries.
205#
206# /set chanact_filter_windowlist_level <int>
207#   Use this level to filter all windows listed in chanact_filter_windowlist.
208#   You can use these two settings to apply different filter levels to different
209#   windows. Defaults to 0.
210#
211#########
212# HINTS
213#########
214#
215# If you have trouble with wrong colored entries your 'default.theme' might
216# be too old. Try on a shell:
217#
218# 	$ mv ~/.irssi/default.theme /tmp/
219#
220# And in irssi:
221#	/reload
222#	/save
223#
224###
225#################
226
227my %show = (
228	0 => "{%n ",			# NOTHING
229	1 => "{sb_act_text ",		# TEXT
230	2 => "{sb_act_msg ",		# MSG
231	3 => "{sb_act_hilight ",	# HILIGHT
232);
233
234# comparison operators for our sort methods
235my %sort = (
236	'refnum'	=> '$a->{refnum} <=> $b->{refnum};',
237	'activity'	=> '$b->{last_line} <=> $a->{last_line};',
238	'level+refnum'	=> '$b->{data_level} <=> $a->{data_level} ||
239				$a->{refnum} <=> $b->{refnum};',
240	'level+activity'=> '$b->{data_level} <=> $a->{data_level} ||
241				$b->{last_line} <=> $a->{last_line};',
242);
243
244my ($actString,$needRemake);
245
246sub expand {
247  my ($string, %format) = @_;
248  my ($exp, $repl);
249  $string =~ s/\$$exp/$repl/g while (($exp, $repl) = each(%format));
250  return $string;
251}
252
253# method will get called every time the statusbar item will be displayed
254# but we dont need to recreate the item every time so we first
255# check if something has changed and only then we recreate the string
256# this might just save some cycles
257sub chanact {
258	my ($item, $get_size_only) = @_;
259
260	if ($needRemake) {
261		remake();
262	}
263
264	$item->default_handler($get_size_only, $actString, "", 1);
265}
266
267# build a hash to easily access special levels based on
268# chanact_filter_windowlist
269sub calculate_windowlist() {
270	my @matchlist = split ' ', Irssi::settings_get_str('chanact_filter_windowlist');
271	my $default = Irssi::settings_get_int('chanact_filter_windowlist_level');
272
273	my %windowlist;
274	foreach my $m (@matchlist) {
275		my ($name, $level) = split(/,/, $m);
276		$windowlist{$name} = $level ? $level : $default;
277	}
278
279	return %windowlist;
280}
281
282# calculate level per window
283sub calculate_levels(@) {
284	my (@windows) = @_;
285
286	my %matches = calculate_windowlist();
287	my $default = Irssi::settings_get_int('chanact_filter');
288
289	my %levels;
290
291	foreach my $win (@windows) {
292		!ref($win) && next;
293
294		my $name = $win->get_active_name;
295		# skip nameless windows
296		next unless $name;
297
298		if ($name && exists($matches{$name})) {
299			$levels{$name} = $matches{$name};
300		} else {
301			$levels{$name} = $default;
302		}
303	}
304
305	if (exists($matches{'@QUERIES'})) {
306		$levels{'@QUERIES'} = $matches{'@QUERIES'};
307	} else {
308		$levels{'@QUERIES'} = $default;
309	}
310
311	return %levels;
312}
313
314# this is the real creation method
315sub remake() {
316	my ($afternumber,$finish,$hilight,$mode,$number,$display,@windows);
317	my $separator = Irssi::settings_get_str('chanact_separator');
318	my $abbrev = Irssi::settings_get_int('chanact_abbreviate_names');
319	my $remove_prefix = Irssi::settings_get_str('chanact_remove_prefix');
320	my $remove_hash = Irssi::settings_get_bool('chanact_remove_hash');
321
322	my $method = $sort{Irssi::settings_get_str('chanact_sort')};
323	@windows = sort { eval $method } Irssi::windows();
324
325	my %levels = calculate_levels(@windows);
326
327	$actString = "";
328	foreach my $win (@windows) {
329		# since irssi is single threaded this shouldn't happen
330		!ref($win) && next;
331
332		my $active = $win->{active};
333
334		# define $type to emtpy string and overwrite if we do have an
335		# active item. we need this to display windows without active
336		# items e.g. '(status)'
337		my $type = "";
338		$type = $active->{type} if $active;
339
340		my $name = $win->get_active_name;
341		# skip windows without a name
342		next unless $name;
343
344		my $filter_level =
345			$type eq 'QUERY' ? $levels{'@QUERIES'} : $levels{$name};
346
347		# now, skip windows with data of level lower than the
348		# filter level
349		next if ($win->{data_level} < $filter_level);
350
351		# alright, the activity is important, let's show the window
352		# after a bit of additional processing.
353
354		# (status) is an awfull long name, so make it short to 'S'
355		# some people don't like it, so make it configurable
356		if (Irssi::settings_get_bool('chanact_chop_status')
357		    && $name eq "(status)") {
358			$name = "S";
359		}
360
361		# check if we should show the mode
362		$mode = "";
363		if ($type eq "CHANNEL") {
364			my $server = $win->{active_server};
365			!ref($server) && next;
366
367			my $channel = $server->channel_find($name);
368			!ref($channel) && next;
369
370			my $nick = $channel->nick_find($server->{nick});
371			!ref($nick) && next;
372
373			if ($nick->{op}) {
374				$mode = "@";
375			} elsif ($nick->{voice}) {
376				$mode = "+";
377			} elsif ($nick->{halfop}) {
378				$mode = "%";
379			}
380		}
381
382		# in case we have a specific hilightcolor use it
383		if ($win->{hilight_color}) {
384			$hilight = "{sb_act_hilight_color $win->{hilight_color} ";
385		} else {
386			$hilight = $show{$win->{data_level}};
387		}
388
389		if ($remove_prefix) {
390			$name =~ s/^([&#+!=]?)$remove_prefix/$1/;
391		}
392		if ($abbrev) {
393			if ($name =~ /^[&#+!=]/) {
394				$name = substr($name, 1, $abbrev + 1);
395			} else {
396				$name = substr($name, 0, $abbrev);
397			}
398		}
399		if ($remove_hash) {
400			$name =~ s/^[&#+!=]//;
401		}
402
403		if (Irssi::settings_get_bool('chanact_show_alias') == 1 &&
404				$win->{name} =~ /^([a-zA-Z+]):(.+)$/) {
405			$number = "$1";
406			$display = Irssi::settings_get_str('chanact_display_alias');
407		} else {
408			$number = $win->{refnum};
409			$display = Irssi::settings_get_str('chanact_display');
410		}
411
412		# fixup { and } in nicks, those are used by irssi themes
413		$name =~ s/([{}])/%$1/g;
414
415		$actString .= expand($display,"C",$name,"N",$number,"M",$mode,"H",$hilight,"S","}{sb_background}").$separator;
416	}
417
418	# assemble the final string
419	if ($actString ne "") {
420		# Remove the last separator
421		$actString =~ s/$separator$//;
422
423		$actString = "{sb ".Irssi::settings_get_str('chanact_header').$actString."}";
424	}
425
426	# no remake needed any longer
427	$needRemake = 0;
428}
429
430# method called because of some events. here we dont remake the item but just
431# remember that we have to remake it the next time we are called
432sub chanactHasChanged()
433{
434	# if needRemake is already set, no need to trigger a redraw as we will
435	# be redrawing the item anyway.
436	return if $needRemake;
437
438	$needRemake = 1;
439
440	Irssi::statusbar_items_redraw('chanact');
441}
442
443sub setup_changed {
444	my $method = Irssi::settings_get_str('chanact_sort');
445
446	unless (exists($sort{$method})) {
447		Irssi::print("chanact: invalid sort method, setting to 'refnum'."
448			." valid methods are: ".join(", ", sort(keys(%sort))));
449		my $method = Irssi::settings_set_str('chanact_sort', 'refnum');
450	}
451
452	chanactHasChanged();
453}
454
455# Remove key binding for current window
456sub unbind {
457	my ($name, $server) = @_;
458
459	# chanact'ified windows have a name like this: X:servertag/name. if we
460	# can't find anything like this we return and do not unbind nor renumber
461	# anything
462	my ($key, $tag) = split(/:/, $name);
463	return unless $tag;
464
465	($tag, $name) = split('/', $tag);
466	return unless (length($key) == 1);
467
468	if (Irssi::settings_get_bool('chanact_case_sensitive')) {
469		$server->command("/bind -delete meta-$key");
470	} else {
471		$server->command("/bind -delete meta-" . lc($key));
472		$server->command("/bind -delete meta-" . uc($key));
473	}
474}
475
476# Remove alias
477sub cmd_window_unalias {
478	my ($data, $server, $witem) = @_;
479
480	if ($data ne '') {
481		Irssi::print("chanact: /chanact_window_unalias does not take any ".
482			"parameters, Run it in the window you want to unalias");
483		return;
484	}
485
486	my $win = Irssi::active_win();
487	my $name = Irssi::active_win()->{name};
488
489	unbind($name, $server);
490
491	# set the windowname back to it's old one. We don't bother checking
492	# for a vaild name here, as we want to remove the current one and if
493	# worse comes to wors set an empty one.
494	$win->set_name($name);
495
496	# if autorenumbering is off, we are done.
497	return unless (Irssi::settings_get_bool('chanact_autorenumber'));
498
499	# we are renumbering, so move the window to the lowest available
500	# refnum.
501	my $refnum = 1;
502	while (Irssi::window_find_refnum($refnum)) {
503		$refnum++;
504	}
505
506	$win->set_refnum($refnum);
507	Irssi::print("chanact: moved wintow to refnum $refnum");
508}
509
510# Make an alias
511sub cmd_window_alias {
512	my ($data, $server, $witem) = @_;
513	my $rn_start = Irssi::settings_get_int('chanact_renumber_start');
514
515	unless ($data =~ /^[a-zA-Z+]$/) {
516		Irssi::print("Usage: /chanact_window_alias <char>");
517		return;
518	}
519
520	# in case of an itemless window $witem is undef, thus future operations
521	# on it fail. to prevent this we pull in the current window.
522	#
523	# Also we need to initialize $winname, else we would get a broken name:
524	#
525	#	'name' => 'S:IRCnet/S:IRCnet/',
526	#
527	my $window;
528	my $winname = "";
529	if (defined($witem)) {
530		$window = $witem->window();
531		$winname = $witem->{name};
532	} else {
533		$window = Irssi::active_win();
534		$winname = $window->{name};
535	}
536
537	unbind($window->{name}, $server);
538
539	my $winnum = $window->{refnum};
540
541	if (Irssi::settings_get_bool('chanact_autorenumber') == 1 &&
542			$window->{refnum} < $rn_start) {
543		my $old_refnum = $window->{refnum};
544
545		$winnum = $rn_start;
546
547		# Find the first available slot and move the window
548		while (Irssi::window_find_refnum($winnum)) { $winnum++; }
549		$window->set_refnum($winnum);
550
551		Irssi::print("Moved the window from $old_refnum to $winnum");
552	}
553
554	my $winserver = $window->{active_server}->{tag};
555	my $winhandle = "$winserver/$winname";
556	# cmd_window_unalias relies on a certain format here
557	my $name = "$data:$winhandle";
558
559	$window->set_name($name);
560	if (Irssi::settings_get_bool('chanact_case_sensitive')) {
561		$server->command("/bind meta-$data change_window $name");
562	} else {
563		$server->command("/bind meta-" . lc($data) . " change_window $name");
564		$server->command("/bind meta-" . uc($data) . " change_window $name");
565	}
566	Irssi::print("Window $winhandle is now accessible with meta-$data");
567}
568
569$needRemake = 1;
570
571# Window alias command
572Irssi::command_bind('chanact_window_alias','cmd_window_alias');
573Irssi::command_bind('chanact_window_unalias','cmd_window_unalias');
574
575# our config item
576Irssi::settings_add_str('chanact', 'chanact_display', '$H$N:$M$C$S');
577Irssi::settings_add_str('chanact', 'chanact_display_alias', '$H$N$M$S');
578Irssi::settings_add_int('chanact', 'chanact_abbreviate_names', 0);
579Irssi::settings_add_bool('chanact', 'chanact_case_sensitive', 1);
580Irssi::settings_add_bool('chanact', 'chanact_show_alias', 1);
581Irssi::settings_add_str('chanact', 'chanact_separator', " ");
582Irssi::settings_add_bool('chanact', 'chanact_autorenumber', 0);
583Irssi::settings_add_bool('chanact', 'chanact_remove_hash', 0);
584Irssi::settings_add_str('chanact', 'chanact_remove_prefix', "");
585Irssi::settings_add_int('chanact', 'chanact_renumber_start', 50);
586Irssi::settings_add_str('chanact', 'chanact_header', "Act: ");
587Irssi::settings_add_bool('chanact', 'chanact_chop_status', 1);
588Irssi::settings_add_str('chanact', 'chanact_sort', 'refnum');
589Irssi::settings_add_int('chanact', 'chanact_filter', 0);
590Irssi::settings_add_str('chanact', 'chanact_filter_windowlist', "");
591Irssi::settings_add_int('chanact', 'chanact_filter_windowlist_level', 0);
592
593# register the statusbar item
594Irssi::statusbar_item_register('chanact', '$0', 'chanact');
595# according to cras we shall not call this
596# Irssi::statusbars_recreate_items();
597
598# register all that nifty callbacks on special events
599Irssi::signal_add_last('setup changed', 'setup_changed');
600Irssi::signal_add_last('window changed', 'chanactHasChanged');
601Irssi::signal_add_last('window item changed', 'chanactHasChanged');
602Irssi::signal_add_last('window hilight', 'chanactHasChanged');
603Irssi::signal_add_last('window item hilight', 'chanactHasChanged');
604Irssi::signal_add("window created", "chanactHasChanged");
605Irssi::signal_add("window destroyed", "chanactHasChanged");
606Irssi::signal_add("window name changed", "chanactHasChanged");
607Irssi::signal_add("window activity", "chanactHasChanged");
608Irssi::signal_add("print text", "chanactHasChanged");
609Irssi::signal_add('nick mode changed', 'chanactHasChanged');
610
611###############
612###
613#
614# Changelog
615#
616# 0.6.0
617# 	- fixed URL
618# 	- now with 'use warnings'
619# 	- fix cmd_window_unalias call from cmd_window_alias
620# 	- fix Use of uninitialized value $name in hash element warnings
621# 	- return from cmd_window_unalias if the window has no valid
622# 	  chanact'ified name
623#	- rename /window_(un)alias to /chanact_window_(un)alias
624#	- fix refnum renumber race
625# 	- added setting to allow case-insensitive window aliases
626#
627# 0.5.14
628# 	- fix itemless window handling, thx Bazerka
629# 	- fix /window_alias for itemless windows
630# 	- fix /window_unalias. Also longer takes an argument
631# 	- added sorting by level, based on patch by Bazerka
632# 		+ retired chanact_sort_by_activity, integrated in chanact_sort
633#
634# 0.5.13
635# 	- trivial cleanup in cmd_window_alias()
636# 	- updated documentation regarding /layout save, thx Bazerka
637# 	- removed cmd_rebuild_aliases(), no longer working since we use channel
638# 	  names to select windows and not refnums
639# 	- removed refnum_changed(), see cmd_rebuild_aliases() above
640#
641# 0.5.12
642# 	- Use comma instead of colon as windowlist separator, patch by martin f.
643# 	  krafft, reported by James Vega
644#
645# 0.5.11
646#	- added chanact_filter_windowlist based on a patch by madduck@madduck.net
647# 	- fixed display error for nicks/channels with { or } in them
648# 	- fixed chanact_header, was hidden behind chanact_filter
649# 	- fixed documentation
650# 		+ removed chanact_show_mode, long gone
651#
652# 0.5.10
653# 	- fixed irssi crash when using Irssi::print from within remake()
654#       - added option to filter out some data levels, based on a patch by
655#         Juergen Jung <juergen@Winterkaelte.de>, see
656#         https://bc-bd.org/trac/irssi/ticket/15
657#         	+ retired chanact_show_all in favour of chanact_filter
658#
659# 0.5.9
660# 	- changes by stefan voelkel
661# 		+ sort channels by activity, see
662# 		  https://bc-bd.org/trac/irssi/ticket/5, based on a patch by jan
663# 		  krueger
664# 		+ fixed chrash on /exec -interactive, see
665# 		https://bc-bd.org/trac/irssi/ticket/7
666#
667# 	- changes by Jan 'jast' Krueger <jast@heapsort.de>, 2004-06-22
668# 		+ updated documentation in script's comments
669#
670# 	- changes by Ivo Timmermans <ivo@o2w.nl>
671# 		+ honor actcolor /hilight setting if present
672#
673# 0.5.8
674# - made aliases case-sensitive and include network in channel names by madduck
675#
676# 0.5.7
677# - integrated remove patch by Christoph Berg <myon@debian.org>
678#
679# 0.5.6
680# - fixed a bug (#1) reported by Wouter Coekaert
681#
682# 0.5.5
683# - some speedups from David Leadbeater <dgl@dgl.cx>
684#
685#
686# 0.5.4
687# - added help for chanact_display_alias
688#
689# 0.5.3
690# - added '+' to the available chars of aliase's
691# - added chanact_display_alias to allow different display modes if the window
692#   has an alias
693#
694# 0.5.2
695# - removed unused chanact_show_name settings (thx to Qerub)
696# - fixed $mode display
697# - guarded reference operations to (hopefully) fix errors on server disconnect
698#
699# 0.5.1
700# - small typo fixed
701#
702# 0.5.0
703# - changed chanact_show_mode to chanact_display. reversed changes from
704#   Qerub through that, but kept funcionality.
705# - removed chanact_color_all since it is no longer needed
706#
707# 0.4.3
708# - changes by Qerub
709#   + added chanact_show_mode to show the mode just before the channel name
710#   + added chanact_chop_status to be able to control the (status) chopping
711#     [bd] minor implementation changes
712# - moved Changelog to the end of the file since it is getting pretty big
713#
714# 0.4.2
715# - changed back to old version numbering sheme
716# - added '=' to Qrczak's chanact_abbreviate_names stuff :)
717# - added chanact_header
718#
719# 0.41q
720#	- changes by Qrczak
721#		+ added setting 'chanact_abbreviate_names'
722#		+ windows are sorted by refnum; I didn't understand the old
723#		  logic and it broke sorting for numbers above 9
724#
725# 0.41
726#	- minor updates
727#		+ fixed channel sort [veli]
728#		+ removed few typos and added some documentation [veli]
729#
730# 0.4
731#	- merge with window_alias.pl
732#		+ added /window_alias from window_alias.pl by veli@piipiip.net
733#		+ added setting 'chanact_show_alias'
734#		+ added setting 'chanact_show_names'
735#		+ changed setting 'chanact_show_mode' to int
736#		+ added setting 'chanact_separator' [veli]
737#		+ added setting 'chanact_autorenumber' [veli]
738#		+ added setting 'chanact_renumber_start' [veli]
739#		+ added /window_unalias [veli]
740#		+ moved setting to their own group 'chanact' [veli]
741#
742# 0.3
743#	- merge with chanlist.pl
744#		+ added setting 'chanact_show_mode'
745#		+ added setting 'chanact_show_all'
746#
747# 0.2
748#	- added 'Act' to the item
749#		- added setting 'chanact_color_all'
750#		- finally found format for statusbar hilight
751#
752# 0.1
753#	- Initial Release
754#
755###
756################
757