polemon.org
 
Table of Contents

sort.pl

This Irssi script sorts windows.
This one emphasizes on features and speed, you can group windows by networks, decide where queries should appear, etc. Rearranging 30 windows takes just about 200msec.

It adds the command /sort with options and settings. To get a list of them, type /sort help after loading the script.

Grab the code here, or take a look at the source:

sort.pl

  1: # sort.pl
  2: #
  3: # Sort windows based on network and window type
  4: #
  5: # Copyright (c) 2009 - 2010 Szymon 'polemon' Bereziak <polemon@polemon.org>
  6: #
  7: # This script is licensed under ISC license
  8: #
  9:
 10: use strict;
 11: use vars qw($VERSION %IRSSI);
 12:
 13: use Irssi;
 14:
 15: $VERSION = "1.1";
 16:
 17: %IRSSI = (
 18:          author => "Szymon 'polemon' Berziak",
 19:         contact => "polemon\@polemon.org",
 20:            name => "sort",
 21:     description => "Sorting windows based on network and type",
 22:         license => "ISC",
 23:             url => "http://polemon.org/sort.pl",
 24:         changed => "2010-10-20",
 25: );
 26:
 27: # register command
 28: Irssi::command_bind('sort', 'sort');
 29:
 30: # register settings
 31: Irssi::settings_add_str('sort', 'sort_group_networks', 'on');
 32: Irssi::settings_add_str('sort', 'sort_query_position', 'end');
 33: Irssi::settings_add_str('sort', 'sort_on_new_window', 'off');
 34:
 35: # register signal for changed settings
 36: Irssi::signal_add_last('setup changed', 'reg_sigs');
 37:
 38: # initial defaults
 39: my $groups = 1;
 40: my $position = "end";
 41:
 42: # sorted window list and target refnums
 43: my @s_windows = ();
 44: my @refnums = ();
 45:
 46: # check if autosort is desired
 47: &reg_sigs;
 48:
 49: sub reg_sigs {
 50:     if(Irssi::settings_get_str('sort_on_new_window') =~ /\b(on)|(yes)|(true)|(1)\b/i) {
 51:         Irssi::signal_add_last('window item name changed', 'sort');
 52:         Irssi::signal_add_last('channel created', 'sort');
 53:         Irssi::signal_add_last('query created', 'sort');
 54:     }
 55:     else {
 56:         Irssi::signal_remove('window item name changed', 'sort');
 57:         Irssi::signal_remove('channel created', 'sort');
 58:         Irssi::signal_remove('query created', 'sort');
 59:     }
 60: }
 61:
 62: # sort in groups by network
 63: sub grouped {
 64:     my @servers = sort {
 65:         lc($a->{'tag'}) cmp lc($b->{'tag'})
 66:     } Irssi::servers();
 67:
 68:     my @g_channels = ();
 69:     my @g_queries = ();
 70:     my @g_items = ();
 71:
 72:     for my $ser (@servers) {
 73:         my @items;
 74:
 75:         if($position ~~ "inline") {
 76:             @items = sort {
 77:                 my $a_name = $a->{'name'};
 78:                 my $b_name = $b->{'name'};
 79:                 $a_name =~ s/^#//;
 80:                 $b_name =~ s/^#//;
 81:
 82:                 lc($a_name) cmp lc($b_name)
 83:             } ($ser->channels(), $ser->queries());
 84:         }
 85:         else {
 86:             my @channels = sort {
 87:                 lc($a->{'name'}) cmp lc($b->{'name'})
 88:             } $ser->channels();
 89:
 90:             my @queries = sort {
 91:                 lc($a->{'name'}) cmp lc($b->{'name'})
 92:             } $ser->queries();
 93:
 94:             if($position ~~ "groupstart") {
 95:                 @items = (@queries, @channels);
 96:             }
 97:             elsif($position ~~ "groupend") {
 98:                 @items = (@channels, @queries);
 99:             }
100:             elsif( ($position ~~ "start") or
101:                    ($position ~~ "end") ) {
102:                 push(@g_channels, @channels);
103:                 push(@g_queries, @queries);
104:             }
105:         }
106:
107:         if( ($position ~~ "inline") or
108:             ($position ~~ "groupstart") or
109:             ($position ~~ "groupend") ) {
110:             for my $item (@items) {
111:                 my $win = $ser->window_find_item($item->{'name'});
112:                 push(@s_windows, $win);
113:                 push(@refnums, $win->{'refnum'});
114:             }
115:         }
116:     }
117:
118:     if($position ~~ "start") {
119:         @g_items = (@g_queries, @g_channels);
120:     }
121:     elsif($position ~~ "end") {
122:         @g_items = (@g_channels, @g_queries);
123:     }
124:
125:     if( ($position ~~ "start") or
126:         ($position ~~ "end") ) {
127:         for my $g_item (@g_items) {
128:             my $win = $g_item->{'server'}->window_find_item($g_item->{'name'});
129:             push(@s_windows, $win);
130:             push(@refnums, $win->{'refnum'});
131:         }
132:     }
133:     return 1;
134: }
135:
136: # sort linearly, with no groups
137: sub linear {
138:     my @items;
139:
140:     if($position ~~ "inline") {
141:         @items = sort {
142:             my $a_name = $a->{'name'};
143:             my $b_name = $b->{'name'};
144:             $a_name =~ s/^#//;
145:             $b_name =~ s/^#//;
146:
147:             lc($a_name) cmp lc($b_name)
148:         } (Irssi::channels(), Irssi::queries());
149:     }
150:     else {
151:         my @channels = sort {
152:             lc($a->{'name'}) cmp lc($b->{'name'})
153:         } Irssi::channels();
154:
155:         my @queries = sort {
156:             lc($a->{'name'}) cmp lc($b->{'name'})
157:         } Irssi::queries();
158:
159:         if($position =~ /(group)?start/) {
160:             @items = (@queries, @channels);
161:         }
162:         else {
163:             @items = (@channels, @queries);
164:         }
165:     }
166:
167:     for my $item (@items) {
168:         my $win = $item->{'server'}->window_find_item($item->{'name'});
169:         push(@s_windows, $win);
170:         push(@refnums, $win->{'refnum'});
171:     }
172:     return 1;
173: }
174:
175: # command
176: sub sort {
177:     my ($data, $server, $witem) = @_;
178:     @s_windows = ();
179:     @refnums = ();
180:
181:     $groups = 0;
182:     $groups = 1 if(Irssi::settings_get_str('sort_group_networks') =~ /\b(on)|(yes)|(true)|(1)\b/i);
183:
184:     $position = "end";
185:     $position = lc(Irssi::settings_get_str('sort_query_position')) if(Irssi::settings_get_str('sort_query_position') =~ /\b((?:group)?((start)|(end)))|(inline)\b/i );
186:
187:     $groups = 0 if($data =~ /\blinear\b/i);
188:     $groups = 1 if($data =~ /\bnetworks\b/i);
189:
190:     $position = $& if($data =~ /\b((?:group)?((start)|(end)))|(inline)\b/i);
191:
192:     if($data =~ /\bhelp\b/i) {
193:         Irssi::print (<<"END_HELP", MSGLEVEL_CLIENTCRAP);
194: %9Usage:%9
195:     /sort [%9linear%9|%9networks%9]
196:           [%9start%9|%9end%9|%9groupstart%9|%9groupend%9|%9inline%9]
197:           [%9help%9]
198:
199:
200: %9Options:%9
201:     The sequence of options is insignificant.
202:     "/sort start networks" or "/sort networks start" are equal.
203:
204:     If no option is given, defaults are assumed, if no or invalid
205:     settings are used.
206:
207:     %9linear%9
208:         Windows are sorted alphabetically.
209:
210:     %9networks%9
211:         Windows are sorted alphabetically, grouped by networks,
212:         which in turn are sorted alphabetically.
213:         (This is the default.)
214:
215:     %9start%9
216:         Put query windows at the start of the window list.
217:
218:     %9end%9
219:         Put query windows at the end of the window list.
220:         (This is the default.)
221:
222:     %9groupstart%9
223:         Put query windows at the start of the network group.
224:         When not using grouping, this is equal to %9start%9.
225:
226:     %9groupend%9
227:         Put query windows at the end if the network group.
228:         When not using grouping, this is equal to %9end%9.
229:
230:     %9inline%9
231:         Query windows are treated like channel windows, and are
232:         sorted in between them.
233:
234:     %9help%9
235:         Displays this text and returns. When %9help%9 is somewhere
236:         in the option list, no other command is executed.
237:
238:
239: %9Settings:%9
240:
241:     %9sort_group_networks%9
242:         Turns grouping by networks on, if set to a true value.
243:         (Default is "on".)
244:
245:     %9sort_query_position%9
246:         Takes any of the values "%9start%9", "%9end%9",
247:         "%9groupstart%9", or "%9groupend%9". See %9Options%9 for details.
248:         (Default is "end".)
249:
250:     %9sort_on_new_window%9
251:         Windows are sorted after a new channel or query window has been
252:         opened, if set to a true value.
253:         (Default is "off".)
254: END_HELP
255:         return 0;
256:     }
257:
258:     # sort
259:     ($groups == 1) and &grouped() or &linear();
260:
261:     # sort target refnums
262:     @refnums = sort {int($a) <=> int($b)} @refnums;
263:
264:     # move sorted windows to available refnums
265:     for my $i (0..$#s_windows) {
266:         $s_windows[$i]->command("WINDOW MOVE " . $refnums[$i]);
267:     }
268:
269:     # clean screen
270:     Irssi::command("REDRAW");
271: }

Features

Features include:

  • Fast rearrangement of windows
  • Full control of query placement
  • Automatic sort on new windows
  • Easy to use and minimal settings

Known Bugs

There's one oddity, that I can't seem to pinpoint where it stems from.

After windows were moved around, the topic bar will sometimes 'get' strange text, sometimes even spanning two lines. That line returns back to normal after a manual redraw (Ctrl-l), or switching to another window.

I've worked around that by executing a redraw programatically.

Help

Here's the help output:

Usage:
    /sort [linear|networks]
          [start|end|groupstart|groupend|inline]
          [help]


Options:
    The sequence of options is insignificant.
    "/sort start networks" or "/sort networks start" are equal.

    If no option is given, defaults are assumed, if no or invalid
    settings are used.

    linear
        Windows are sorted alphabetically.

    networks
        Windows are sorted alphabetically, grouped by networks,
        which in turn are sorted alphabetically.
        (This is the default.)

    start
        Put query windows at the start of the window list.

    end
        Put query windows at the end of the window list.
        (This is the default.)

    groupstart
        Put query windows at the start of the network group.
        When not using grouping, this is equal to start.

    groupend
        Put query windows at the end if the network group.
        When not using grouping, this is equal to end.

    inline
        Query windows are treated like channel windows, and are
        sorted in between them.

    help
        Displays this text and returns. When help is somewhere
        in the option list, no other command is executed.


Settings:

    sort_group_networks
        Turns grouping by networks on, if set to a true value.
        (Default is "on".)

    sort_query_position
        Takes any of the values "start", "end",
        "groupstart", or "groupend". See Options for details.
        (Default is "end".)

    sort_on_new_window
        Windows are sorted after a new channel or query window has been
        opened, if set to a true value.
        (Default is "off".)
 
sort.pl.txt · Last modified: 2010/10/21 00:47 by polemon
 
RSS • 2012 © --polemon Powered by: