diff --git a/META6.json b/META6.json index c15d7e4..c73f44d 100644 --- a/META6.json +++ b/META6.json @@ -11,9 +11,9 @@ "CLI::Version:ver<0.0.7>:auth", "Edit::Files:ver<0.0.4>:auth", "has-word:ver<0.0.3>:auth", - "highlighter:ver<0.0.12>:auth", + "highlighter:ver<0.0.14>:auth", "JSON::Fast:ver<0.17>:auth", - "rak:ver<0.0.17>:auth", + "rak:ver<0.0.18>:auth", "String::Utils:ver<0.0.8>:auth", "META::constants:ver<0.0.2>:auth" ], diff --git a/README.md b/README.md index a64f6b7..9f4d267 100644 --- a/README.md +++ b/README.md @@ -136,7 +136,7 @@ If information can be obtained, then the associated `Git::Blame::Fil $ rak '*.commits > 10' --blame-per-file --files-with-matches ``` -Requires that the [`Git::Blame::File`](https://raku.land/zef:lizmat/Git::Blame::File) is installed. +Requires that the [`Git::Blame::File`](https://raku.land/zef:lizmat/Git::Blame::File) module is installed. --blame-per-line ---------------- @@ -150,7 +150,7 @@ If information can be obtained, then the associated `Git::Blame::Lin $ rak '{ .author eq "Scooby Doo" }' --blame-per-line ``` -Requires that the [`Git::Blame::File`](https://raku.land/zef:lizmat/Git::Blame::File) is installed. +Requires that the [`Git::Blame::File`](https://raku.land/zef:lizmat/Git::Blame::File) module is installed. --blocks=condition ------------------ @@ -167,6 +167,11 @@ $ rak --find --blocks='* >= 3' Indicate whether there should be a visible division between matches of different files. Can also be specified as a string to be used as the divider. Defaults to `True` (using an empty line as a divider) if `--group-matches` is (implicitly) set to `True`, else defaults to `False`. +--checkout=branch +----------------- + +Only valid if the current directory is under git version control. Indicate the branch to checkout by the general matching logic of App::Rak. Will produce listing of matching branches if more than one, or say that there is no match. Branches need not have been checked out locally yet. + --context=N ----------- @@ -196,6 +201,11 @@ Indicate the number of worker threads that should be maximally. Defaults to the If specified, indicates the `Callable` that should return True to include a file in the selection of files to be checked. The device number of the filesystem on which the file is located, will be passed as the only argument. +--dir=condition +--------------- + +If specified, indicates the `Callable` that should return True to have a directory be included for further recursions in file selection. The basename of the directory will be passed as the only argument. Defaults to all directories that do not start with a period. Can specify as a flag to include **all** directories for recursion. + --dryrun -------- @@ -236,6 +246,11 @@ $ rak foo --extensions= Predefined groups are `#raku`, `#perl`, `#c`, `#c++`, `#yaml`, <#ruby> `#python`, `#markdown` and `#text`. +--file=condition +---------------- + +If specified, indicates the `Callable` that should return True to have a file be included in the file selection process. The basename of the file will be passed as the only argument. Defaults to `True`, indicating that all files should be included. + --file-separator-null --------------------- @@ -271,6 +286,11 @@ $ rak --find --filesize='* >= 30' Flag. If specified with a true value, will **not** look at the contents of the selected paths, but instead consider the selected paths as lines in a virtual file. +--find-all +---------- + +Flag. If specified with a true value, will override any file or directory filter settings and include all possible files for inspection. + --first-only[=N] ---------------- @@ -388,12 +408,22 @@ Flag. Indicate whether the pattern should be highlighted in the line in which it --highlight--after[=string] --------------------------- -Indicate the string that should be used at the end of the pattern found in a line. Specifying implies `--highlight`ing implicitely. If `--highlight` or `--highlight-before` are explicitely specified, will default to the empty string if `--matches-only` is specified with a `True` value, or whatever is specified with `--highlight-before`, or to the ANSI code to end **bold**. +Indicate the string that should be used at the end of the pattern found in a line. Specifying implies `--highlight`ing implicitely. If `--highlight` or `--highlight-before` are explicitely specified, will default to whatever is specified with `--highlight-before`, or to the ANSI code to end **bold**. --highlight--before[=string] ---------------------------- -Indicate the string that should be used at the end of the pattern found in a line. Specifying implies `--highlight`ing implicitly. If `highlight` is explicitely specified with a trueish value, will default to a space if `--matches-only` is specified with a `True` value, or to the terminal code to start **bold** otherwise. +Indicate the string that should be used at the end of the pattern found in a line. Specifying implies `--highlight`ing implicitly. If `highlight` is explicitely specified with a trueish value, will default to the terminal code to start **bold**. + +--ignorecase +------------ + +Flag. If specified with a trueish value, indicates that any matching should be done case insensitively. Default is `False`. + +--ignoremark +------------ + +Flag. If specified with a trueish value, indicates that any matching should be done without consideration of any accents. Default is `False`. --inode=condition ----------------- @@ -475,13 +505,13 @@ Flag. If specified with a trueish value, will only select files that can be exec Flag. If specified with a trueish value, will only select files that can be read by anybody. Use negation `--/is-world-readable` to only select files that are **not** readable by anybody. ---is-world-writable File can (not) be written to by anybody ------------------------------------------------------------ +--is-world-writable +------------------- Flag. If specified with a trueish value, will only select files that can be written to by anybody. Use negation `--/is-world-writable` to only select files that can **not** be written to by anybody. ---is-writable File can (not) be written to by owner ---------------------------------------------------- +--is-writable +------------- Flag. If specified with a trueish value, will only select files that can be written to by the current user. Use negation `--/is-writable` to only select files that can **not** be written to by the current user. @@ -606,7 +636,7 @@ Indicate the Raku module that should be loaded. Only makes sense if the pattern --matches-only -------------- -Flag. Indicate whether only the matched pattern should be produced, rather than the line in which the pattern was found. Defaults to `False`. +Flag. Indicate whether only the matched pattern should be produced, rather than the line in which the pattern was found. Defaults to `False`. Frequently used in conjunction with `--per-file`. Will show separated by space if multiple matches are found on the same line. --output-file=filename ---------------------- @@ -654,6 +684,16 @@ Indicate the path of the file to read path specifications from instead of from a Alternative way to specify the pattern to search for. If (implicitly) specified, will assume the first positional parameter specified is actually a path specification, rather than a pattern. This allows the pattern to be searched for to be saved with `--save`. +--per-file[=code] +----------------- + +Indicate whether matching should be done per file, rather than per line. If specified as a flag, will slurp a file with the indicated `--encoding` and present that to the matcher. Optionally takes a `Callable` specification: this will be given an `IO::Path` object of the file: whatever it produces will be presented to the matcher. Usually used in conjunction with `--matches-only` and/or `count-only`. + +```bash +# look for foo in only the first 10 lines of each file +$ rak foo --per-file='*.lines(:!chomp).head(10).join' +``` + --quietly --------- @@ -730,7 +770,9 @@ Only applicable if `--csv-per-line` has been specified. Indicates the character --show-blame ------------ -Flag. Indicate whether to show `git blame` information for matching lines if possible, instead of just the line. Defaults to `False`. **TEMPORARILY UNAVAILABLE**. +Flag. Indicate whether to show `git blame` information for matching lines if possible, instead of just the line. Defaults to `False`. + +Requires that the [`Git::Blame::File`](https://raku.land/zef:lizmat/Git::Blame::File) module is installed. --show-filename --------------- diff --git a/TODO b/TODO new file mode 100644 index 0000000..d14b4bc --- /dev/null +++ b/TODO @@ -0,0 +1,7 @@ +Ideas / Todo's +============== + +- run a raku program and interpret the execution error as an --edit +- modified-after/before etc, instead of just modified etc. +- expose mapper +- create plugin structure diff --git a/doc/App-Rak.rakudoc b/doc/App-Rak.rakudoc index 4bae7dc..b439148 100644 --- a/doc/App-Rak.rakudoc +++ b/doc/App-Rak.rakudoc @@ -166,7 +166,7 @@ $ rak '*.commits > 10' --blame-per-file --files-with-matches =end code -Requires that the L|https://raku.land/zef:lizmat/Git::Blame::File> is installed. +Requires that the L|https://raku.land/zef:lizmat/Git::Blame::File> module is installed. =head2 --blame-per-line @@ -189,7 +189,7 @@ $ rak '{ .author eq "Scooby Doo" }' --blame-per-line =end code -Requires that the L|https://raku.land/zef:lizmat/Git::Blame::File> is installed. +Requires that the L|https://raku.land/zef:lizmat/Git::Blame::File> module is installed. =head2 --blocks=condition @@ -211,6 +211,13 @@ different files. Can also be specified as a string to be used as the divider. Defaults to C (using an empty line as a divider) if C<--group-matches> is (implicitly) set to C, else defaults to C. +=head2 --checkout=branch + +Only valid if the current directory is under git version control. Indicate +the branch to checkout by the general matching logic of App::Rak. Will +produce listing of matching branches if more than one, or say that there +is no match. Branches need not have been checked out locally yet. + =head2 --context=N Indicate the number of lines that should be shown B any line that @@ -250,6 +257,14 @@ If specified, indicates the C that should return True to include a file in the selection of files to be checked. The device number of the filesystem on which the file is located, will be passed as the only argument. +=head2 --dir=condition + +If specified, indicates the C that should return True to have a +directory be included for further recursions in file selection. The basename +of the directory will be passed as the only argument. Defaults to all +directories that do not start with a period. Can specify as a flag to +include B directories for recursion. + =head2 --dryrun Flag. Indicate to B actually make any changes to any content @@ -300,6 +315,13 @@ $ rak foo --extensions= Predefined groups are C<#raku>, C<#perl>, C<#c>, C<#c++>, C<#yaml>, <#ruby> C<#python>, C<#markdown> and C<#text>. +=head2 --file=condition + +If specified, indicates the C that should return True to have a +file be included in the file selection process. The basename of the file +will be passed as the only argument. Defaults to C, indicating that +all files should be included. + =head2 --file-separator-null Flag. Indicate to separate filenames by null bytes rather than newlines @@ -340,6 +362,11 @@ Flag. If specified with a true value, will B look at the contents of the selected paths, but instead consider the selected paths as lines in a virtual file. +=head2 --find-all + +Flag. If specified with a true value, will override any file or directory +filter settings and include all possible files for inspection. + =head2 --first-only[=N] Indicate the number of matches to show. If specified without a value, will @@ -459,17 +486,25 @@ are explicitely specified, or C otherwise. Indicate the string that should be used at the end of the pattern found in a line. Specifying implies C<--highlight>ing implicitely. If C<--highlight> -or C<--highlight-before> are explicitely specified, will default to the empty -string if C<--matches-only> is specified with a C value, or whatever +or C<--highlight-before> are explicitely specified, will default to whatever is specified with C<--highlight-before>, or to the ANSI code to end B. =head2 --highlight--before[=string] Indicate the string that should be used at the end of the pattern found in a line. Specifying implies C<--highlight>ing implicitly. If C -is explicitely specified with a trueish value, will default to a space if -C<--matches-only> is specified with a C value, or to the terminal code -to start B otherwise. +is explicitely specified with a trueish value, will default to the terminal +code to start B. + +=head2 --ignorecase + +Flag. If specified with a trueish value, indicates that any matching should +be done case insensitively. Default is C. + +=head2 --ignoremark + +Flag. If specified with a trueish value, indicates that any matching should +be done without consideration of any accents. Default is C. =head2 --inode=condition @@ -571,13 +606,13 @@ Flag. If specified with a trueish value, will only select files that can be read by anybody. Use negation C<--/is-world-readable> to only select files that are B readable by anybody. -=head2 --is-world-writable File can (not) be written to by anybody +=head2 --is-world-writable Flag. If specified with a trueish value, will only select files that can be written to by anybody. Use negation C<--/is-world-writable> to only select files that can B be written to by anybody. -=head2 --is-writable File can (not) be written to by owner +=head2 --is-writable Flag. If specified with a trueish value, will only select files that can be written to by the current user. Use negation C<--/is-writable> to only select @@ -736,6 +771,8 @@ pattern is executable code. Flag. Indicate whether only the matched pattern should be produced, rather than the line in which the pattern was found. Defaults to C. +Frequently used in conjunction with C<--per-file>. Will show separated by +space if multiple matches are found on the same line. =head2 --output-file=filename @@ -793,6 +830,22 @@ specified, will assume the first positional parameter specified is actually a path specification, rather than a pattern. This allows the pattern to be searched for to be saved with C<--save>. +=head2 --per-file[=code] + +Indicate whether matching should be done per file, rather than per line. +If specified as a flag, will slurp a file with the indicated C<--encoding> +and present that to the matcher. Optionally takes a C +specification: this will be given an C object of the file: +whatever it produces will be presented to the matcher. Usually used in +conjunction with C<--matches-only> and/or C. + +=begin code :lang + +# look for foo in only the first 10 lines of each file +$ rak foo --per-file='*.lines(:!chomp).head(10).join' + +=end code + =head2 --quietly Flag. Only makes sense if the pattern is a C. If specified @@ -883,7 +936,8 @@ character to indicate the field separator. Defaults to the B. Flag. Indicate whether to show C information for matching lines if possible, instead of just the line. Defaults to C. -B. + +Requires that the L|https://raku.land/zef:lizmat/Git::Blame::File> module is installed. =head2 --show-filename diff --git a/lib/App/Rak.rakumod b/lib/App/Rak.rakumod index 80c8c5e..4f4e149 100644 --- a/lib/App/Rak.rakumod +++ b/lib/App/Rak.rakumod @@ -2,9 +2,9 @@ use as-cli-arguments:ver<0.0.4>:auth; use Edit::Files:ver<0.0.4>:auth; use has-word:ver<0.0.3>:auth; -use highlighter:ver<0.0.12>:auth; +use highlighter:ver<0.0.14>:auth; use JSON::Fast:ver<0.17>:auth; -use rak:ver<0.0.17>:auth; +use rak:ver<0.0.18>:auth; use String::Utils:ver<0.0.8>:auth; # Defaults for highlighting on terminals @@ -99,12 +99,12 @@ my sub named-args(%args, *%wanted) { } # Return prelude from --repository and --module parameters -my sub prelude(%_) { +my sub prelude(%n) { my $prelude = ""; - if %_:delete -> \libs { + if %n:delete -> \libs { $prelude = libs.map({"use lib '$_'; "}).join; } - if %_:delete -> \modules { + if %n:delete -> \modules { $prelude ~= modules.map({"use $_; "}).join; } $prelude @@ -403,7 +403,7 @@ my sub setup-sources-selection(@specs, %n, %rak) { } # Really want to check *all* files - if %n:delete { + if %n:delete { meh "Cannot specify --dir with --find-all" if %n:delete; meh "Cannot specify --file with --find-all" if %n:delete; %rak := %rak := True; @@ -466,6 +466,7 @@ my sub setup-sources-selection(@specs, %n, %rak) { } # Boolean flags that can also be negated + # %n # for option parsing for # for option parsing for { # TODO } @@ -589,6 +591,7 @@ my sub setup-sources-selection(@specs, %n, %rak) { } # Checking for numeric value + # %n # option parser for { if %n{$_}:exists { my $code := %n{$_}:delete; @@ -610,14 +613,15 @@ my sub setup-producers(@specs, %n, %rak) { # Set up producers %rak := my $enc := (%n:delete) // 'utf8-c8'; if %n:delete -> $per-file { - %rak := $per-file =:= True + %rak := True; + %rak := $per-file<> =:= True ?? *.slurp(:$enc) !! convert-to-simple-Callable($per-file) } elsif %n:delete -> $per-line { %rak := convert-to-simple-Callable($per-line) - unless $per-line =:= True; + unless $per-line<> =:= True; } # after this, these all require simple Callables @@ -662,21 +666,31 @@ my sub setup-producers(@specs, %n, %rak) { %rak = True; } elsif %n:delete { - CATCH { - meh-not-installed 'Git::Blame::File', 'blame-per-line'; - } + CATCH { meh-not-installed 'Git::Blame::File', 'blame-per-line' } require Git::Blame::File; %rak := -> $io { Git::Blame::File.new($io).lines } %rak := True; } + elsif %n:delete { + CATCH { meh-not-installed 'Git::Blame::File', 'show-blame' } + require Git::Blame::File; + %rak := -> $source, @matches { + my @line-numbers = @matches.map: *.key; + with Git::Blame::File.new($source, :@line-numbers) -> $blamer { + $blamer.lines.Slip + } + else { + @matches.map({ .key ~ ':' ~ .value }).Slip + } + } + } } # Return a Callable to do highlighting my sub make-highlighter($needle, %n, %rak) { - my $type := %n; - my $trim := %n:delete; - my $only := %n:delete; + my $type := %n; + my $trim := %n:delete; my Int() $summary-if-larger-than := %n:delete // 160; @@ -702,11 +716,11 @@ my sub make-highlighter($needle, %n, %rak) { if $highlight { my Str() $pre = my Str() $post = $_ with $highlight-before; $post = $_ with $highlight-after; - $pre = $only ?? " " !! BON without $pre; - $post = $only ?? "" !! BOFF without $post; + $pre = BON without $pre; + $post = BOFF without $post; my %nameds = - |(%n:p), :$only, :$summary-if-larger-than; + |(%n:p), :$summary-if-larger-than; %nameds = $_ with $type; $trim @@ -720,15 +734,7 @@ my sub make-highlighter($needle, %n, %rak) { # No highlighting wanted, abuse highlighter logic anyway else { - $only - ?? $type - ?? -> $line { - highlighter $line, $needle, "", " ", :$only, :$type - } - !! -> $line { - highlighter $line, $needle, "", " ", :$only - } - !! $trim ?? *.Str.trim !! *.Str + $trim ?? *.Str.trim !! *.Str } } @@ -776,7 +782,7 @@ my sub handle-vimgrep($pattern, %n, %rak) { # Handle --modify-files my sub handle-modify-files($pattern, %n, %rak) { - my $dry-run := %n:delete; + my $dryrun := %n:delete; my $verbose := %n:delete; my $backup = %n:delete; @@ -784,7 +790,7 @@ my sub handle-modify-files($pattern, %n, %rak) { $backup = ".$backup" if $backup && !$backup.starts-with('.'); my constant no-changes = - "\n*** no changes where made because of --dry-run ***"; + "\n*** no changes where made because of --dryrun ***"; my @changed-files; my int $nr-files-seen; @@ -814,10 +820,10 @@ my sub handle-modify-files($pattern, %n, %rak) { $fb ~= " $removed removal&s($removed)" if $removed; $fb ~= "\n"; } - $fb ~= no-changes if $dry-run; + $fb ~= no-changes if $dryrun; $fb .= chomp; } - elsif $dry-run { + elsif $dryrun { $fb ~= no-changes; } @@ -836,7 +842,7 @@ my sub handle-modify-files($pattern, %n, %rak) { ++$lines-changed if .matched; } if $lines-changed || $lines-removed { - unless $dry-run { + unless $dryrun { if $backup { $io.spurt(@matches.map(*.value).join) if $io.rename($io.sibling($io.basename ~ $backup)); @@ -935,11 +941,26 @@ my multi sub MAIN(*@specs, *%n) { # *%_ causes compilation issues # Make sure needle is executable and create appropriate highlighter my &line-post-proc = *.Str; if Regex.ACCEPTS($needle) { - &line-post-proc = make-highlighter($needle, %n, %rak) + if %n:delete { + my $old-needle = $needle<>; + $needle = *.&matches($old-needle); + } + else { + &line-post-proc = make-highlighter($needle, %n, %rak) + } } elsif Callable.ACCEPTS($needle) { $is-simple-Callable = True; } + + # non-executable + elsif %n:delete { + my %nameds = %n:p; + $needle = %nameds + ?? *.&matches($pattern, |%nameds) + !! *.&matches($pattern) + } + # non-executable, create executable needle and highlighter else { $needle = needleify($pattern, %n); @@ -949,6 +970,7 @@ my multi sub MAIN(*@specs, *%n) { # *%_ causes compilation issues # Pass on any context settings %rak{.key} := .value for %n< context before-context after-context paragraph-context passthru-context + passthru >:delete:p; # Various setups @@ -992,7 +1014,7 @@ my multi sub MAIN(*@specs, *%n) { # *%_ causes compilation issues } # Want to know files without matches - if %n:delete { + elsif %n:delete { # Only interested in number of files if %n:delete { @@ -1051,7 +1073,6 @@ my multi sub MAIN(*@specs, *%n) { # *%_ causes compilation issues # Just find path names elsif %n:delete { %rak := True; - %rak := $_ with %n:delete; %rak = True; } @@ -1137,7 +1158,7 @@ my multi sub MAIN(*@specs, *%n) { # *%_ causes compilation issues if PairContext.ACCEPTS(@matches.head) { if $group-matches { sayer $source if $show-filename; - for @matches { + for @matches.map({ $_ if .value.elems }) { sayer .key ~ ':' ~ (.matched ?? line-post-proc .value !! .value.Str @@ -1148,7 +1169,7 @@ my multi sub MAIN(*@specs, *%n) { # *%_ causes compilation issues # Not grouping elsif $show-filename { - for @matches { + for @matches.map({ $_ if .value.elems }) { sayer $source ~ ':' ~ .key ~ ':' ~ (.matched @@ -1161,7 +1182,7 @@ my multi sub MAIN(*@specs, *%n) { # *%_ causes compilation issues # Not grouping and don't want to know the filename else { - for @matches { + for @matches.map({ $_ if .value.elems }) { sayer .key ~ ':' ~ (.matched ?? line-post-proc .value diff --git a/resources/help.txt b/resources/help.txt index f5466cc..1186dd6 100644 --- a/resources/help.txt +++ b/resources/help.txt @@ -37,6 +37,9 @@ Haystack specification: --recurse-symlinked-dir Recurse into symlinked directories? (default: don't) --recurse-unmatched-dir Recurse into directories not matching (default: don't) --under-version-control Only select paths that are under version control + --dir=expression Directory basename filter, default: not ^. + --file=expression File basename filter, default: all + --find-all Override --dir / --file defaults Filesystem filters: --blocks Number of filesystem blocks used by file diff --git a/resources/help/haystack.txt b/resources/help/haystack.txt index 1246944..9f67a9c 100644 --- a/resources/help/haystack.txt +++ b/resources/help/haystack.txt @@ -7,3 +7,7 @@ Haystack specification: --recurse-symlinked-dir Recurse into symlinked directories? (default: don't) --recurse-unmatched-dir Recurse into directories not matching (default: don't) --under-version-control Only select paths that are under version control + --dir=expression Directory basename filter, default: not ^. + --file=expression File basename filter, default: all + --find-all Override --dir / --file defaults + diff --git a/xt/02-simple.rakutest b/xt/02-simple.rakutest index a62eb0e..4d6ad1a 100644 --- a/xt/02-simple.rakutest +++ b/xt/02-simple.rakutest @@ -5,6 +5,7 @@ my constant BON = "\e[1m"; # BOLD ON my constant BOFF = "\e[22m"; # BOLD OFF my $dir = $*TMPDIR.add("App-Rak"); +my $dira = $dir.absolute ~ $*SPEC.dir-sep; my $rel := $dir.relative ~ $*SPEC.dir-sep; my $dot = $?FILE.IO.parent.parent; my $rak := $dot.add("bin").add("rak").relative; @@ -134,8 +135,8 @@ nine OK query-ok , ok => qq:to/OK/; -tw{BON}o{BOFF} -zer{BON}o{BOFF} +{$dira}tw{BON}o{BOFF} +{$dira}zer{BON}o{BOFF} OK query-ok q/{.uc if .contains("u")}/, :head(2), ok => q:to/OK/; @@ -428,16 +429,16 @@ my $uid := +$*USER; for "--user=$user", qq/--user=*eq"$user"/, "--user=$user,$user", "--uid=$uid", "--uid=*==$uid" { query-ok '--find', $_, ok => qq:to/OK/; -eight -five -four -nine -one -seven -six -three -two -zero +{$dira}eight +{$dira}five +{$dira}four +{$dira}nine +{$dira}one +{$dira}seven +{$dira}six +{$dira}three +{$dira}two +{$dira}zero OK } @@ -451,16 +452,16 @@ my $gid := +$*GROUP; for "--group=$group", qq/--group=*eq"$group"/, "--group=$group,$group", "--gid=$gid", "--gid=*==$gid" { query-ok '--find', $_, ok => qq:to/OK/; -eight -five -four -nine -one -seven -six -three -two -zero +{$dira}eight +{$dira}five +{$dira}four +{$dira}nine +{$dira}one +{$dira}seven +{$dira}six +{$dira}three +{$dira}two +{$dira}zero OK } @@ -497,6 +498,59 @@ for ( ok => "zero\0one\0two\0three\0four\0five\0six\0seven\0eight\0nine"; } +for '--per-file', q/--per-file=*.slurp/ { + query-ok , $_, :!head, ok => q:to/OK/; +nine:zero +one +two + +four +five +SIX +seven +eight +nine + +OK +} + +for '--per-file', q/--per-file=*.slurp/ { + query-ok '/ \w* v \w* /', $_, '--matches-only', :head(2), ok => q:to/OK/; +five +five + +six +five + +seven +five +seven + +eight +five +seven + +nine +five +seven +OK +} + +for '--per-file', q/--per-file=*.slurp/ { + query-ok '/ \w* v \w* /', $_, '--matches-only', '--unique', ok => q:to/OK/; +five +seven +OK +} + +for '--per-file', q/--per-file=*.slurp/ { + query-ok '/ \w* v \w* /', $_, '--matches-only', '--frequencies', + ok => q:to/OK/; +5:five +3:seven +OK +} + done-testing; # vim: expandtab shiftwidth=4