Skip to content
Browse files

Add shortcut for equality search

  • Loading branch information...
1 parent 64ae5a1 commit d86a5c9654f33b4287cf6a7bc8e0654b68d307ef @dgl committed Jul 15, 2012
Showing with 18 additions and 11 deletions.
  1. +12 −9 lib/WWW/CPANGrep/Search.pm
  2. +3 −1 share/html/about.html
  3. +3 −1 t/search.t
View
21 lib/WWW/CPANGrep/Search.pm
@@ -53,17 +53,19 @@ sub _parse_search {
my($file, $type) = @_;
# Shortcut for .pm -> \.(?i:pm)$
$file = '(?i:\\' . $file . ')$' if $file =~ /^\.\w+$/;
- { type => "file", re => _re2_compile($file), negate => $type eq '-' }
+ { type => "file", re => _re2_compile($type eq '=' ? "^$file\$" : $file), negate => $negate }
},
dist => sub {
- my($dist, $type) = @_;
- { type => "dist", re => _re2_compile($dist), negate => $type eq '-' }
+ my($dist, $type, $negate) = @_;
+ { type => "dist", re => _re2_compile($type eq '=' ? "^$dist\$" : $dist), negate => $negate }
},
author => sub {
- my($author, $type) = @_;
- { type => "author",
- re => _re2_compile($author =~ /^\w+/ ? uc $author : $author),
- negate => $type eq '-'
+ my($author, $type, $negate) = @_;
+ my $match = $author =~ /^\w+/ ? uc $author : $author;
+ {
+ type => "author",
+ re => _re2_compile($type eq '=' ? "^$re\$" : $re),
+ negate => $negate,
}
},
);
@@ -72,12 +74,13 @@ sub _parse_search {
my $opt_re = '(?:' . join('|', keys %options) . ')';
my $arg_re = '(?:' . gen_delimited_pat(q{"/}) . '|\S+)';
- while($q =~ s/(^|\s)(?<type>-?)(?<opt>$opt_re):(?<arg>$arg_re)(?:$|\s)/$1/g) {
+ while($q =~ s/(^|\s)(?<negate>-?)(?<opt>$opt_re)(?<type>[:=])(?<arg>$arg_re)(?:$|\s)/$1/g) {
my $opt = $options{$+{opt}};
next unless $opt;
+ my $negate = $+{negate} eq '-';
my $type = $+{type};
my $arg = $+{arg} =~ s/(?:^"(.*)"$|(.*))/$2||$1 =~ s{\\(.)}{$1}gr/re;
- push @options, $opt->($arg, $type);
+ push @options, $opt->($arg, $type, $negate);
}
$q =~ s/\s+$//;
View
4 share/html/about.html
@@ -50,7 +50,9 @@
<li><code>author:</code> Search CPAN author ID.</li>
</ul>
- <p>For example <code>-dist:^perl$</code> to exclude perl, <code>file:.xs</code> to search only XS files or <code>-file:"ppport\.h"</code> to exclude ppport.h.</p>
+ <p>A useful shortcut for these operators is to use '=' rather than ':' as a seperator, this does a full string match (i.e. wraps anchors around the supplied regexp).</p>
+
+ <p>For example <code>-dist=perl</code> to exclude perl, <code>file:.xs</code> to search only XS files or <code>-file:"ppport\.h"</code> to exclude ppport.h.</p>
<p>Much of the power of this tool comes from the fact raw regexps can be used. By default the search is case sensitive, but <code>(?i)</code> or <code>(?i:regexp)</code> syntax can be used to make it case insensitive. Escapes such as \n can be used to match on newlines or the <code>(?s)</code> modifier (be careful with this, very greedy matching is limited for resource reasons, you may find writing a regexp such as <code>.{1,10}</code> rather than blindly writing <code>.*</code> is more effective).</p>
View
4 t/search.t
@@ -1,7 +1,7 @@
use Test::More;
use_ok q{WWW::CPANGrep::Search};
-my $s = new_ok "WWW::CPANGrep::Search", [q => "foo file:test.pm dist:dist.foo"];
+my $s = new_ok "WWW::CPANGrep::Search", [q => "foo file:test.pm dist:dist.foo -dist=bar author:dgl"];
{
use re::engine::RE2;
@@ -11,6 +11,8 @@ my $s = new_ok "WWW::CPANGrep::Search", [q => "foo file:test.pm dist:dist.foo"];
is_deeply $s->{_options}, [
{ type => "file", negate => "", re => qr/test.pm/ },
{ type => "dist", negate => "", re => qr/dist.foo/ },
+ { type => "dist", negate => 1, re => qr/^bar$/ },
+ { type => "author", negate => "", re => qr/DGL/ },
];
}

0 comments on commit d86a5c9

Please sign in to comment.
Something went wrong with that request. Please try again.