scripts/window_switcher.pl
# window_switcher: makes switching windows easy
#
# Usage:
# * Add the statusbar item:
# /STATUSBAR window add window_switcher
# * Type /ws followed by a window number or part of a window or channel name.
# * When the right item is at the first place in the statusbar, press enter.
# * For faster usage, do "/BIND ^G multi erase_line;insert_text /ws ",
# type ctrl-G, and start typing...
# Copyright 2007 Wouter Coekaerts <coekie@irssi.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
use strict;
use Irssi;
use Irssi::TextUI;
use vars qw($VERSION %IRSSI);
$VERSION = '1.0';
%IRSSI = (
authors => 'Wouter Coekaerts',
contact => 'coekie@irssi.org',
name => 'window_switcher',
description => 'makes switching windows easy',
license => 'GPLv2 or later',
url => 'http://wouter.coekaerts.be/irssi/',
changed => '29/07/07'
);
sub window_switcher_sb {
my ($sbItem, $get_size_only) = @_;
my $prompt = Irssi::parse_special('$L');
my $cmdchars = Irssi::parse_special('$K');
my $sb = '';
if ($prompt =~ /^(.)ws (.+)$/i && index($cmdchars,$1) != -1) {
my $arg = $2;
my $wins = find_wins($arg);
foreach my $win (@$wins) {
$sb .= $win->{text} . ' ';
}
$sb =~ s/ $//;
}
$sbItem->default_handler($get_size_only, "{sb $sb}", undef, 1);
}
sub find_wins {
my ($arg) = @_;
my @wins;
foreach my $window (Irssi::windows()) {
my @items = $window->items();
my $regex = qr/^(.*?)(\Q$arg\E)(.*)$/i;
my $match = 0;
my $text;
my $refnumtext = $window->{refnum};
my $itemname;
if ($window->{refnum} eq $arg) {
$match = 1;
if ($window->{name} ne '') {
$text = $window->{name};
} elsif (scalar(@items) > 0) {
$text = $items[0]->{visible_name};
} else {
$text = '';
}
$refnumtext = "%G$refnumtext%n";
} elsif ($window->{name} =~ $regex) {
($match, $text) = do_match($1, $2, $3);
} else {
foreach my $item (@items) {
if ($item->{visible_name} =~ $regex) {
($match, $text) = do_match($1, $2, $3);
$itemname = $item->{name};
last;
}
}
}
if ($match) {
push @wins, {
match => 1000 * $match + $window->{refnum},
refnum => $window->{refnum},
text => "$refnumtext:$text",
itemname => $itemname
};
}
}
@wins = sort {$a->{match} <=> $b->{match}} @wins;
return \@wins;
}
sub do_match {
my ($begin, $mid, $end) = @_;
my $match;
if ($begin eq '' || $begin eq '#') {
$match = ($end eq '') ? 2 : 3;
} else {
$match = 4;
}
return ($match, "%g$begin%G$mid%g$end%n");
}
Irssi::command_bind('ws', sub {
my ($data, $server, $win) = @_;
my $wins = find_wins($data);
if (scalar(@$wins) > 0) {
my $win = $wins->[0];
Irssi::command('window goto ' . $win->{refnum});
if (defined($win->{itemname})) {
Irssi::command('window item goto ' . $win->{itemname});
}
}
});
Irssi::statusbar_item_register ('window_switcher', 0, 'window_switcher_sb');
my $scheduled = 0;
Irssi::signal_add_last 'gui key pressed' => sub {
unless ($scheduled) {
$scheduled = 1;
Irssi::timeout_add_once(100, sub {
Irssi::statusbar_items_redraw ('window_switcher');
$scheduled = 0;
}, []);
}
};