html/window_switcher.pl
1 # window_switcher: makes switching windows easy
2 #
3 # Usage:
4 # * Add the statusbar item:
5 # /STATUSBAR window add window_switcher
6 # * Type /ws followed by a window number or part of a window or channel name.
7 # * When the right item is at the first place in the statusbar, press enter.
8 # * For faster usage, do "/BIND ^G multi erase_line;insert_text /ws ",
9 # type ctrl-G, and start typing...
10
11 # Copyright 2007 Wouter Coekaerts <coekie@irssi.org>
12 #
13 # This program is free software; you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation; either version 2 of the License, or
16 # (at your option) any later version.
17 #
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
22 #
23 # You should have received a copy of the GNU General Public License
24 # along with this program; if not, write to the Free Software
25 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26
27 use strict;
28 use Irssi;
29 use Irssi::TextUI;
30
31 use vars qw($VERSION %IRSSI);
32 $VERSION = '1.0';
33 %IRSSI = (
34 authors => 'Wouter Coekaerts',
35 contact => 'coekie@irssi.org',
36 name => 'window_switcher',
37 description => 'makes switching windows easy',
38 license => 'GPLv2 or later',
39 url => 'http://wouter.coekaerts.be/irssi/',
40 changed => '29/07/07'
41 );
42
43 sub window_switcher_sb {
44 my ($sbItem, $get_size_only) = @_;
45
46 my $prompt = Irssi::parse_special('$L');
47 my $cmdchars = Irssi::parse_special('$K');
48
49 my $sb = '';
50
51 if ($prompt =~ /^(.)ws (.+)$/i && index($cmdchars,$1) != -1) {
52 my $arg = $2;
53 my $wins = find_wins($arg);
54
55 foreach my $win (@$wins) {
56 $sb .= $win->{text} . ' ';
57 }
58 $sb =~ s/ $//;
59 }
60
61 $sbItem->default_handler($get_size_only, "{sb $sb}", undef, 1);
62 }
63
64 sub find_wins {
65 my ($arg) = @_;
66 my @wins;
67 foreach my $window (Irssi::windows()) {
68 my @items = $window->items();
69 my $regex = qr/^(.*?)(\Q$arg\E)(.*)$/i;
70
71 my $match = 0;
72 my $text;
73 my $refnumtext = $window->{refnum};
74 my $itemname;
75
76 if ($window->{refnum} eq $arg) {
77 $match = 1;
78 if ($window->{name} ne '') {
79 $text = $window->{name};
80 } elsif (scalar(@items) > 0) {
81 $text = $items[0]->{visible_name};
82 } else {
83 $text = '';
84 }
85 $refnumtext = "%G$refnumtext%n";
86 } elsif ($window->{name} =~ $regex) {
87 ($match, $text) = do_match($1, $2, $3);
88 } else {
89 foreach my $item (@items) {
90 if ($item->{visible_name} =~ $regex) {
91 ($match, $text) = do_match($1, $2, $3);
92 $itemname = $item->{name};
93 last;
94 }
95 }
96 }
97
98 if ($match) {
99 push @wins, {
100 match => 1000 * $match + $window->{refnum},
101 refnum => $window->{refnum},
102 text => "$refnumtext:$text",
103 itemname => $itemname
104 };
105 }
106 }
107
108 @wins = sort {$a->{match} <=> $b->{match}} @wins;
109 return \@wins;
110 }
111
112 sub do_match {
113 my ($begin, $mid, $end) = @_;
114 my $match;
115 if ($begin eq '' || $begin eq '#') {
116 $match = ($end eq '') ? 2 : 3;
117 } else {
118 $match = 4;
119 }
120 return ($match, "%g$begin%G$mid%g$end%n");
121 }
122
123 Irssi::command_bind('ws', sub {
124 my ($data, $server, $win) = @_;
125 my $wins = find_wins($data);
126 if (scalar(@$wins) > 0) {
127 my $win = $wins->[0];
128 Irssi::command('window goto ' . $win->{refnum});
129 if (defined($win->{itemname})) {
130 Irssi::command('window item goto ' . $win->{itemname});
131 }
132 }
133 });
134
135 Irssi::statusbar_item_register ('window_switcher', 0, 'window_switcher_sb');
136
137 my $scheduled = 0;
138 Irssi::signal_add_last 'gui key pressed' => sub {
139 unless ($scheduled) {
140 $scheduled = 1;
141 Irssi::timeout_add_once(100, sub {
142 Irssi::statusbar_items_redraw ('window_switcher');
143 $scheduled = 0;
144 }, []);
145 }
146 };