diff --git a/Changes b/Changes index 11863b4..77d40ac 100644 --- a/Changes +++ b/Changes @@ -2,6 +2,9 @@ Revision history for App-Rak {{$NEXT}} +0.0.32 2022-07-29T17:23:05+02:00 + - Add "paragraph-context" option to show paragraph around match + 0.0.31 2022-07-28T23:46:56+02:00 - Bump dependency on Git::Blame::File to get latest fixes - Add -blame-per-line option to filter on `git blame` objects diff --git a/META6.json b/META6.json index 1b386c1..04f681a 100644 --- a/META6.json +++ b/META6.json @@ -50,5 +50,5 @@ ], "test-depends": [ ], - "version": "0.0.31" + "version": "0.0.32" } diff --git a/README.md b/README.md index c407189..88af523 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ App::Rak provides a CLI called `rak` that allows you to look for a needle in (a To a large extent, the arguments are the same as with the `grep` utility provided on most Unixes. -Note: this is still very much in alpha development phase. Comments and suggestions are more than welcome! +Note: this is still very much in alpha development phase. Comments, suggestions and bug reports are more than welcome! POSITIONAL ARGUMENTS ==================== @@ -315,6 +315,11 @@ $ RAK_PAGER='more -r' rak foo $ rak foo --pager='less -r' ``` +--paragraph-context +------------------- + +Indicate all lines that are part of the same paragraph **around** any line that matches. Defaults to `False`. + --passthru ---------- diff --git a/lib/App/Rak.rakumod b/lib/App/Rak.rakumod index b949d19..b8e624f 100644 --- a/lib/App/Rak.rakumod +++ b/lib/App/Rak.rakumod @@ -119,29 +119,64 @@ my sub add-before-after($io, @initially-selected, int $before, int $after) { my int $last-linenr = @lines.end; my int8 @seen; - my @selected; + my $selected := IterationBuffer.CREATE; for @initially-selected { my int $linenr = .key; if $before { for max($linenr - $before, 1) ..^ $linenr -> int $_ { - @selected.push: + $selected.push: Pair.new($_, @lines.AT-POS($_) but delimiter('-')) unless @seen.AT-POS($_)++; } } - @selected.push: Pair.new(.key, .value but delimiter(':')) + $selected.push: Pair.new(.key, .value but delimiter(':')) unless @seen.AT-POS($linenr)++; if $after { for $linenr ^.. min($linenr + $after, $last-linenr ) -> int $_ { - @selected.push: + $selected.push: Pair.new($_, @lines.AT-POS($_) but delimiter('-')) unless @seen.AT-POS($_)++; } } } + $selected.List +} +# Add any lines until any paragraph boundary +my sub add-paragraph($io, @initially-selected) { + my str @lines = $io.lines(:enc<utf8-c8>); + @lines.unshift: ""; # make 1-base indexing natural + my int $last-linenr = @lines.end; + + my int8 @seen; + my @selected = @initially-selected.map: { + my int $linenr = .key; + my int $pos = $linenr; + my $selected := IterationBuffer.CREATE; + while --$pos + && !@seen.AT-POS($pos) + && @lines.AT-POS($pos) -> $line { + $selected.unshift: Pair.new($pos, $line but delimiter('-')); + } + + $selected.push: Pair.new(.key, .value but delimiter(':')) + unless @seen.AT-POS($linenr)++; + + if $linenr < $last-linenr { + $pos = $linenr; + while ++$pos < $last-linenr + && !@seen.AT-POS($pos) + && @lines.AT-POS($pos) -> $line { + $selected.push: + Pair.new($pos, $line but delimiter('-')); + } + $selected.push: + Pair.new($pos, @lines.AT-POS($pos) but delimiter('-')); + } + $selected.Slip + } @selected } @@ -652,11 +687,23 @@ my sub want-lines($needle, @paths, %_ --> Nil) { |named-args %_, :invert-match, :max-count, :type, :batch, :degree, ; - my UInt() $before = $_ with %_<before-context>:delete; - my UInt() $after = $_ with %_<after-context>:delete; - $before = $after = $_ with %_<context>:delete; + my Bool() $paragraph; + my UInt() $before; + my UInt() $after; + + if %_<paragraph-context>:delete { + $paragraph = True; + } + elsif %_<context>:delete -> $context { + $before = $after = $context; + } + else { + $before = $_ with %_<before-context>:delete; + $after = $_ with %_<after-context>:delete; + } $before = 0 without $before; $after = 0 without $after; + my $with-context = $paragraph || $before || $after; my Bool() $highlight; my Bool() $trim; @@ -673,7 +720,7 @@ my sub want-lines($needle, @paths, %_ --> Nil) { $highlight = !is-simple-Callable($needle); $break = $group-matches = $show-filename = $show-line-number = True; $only = $show-blame = False; - $trim = !($before || $after || is-simple-Callable($needle)); + $trim = !($with-context || is-simple-Callable($needle)); $summary-if-larger-than = 160; } @@ -694,13 +741,13 @@ my sub want-lines($needle, @paths, %_ --> Nil) { &show-line = $trim && !$show-blame ?? -> $line { highlighter $line.trim, $needle<>, $pre, $post, - :$ignorecase, :$ignoremark, :$only, - :$summary-if-larger-than + :$ignorecase, :$ignoremark, :$only, + :$summary-if-larger-than } !! -> $line { highlighter $line, $needle<>, $pre, $post, - :$ignorecase, :$ignoremark, :$only, - :$summary-if-larger-than + :$ignorecase, :$ignoremark, :$only, + :$summary-if-larger-than } ; } @@ -723,7 +770,6 @@ my sub want-lines($needle, @paths, %_ --> Nil) { $break = "" but True if Bool.ACCEPTS($break) || ($break.defined && !$break); } - my $before-or-after := $before || $after; my $show-header = $show-filename && $group-matches; $show-filename = False if $show-header; @@ -743,8 +789,10 @@ my sub want-lines($needle, @paths, %_ --> Nil) { say show-line(@blames[.key - 1].Str) for add-before-after($io, @matches, $before, $after); } - elsif $before-or-after { - my @selected := add-before-after($io, @matches, $before, $after); + elsif $with-context { + my @selected := $paragraph + ?? add-paragraph($io, @matches) + !! add-before-after($io, @matches, $before, $after); my $format := '%' ~ (@selected.tail.key.chars) ~ 'd'; if $show-line-number { for @selected { @@ -976,8 +1024,8 @@ in (a selection of files) from a given directory recursively. To a large extent, the arguments are the same as with the C<grep> utility provided on most Unixes. -Note: this is still very much in alpha development phase. Comments and -suggestions are more than welcome! +Note: this is still very much in alpha development phase. Comments, +suggestions and bug reports are more than welcome! =head1 POSITIONAL ARGUMENTS @@ -1323,6 +1371,11 @@ $ rak foo --pager='less -r' =end code +=head2 --paragraph-context + +Indicate all lines that are part of the same paragraph B<around> any line +that matches. Defaults to C<False>. + =head2 --passthru Indicate whether B<all> lines from source should be shown, even if they diff --git a/resources/help.txt b/resources/help.txt index 5ccedc1..fa32909 100644 --- a/resources/help.txt +++ b/resources/help.txt @@ -36,6 +36,7 @@ Result modifiers: --before-context=N List N lines before any line with a match --after-context=N List N lines after any line with a match --context=N List N lines around any line with a match + --paragraph-context List all lines in the same paragraph around a match --count-only Only return count of matches --files-with-matches Only return filenames with matches --file-separator-null Separate filenames with null bytes diff --git a/resources/help/result.txt b/resources/help/result.txt index c00b849..379a979 100644 --- a/resources/help/result.txt +++ b/resources/help/result.txt @@ -2,6 +2,7 @@ Result modifiers: --before-context=N List N lines before any line with a match --after-context=N List N lines after any line with a match --context=N List N lines around any line with a match + --paragraph-context List all lines in the same paragraph around a match --count-only Only return count of matches --files-with-matches Only return filenames with matches --file-separator-null Separate filenames with null bytes