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:
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: ®_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 include:
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.
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".)