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 };