diff options
| author | Wouter Coekaerts | 2015-10-01 18:41:05 -0300 |
|---|---|---|
| committer | dequis | 2015-10-01 18:41:05 -0300 |
| commit | 2344e7128f65a3457c6fdedc05d99e81a114fc85 (patch) | |
| tree | c0c11ef23df039f808daf45cde1ad43bcf0f7bd2 /scripts | |
| parent | 07ca2e4f7c7c4dac17d26d6ca25669daf2775e98 (diff) | |
| download | scripts.irssi.org-2344e7128f65a3457c6fdedc05d99e81a114fc85.tar.bz2 | |
Add sb_search.pl
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/sb_search.pl | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/scripts/sb_search.pl b/scripts/sb_search.pl new file mode 100644 index 0000000..51b9100 --- /dev/null +++ b/scripts/sb_search.pl @@ -0,0 +1,159 @@ +# sb_search.pl - search in your scrollback, scroll to a match +# Do /HELP SCROLLBACK for help + +# Copyright (C) 2008 Wouter Coekaerts <wouter@coekaerts.be>, Emanuele Giaquinta <exg@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.1'; +%IRSSI = ( + authors => 'Wouter Coekaerts, Emanuele Giaquinta', + contact => 'wouter@coekaerts.be, exg@irssi.org', + name => 'sb_search', + description => 'search in your scrollback, scroll to a match', + license => 'GPLv2 or later', + url => 'http://wouter.coekaerts.be/irssi/', + changed => '$LastChangedDate$', +); + +sub cmd_help { + my ($args, $server, $witem) = @_; + if ($args =~ /^scrollback( search)? *$/i) { + Irssi::print ( <<SCRIPTHELP_EOF + +SCROLLBACK SEARCH [-level <level>] [-regexp] [-case] [-word] [-forward] [-all] [<pattern>] + + SEARCH: Search for text in the scrollback buffer. + + -regexp: The given text pattern is a regular expression. + -case: Performs a case-sensitive matching. + -word: The text must match full words. + -forward: Search forwards (default is backwards). + -all: Search in all windows. + + Without arguments, the last search is repeated. +SCRIPTHELP_EOF + ,MSGLEVEL_CLIENTCRAP); + } +} + +my $regex; +my $all; +my $level; + +sub cmd_sb_search { + my ($args, $server, $witem) = @_; + + ### handle options + + my ($options, $pattern) = Irssi::command_parse_options('scrollback search', $args); + + my $forward = defined(delete $options->{forward}); + + if (!%$options && !$pattern) { + return if !$regex && !defined $level; + } else { + $all = defined($options->{all}); + $level = MSGLEVEL_ALL; + undef $regex; + } + + if (defined($options->{level})) { + $level = $options->{level}; + $level =~ y/,/ /; + $level = Irssi::combine_level(0, $level); + } + + if ($pattern) { + my $flags = defined($options->{case}) ? '' : '(?i)'; + my $b = defined($options->{word}) ? '\b' : ''; + if (defined($options->{regexp})) { + local $@; + eval { + $regex = qr/$flags$b$pattern$b/; + }; + if ($@) { + my ($err) = $@ =~ /^(.*)/; + $err =~ s/\sat .* line \d+\.$//; + print CLIENTERROR $err; + return; + } + } else { + $regex = qr/$flags$b\Q$pattern\E$b/; + } + } + + + ### determine window(s) to search in + + my $current_win = ref $witem ? $witem->window() : Irssi::active_win(); + + my @windows; + if ($all) { + # cycle backward or forwards over all windows starting from current + # for example, searching backward through 5 windows, with window 3 active: search order is 3,2,1,5,4 + # if we're searching forward: 3,4,5,1,2 + my $order = $forward ? 1 : -1; + @windows = sort {$order * ($a->{refnum} cmp $b->{refnum})} Irssi::windows(); + my @before_windows = grep {($_->{refnum} cmp $current_win->{refnum}) == $order} @windows; + my @after_windows = grep {($_->{refnum} cmp $current_win->{refnum}) == -$order} @windows; + @windows = ($current_win, @before_windows, @after_windows); + } else { + @windows = ($current_win); + } + + ### do the search + + foreach my $win (@windows) { + my $view = $win->view; + + ## determine line to start from + my $line; + if ($all && $win != $current_win) { + if ($forward) { # first line + $line = $view->get_lines; + } else { # last line + $line = $view->{startline}; + while ($line->next) { + $line = $line->next + } + } + } else { # line after or before first visible line + $line = $forward ? $view->{startline}->next : $view->{startline}->prev; + } + + ## loop over the lines + while (defined $line) { + my $line_level = $line->{info}{level}; + if ($line_level & $level && $line->get_text(0) =~ $regex) { + $view->scroll_line($line); + if ($all) { + Irssi::command('window goto ' . $win->{refnum}); + } + return; + } + $line = $forward ? $line->next : $line->prev; + } + } +} + +Irssi::command_bind('scrollback search', \&cmd_sb_search); +Irssi::command_bind_last('help', \&cmd_help); +Irssi::command_set_options('scrollback search', '-level regexp case word forward all'); |
