From 93f74d5acb9fadad1a1eb88617d850151a8bf13e Mon Sep 17 00:00:00 2001 From: Dabrien 'Dabe' Murphy Date: Fri, 3 Dec 2021 21:26:02 -0500 Subject: [PATCH 1/2] Merge branch 'output-color' (Squashed) Squashed commit of the following: commit 1ffe7e4d9f9289fb7dead15dc502f809f4ed95e7 Author: Dabrien 'Dabe' Murphy Date: Fri Dec 3 19:48:42 2021 -0500 Implement 'output-color' Changes (TDD "Green") commit bbf6ca19b161685a27d45392e0d84e6d09492167 Author: Dabrien 'Dabe' Murphy Date: Fri Dec 3 19:47:11 2021 -0500 Add Desired (TDD "Red") 'output-color' Test commit 1fe31ee1671ed1c576a4480a4926db39d9ab37e9 Author: Dabrien 'Dabe' Murphy Date: Fri Dec 3 19:07:14 2021 -0500 Add Initial (Passing) `t/ack-output-color.t` Test NOTE: This serves to document *current* behavior --- ack | 19 +- t/ack-output-color.t | 442 +++++++++++++++++++++++++++++++++++++++++++ t/ack-output.t | 38 +++- 3 files changed, 489 insertions(+), 10 deletions(-) create mode 100644 t/ack-output-color.t diff --git a/ack b/ack index 6323d96c..729ed563 100755 --- a/ack +++ b/ack @@ -905,20 +905,23 @@ sub print_line_with_options { my @line_parts; if ( $opt_show_filename && defined($filename) ) { - my $colno; - $colno = get_match_colno() if $opt_column; + # Because you can't "local"-ize lexical variables... + my ( $_filename, $_lineno ) = ( $filename, $lineno ); + + my $_colno; + $_colno = get_match_colno() if $opt_column; if ( $opt_color ) { - $filename = Term::ANSIColor::colored( $filename, $ENV{ACK_COLOR_FILENAME} ); - $lineno = Term::ANSIColor::colored( $lineno, $ENV{ACK_COLOR_LINENO} ); - $colno = Term::ANSIColor::colored( $colno, $ENV{ACK_COLOR_COLNO} ) if $opt_column; + $_filename = Term::ANSIColor::colored( $_filename, $ENV{ACK_COLOR_FILENAME} ); + $_lineno = Term::ANSIColor::colored( $_lineno, $ENV{ACK_COLOR_LINENO} ); + $_colno = Term::ANSIColor::colored( $_colno, $ENV{ACK_COLOR_COLNO} ) if $opt_column; } if ( $opt_heading ) { - push @line_parts, $lineno; + push @line_parts, $_lineno; } else { - push @line_parts, $filename, $lineno; + push @line_parts, $_filename, $_lineno; } - push @line_parts, $colno if $opt_column; + push @line_parts, $_colno if $opt_column; } if ( $opt_output ) { diff --git a/t/ack-output-color.t b/t/ack-output-color.t new file mode 100644 index 00000000..407deb32 --- /dev/null +++ b/t/ack-output-color.t @@ -0,0 +1,442 @@ +#!perl + +use warnings; +use strict; + +use Test::More tests => 26; +use Term::ANSIColor qw(color); + +use lib 't'; +use Util; + +prep_environment(); + +my $CFN = color 'bold green'; +my $CRESET = color 'reset'; +my $CLN = color 'bold yellow'; +my $CM = color 'black on_yellow'; +my $LINE_END = "\e[0m\e[K"; + +DOLLAR_1: { + my @files = qw( t/text/ ); + my @args = qw/ --output=x$1x free(\\S+) --sort-files /; + + my @target_file = map { reslash($_) } qw( + t/text/bill-of-rights.txt + t/text/gettysburg.txt + ); + my @expected = ( + "$target_file[0]:4:xdomx", + "$target_file[1]:23:xdomx", + ); + + ack_sets_match( [ @args, @files ], \@expected, 'Find all the things with --output function' ); +} + + +DOLLAR_UNDERSCORE: { + my @expected = line_split( <<'HERE' ); +shall have a new birth of freedom -- and that government of the people,xshall have a new birth of freedom -- and that government of the people, +HERE + + my @files = qw( t/text/gettysburg.txt ); + my @args = qw( free --output=$_x$_ ); + my @results = run_ack_interactive( @args, @files ); + + lists_match( \@results, \@expected, 'Matching line' ); +} + + +ARG_MULTIPLE_FILES: { + # Note the first line is there twice because it matches twice. + # Blank lines are a result of '--break' being enabled by default + my @expected = line_split( <<'HERE' ); +or prohibiting the free exercise thereof; or abridging the freedom of +or prohibiting the free exercise thereof; or abridging the freedom of +A well regulated Militia, being necessary to the security of a free State, + +Number of free Persons, including those bound to Service for a Term + +shall have a new birth of freedom -- and that government of the people, +HERE + + my @files = qw( t/text ); + my @args = qw( free --sort-files -h --output=$_ ); + my @results = run_ack_interactive( @args, @files ); + + lists_match( \@results, \@expected, 'Matching line' ); +} + + +# Find a match in multiple files, and output it in double quotes. +DOUBLE_QUOTES: { + my @files = qw( t/text/ ); + my @args = ( '--output="$1"', '(free\\w*)', '--sort-files' ); + + my @target_file = map { reslash($_) } qw( + t/text/bill-of-rights.txt + t/text/constitution.txt + t/text/gettysburg.txt + ); + my @expected = ( + qq{$target_file[0]:4:"free"}, + qq{$target_file[0]:4:"freedom"}, + qq{$target_file[0]:10:"free"}, + qq{$target_file[1]:32:"free"}, + qq{$target_file[2]:23:"freedom"}, + ); + + ack_sets_match( [ @args, @files ], \@expected, 'Find all the things with --output function' ); +} + + +MATCH: { + my @expected = ( + 'free' + ); + + my @files = qw( t/text/gettysburg.txt ); + my @args = qw( free --output=$& ); + my @results = run_ack_interactive( @args, @files ); + + lists_match( \@results, \@expected, 'Part of a line matching pattern' ); +} + +MATCH_MULTIPLE_FILES: { + my @expected = line_split( <<"HERE" ); +${CFN}t/text/bill-of-rights.txt${CRESET} +${CLN}4${CRESET}:free +${CLN}4${CRESET}:free +${CLN}10${CRESET}:free + +${CFN}t/text/constitution.txt${CRESET} +${CLN}32${CRESET}:free + +${CFN}t/text/gettysburg.txt${CRESET} +${CLN}23${CRESET}:free +HERE + + my @files = qw ( t/text ); + my @args = qw( free --sort-files --output=$& ); + my @results = run_ack_interactive( @args, @files ); + + lists_match( \@results, \@expected, 'Part of a line matching pattern' ); +} + +PREMATCH: { + # No HEREDOC here since we do not want our editor/IDE messing with trailing whitespace. + my @expected = ( + 'shall have a new birth of ' + ); + + my @files = qw( t/text/gettysburg.txt ); + my @args = qw( freedom --output=$` ); + my @results = run_ack_interactive( @args, @files ); + + lists_match( \@results, \@expected, 'Part of a line preceding match' ); +} + +PREMATCH_MULTIPLE_FILES: { + # No HEREDOC here since we do not want our editor/IDE messing with trailing whitespace. + my @expected = ( + 'or prohibiting the free exercise thereof; or abridging the ', + '', + 'shall have a new birth of ' + ); + + my @files = qw( t/text/); + my @args = qw( freedom -h --sort-files --output=$` ); + my @results = run_ack_interactive( @args, @files ); + + lists_match( \@results, \@expected, 'Part of a line preceding match' ); +} + +POSTMATCH: { + my @expected = split( /\n/, <<'HERE' ); + -- and that government of the people, +HERE + + my @files = qw( t/text/gettysburg.txt ); + my @args = qw( freedom --output=$' ); + my @results = run_ack_interactive( @args, @files ); + + lists_match( \@results, \@expected, 'Part of a line that follows match' ); +} + +POSTMATCH_MULTIPLE_FILES: { + my @expected = line_split( <<'HERE' ); + of + + -- and that government of the people, +HERE + + my @files = qw( t/text/ ); + my @args = qw( freedom -h --sort-files --output=$' ); + my @results = run_ack_interactive( @args, @files ); + + lists_match( \@results, \@expected, 'Part of a line that follows match' ); +} + +SUBPATTERN_MATCH: { + my @expected = ( + 'love-God-Montresor' + ); + + my @files = qw( t/text/amontillado.txt ); + my @args = qw( (love).+(God).+(Montresor) --output=$1-$2-$3 ); + my @results = run_ack_interactive( @args, @files ); + + lists_match( \@results, \@expected, 'Capturing parentheses match' ); +} + +SUBPATTERN_MATCH_MULTIPLE_FILES: { + my @expected = line_split( <<'HERE' ); +the-free-exercise +a-free-State + +of-free-Persons +HERE + + my @files = qw( t/text/ ); + my @args = qw( (\w+)\s(free)\s(\w+) -h --sort-files --output=$1-$2-$3 ); + my @results = run_ack_interactive( @args, @files ); + + lists_match( \@results, \@expected, 'Capturing parentheses match' ); +} + +INPUT_LINE_NUMBER: { + my @expected = ( + 'line:15' + ); + + my @files = qw( t/text/bill-of-rights.txt ); + my @args = qw( quartered --output=line:$. ); + my @results = run_ack_interactive( @args, @files ); + + lists_match( \@results, \@expected, 'Line number' ); +} + +INPUT_LINE_NUMBER_MULTIPLE_FILES: { + my @expected = line_split( <<"HERE" ); +${CFN}t/text/bill-of-rights.txt${CRESET} +${CLN}4${CRESET}:line:4 +${CLN}4${CRESET}:line:4 +${CLN}10${CRESET}:line:10 + +${CFN}t/text/constitution.txt${CRESET} +${CLN}32${CRESET}:line:32 + +${CFN}t/text/gettysburg.txt${CRESET} +${CLN}23${CRESET}:line:23 +HERE + + my @files = qw( t/text/ ); + my @args = qw( free --sort-files --output=line:$. ); + my @results = run_ack_interactive( @args, @files ); + + lists_match( \@results, \@expected, 'Line number' ); +} + +LAST_PAREN_MATCH: { + my @expected = line_split( <<"HERE" ); +${CFN}t/text/amontillado.txt${CRESET} +${CLN}124${CRESET}:love +${CLN}309${CRESET}:love +${CLN}311${CRESET}:love + +${CFN}t/text/constitution.txt${CRESET} +${CLN}267${CRESET}:hate +HERE + + my @files = qw( t/text/ ); + my @args = qw( (love)|(hate) --sort-files --output=$+ ); + my @results = run_ack_interactive( @args, @files ); + + lists_match( \@results, \@expected, 'Last paren match' ); +} + + +COMBOS_1: { + my @expected = line_split( <<"HERE" ); +${CFN}t/text/amontillado.txt${CRESET} +${CLN}124${CRESET}:love-124-d; you are happy, +${CLN}309${CRESET}:love-309- of God, Montresor!" +${CLN}311${CRESET}:love-311- of God!" + +${CFN}t/text/constitution.txt${CRESET} +${CLN}267${CRESET}:hate-267-ver, from any King, Prince, or foreign State. +HERE + + my @files = qw( t/text/ ); + my @args = qw( (love)|(hate) --sort-files --output=$+-$.-$' ); + my @results = run_ack_interactive( @args, @files ); + + lists_match( \@results, \@expected, 'Combos 1' ); +} + + +COMBOS_2: { + my @expected = line_split( <<"HERE" ); +${CFN}t/text/amontillado.txt${CRESET} +${CLN}124${CRESET}:happy-happy-happy + +${CFN}t/text/raven.txt${CRESET} +${CLN}73${CRESET}:happy-happy-happy +HERE + + my @files = qw( t/text/ ); + my @args = qw( (happy) --sort-files -i --output=$1-$&-$1 ); + my @results = run_ack_interactive( @args, @files ); + + lists_match( \@results, \@expected, 'Combos 2' ); +} + + +COMBOS_3: { + my @expected = line_split( <<"HERE" ); +${CFN}t/text/amontillado.txt${CRESET} +${CLN}124${CRESET}:precious. You are rich, respected, admired, beloved; you are ---,--happy + +${CFN}t/text/raven.txt${CRESET} +${CLN}73${CRESET}:Caught from some un--- master whom unmerciful Disaster--happy +HERE + + my @files = qw( t/text/ ); + my @args = qw( (happy) --sort-files -i --output=$`---$'--$+ ); + my @results = run_ack_interactive( @args, @files ); + + lists_match( \@results, \@expected, 'Combos 2' ); +} + + +NUMERIC_SUBSTITUTIONS: { + # Make sure that substitutions don't affect future substitutions. + my @expected = line_split( <<"HERE" ); +${CFN}t/text/constitution.txt${CRESET} +${CLN}269${CRESET}:Section 10 on line 269 +HERE + + my @files = qw( t/text/bill-of-rights.txt t/text/constitution.txt ); + my @args = ( '(\d\d)', '--output=Section $1 on line $.' ); + my @results = run_ack_interactive( @args, @files ); + + lists_match( \@results, \@expected, 'Numeric substitutions' ); +} + + +CHARACTER_SUBSTITUTIONS: { + # Make sure that substitutions don't affect future substitutions. + my @expected = line_split( <<"HERE" ); +${CFN}t/text/bill-of-rights.txt${CRESET} +${CLN}15${CRESET}:No Soldier shall, in time of peace be +in any house, without\tin any house, without +HERE + + my @files = qw( t/text/ ); + my @args = ( '\s+quartered\s+(.+)', '--output=$`\n$1\t$1' ); + my @results = run_ack_interactive( @args, @files ); + + lists_match( \@results, \@expected, 'Character substitutions' ); +} + + +# $f is the filenname, needed for grep, emulating ack2 $filename:$lineno:$_ +FILENAME_SUBSTITUTION_1 : { + my @expected = line_split( <<'HERE' ); +t/text/ozymandias.txt:4:Half sunk, a shattered visage lies, whose frown, +HERE + + my @files = qw( t/text/ozymandias.txt ); + my @args = qw( visage --output=$f:$.:$_ ); + my @results = run_ack_interactive( @args, @files ); + + lists_match( \@results, \@expected, 'Filename with matching line' ); +} + + +FILENAME_SUBSTITUTION_2 : { + my @expected = line_split( <<'HERE' ); +t/text/ozymandias.txt:4:visage +HERE + + my @files = qw( t/text/ozymandias.txt ); + my @args = qw( visage --output=$f:$.:$& ); + my @results = run_ack_interactive( @args, @files ); + + lists_match( \@results, \@expected, 'Filename with match' ); +} + + +FILENAME_SUBSTITUTION_3 : { + my @expected = line_split( <<'HERE' ); +t/text/ozymandias.txt:4:visage +HERE + + my @files = qw( t/text/ozymandias.txt ); + my @args = qw( (visage) --output=$f:$.:$+ ); + my @results = run_ack_interactive( @args, @files ); + + lists_match( \@results, \@expected, 'Filename with last match' ); +} + +FILENAME_SUBSTITUTION_MULTIPLE : { + my @expected = line_split( <<"HERE" ); +${CFN}t/text/amontillado.txt${CRESET} +${CLN}3${CRESET}:t/text/amontillado.txt:3:The thousand injuries of Fortunato I had borne as I best could; but + +${CFN}t/text/constitution.txt${CRESET} +${CLN}38${CRESET}:t/text/constitution.txt:38:thirty Thousand, but each State shall have at Least one Representative; +${CLN}241${CRESET}:t/text/constitution.txt:241:Congress prior to the Year one thousand eight hundred and eight, but +${CLN}501${CRESET}:t/text/constitution.txt:501:which may be made prior to the Year One thousand eight hundred and eight + +${CFN}t/text/ozymandias.txt${CRESET} +${CLN}3${CRESET}:t/text/ozymandias.txt:3:Stand in the desert... Near them, on the sand, +${CLN}14${CRESET}:t/text/ozymandias.txt:14:The lone and level sands stretch far away. +HERE + + my @files = qw( t/text ); + my @args = qw( sand --output=$f:$.:$_ ); + my @results = run_ack_interactive( @args, @files ); + + lists_match( \@results, \@expected, 'Multiple files with matching line' ); +} + + +NO_SPECIALS_IN_OUTPUT_EXPRESSION : { + my @expected = line_split( <<'HERE' ); +literal +literal +HERE + + my @files = qw( t/text/ozymandias.txt ); + my @args = qw( sand --output=literal ); + my @results = run_ack_interactive( @args, @files ); + + lists_match( \@results, \@expected, 'Filename with last match' ); +} + +LITERAL_MULTIPLE_FILES : { + my @expected = line_split( <<"HERE" ); +${CFN}t/text/amontillado.txt${CRESET} +${CLN}3${CRESET}:literal + +${CFN}t/text/constitution.txt${CRESET} +${CLN}38${CRESET}:literal +${CLN}241${CRESET}:literal +${CLN}501${CRESET}:literal + +${CFN}t/text/ozymandias.txt${CRESET} +${CLN}3${CRESET}:literal +${CLN}14${CRESET}:literal +HERE + + my @files = qw( t/text ); + my @args = qw( sand --output=literal ); + my @results = run_ack_interactive( @args, @files ); + + lists_match( \@results, \@expected, 'Multiple files with literal replacement' ); +} + + +done_testing(); +exit 0; diff --git a/t/ack-output.t b/t/ack-output.t index e26dbb65..9958d31a 100644 --- a/t/ack-output.t +++ b/t/ack-output.t @@ -3,7 +3,7 @@ use warnings; use strict; -use Test::More tests => 46; +use Test::More tests => 50; use lib 't'; use Util; @@ -342,6 +342,23 @@ HERE lists_match( \@results, \@expected, 'Filename with last match' ); } +FILENAME_SUBSTITUTION_MULTIPLE : { + my @expected = line_split( <<'HERE' ); +t/text/amontillado.txt:3:t/text/amontillado.txt:3:The thousand injuries of Fortunato I had borne as I best could; but +t/text/constitution.txt:38:t/text/constitution.txt:38:thirty Thousand, but each State shall have at Least one Representative; +t/text/constitution.txt:241:t/text/constitution.txt:241:Congress prior to the Year one thousand eight hundred and eight, but +t/text/constitution.txt:501:t/text/constitution.txt:501:which may be made prior to the Year One thousand eight hundred and eight +t/text/ozymandias.txt:3:t/text/ozymandias.txt:3:Stand in the desert... Near them, on the sand, +t/text/ozymandias.txt:14:t/text/ozymandias.txt:14:The lone and level sands stretch far away. +HERE + + my @files = qw( t/text ); + my @args = qw( sand --output=$f:$.:$_ ); + my @results = run_ack( @args, @files ); + + lists_match( \@results, \@expected, 'Multiple files with matching line' ); +} + NO_SPECIALS_IN_OUTPUT_EXPRESSION : { my @expected = line_split( <<'HERE' ); @@ -353,7 +370,24 @@ HERE my @args = qw( sand --output=literal ); my @results = run_ack( @args, @files ); - lists_match( \@results, \@expected, 'Filename with last match' ); + lists_match( \@results, \@expected, 'Single file with literal replacement' ); +} + +LITERAL_MULTIPLE_FILES : { + my @expected = line_split( <<'HERE' ); +t/text/amontillado.txt:3:literal +t/text/constitution.txt:38:literal +t/text/constitution.txt:241:literal +t/text/constitution.txt:501:literal +t/text/ozymandias.txt:3:literal +t/text/ozymandias.txt:14:literal +HERE + + my @files = qw( t/text ); + my @args = qw( sand --output=literal ); + my @results = run_ack( @args, @files ); + + lists_match( \@results, \@expected, 'Multiple files with literal replacement' ); } From cfaedd744db8057b690eb86cefbaeb06559c8845 Mon Sep 17 00:00:00 2001 From: Dabrien 'Dabe' Murphy Date: Fri, 3 Dec 2021 21:36:34 -0500 Subject: [PATCH 2/2] Add `--no-lineno` Option to Omit Line Numbers Squashed commit of the following: commit 9f8ef37b9c81a6a386f8530eeb8cb5264b76f0f8 Author: Dabrien 'Dabe' Murphy Date: Fri Dec 3 20:26:10 2021 -0500 Make `--no-lineno` and `--column` Mutually Exclusive Turning line numbers off when you're showing "--column" output could lead to ambiguous results. commit 7a7736f06964aa19403d647647ed5efd4cfb5c73 Author: Dabrien 'Dabe' Murphy Date: Fri Dec 3 20:09:35 2021 -0500 Implement "--no-lineno" Functionality commit 1512fd0a872979b7b996e3d9be8fb47052e2a4dc Author: Dabrien 'Dabe' Murphy Date: Fri Dec 3 20:07:20 2021 -0500 Add Initial "--no-lineno" Option NOTE: Not Yet Implemented --- ack | 15 +++-- dev/crank-mutex | 2 +- dev/generate-completion-scripts.pl | 1 + lib/App/Ack.pm | 1 + lib/App/Ack/ConfigLoader.pm | 5 ++ t/Util.pm | 1 + t/ack-no-lineno.t | 101 +++++++++++++++++++++++++++++ t/mutex-options.t | 4 +- 8 files changed, 122 insertions(+), 8 deletions(-) create mode 100644 t/ack-no-lineno.t diff --git a/ack b/ack index 729ed563..b85913d4 100755 --- a/ack +++ b/ack @@ -41,6 +41,7 @@ our $opt_heading; our $opt_L; our $opt_l; our $opt_m; +our $opt_no_lineno; our $opt_output; our $opt_passthru; our $opt_p; @@ -144,6 +145,7 @@ MAIN: { $opt_L = $opt->{L}; $opt_l = $opt->{l}; $opt_m = $opt->{m}; + $opt_no_lineno = $opt->{no_lineno}; $opt_output = $opt->{output}; $opt_p = $opt->{p}; $opt_passthru = $opt->{passthru}; @@ -915,12 +917,8 @@ sub print_line_with_options { $_lineno = Term::ANSIColor::colored( $_lineno, $ENV{ACK_COLOR_LINENO} ); $_colno = Term::ANSIColor::colored( $_colno, $ENV{ACK_COLOR_COLNO} ) if $opt_column; } - if ( $opt_heading ) { - push @line_parts, $_lineno; - } - else { - push @line_parts, $_filename, $_lineno; - } + push @line_parts, $_filename unless $opt_heading; # We've already printed it... + push @line_parts, $_lineno unless $opt_no_lineno; push @line_parts, $_colno if $opt_column; } @@ -1460,6 +1458,11 @@ searched. Print a filename heading above each file's results. This is the default when used interactively. +=item B<--no-lineno> + +Suppress the prefixing of line numbers on output. Can't be combined with +B<--column>. + =item B<--help> Print a short help statement. diff --git a/dev/crank-mutex b/dev/crank-mutex index 505817db..92390df6 100755 --- a/dev/crank-mutex +++ b/dev/crank-mutex @@ -25,7 +25,7 @@ sub invalid_combinations { [qw(-h)] => [@file_lists], [qw(-H)] => [@file_lists], [qw(-c)] => [@context, @pretty, @fg, qw(--column)], - [qw(--column)] => [@file_lists], + [qw(--column)] => [@file_lists, qw(--no-lineno)], [@context] => [@file_lists], [qw(-f)] => [qw(-v)], [@fg] => [@fg, @pretty, qw(-x -c -u --files-from)], diff --git a/dev/generate-completion-scripts.pl b/dev/generate-completion-scripts.pl index 0b2c332b..3be38d55 100755 --- a/dev/generate-completion-scripts.pl +++ b/dev/generate-completion-scripts.pl @@ -50,6 +50,7 @@ '--match' => 'specify PATTERN explicitly', '--max-count' => 'stop reading after NUM matches', '--no-filename' => q{don't print filenames on output}, + '--no-lineno' => q{don't print line numbers on output}, '--noenv' => q{don't consider ackrc files/environment variables for configuration}, '--output' => 'output the evaluation of EXPR for each line', '--pager' => q{direct ack's output through PAGER}, diff --git a/lib/App/Ack.pm b/lib/App/Ack.pm index 7753534f..cec4e01c 100644 --- a/lib/App/Ack.pm +++ b/lib/App/Ack.pm @@ -258,6 +258,7 @@ Search output: -H, --with-filename Print the filename for each match (default: on unless explicitly searching a single file) -h, --no-filename Suppress the prefixing filename on output + --no-lineno Suppress the prefixing line number on output --[no]column Show the column number of the first match -A NUM, --after-context=NUM Print NUM lines of trailing context after diff --git a/lib/App/Ack/ConfigLoader.pm b/lib/App/Ack/ConfigLoader.pm index 47389ee6..51c42408 100644 --- a/lib/App/Ack/ConfigLoader.pm +++ b/lib/App/Ack/ConfigLoader.pm @@ -296,6 +296,7 @@ sub get_arg_spec { 'heading!' => \$opt->{heading}, 'h|no-filename' => \$opt->{h}, 'H|with-filename' => \$opt->{H}, + 'no-lineno' => \$opt->{no_lineno}, 'i|ignore-case' => sub { $opt->{i} = 1; $opt->{S} = 0; }, 'I|no-ignore-case' => sub { $opt->{i} = 0; $opt->{S} = 0; }, 'ignore-directory|ignore-dir=s' => _generate_ignore_dir('--ignore-dir', $opt), @@ -949,6 +950,7 @@ sub mutex_options { f => 1, g => 1, l => 1, + 'no-lineno' => 1, o => 1, output => 1, passthru => 1, @@ -1067,6 +1069,9 @@ sub mutex_options { L => 1, l => 1, }, + 'no-lineno' => { + column => 1, + }, o => { A => 1, B => 1, diff --git a/t/Util.pm b/t/Util.pm index 612a6370..e0ccb5ca 100644 --- a/t/Util.pm +++ b/t/Util.pm @@ -864,6 +864,7 @@ sub get_expected_options { '--match', '--max-count', '--no-filename', + '--no-lineno', '--no-recurse', '--nobreak', '--nocolor', diff --git a/t/ack-no-lineno.t b/t/ack-no-lineno.t new file mode 100644 index 00000000..87582e44 --- /dev/null +++ b/t/ack-no-lineno.t @@ -0,0 +1,101 @@ +#!perl + +use strict; +use warnings; + +use Test::More tests => 8; + +use lib 't'; +use Util; + +prep_environment(); + +INTERACTIVE_MULTIPLE_FILES: { + my @args = qw( --no-lineno --no-color strict ); + my @files = qw( t/swamp/options.pl t/swamp/pipe-stress-freaks.F ); + + my $target_file = reslash( 't/swamp/options.pl' ); + my @expected = line_split( <<"HERE" ); +$target_file +use strict; +HERE + + my @results = run_ack_interactive( @args, @files ); + + lists_match( \@results, \@expected, 'Looking for strict interactively in multiple files' ); +} + +INTERACTIVE_MULTIPLE_FILES_NO_HEADING: { + my @args = qw( --no-lineno --no-heading --no-color strict ); + my @files = qw( t/swamp/options.pl t/swamp/pipe-stress-freaks.F ); + + my $target_file = reslash( 't/swamp/options.pl' ); + my @expected = line_split( <<"HERE" ); +$target_file:use strict; +HERE + + my @results = run_ack_interactive( @args, @files ); + + lists_match( \@results, \@expected, 'Looking for strict interactively in multiple files with --no-heading' ); +} + +INTERACTIVE_ONE_FILE: { + my @args = ( qw( --no-lineno --with-filename --no-color strict ) ); + my @files = qw( t/swamp/options.pl ); + + my $target_file = reslash( 't/swamp/options.pl' ); + my @expected = line_split( <<"HERE" ); +$target_file +use strict; +HERE + + my @results = run_ack_interactive( @args, @files ); + + lists_match( \@results, \@expected, 'Looking for strict interactively in one file with filename' ); +} + +INTERACTIVE_ONE_FILE_NO_HEADING: { + my @args = ( qw( --no-lineno --with-filename --no-heading --no-color strict ) ); + my @files = qw( t/swamp/options.pl ); + + my $target_file = reslash( 't/swamp/options.pl' ); + my @expected = line_split( <<"HERE" ); +$target_file:use strict; +HERE + + my @results = run_ack_interactive( @args, @files ); + + lists_match( \@results, \@expected, 'Looking for strict interactively in one file with filename and --no-heading' ); +} + +NON_INTERACTIVE_MULTIPLE_FILES: { + my @args = qw( --no-lineno strict ); + my @files = qw( t/swamp/options.pl t/swamp/pipe-stress-freaks.F ); + + my $target_file = reslash( 't/swamp/options.pl' ); + my @expected = line_split( <<"HERE" ); +$target_file:use strict; +HERE + + my @results = run_ack( @args, @files ); + + lists_match( \@results, \@expected, 'Looking for strict in multiple files' ); +} + +NON_INTERACTIVE_ONE_FILE: { + my @args = ( qw( --no-lineno --with-filename strict ) ); + my @files = qw( t/swamp/options.pl ); + + my $target_file = reslash( 't/swamp/options.pl' ); + my @expected = line_split( <<"HERE" ); +$target_file:use strict; +HERE + + my @results = run_ack( @args, @files ); + + lists_match( \@results, \@expected, 'Looking for strict in one file with filename' ); +} + +done_testing(); + +exit 0; diff --git a/t/mutex-options.t b/t/mutex-options.t index b580a7c3..804749f4 100644 --- a/t/mutex-options.t +++ b/t/mutex-options.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 196; +use Test::More tests => 197; use lib 't'; use Util; @@ -159,6 +159,8 @@ for my $opt ( qw( -c --count ) ) { are_mutually_exclusive( $opt, '-g', [ $opt, '-g', $word, $file ] ); } +are_mutually_exclusive('--column', '--no-lineno', ['--column', '--no-lineno', $word, $file]); + # -A/-B/-C/--after-context/--before-context/--context for my $opt ( qw( -A -B -C --after-context --before-context --context ) ) { are_mutually_exclusive( $opt, '-f', [$opt, 1, '-f', $word, $file] );