diff options
-rw-r--r-- | fixery/grep.pl | 142 |
1 files changed, 102 insertions, 40 deletions
diff --git a/fixery/grep.pl b/fixery/grep.pl index 0215bca..ef5d043 100644 --- a/fixery/grep.pl +++ b/fixery/grep.pl @@ -10,73 +10,135 @@ use Irssi; use strict; use Text::ParseWords; -use vars qw($VERSION %IRSSI); -$VERSION = "2.1"; -%IRSSI = ( - authors => "Timo \'cras\' Sirainen, Wouter Coekaerts", - contact => "tss\@iki.fi, wouter\@coekaerts.be", + +my $HELP_SUMMARY = "GREP [-i] [-w] [-v] [-F] <perl-regex> /irssi-command"; + +our $VERSION = "2.1"; +our %IRSSI = ( + authors => "Timo 'cras' Sirainen, Wouter Coekaerts, Tom Feist", + contact => 'tss@iki.fi, wouter@coekaerts.be', name => "grep", - description => "/GREP [-i] [-w] [-v] [-F] <perl-regexp> <command to run>", + description => $HELP_SUMMARY, license => "Public Domain", url => "http://wouter.coekaerts.be/irssi/", - changed => "2008-01-13" + changed => "2012-02-02" ); -my ($match, $v); +my $HELP_TEXT + = [ $HELP_SUMMARY, + "", + "The following options are supported:", + " \x{02}-i\x{02}: match case insensitively", + " \x{02}-w\x{02}: only print matches that form whole words", + " \x{02}-v\x{02}: Invert the sense of matching, to print non-matching lines.", + " \x{02}-F\x{02}: match as a fixed string, not a regexp", + "", + "Examples:", + "", + " \x{02}*\x{02} /GREP -i bacon /echo I LOVE BACON", + "", + "if you want /FGREP, do: /alias FGREP GREP -F" + ]; + +my $match_pattern; +my $match_count = 0; + +my $options = { }; -sub sig_text { +sub sig_grep_text { my ($dest, $text, $stripped_text) = @_; - Irssi::signal_stop() if (($stripped_text =~ /$match/) == $v); + + if ($stripped_text =~ $match_pattern) { + + if (not $options->{'-v'}) { + $match_count++; + return; + } + } + + Irssi::signal_stop; } sub cmd_grep { - my ($data,$server,$item) = @_; - my ($option,$cmd,$i,$w,$F); - $v = 0; - $F = 0; + my ($data, $server, $item) = @_; + + if ($data =~ m/^\s*$/) { + + Irssi::print("\x{02}GREP Error\x{02} Invalid arguments. " + . "Usage: $HELP_SUMMARY", MSGLEVEL_CLIENTERROR); + return; + } + + $options = { map { $_ => 0 } qw/-i -v -w -F/ }; # split the arguments, keep quotes - my (@args) = "ewords(' ', 1, $data); + my @args = quotewords(' ', 1, $data); # search for options - while ($args[0] =~ /^-/) { - $option = shift(@args); - if ($option eq '-i') {$i = 1;} - elsif ($option eq '-v') {$v = 1;} - elsif ($option eq '-w') {$w = 1;} - elsif ($option eq '-F') {$F = 1;} - else { - Irssi::print("Unknown option: $option",MSGLEVEL_CLIENTERROR); + while ($args[0] =~ /^-\w/) { + + my $opt_arg = shift @args; + + if (exists $options->{$opt_arg}) { + $options->{$opt_arg} = 1; + } else { + Irssi::print("Unknown option: $opt_arg", MSGLEVEL_CLIENTERROR); return; } } # match = first argument, but remove quotes - ($match) = "ewords(' ', 0, shift(@args)); + my ($match_str) = quotewords(' ', 0, shift @args); + print "Match string >>$match_str<<"; + # cmd = the rest (with quotes) - $cmd = join(' ',@args); + my $cmd = join(' ', @args); - # check if the regexp is valid - eval("'' =~ /$match/"); - if($@) { # there was an error - chomp $@; - Irssi::print($@,MSGLEVEL_CLIENTERROR); - return; - } + print "CMD >>$cmd<<"; - if ($F) { - $match =~ s/(\(|\)|\[|\]|\{|\}|\\|\*|\.|\?|\|)/\\$1/g; + if ($options->{'-F'}) { + $match_str = quotemeta($match_str); } - if ($w) { - $match = '\b' . $match . '\b'; + + if ($options->{'-w'}) { + $match_str = '\b' . $match_str . '\b'; } - if ($i) { - $match = '(?i)' . $match; + + if ($options->{'-i'}) { + $match_str = '(?i)' . $match_str; } - Irssi::signal_add_first('print text', 'sig_text'); + $match_pattern = eval { + qr/$match_str/; + }; + + if ($@) { + chomp $@; + Irssi::print("\x{02}Invalid pattern\x{02}: $@", MSGLEVEL_CLIENTERROR); + return; + } + + $match_count = 0; + + Irssi::signal_add_first('print text', 'sig_grep_text'); Irssi::signal_emit('send command', $cmd, $server, $item); - Irssi::signal_remove('print text', 'sig_text'); + Irssi::signal_remove('print text', 'sig_grep_text'); + + if ($match_count > 0) { + Irssi::print(sprintf("Matched %d entr%s", $match_count, + $match_count == 1?"y":"ies"), + MSGLEVEL_CLIENTCRAP); + } else { + Irssi::print("No matches", MSGLEVEL_CLIENTCRAP); + } +} + +sub cmd_help_intercept_grep { + if ($_[0] =~ m/grep/i) { + Irssi::print($_, MSGLEVEL_CLIENTCRAP) for (@$HELP_TEXT); + Irssi::signal_stop; + } } Irssi::command_bind('grep', 'cmd_grep'); +Irssi::command_bind('help', 'cmd_help_intercept_grep'); |