3 # This file, ack, is generated code.
4 # Please DO NOT EDIT or send patches for it.
6 # Please take a look at the source from
7 # http://github.com/petdance/ack2
8 # and submit patches against the individual files
18 our $VERSION = '1.12';
24 our $name; # name of the current file
25 our $dir; # dir of the current file
33 descend_filter
=> undef,
34 error_handler
=> sub { CORE
::die @_ },
35 warning_handler
=> sub { CORE
::warn @_ },
40 %skip_dirs = map {($_,1)} (File
::Spec-
>curdir, File
::Spec-
>updir);
45 die _bad_invocation
() if @_ && defined($_[0]) && ($_[0] eq __PACKAGE__
);
47 my ($parms,@queue) = _setup
( \
%files_defaults, @_ );
48 my $filter = $parms->{file_filter
};
52 my ($dirname,$file,$fullpath) = splice( @queue, 0, 3 );
53 if ( -f
$fullpath || -p
$fullpath || $fullpath =~ m{^/dev/fd} ) {
56 local $File::Next
::dir
= $dirname;
57 local $File::Next
::name
= $fullpath;
58 next if not $filter->();
60 return wantarray ? ($dirname,$file,$fullpath) : $fullpath;
63 unshift( @queue, _candidate_files
( $parms, $fullpath ) );
77 die _bad_invocation
() if @_ && defined($_[0]) && ($_[0] eq __PACKAGE__
);
79 my ($parms,@queue) = _setup
( \
%files_defaults, @_ );
80 my $err = $parms->{error_handler
};
81 my $warn = $parms->{error_handler
};
83 my $filename = $queue[1];
85 if ( !defined($filename) ) {
86 $err->( 'Must pass a filename to from_file()' );
91 if ( $filename eq '-' ) {
95 if ( !open( $fh, '<', $filename ) ) {
96 $err->( "Unable to open $filename: $!" );
100 my $filter = $parms->{file_filter
};
103 local $/ = $parms->{nul_separated
} ? "\x00" : $/;
104 while ( my $fullpath = <$fh> ) {
106 next unless $fullpath =~ /./;
107 if ( not ( -f
$fullpath || -p _
) ) {
108 $warn->( "$fullpath: No such file" );
112 my ($volume,$dirname,$file) = File
::Spec-
>splitpath( $fullpath );
115 local $File::Next
::dir
= $dirname;
116 local $File::Next
::name
= $fullpath;
117 next if not $filter->();
119 return wantarray ? ($dirname,$file,$fullpath) : $fullpath;
127 sub _bad_invocation
{
128 my $good = (caller(1))[3];
130 $bad =~ s/(.+)::/$1->/;
131 return "$good must not be invoked as $bad";
134 sub sort_standard
($$) { return $_[0]->[1] cmp $_[1]->[1] }
135 sub sort_reverse
($$) { return $_[1]->[1] cmp $_[0]->[1] }
140 my @parts = split( /\//, $path );
142 return $path if @parts < 2;
144 return File
::Spec-
>catfile( @parts );
150 my $defaults = shift;
151 my $passed_parms = ref $_[0] eq 'HASH' ? {%{+shift}} : {}; # copy parm hash
153 my %passed_parms = %{$passed_parms};
156 for my $key ( keys %{$defaults} ) {
158 exists $passed_parms{$key}
159 ? delete $passed_parms{$key}
163 # Any leftover keys are bogus
164 for my $badkey ( keys %passed_parms ) {
165 my $sub = (caller(1))[3];
166 $parms->{error_handler
}->( "Invalid option passed to $sub(): $badkey" );
169 # If it's not a code ref, assume standard sort
170 if ( $parms->{sort_files
} && ( ref($parms->{sort_files
}) ne 'CODE' ) ) {
171 $parms->{sort_files
} = \
&sort_standard
;
176 my $start = reslash
( $_ );
178 push @queue, ($start,undef,$start);
181 push @queue, (undef,$start,$start);
185 return ($parms,@queue);
189 sub _candidate_files
{
194 if ( !opendir $dh, $dirname ) {
195 $parms->{error_handler
}->( "$dirname: $!" );
200 my $descend_filter = $parms->{descend_filter
};
201 my $follow_symlinks = $parms->{follow_symlinks
};
202 my $sort_sub = $parms->{sort_files
};
204 for my $file ( grep { !exists $skip_dirs{$_} } readdir $dh ) {
207 # Only do directory checking if we have a descend_filter
208 my $fullpath = File
::Spec-
>catdir( $dirname, $file );
209 if ( !$follow_symlinks ) {
210 next if -l
$fullpath;
214 if ( $descend_filter ) {
215 if ( $has_stat ? (-d _
) : (-d
$fullpath) ) {
216 local $File::Next
::dir
= $fullpath;
218 next if not $descend_filter->();
222 push( @newfiles, [ $dirname, $file, $fullpath ] );
225 push( @newfiles, $dirname, $file, $fullpath );
231 return map { @{$_} } sort $sort_sub @newfiles;
238 1; # End of File::Next
250 $COPYRIGHT = 'Copyright 2005-2013 Andy Lester.';
251 $GIT_REVISION = q{af91cce};
273 use File
::Spec
1.00015 ();
276 # These have to be checked before any filehandle diddling.
277 $output_to_pipe = not -t
*STDOUT
;
278 $is_filter_mode = -p STDIN
;
280 $is_cygwin = ($^O eq 'cygwin');
281 $is_windows = ($^O eq 'MSWin32');
282 $dir_sep_chars = $is_windows ? quotemeta( '\\/' ) : quotemeta( File
::Spec-
>catfile( '', '' ) );
289 $path =~ s/[$dir_sep_chars]$//;
297 return CORE
::warn( _my_program
(), ': ', @_, "\n" );
302 return CORE
::die( _my_program
(), ': ', @_, "\n" );
306 require File
::Basename
;
307 return File
::Basename
::basename
( $0 );
312 sub filetypes_supported
{
313 return keys %mappings;
317 my $y = q{_ /|,\\'!.x',=(www)=, U };
318 $y =~ tr/,x!w/\nOo_/;
323 my $y = _get_thpppt
();
324 App
::Ack
::print( "$y ack $_[0]!\n" );
332 3~!I#7#I"7#I!?!+!="+"="+!:!
333 2?#I!7!I!?#I!7!I"+"=%+"=#
334 1?"+!?*+!=#~"=!+#?"="+!
335 0?"+!?"I"?&+!="~!=!~"=!+%="+"
336 /I!+!?)+!?!+!=$~!=!~!="+!="+"?!="?!
338 ,,!?%I"?(+$=$~!=#:"~$:!~!
339 ,I!?!I!?"I"?!+#?"+!?!+#="~$:!~!:!~!:!,!:!,":#~!
340 +I!?&+!="+!?#+$=!~":!~!:!~!:!,!:#,!:!,%:"
341 *+!I!?!+$=!+!=!+!?$+#=!~":!~":#,$:",#:!,!:!
342 *I!?"+!?!+!=$+!?#+#=#~":$,!:",!:!,&:"
343 )I!?$=!~!=#+"?!+!=!+!=!~!="~!:!~":!,'.!,%:!~!
344 (=!?"+!?!=!~$?"+!?!+!=#~"=",!="~$,$.",#.!:!=!
345 (I"+"="~"=!+&=!~"=!~!,!~!+!=!?!+!?!=!I!?!+"=!.",!.!,":!
346 %I$?!+!?!=%+!~!+#~!=!~#:#=!~!+!~!=#:!,%.!,!.!:"
347 $I!?!=!?!I!+!?"+!=!~!=!~!?!I!?!=!+!=!~#:",!~"=!~!:"~!=!:",&:" '-/
348 $?!+!I!?"+"=!+"~!,!:"+#~#:#,"=!~"=!,!~!,!.",!:".!:! */! !I!t!'!s! !a! !g!r!e!p!!! !/!
349 $+"=!+!?!+"~!=!:!~!:"I!+!,!~!=!:!~!,!:!,$:!~".&:"~!,# (-/
350 %~!=!~!=!:!.!+"~!:!,!.!,!~!=!:$.!,":!,!.!:!~!,!:!=!.#="~!,!:" ./!
351 %=!~!?!+"?"+!=!~",!.!:!?!~!.!:!,!:!,#.!,!:","~!:!=!~!=!:",!~! ./!
352 %+"~":!~!=#~!:!~!,!.!~!:",!~!=!~!.!:!,!.",!:!,":!=":!.!,!:!7! -/!
353 %~",!:".#:!=!:!,!:"+!:!~!:!.!,!~!,!.#,!.!,$:"~!,":"~!=! */!
354 &=!~!=#+!=!~",!.!:",#:#,!.",+:!,!.",!=!+!?!
355 &~!=!~!=!~!:"~#:",!.!,#~!:!.!+!,!.",$.",$.#,!+!I!?!
356 &~!="~!:!~":!~",!~!=!~":!,!:!~!,!:!,&.$,#."+!?!I!?!I!
357 &~!=!~!=!+!,!:!~!:!=!,!:!~&:$,!.!,".!,".!,#."~!+!?$I!
358 &~!=!~!="~!=!:!~":!,!~%:#,!:",!.!,#.",#I!7"I!?!+!?"I"
359 &+!I!7!:#~"=!~!:!,!:"~$.!=!.!,!~!,$.#,!~!7!I#?!+!?"I"7!
360 %7#?!+!~!:!=!~!=!~":!,!:"~":#.!,)7#I"?"I!7&
361 %7#I!=":!=!~!:"~$:"~!:#,!:!,!:!~!:#,!7#I!?#7)
362 $7$+!,!~!=#~!:!~!:!~$:#,!.!~!:!=!,":!7#I"?#7+=!?!
363 $7#I!~!,!~#=!~!:"~!:!,!:!,#:!=!~",":!7$I!?#I!7*+!=!+"
364 "I!7$I!,":!,!.!=":$,!:!,$:$7$I!+!?"I!7+?"I!7!I!7!,!
365 !,!7%I!:",!."~":!,&.!,!:!~!I!7$I!+!?"I!7,?!I!7',!
366 !7(,!.#~":!,%.!,!7%I!7!?#I"7,+!?!7*
367 7+:!,!~#,"=!7'I!?#I"7/+!7+
377 0|! "C!H!O!C!O!L!A!T!E!!! !|!
378 0|! "C!H!O!C!O!L!A!T!E!!! !|!
379 0|! "C!H!O!C!O!L!A!T!E!!! !|!
385 4.! $\! /M!~!.!8! +.!M# 4
386 0,!.! (\! .~!M!N! ,+!I!.!M!.! 3
387 /?!O!.!M!:! '\! .O!.! +~!Z!=!N!.! 4
388 ..! !D!Z!.!Z!.! '\! 9=!M".! 6
389 /.! !.!~!M".! '\! 8~! 9
391 4.! &:!M! !N"M# !M"N!M! #D!M&=! =
392 :M!7!M#:! !~!M!7!,!$!M!:! #.! !O!N!.!M!:!M# ;
393 8Z!M"~!N!$!D!.!N!?! !I!N!.! (?!M! !M!,!D!M".! 9
394 (?!Z!M!N!:! )=!M!O!8!.!M!+!M! !M!,! !O!M! +,!M!.!M!~!Z!N!M!:! &:!~! 0
395 &8!7!.!~!M"D!M!,! &M!?!=!8! !M!,!O! !M!+! !+!O!.!M! $M#~! !.!8!M!Z!.!M! !O!M"Z! %:!~!M!Z!M!Z!.! +
396 &:!M!7!,! *M!.!Z!M! !8"M!.!M!~! !.!M!.!=! #~!8!.!M! !7!M! "N!Z#I! !D!M!,!M!.! $."M!,! !M!.! *
397 2$!O! "N! !.!M!I! !7" "M! "+!O! !~!M! !d!O!.!7!I!M!.! !.!O!=!M!.! !M",!M!.! %.!$!O!D! +
398 1~!O! "M!+! !8!$! "M! "?!O! %Z!8!D!M!?!8!I!O!7!M! #M!.!M! "M",!M! 4
399 07!~! ".!8! !.!M! "I!+! !.!M! &Z!D!.!7!=!M! !:!.!M! #:!8"+! !.!+!8! !8! 3
400 /~!M! #N! !~!M!$! !.!M! !.!M" &~!M! "~!M!O! "D! $M! !8! "M!,!M!+!D!.! 1
401 #.! #?!M!N!.! #~!O! $M!.!7!$! "?" !?!~!M! '7!8!?!M!.!+!M"O! $?"$!D! !.!O! !$!7!I!.! 0
402 $,!M!:!O!?! ".! !?!=! $=!:!O! !M! "M! !M! !+!$! (.! +.!M! !M!.! !8! !+"Z!~! $:!M!$! !.! '
403 #.!8!.!I!$! $7!I! %M" !=!M! !~!M!D! "7!I! .I!O! %?!=!,!D! !,!M! !D!~!8!~! %D!M! (
404 #.!M"?! $=!O! %=!N! "8!.! !Z!M! #M!~! (M!:! #.!M" &O! !M!.! !?!,! !8!.!N!~! $8!N!M!,!.! %
405 *$!O! &M!,! "O! !.!M!.! #M! (~!M( &O!.! !7! "M! !.!M!.!M!,! #.!M! !M! &
406 )=!8!.! $.!M!O!.! "$!.!I!N! !I!M# (7!M(I! %D"Z!M! "=!I! "M! !M!:! #~!D! '
407 )D! &8!N!:! ".!O! !M!="M! "M! (7!M) %." !M!D!."M!.! !$!=! !M!,! +
408 (M! &+!.!M! #Z!7!O!M!.!~!8! +,!M#D!?!M#D! #.!Z!M#,!Z!?! !~!N! "N!.! !M! +
409 'D!:! %$!D! !?! #M!Z! !8!.! !M"?!7!?!7! '+!I!D! !?!O!:!M!:! ":!M!:! !M!7".!M! "8!+! !:!D! !.!M! *
410 %.!O!:! $.!O!+! !D!.! #M! "M!.!+!N!I!Z! "7!M!N!M!N!?!I!7!Z!=!M'D"~! #M!.!8!$! !:! !.!M! "N!?! !,!O! )
411 !.!?!M!:!M!I! %8!,! "M!.! #M! "N! !M!.! !M!.! !+!~! !.!M!.! ':!M! $M! $M!Z!$! !M!.! "D! "M! "?!M! (
412 !7!8! !+!I! ".! "$!=! ":!$! "+! !M!.! !O! !M!I!M".! !=!~! ",!O! '=!M! $$!,! #N!:! ":!8!.! !D!~! !,!M!.! !:!M!.! &
413 !:!,!.! &Z" #D! !.!8!."M!.! !8!?!Z!M!.!M! #Z!~! !?!M!Z!.! %~!O!.!8!$!N!8!O!I!:!~! !+! #M!.! !.!M!.! !+!M! ".!~!M!+! $
414 !.! 'D!I! #?!M!.!M!,! !.!Z! !.!8! #M&O!I!?! (~!I!M"." !M!Z!.! !M!N!.! "+!$!.! "M!.! !M!?!.! "8!M! $
415 (O!8! $M! !M!.! ".!:! !+!=! #M! #.!M! !+" *$!M":!.! !M!~! "M!7! #M! #7!Z! "M"$!M!.! !.! #
416 '$!Z! #.!7!+!M! $.!,! !+!:! #N! #.!M!.!+!M! +D!M! #=!N! ":!O! #=!M! #Z!D! $M!I! %
417 $,! ".! $.!M" %$!.! !?!~! "+!7!." !.!M!,! !M! *,!N!M!.$M!?! "D!,! #M!.! #N! +
418 ,M!Z! &M! "I!,! "M! %I!M! !?!=!.! (Z!8!M! $:!M!.! !,!M! $D! #.!M!.! )
419 +8!O! &.!8! "I!,! !~!M! &N!M! !M!D! '?!N!O!." $?!7! "?!~! #M!.! #I!D!.! (
420 3M!,! "N!.! !D" &.!+!M!.! !M":!.":!M!7!M!D! 'M!.! "M!.! "M!,! $I! )
421 3I! #M! "M!,! !:! &.!M" ".!,! !.!$!M!I! #.! !:! !.!M!?! "N!+! ".! /
422 1M!,! #.!M!8!M!=!.! +~!N"O!Z"~! *+!M!.! "M! 2
423 0.!M! &M!.! 8:! %.!M!Z! "M!=! *O!,! %
424 0?!$! &N! )." .,! %."M! ":!M!.! 0
425 0N!:! %?!O! #.! ..! &,! &.!D!,! "N!I! 0
431 my($compressed) = @_;
432 $compressed =~ s/(.)(.)/$1x(ord($2)-32)/eg;
433 App
::Ack
::print( $compressed );
439 my $help_arg = shift || 0;
441 return show_help_types
() if $help_arg =~ /^types?/;
443 App
::Ack
::print( <<"END_OF_HELP" );
444 Usage: ack [OPTION]... PATTERN [FILES OR DIRECTORIES]
446 Search for PATTERN in each source file in the tree from the current
447 directory on down. If any files or directories are specified, then
448 only those files and directories are checked. ack may also search
449 STDIN, but only if no file or directory arguments are specified,
450 or if one of them is "-".
452 Default switches may be specified in ACK_OPTIONS environment variable or
453 an .ackrc file. If you want no dependency on the environment, turn it
456 Example: ack -i select
459 -i, --ignore-case Ignore case distinctions in PATTERN
460 --[no]smart-case Ignore case distinctions in PATTERN,
461 only if PATTERN contains no upper case.
462 Ignored if -i is specified
463 -v, --invert-match Invert match: select non-matching lines
464 -w, --word-regexp Force PATTERN to match only whole words
465 -Q, --literal Quote all metacharacters; PATTERN is literal
468 --lines=NUM Only print line(s) NUM of each file
469 -l, --files-with-matches Only print filenames containing matches
470 -L, --files-without-matches Only print filenames with no matches
471 --output=expr Output the evaluation of expr for each line
472 (turns off text highlighting)
473 -o Show only the part of a line matching PATTERN
474 Same as --output='\$&'
475 --passthru Print all lines, whether matching or not
476 --match PATTERN Specify PATTERN explicitly.
477 -m, --max-count=NUM Stop searching in each file after NUM matches
478 -1 Stop searching after one match of any kind
479 -H, --with-filename Print the filename for each match (default:
480 on unless explicitly searching a single file)
481 -h, --no-filename Suppress the prefixing filename on output
482 -c, --count Show number of lines matching per file
483 --[no]column Show the column number of the first match
485 -A NUM, --after-context=NUM Print NUM lines of trailing context after
487 -B NUM, --before-context=NUM Print NUM lines of leading context before
489 -C [NUM], --context[=NUM] Print NUM lines (default 2) of output context.
491 --print0 Print null byte as separator between filenames,
492 only works with -f, -g, -l, -L or -c.
494 -s Suppress error messages about nonexistent or
499 --pager=COMMAND Pipes all ack output through COMMAND. For
500 example, --pager="less -R". Ignored if output
502 --nopager Do not send output through a pager. Cancels
503 any setting in ~/.ackrc, ACK_PAGER or
505 --[no]heading Print a filename heading above each file's
506 results. (default: on when used interactively)
507 --[no]break Print a break between results from different
508 files. (default: on when used interactively)
509 --group Same as --heading --break
510 --nogroup Same as --noheading --nobreak
511 --[no]color Highlight the matching text (default: on unless
512 output is redirected, or on Windows)
513 --[no]colour Same as --[no]color
514 --color-filename=COLOR
516 --color-lineno=COLOR Set the color for filenames, matches, and line
518 --flush Flush output immediately, even when ack is used
519 non-interactively (when output goes to a pipe or
524 -f Only print the files selected, without
525 searching. The PATTERN must not be specified.
526 -g Same as -f, but only select files matching
528 --sort-files Sort the found files lexically.
529 --show-types Show which types each file has.
530 --files-from=FILE Read the list of files to search from FILE.
531 -x Read the list of files to search from STDIN.
533 File inclusion/exclusion:
534 --[no]ignore-dir=name Add/remove directory from list of ignored dirs
535 --[no]ignore-directory=name Synonym for ignore-dir
536 --ignore-file=filter Add filter for ignoring files
537 -r, -R, --recurse Recurse into subdirectories (default: on)
538 -n, --no-recurse No descending into subdirectories
539 --[no]follow Follow symlinks. Default is off.
540 -k, --known-types Include only files of types that ack recognizes.
542 --type=X Include only X files, where X is a recognized
544 --type=noX Exclude X files.
545 See "ack --help-types" for supported filetypes.
547 File type specification:
548 --type-set TYPE:FILTER:FILTERARGS
549 Files with the given FILTERARGS applied to the
550 given FILTER are recognized as being of type
551 TYPE. This replaces an existing definition for
553 --type-add TYPE:FILTER:FILTERARGS
554 Files with the given FILTERARGS applied to the
555 given FILTER are recognized as being type TYPE.
556 --type-del TYPE Removes all filters associated with TYPE.
560 --[no]env Ignore environment variables and global ackrc
561 files. --env is legal but redundant.
562 --ackrc=filename Specify an ackrc file to use
563 --ignore-ack-defaults Ignore default definitions included with ack.
564 --create-ackrc Outputs a default ackrc for your customization
567 --help-types Display all known types
568 --dump Dump information on which options are loaded
570 --[no]filter Force ack to treat standard input as a pipe
571 (--filter) or tty (--nofilter)
573 --version Display version & copyright
574 --thpppt Bill the Cat
575 --bar The warning admiral
576 --cathy Chocolate! Chocolate! Chocolate!
578 Exit status is 0 if match, 1 if no match.
580 This is version $VERSION of ack.
588 sub show_help_types
{
589 App
::Ack
::print( <<'END_OF_HELP' );
590 Usage: ack [OPTION]... PATTERN [FILES OR DIRECTORIES]
592 The following is the list of filetypes supported by ack. You can
593 specify a file type with the --type=TYPE format, or the --TYPE
594 format. For example, both --type=perl and --perl work.
596 Note that some extensions may appear in multiple types. For example,
597 .pod files are both Perl and Parrot.
601 my @types = filetypes_supported
();
604 $maxlen = length if $maxlen < length;
606 for my $type ( sort @types ) {
607 next if $type =~ /^-/; # Stuff to not show
608 my $ext_list = $mappings{$type};
610 if ( ref $ext_list ) {
611 $ext_list = join( '; ', map { $_->to_string } @{$ext_list} );
613 App
::Ack
::print( sprintf( " --[no]%-*.*s %s\n", $maxlen, $maxlen, $type, $ext_list ) );
622 Pod
::Usage
::pod2usage
({
623 -input
=> $App::Ack
::orig_program_name
,
632 sub get_version_statement
{
635 my $copyright = get_copyright
();
636 my $this_perl = $Config::Config
{perlpath
};
638 my $ext = $Config::Config
{_exe
};
639 $this_perl .= $ext unless $this_perl =~ m/$ext$/i;
641 my $ver = sprintf( '%vd', $^V );
643 my $git_revision = $GIT_REVISION ? " (git commit $GIT_REVISION)" : '';
645 return <<"END_OF_VERSION";
646 ack ${VERSION}${git_revision}
647 Running under Perl $ver at $this_perl
651 This program is free software. You may modify or distribute it
652 under the terms of the Artistic License v2.0.
657 sub print_version_statement
{
658 App
::Ack
::print( get_version_statement
() );
669 # print subs added in order to make it easy for a third party
670 # module (such as App::Wack) to redefine the display methods
671 # and show the results in a different way.
672 sub print { print {$fh} @_; return; }
673 sub print_first_filename
{ App
::Ack
::print( $_[0], "\n" ); return; }
674 sub print_blank_line
{ App
::Ack
::print( "\n" ); return; }
675 sub print_separator
{ App
::Ack
::print( "--\n" ); return; }
676 sub print_filename
{ App
::Ack
::print( $_[0], $_[1] ); return; }
677 sub print_line_no
{ App
::Ack
::print( $_[0], $_[1] ); return; }
678 sub print_column_no
{ App
::Ack
::print( $_[0], $_[1] ); return; }
680 my $filename = shift;
681 my $nmatches = shift;
684 my $show_filename = shift;
686 if ($show_filename) {
687 App
::Ack
::print( $filename );
688 App
::Ack
::print( ':', $nmatches ) if $count;
691 App
::Ack
::print( $nmatches ) if $count;
693 App
::Ack
::print( $ors );
699 my $filename = shift;
701 my $show_filename = shift;
703 if ($show_filename) {
704 App
::Ack
::print( $filename, ':0', $ors );
707 App
::Ack
::print( '0', $ors );
716 return if App
::Ack
::output_to_pipe
();
719 if ( not open( $pager, '|-', $command ) ) {
720 App
::Ack
::die( qq{Unable to pipe to pager "$command": $!} );
729 return $output_to_pipe;
734 my $nmatches = shift;
736 my $rc = $nmatches ? 0 : 1;
743 package App
::Ack
::Resource
;
753 Carp
::confess
( 'Must be overloaded' );
777 sub needs_line_scan
{
802 package App
::Ack
::Resources
;
815 my $self = bless {}, $class;
817 my $file_filter = undef;
818 my $descend_filter = $opt->{descend_filter
};
821 $descend_filter = sub {
828 file_filter
=> $opt->{file_filter
},
829 descend_filter
=> $descend_filter,
830 error_handler
=> sub { my $msg = shift; App
::Ack
::warn( $msg ) },
831 sort_files
=> $opt->{sort_files
},
832 follow_symlinks
=> $opt->{follow
},
845 File
::Next
::from_file
( {
846 error_handler
=> sub { my $msg = shift; App
::Ack
::warn( $msg ) },
847 warning_handler
=> sub { my $msg = shift; App
::Ack
::warn( $msg ) },
848 sort_files
=> $opt->{sort_files
},
849 }, $file ) or return undef;
856 # This is for reading input lines from STDIN, not the list of files from STDIN
861 my $self = bless {}, $class;
863 my $has_been_called = 0;
865 $self->{iter
} = sub {
866 if ( !$has_been_called ) {
867 $has_been_called = 1;
879 my $file = $self->{iter
}->() or return;
881 return App
::Ack
::Resource
::Basic-
>new( $file );
885 package App
::Ack
::Resource
::Basic
;
894 our @ISA = 'App::Ack::Resource';
900 my $filename = shift;
903 filename
=> $filename,
908 if ( $self->{filename
} eq '-' ) {
909 $self->{fh
} = *STDIN
;
918 return $_[0]->{filename
};
923 sub needs_line_scan
{
927 return 1 if $opt->{v
};
929 my $size = -s
$self->{fh
};
933 elsif ( $size > 100_000 ) {
938 my $rc = sysread( $self->{fh
}, $buffer, $size );
939 if ( !defined($rc) && $App::Ack
::report_bad_filenames
) {
940 App
::Ack
::warn( "$self->{filename}: $!" );
943 return 0 unless $rc && ( $rc == $size );
945 my $regex = $opt->{regex
};
946 return $buffer =~ /$regex/m;
953 # return if we haven't opened the file yet
954 if ( !defined($self->{fh
}) ) {
958 if( !seek( $self->{fh
}, 0, 0 ) && $App::Ack
::report_bad_filenames
) {
959 App
::Ack
::warn( "$self->{filename}: $!" );
969 # return if we haven't opened the file yet
970 if ( !defined($self->{fh
}) ) {
974 if ( !close($self->{fh
}) && $App::Ack
::report_bad_filenames
) {
975 App
::Ack
::warn( $self->name() . ": $!" );
987 return __PACKAGE__-
>new($self->name);
993 my $fh = $self->open();
995 unless(exists $self->{firstliney
}) {
997 my $rc = sysread( $fh, $buffer, 250 );
998 unless($rc) { # XXX handle this better?
1001 $buffer =~ s/[\r\n].*//s;
1002 $self->{firstliney
} = $buffer;
1008 return $self->{firstliney
};
1014 return $self->{fh
} if $self->{opened
};
1016 unless ( open $self->{fh
}, '<', $self->{filename
} ) {
1020 $self->{opened
} = 1;
1026 package App
::Ack
::ConfigDefault
;
1032 my @options = split( /\n/, _options_block
() );
1033 @options = grep { /./ && !/^#/ } @options;
1038 sub _options_block
{
1040 # This is the default ackrc for ack 2.0
1042 # There are four different ways to match
1044 # is: Match the filename exactly
1046 # ext: Match the extension of the filename exactly
1048 # match: Match the filename against a Perl regular expression
1050 # firstlinematch: Match the first 250 characters of the first line
1051 # of text against a Perl regular expression. This is only for
1052 # the --type-add option.
1055 ### Directories to ignore
1058 --ignore-directory=is:.bzr
1061 --ignore-directory=is:.cdv
1064 --ignore-directory=is:~.dep
1065 --ignore-directory=is:~.dot
1066 --ignore-directory=is:~.nib
1067 --ignore-directory=is:~.plst
1070 --ignore-directory=is:.git
1073 --ignore-directory=is:.hg
1076 --ignore-directory=is:.pc
1079 --ignore-directory=is:.svn
1082 --ignore-directory=is:_MTN
1085 --ignore-directory=is:CVS
1088 --ignore-directory=is:RCS
1091 --ignore-directory=is:SCCS
1094 --ignore-directory=is:_darcs
1097 --ignore-directory=is:_sgbak
1100 --ignore-directory=is:autom4te.cache
1102 # Perl module building
1103 --ignore-directory=is:blib
1104 --ignore-directory=is:_build
1106 # Perl Devel::Cover module's output directory
1107 --ignore-directory=is:cover_db
1109 # Node modules created by npm
1110 --ignore-directory=is:node_modules
1113 --ignore-directory=is:CMakeFiles
1118 --ignore-file=ext:bak
1119 --ignore-file=match:/~$/
1122 --ignore-file=match:/^#.+#$/
1125 --ignore-file=match:/[._].*\.swp$/
1128 --ignore-file=match:/core\.\d+$/
1130 # minified Javascript
1131 --ignore-file=match:/[.-]min[.]js$/
1132 --ignore-file=match:/[.]js[.]min$/
1135 --ignore-file=match:/[.]min[.]css$/
1136 --ignore-file=match:/[.]css[.]min$/
1138 # PDFs, because they pass Perl's -T detection
1139 --ignore-file=ext:pdf
1141 # Common graphics, just as an optimization
1142 --ignore-file=ext:gif,jpg,jpeg,png
1145 ### Filetypes defined
1147 # Perl http://perl.org/
1148 --type-add=perl:ext:pl,pm,pod,t,psgi
1149 --type-add=perl:firstlinematch:/^#!.*\bperl/
1152 --type-add=perltest:ext:t
1154 # Makefiles http://www.gnu.org/s/make/
1155 --type-add=make:ext:mk
1156 --type-add=make:ext:mak
1157 --type-add=make:is:makefile
1158 --type-add=make:is:Makefile
1159 --type-add=make:is:GNUmakefile
1161 # Rakefiles http://rake.rubyforge.org/
1162 --type-add=rake:is:Rakefile
1164 # CMake http://www.cmake.org/
1165 --type-add=cmake:is:CMakeLists.txt
1166 --type-add=cmake:ext:cmake
1169 --type-add=actionscript:ext:as,mxml
1171 # Ada http://www.adaic.org/
1172 --type-add=ada:ext:ada,adb,ads
1174 # ASP http://msdn.microsoft.com/en-us/library/aa286483.aspx
1175 --type-add=asp:ext:asp
1177 # ASP.Net http://www.asp.net/
1178 --type-add=aspx:ext:master,ascx,asmx,aspx,svc
1181 --type-add=asm:ext:asm,s
1184 --type-add=batch:ext:bat,cmd
1186 # ColdFusion http://en.wikipedia.org/wiki/ColdFusion
1187 --type-add=cfmx:ext:cfc,cfm,cfml
1189 # Clojure http://clojure.org/
1190 --type-add=clojure:ext:clj
1193 # .xs are Perl C files
1194 --type-add=cc:ext:c,h,xs
1199 # CoffeeScript http://coffeescript.org/
1200 --type-add=coffeescript:ext:coffee
1203 --type-add=cpp:ext:cpp,cc,cxx,m,hpp,hh,h,hxx
1206 --type-add=csharp:ext:cs
1208 # CSS http://www.w3.org/Style/CSS/
1209 --type-add=css:ext:css
1211 # Dart http://www.dartlang.org/
1212 --type-add=dart:ext:dart
1214 # Delphi http://en.wikipedia.org/wiki/Embarcadero_Delphi
1215 --type-add=delphi:ext:pas,int,dfm,nfm,dof,dpk,dproj,groupproj,bdsgroup,bdsproj
1217 # Elixir http://elixir-lang.org/
1218 --type-add=elixir:ext:ex,exs
1220 # Emacs Lisp http://www.gnu.org/software/emacs
1221 --type-add=elisp:ext:el
1223 # Erlang http://www.erlang.org/
1224 --type-add=erlang:ext:erl,hrl
1226 # Fortran http://en.wikipedia.org/wiki/Fortran
1227 --type-add=fortran:ext:f,f77,f90,f95,f03,for,ftn,fpp
1229 # Google Go http://golang.org/
1230 --type-add=go:ext:go
1232 # Groovy http://groovy.codehaus.org/
1233 --type-add=groovy:ext:groovy,gtmpl,gpp,grunit,gradle
1235 # Haskell http://www.haskell.org/
1236 --type-add=haskell:ext:hs,lhs
1239 --type-add=html:ext:htm,html
1241 # Java http://www.oracle.com/technetwork/java/index.html
1242 --type-add=java:ext:java,properties
1245 --type-add=js:ext:js
1247 # JSP http://www.oracle.com/technetwork/java/javaee/jsp/index.html
1248 --type-add=jsp:ext:jsp,jspx,jhtm,jhtml
1250 # JSON http://www.json.org/
1251 --type-add=json:ext:json
1253 # Less http://www.lesscss.org/
1254 --type-add=less:ext:less
1256 # Common Lisp http://common-lisp.net/
1257 --type-add=lisp:ext:lisp,lsp
1259 # Lua http://www.lua.org/
1260 --type-add=lua:ext:lua
1261 --type-add=lua:firstlinematch:/^#!.*\blua(jit)?/
1264 --type-add=objc:ext:m,h
1267 --type-add=objcpp:ext:mm,h
1269 # OCaml http://caml.inria.fr/
1270 --type-add=ocaml:ext:ml,mli
1272 # Matlab http://en.wikipedia.org/wiki/MATLAB
1273 --type-add=matlab:ext:m
1275 # Parrot http://www.parrot.org/
1276 --type-add=parrot:ext:pir,pasm,pmc,ops,pod,pg,tg
1278 # PHP http://www.php.net/
1279 --type-add=php:ext:php,phpt,php3,php4,php5,phtml
1280 --type-add=php:firstlinematch:/^#!.*\bphp/
1282 # Plone http://plone.org/
1283 --type-add=plone:ext:pt,cpt,metadata,cpy,py
1285 # Python http://www.python.org/
1286 --type-add=python:ext:py
1287 --type-add=python:firstlinematch:/^#!.*\bpython/
1289 # R http://www.r-project.org/
1292 # Ruby http://www.ruby-lang.org/
1293 --type-add=ruby:ext:rb,rhtml,rjs,rxml,erb,rake,spec
1294 --type-add=ruby:is:Rakefile
1295 --type-add=ruby:firstlinematch:/^#!.*\bruby/
1297 # Rust http://www.rust-lang.org/
1298 --type-add=rust:ext:rs
1300 # Sass http://sass-lang.com
1301 --type-add=sass:ext:sass,scss
1303 # Scala http://www.scala-lang.org/
1304 --type-add=scala:ext:scala
1306 # Scheme http://groups.csail.mit.edu/mac/projects/scheme/
1307 --type-add=scheme:ext:scm,ss
1310 --type-add=shell:ext:sh,bash,csh,tcsh,ksh,zsh,fish
1311 --type-add=shell:firstlinematch:/^#!.*\b(?:ba|t?c|k|z|fi)?sh\b/
1313 # Smalltalk http://www.smalltalk.org/
1314 --type-add=smalltalk:ext:st
1316 # SQL http://www.iso.org/iso/catalogue_detail.htm?csnumber=45498
1317 --type-add=sql:ext:sql,ctl
1319 # Tcl http://www.tcl.tk/
1320 --type-add=tcl:ext:tcl,itcl,itk
1322 # LaTeX http://www.latex-project.org/
1323 --type-add=tex:ext:tex,cls,sty
1325 # Template Toolkit http://template-toolkit.org/
1326 --type-add=tt:ext:tt,tt2,ttml
1329 --type-add=vb:ext:bas,cls,frm,ctl,vb,resx
1332 --type-add=verilog:ext:v,vh,sv
1334 # VHDL http://www.eda.org/twiki/bin/view.cgi/P1076/WebHome
1335 --type-add=vhdl:ext:vhd,vhdl
1337 # Vim http://www.vim.org/
1338 --type-add=vim:ext:vim
1340 # XML http://www.w3.org/TR/REC-xml/
1341 --type-add=xml:ext:xml,dtd,xsl,xslt,ent
1342 --type-add=xml:firstlinematch:/<[?]xml/
1344 # YAML http://yaml.org/
1345 --type-add=yaml:ext:yaml,yml
1350 package App
::Ack
::ConfigFinder
;
1357 use File
::Spec
3.00;
1359 use if ($^O eq 'MSWin32'), 'Win32';
1365 return bless {}, $class;
1368 sub _remove_redundancies
{
1369 my ( @configs ) = @_;
1371 if ( $App::Ack
::is_windows
) {
1372 # inode stat always returns 0 on windows, so just check filenames.
1375 foreach my $path (@configs) {
1376 push @uniq, $path unless $seen{$path};
1385 my %dev_and_inode_seen;
1387 foreach my $path ( @configs ) {
1388 my ( $dev, $inode ) = (stat $path)[0, 1];
1390 if( defined($dev) ) {
1391 if( $dev_and_inode_seen{"$dev:$inode"} ) {
1395 $dev_and_inode_seen{"$dev:$inode"} = 1;
1400 return grep { defined() } @configs;
1405 sub _check_for_ackrc
{
1406 return unless defined $_[0];
1408 my @files = grep { -f
}
1409 map { File
::Spec-
>catfile(@_, $_) }
1412 die File
::Spec-
>catdir(@_) . " contains both .ackrc and _ackrc.\n" .
1413 "Please remove one of those files.\n"
1416 return wantarray ? @files : $files[0];
1417 } # end _check_for_ackrc
1420 sub find_config_files
{
1423 if ( $App::Ack
::is_windows
) {
1424 push @config_files, map { File
::Spec-
>catfile($_, 'ackrc') } (
1425 Win32
::GetFolderPath
(Win32
::CSIDL_COMMON_APPDATA
()),
1426 Win32
::GetFolderPath
(Win32
::CSIDL_APPDATA
()),
1430 push @config_files, '/etc/ackrc';
1434 if ( $ENV{'ACKRC'} && -f
$ENV{'ACKRC'} ) {
1435 push @config_files, $ENV{'ACKRC'};
1438 push @config_files, _check_for_ackrc
($ENV{'HOME'});
1441 my @dirs = File
::Spec-
>splitdir(Cwd
::getcwd
());
1443 my $ackrc = _check_for_ackrc
(@dirs);
1444 if(defined $ackrc) {
1445 push @config_files, $ackrc;
1451 # XXX we only test for existence here, so if the file is
1452 # deleted out from under us, this will fail later. =(
1453 return _remove_redundancies
( @config_files );
1460 return unless defined $file && -e
$file;
1464 open( my $fh, '<', $file ) or App
::Ack
::die( "Unable to read $file: $!" );
1465 while ( my $line = <$fh> ) {
1470 next if $line eq '';
1471 next if $line =~ /^#/;
1473 push( @lines, $line );
1481 package App
::Ack
::ConfigLoader
;
1487 use Getopt
::Long
2.35 ();
1488 use Text
::ParseWords
3.1 ();
1491 my @INVALID_COMBINATIONS;
1494 my @context = qw( -A -B -C --after-context --before-context --context );
1495 my @pretty = qw( --heading --group --break );
1496 my @filename = qw( -h -H --with-filename --no-filename );
1498 @INVALID_COMBINATIONS = (
1500 [qw(-l)] => [@context, @pretty, @filename, qw(-L -o --passthru --output --max-count --column -f -g --show-types)],
1501 [qw(-L)] => [@context, @pretty, @filename, qw(-l -o --passthru --output --max-count --column -f -g --show-types -c --count)],
1502 [qw(--line)] => [@context, @pretty, @filename, qw(-l --files-with-matches --files-without-matches -L -o --passthru --match -m --max-count -1 -c --count --column --print0 -f -g --show-types)],
1503 [qw(-o)] => [@context, qw(--output -c --count --column --column -f --show-types)],
1504 [qw(--passthru)] => [@context, qw(--output --column -m --max-count -1 -c --count -f -g)],
1505 [qw(--output)] => [@context, qw(-c --count -f -g)],
1506 [qw(--match)] => [qw(-f -g)],
1507 [qw(-m --max-count)] => [qw(-1 -f -g -c --count)],
1508 [qw(-h --no-filename)] => [qw(-H --with-filename -f -g --group --heading)],
1509 [qw(-H --with-filename)] => [qw(-h --no-filename -f -g)],
1510 [qw(-c --count)] => [@context, @pretty, qw(--column -f -g)],
1511 [qw(--column)] => [qw(-f -g)],
1512 [@context] => [qw(-f -g)],
1513 [qw(-f)] => [qw(-g), @pretty],
1514 [qw(-g)] => [qw(-f), @pretty],
1518 sub process_filter_spec
{
1521 if ( $spec =~ /^(\w+):(\w+):(.*)/ ) {
1522 my ( $type_name, $ext_type, $arguments ) = ( $1, $2, $3 );
1524 return ( $type_name,
1525 App
::Ack
::Filter-
>create_filter($ext_type, split(/,/, $arguments)) );
1527 elsif ( $spec =~ /^(\w+)=(.*)/ ) { # Check to see if we have ack1-style argument specification.
1528 my ( $type_name, $extensions ) = ( $1, $2 );
1530 my @extensions = split(/,/, $extensions);
1531 foreach my $extension ( @extensions ) {
1532 $extension =~ s/^[.]//;
1535 return ( $type_name, App
::Ack
::Filter-
>create_filter('ext', @extensions) );
1538 Carp
::croak
"invalid filter specification '$spec'";
1542 sub uninvert_filter
{
1543 my ( $opt, @filters ) = @_;
1545 return unless defined $opt->{filters
} && @filters;
1547 # Loop through all the registered filters. If we hit one that
1548 # matches this extension and it's inverted, we need to delete it from
1550 for ( my $i = 0; $i < @{ $opt->{filters
} }; $i++ ) {
1551 my $opt_filter = @{ $opt->{filters
} }[$i];
1553 # XXX Do a real list comparison? This just checks string equivalence.
1554 if ( $opt_filter->is_inverted() && "$opt_filter->{filter}" eq "@filters" ) {
1555 splice @{ $opt->{filters
} }, $i, 1;
1561 sub process_filetypes
{
1562 my ( $opt, $arg_sources ) = @_;
1564 Getopt
::Long
::Configure
('default', 'no_auto_help', 'no_auto_version'); # start with default options, minus some annoying ones
1565 Getopt
::Long
::Configure
(
1570 my %additional_specs;
1572 my $add_spec = sub {
1573 my ( undef, $spec ) = @_;
1575 my ( $name, $filter ) = process_filter_spec
($spec);
1577 push @{ $App::Ack
::mappings
{$name} }, $filter;
1579 $additional_specs{$name . '!'} = sub {
1580 my ( undef, $value ) = @_;
1582 my @filters = @{ $App::Ack
::mappings
{$name} };
1584 @filters = map { $_->invert() } @filters;
1587 uninvert_filter
( $opt, @filters );
1590 push @{ $opt->{'filters'} }, @filters;
1594 my $set_spec = sub {
1595 my ( undef, $spec ) = @_;
1597 my ( $name, $filter ) = process_filter_spec
($spec);
1599 $App::Ack
::mappings
{$name} = [ $filter ];
1601 $additional_specs{$name . '!'} = sub {
1602 my ( undef, $value ) = @_;
1604 my @filters = @{ $App::Ack
::mappings
{$name} };
1606 @filters = map { $_->invert() } @filters;
1609 push @{ $opt->{'filters'} }, @filters;
1613 my $delete_spec = sub {
1614 my ( undef, $name ) = @_;
1616 delete $App::Ack
::mappings
{$name};
1617 delete $additional_specs{$name . '!'};
1620 my %type_arg_specs = (
1621 'type-add=s' => $add_spec,
1622 'type-set=s' => $set_spec,
1623 'type-del=s' => $delete_spec,
1626 for ( my $i = 0; $i < @{$arg_sources}; $i += 2) {
1627 my ( $source_name, $args ) = @{$arg_sources}[ $i, $i + 1];
1630 # $args are modified in place, so no need to munge $arg_sources
1631 local @ARGV = @{$args};
1632 Getopt
::Long
::GetOptions
(%type_arg_specs);
1636 ( undef, $arg_sources->[$i + 1] ) =
1637 Getopt
::Long
::GetOptionsFromString
($args, %type_arg_specs);
1641 $additional_specs{'k|known-types'} = sub {
1642 my ( undef, $value ) = @_;
1644 my @filters = map { @{$_} } values(%App::Ack
::mappings
);
1646 push @{ $opt->{'filters'} }, @filters;
1649 return \
%additional_specs;
1652 sub removed_option
{
1653 my ( $option, $explanation ) = @_;
1655 $explanation ||= '';
1657 warn "Option '$option' is not valid in ack 2\n$explanation";
1663 my ( $opt, $extra_specs ) = @_;
1665 my $dash_a_explanation = <<EOT;
1666 This is because we now have -k/--known-types which makes it only select files
1667 of known types, rather than any text file (which is the behavior of ack 1.x).
1668 You may have options in a .ackrc, or in the ACKRC_OPTIONS environment variable.
1669 Try using the --dump flag.
1673 1 => sub { $opt->{1} = $opt->{m
} = 1 },
1674 'A|after-context=i' => \
$opt->{after_context
},
1675 'B|before-context=i'
1676 => \
$opt->{before_context
},
1677 'C|context:i' => sub { shift; my $val = shift; $opt->{before_context
} = $opt->{after_context
} = ($val || 2) },
1678 'a' => removed_option
('-a', $dash_a_explanation),
1679 'all' => removed_option
('--all', $dash_a_explanation),
1680 'break!' => \
$opt->{break},
1681 c
=> \
$opt->{count
},
1682 'color|colour!' => \
$opt->{color
},
1683 'color-match=s' => \
$ENV{ACK_COLOR_MATCH
},
1684 'color-filename=s' => \
$ENV{ACK_COLOR_FILENAME
},
1685 'color-lineno=s' => \
$ENV{ACK_COLOR_LINENO
},
1686 'column!' => \
$opt->{column
},
1687 count
=> \
$opt->{count
},
1688 'create-ackrc' => sub { print "$_\n" for ( '--ignore-ack-defaults', App
::Ack
::ConfigDefault
::options
() ); exit; },
1690 my ( undef, $value ) = @_;
1693 $opt->{noenv_seen
} = 1;
1697 'files-from=s' => \
$opt->{files_from
},
1698 'filter!' => \
$App::Ack
::is_filter_mode
,
1699 flush
=> \
$opt->{flush
},
1700 'follow!' => \
$opt->{follow
},
1702 G
=> removed_option
('-G'),
1703 'group!' => sub { shift; $opt->{heading
} = $opt->{break} = shift },
1704 'heading!' => \
$opt->{heading
},
1705 'h|no-filename' => \
$opt->{h
},
1706 'H|with-filename' => \
$opt->{H
},
1707 'i|ignore-case' => \
$opt->{i
},
1708 'ignore-directory|ignore-dir=s' # XXX Combine this version with the negated version below
1710 my ( undef, $dir ) = @_;
1712 $dir = App
::Ack
::remove_dir_sep
( $dir );
1713 if ( $dir !~ /^(?:is|match):/ ) {
1714 $dir = 'is:' . $dir;
1716 push @{ $opt->{idirs
} }, $dir;
1718 'ignore-file=s' => sub {
1719 my ( undef, $file ) = @_;
1720 push @{ $opt->{ifiles
} }, $file;
1722 'lines=s' => sub { shift; my $val = shift; push @{$opt->{lines
}}, $val },
1723 'l|files-with-matches'
1725 'L|files-without-matches'
1727 'm|max-count=i' => \
$opt->{m
},
1728 'match=s' => \
$opt->{regex
},
1729 'n|no-recurse' => \
$opt->{n
},
1730 o
=> sub { $opt->{output
} = '$&' },
1731 'output=s' => \
$opt->{output
},
1733 my ( undef, $value ) = @_;
1735 $opt->{pager
} = $value || $ENV{PAGER
};
1737 'noignore-directory|noignore-dir=s'
1739 my ( undef, $dir ) = @_;
1741 # XXX can you do --noignore-dir=match,...?
1742 $dir = App
::Ack
::remove_dir_sep
( $dir );
1743 if ( $dir !~ /^(?:is|match):/ ) {
1744 $dir = 'is:' . $dir;
1746 if ( $dir !~ /^(?:is|match):/ ) {
1747 Carp
::croak
("invalid noignore-directory argument: '$dir'");
1750 @{ $opt->{idirs
} } = grep {
1752 } @{ $opt->{idirs
} };
1754 push @{ $opt->{no_ignore_dirs
} }, $dir;
1756 'nopager' => sub { $opt->{pager
} = undef },
1757 'passthru' => \
$opt->{passthru
},
1758 'print0' => \
$opt->{print0
},
1759 'Q|literal' => \
$opt->{Q
},
1760 'r|R|recurse' => sub { $opt->{n
} = 0 },
1761 's' => \
$opt->{dont_report_bad_filenames
},
1762 'show-types' => \
$opt->{show_types
},
1763 'smart-case!' => \
$opt->{smart_case
},
1764 'sort-files' => \
$opt->{sort_files
},
1766 my ( $getopt, $value ) = @_;
1769 if ( $value =~ s/^no// ) {
1773 my $callback = $extra_specs->{ $value . '!' };
1776 $callback->( $getopt, $cb_value );
1779 Carp
::croak
( "Unknown type '$value'" );
1782 'u' => removed_option
('-u'),
1783 'unrestricted' => removed_option
('--unrestricted'),
1784 'v|invert-match' => \
$opt->{v
},
1785 'w|word-regexp' => \
$opt->{w
},
1786 'x' => sub { $opt->{files_from
} = '-' },
1788 'version' => sub { App
::Ack
::print_version_statement
(); exit; },
1789 'help|?:s' => sub { shift; App
::Ack
::show_help
(@_); exit; },
1790 'help-types' => sub { App
::Ack
::show_help_types
(); exit; },
1791 'man' => sub { App
::Ack
::show_man
(); exit; },
1792 $extra_specs ? %{$extra_specs} : (),
1797 my ( $opt, $extra_specs, $arg_sources ) = @_;
1799 Getopt
::Long
::Configure
('default', 'no_auto_help', 'no_auto_version'); # start with default options, minus some annoying ones
1800 Getopt
::Long
::Configure
(
1806 my $is_help_types_active;
1808 for ( my $i = 0; $i < @{$arg_sources}; $i += 2 ) {
1809 my ( $source_name, $args ) = @{$arg_sources}[ $i, $i + 1 ];
1811 if ( $source_name eq 'ARGV' ) {
1812 $argv_source = $args;
1817 if ( $argv_source ) { # This *should* always be true, but you never know...
1818 my @copy = @{$argv_source};
1819 local @ARGV = @copy;
1821 Getopt
::Long
::Configure
('pass_through');
1823 Getopt
::Long
::GetOptions
(
1824 'help-types' => \
$is_help_types_active,
1827 Getopt
::Long
::Configure
('no_pass_through');
1830 my $arg_specs = get_arg_spec
($opt, $extra_specs);
1832 for ( my $i = 0; $i < @{$arg_sources}; $i += 2) {
1833 my ($source_name, $args) = @{$arg_sources}[$i, $i + 1];
1837 local @ARGV = @{$args};
1838 $ret = Getopt
::Long
::GetOptions
( %{$arg_specs} );
1842 ( $ret, $arg_sources->[$i + 1] ) =
1843 Getopt
::Long
::GetOptionsFromString
( $args, %{$arg_specs} );
1846 if ( !$is_help_types_active ) {
1847 my $where = $source_name eq 'ARGV' ? 'on command line' : "in $source_name";
1848 App
::Ack
::die( "Invalid option $where" );
1851 if ( $opt->{noenv_seen
} ) {
1852 App
::Ack
::die( "--noenv found in $source_name" );
1856 # XXX We need to check on a -- in the middle of a non-ARGV source
1861 sub should_dump_options
{
1862 my ( $sources ) = @_;
1864 for(my $i = 0; $i < @{$sources}; $i += 2) {
1865 my ( $name, $options ) = @{$sources}[$i, $i + 1];
1866 if($name eq 'ARGV') {
1868 local @ARGV = @{$options};
1869 Getopt
::Long
::Configure
('default', 'pass_through', 'no_auto_help', 'no_auto_version');
1870 Getopt
::Long
::GetOptions
(
1873 @{$options} = @ARGV;
1880 sub explode_sources
{
1881 my ( $sources ) = @_;
1885 Getopt
::Long
::Configure
('default', 'pass_through', 'no_auto_help', 'no_auto_version');
1888 my $arg_spec = get_arg_spec
(\
%opt);
1890 my $add_type = sub {
1891 my ( undef, $arg ) = @_;
1894 if ( $arg =~ /(\w+)=/) {
1895 $arg_spec->{$1} = sub {};
1898 ( $arg ) = split /:/, $arg;
1899 $arg_spec->{$arg} = sub {};
1903 my $del_type = sub {
1904 my ( undef, $arg ) = @_;
1906 delete $arg_spec->{$arg};
1909 for(my $i = 0; $i < @{$sources}; $i += 2) {
1910 my ( $name, $options ) = @{$sources}[$i, $i + 1];
1911 if ( ref($options) ne 'ARRAY' ) {
1912 $sources->[$i + 1] = $options =
1913 [ Text
::ParseWords
::shellwords
($options) ];
1915 for ( my $j = 0; $j < @{$options}; $j++ ) {
1916 next unless $options->[$j] =~ /^-/;
1917 my @chunk = ( $options->[$j] );
1918 push @chunk, $options->[$j] while ++$j < @{$options} && $options->[$j] !~ /^-/;
1922 local @ARGV = @chunk;
1923 Getopt
::Long
::GetOptions
(
1924 'type-add=s' => $add_type,
1925 'type-set=s' => $add_type,
1926 'type-del=s' => $del_type,
1928 Getopt
::Long
::GetOptions
( %{$arg_spec} );
1930 push @new_sources, $name, \
@copy;
1934 return \
@new_sources;
1940 my $first_a = $a->[0];
1941 my $first_b = $b->[0];
1943 $first_a =~ s/^--?//;
1944 $first_b =~ s/^--?//;
1946 return $first_a cmp $first_b;
1950 my ( $sources ) = @_;
1952 $sources = explode_sources
($sources);
1957 for(my $i = 0; $i < @{$sources}; $i += 2) {
1958 my ( $name, $contents ) = @{$sources}[$i, $i + 1];
1959 if ( not $opts_by_source{$name} ) {
1960 $opts_by_source{$name} = [];
1961 push @source_names, $name;
1963 push @{$opts_by_source{$name}}, $contents;
1966 foreach my $name (@source_names) {
1967 my $contents = $opts_by_source{$name};
1970 print '=' x
length($name), "\n";
1971 print ' ', join(' ', @{$_}), "\n" foreach sort { compare_opts
($a, $b) } @{$contents};
1977 sub remove_default_options_if_needed
{
1978 my ( $sources ) = @_;
1982 foreach my $index ( 0 .. $#$sources ) {
1983 if ( $sources->[$index] eq 'Defaults' ) {
1984 $default_index = $index;
1989 return $sources unless defined $default_index;
1991 my $should_remove = 0;
1993 # Start with default options, minus some annoying ones.
1994 Getopt
::Long
::Configure
('default', 'no_auto_help', 'no_auto_version');
1995 Getopt
::Long
::Configure
(
2001 foreach my $index ( $default_index + 2 .. $#$sources ) {
2002 next if $index % 2 != 0;
2004 my ( $name, $args ) = @{$sources}[ $index, $index + 1 ];
2007 local @ARGV = @{$args};
2008 Getopt
::Long
::GetOptions
(
2009 'ignore-ack-defaults' => \
$should_remove,
2014 ( undef, $sources->[$index + 1] ) = Getopt
::Long
::GetOptionsFromString
($args,
2015 'ignore-ack-defaults' => \
$should_remove,
2020 Getopt
::Long
::Configure
('default');
2021 Getopt
::Long
::Configure
('default', 'no_auto_help', 'no_auto_version');
2023 return $sources unless $should_remove;
2025 my @copy = @{$sources};
2026 splice @copy, $default_index, 2;
2030 sub check_for_mutually_exclusive_options
{
2031 my ( $arg_sources ) = @_;
2033 my %mutually_exclusive_with;
2034 my @copy = @{$arg_sources};
2036 for(my $i = 0; $i < @INVALID_COMBINATIONS; $i += 2) {
2037 my ( $lhs, $rhs ) = @INVALID_COMBINATIONS[ $i, $i + 1 ];
2039 foreach my $l_opt ( @{$lhs} ) {
2040 foreach my $r_opt ( @{$rhs} ) {
2041 push @{ $mutually_exclusive_with{ $l_opt } }, $r_opt;
2042 push @{ $mutually_exclusive_with{ $r_opt } }, $l_opt;
2050 my ( $source_name, $args ) = splice @copy, 0, 2;
2051 $args = ref($args) ? [ @{$args} ] : [ Text
::ParseWords
::shellwords
($args) ];
2053 foreach my $opt ( @{$args} ) {
2054 next unless $opt =~ /^[-+]/;
2055 last if $opt eq '--';
2057 if( $opt =~ /^(.*)=/ ) {
2060 elsif ( $opt =~ /^(-[^-]).+/ ) {
2064 $set_opts{ $opt } = 1;
2066 my $mutex_opts = $mutually_exclusive_with{ $opt };
2068 next unless $mutex_opts;
2070 foreach my $mutex_opt ( @{$mutex_opts} ) {
2071 if($set_opts{ $mutex_opt }) {
2072 die "Options '$mutex_opt' and '$opt' are mutually exclusive\n";
2080 my $arg_sources = \
@_;
2083 pager
=> $ENV{ACK_PAGER_COLOR
} || $ENV{ACK_PAGER
},
2086 check_for_mutually_exclusive_options
($arg_sources);
2088 $arg_sources = remove_default_options_if_needed
($arg_sources);
2090 if ( should_dump_options
($arg_sources) ) {
2091 dump_options
($arg_sources);
2095 my $type_specs = process_filetypes
(\
%opt, $arg_sources);
2096 process_other
(\
%opt, $type_specs, $arg_sources);
2097 while ( @{$arg_sources} ) {
2098 my ( $source_name, $args ) = splice( @{$arg_sources}, 0, 2 );
2100 # All of our sources should be transformed into an array ref
2102 if ( $source_name eq 'ARGV' ) {
2106 Carp
::croak
"source '$source_name' has extra arguments!";
2110 Carp
::croak
'The impossible has occurred!';
2113 my $filters = ($opt{filters
} ||= []);
2115 # Throw the default filter in if no others are selected.
2116 if ( not grep { !$_->is_inverted() } @{$filters} ) {
2117 push @{$filters}, App
::Ack
::Filter
::Default-
>new();
2123 sub retrieve_arg_sources
{
2129 Getopt
::Long
::Configure
('default', 'no_auto_help', 'no_auto_version');
2130 Getopt
::Long
::Configure
('pass_through');
2131 Getopt
::Long
::Configure
('no_auto_abbrev');
2133 Getopt
::Long
::GetOptions
(
2135 'ackrc=s' => \
$ackrc,
2138 Getopt
::Long
::Configure
('default', 'no_auto_help', 'no_auto_version');
2143 my $finder = App
::Ack
::ConfigFinder-
>new;
2144 @files = $finder->find_config_files;
2147 # We explicitly use open so we get a nice error message.
2148 # XXX This is a potential race condition!.
2149 if(open my $fh, '<', $ackrc) {
2153 die "Unable to load ackrc '$ackrc': $!"
2155 push( @files, $ackrc );
2158 push @arg_sources, Defaults
=> [ App
::Ack
::ConfigDefault
::options
() ];
2160 foreach my $file ( @files) {
2161 my @lines = App
::Ack
::ConfigFinder
::read_rcfile
($file);
2162 push ( @arg_sources, $file, \
@lines ) if @lines;
2165 if ( $ENV{ACK_OPTIONS
} && !$noenv ) {
2166 push( @arg_sources, 'ACK_OPTIONS' => $ENV{ACK_OPTIONS
} );
2169 push( @arg_sources, 'ARGV' => [ @ARGV ] );
2171 return @arg_sources;
2174 1; # End of App::Ack::ConfigLoader
2175 package App
::Ack
::Filter
;
2180 '""' => 'to_string';
2188 my ( undef, $type, @args ) = @_;
2190 if ( my $package = $filter_types{$type} ) {
2191 return $package->new(@args);
2193 Carp
::croak
"Unknown filter type '$type'";
2197 sub register_filter
{
2198 my ( undef, $type, $package ) = @_;
2200 $filter_types{$type} = $package;
2209 return App
::Ack
::Filter
::Inverse-
>new( $self );
2221 return '(unimplemented to_string)';
2232 package App
::Ack
::Filter
::Extension
;
2237 our @ISA = 'App::Ack::Filter';
2242 my ( $class, @extensions ) = @_;
2244 my $exts = join('|', map { "\Q$_\E"} @extensions);
2245 my $re = qr/[.](?:$exts)$/i;
2248 extensions
=> \
@extensions,
2250 groupname
=> 'ExtensionGroup',
2255 return App
::Ack
::Filter
::ExtensionGroup-
>new();
2259 my ( $self, $resource ) = @_;
2261 my $re = $self->{'regex'};
2263 return $resource->name =~ /$re/;
2269 my $re = $self->{'regex'};
2271 return ref($self) . " - $re";
2277 my $exts = $self->{'extensions'};
2279 return join(' ', map { ".$_" } @{$exts});
2283 App
::Ack
::Filter-
>register_filter(ext
=> __PACKAGE__
);
2287 package App
::Ack
::Filter
::FirstLineMatch
;
2292 our @ISA = 'App::Ack::Filter';
2296 my ( $class, $re ) = @_;
2298 $re =~ s{^/|/$}{}g; # XXX validate?
2306 # This test reads the first 250 characters of a file, then just uses the
2307 # first line found in that. This prevents reading something like an entire
2308 # .min.js file (which might be only one "line" long) into memory.
2311 my ( $self, $resource ) = @_;
2313 my $re = $self->{'regex'};
2315 my $line = $resource->firstliney;
2317 return $line =~ /$re/;
2323 my $re = $self->{'regex'};
2325 return ref($self) . " - $re";
2331 (my $re = $self->{regex
}) =~ s{\([^:]*:(.*)\)$}{$1};
2333 return "first line matches /$re/";
2337 App
::Ack
::Filter-
>register_filter(firstlinematch
=> __PACKAGE__
);
2341 package App
::Ack
::Filter
::Is
;
2346 our @ISA = 'App::Ack::Filter';
2349 use File
::Spec
3.00 ();
2352 my ( $class, $filename ) = @_;
2355 filename
=> $filename,
2356 groupname
=> 'IsGroup',
2361 return App
::Ack
::Filter
::IsGroup-
>new();
2365 my ( $self, $resource ) = @_;
2367 my $filename = $self->{'filename'};
2368 my $base = (File
::Spec-
>splitpath($resource->name))[2];
2370 return $base eq $filename;
2376 my $filename = $self->{'filename'};
2378 return ref($self) . " - $filename";
2384 my $filename = $self->{'filename'};
2390 App
::Ack
::Filter-
>register_filter(is => __PACKAGE__
);
2394 package App
::Ack
::Filter
::Match
;
2399 our @ISA = 'App::Ack::Filter';
2402 use File
::Spec
3.00;
2405 my ( $class, $re ) = @_;
2407 $re =~ s{^/|/$}{}g; # XXX validate?
2416 my ( $self, $resource ) = @_;
2418 my $re = $self->{'regex'};
2419 my $base = (File
::Spec-
>splitpath($resource->name))[2];
2421 return $base =~ /$re/;
2427 my $re = $self->{'regex'};
2429 print ref($self) . " - $re";
2435 my $re = $self->{'regex'};
2437 return "filename matches $re";
2441 App
::Ack
::Filter-
>register_filter(match
=> __PACKAGE__
);
2445 package App
::Ack
::Filter
::Default
;
2450 our @ISA = 'App::Ack::Filter';
2456 return bless {}, $class;
2460 my ( $self, $resource ) = @_;
2462 return -T
$resource->name;
2466 package App
::Ack
::Filter
::Inverse
;
2471 our @ISA = 'App::Ack::Filter';
2475 my ( $class, $filter ) = @_;
2483 my ( $self, $resource ) = @_;
2485 my $filter = $self->{'filter'};
2486 return !$filter->filter( $resource );
2492 return $self->{'filter'};
2502 my $filter = $self->{'filter'};
2508 package App
::Ack
::Filter
::Collection
;
2513 our @ISA = 'App::Ack::Filter';
2516 use File
::Spec
3.00 ();
2528 my ( $self, $resource ) = @_;
2530 for my $group (values %{$self->{'groups'}}) {
2531 if ($group->filter($resource)) {
2536 for my $filter (@{$self->{'ungrouped'}}) {
2537 if ($filter->filter($resource)) {
2546 my ( $self, $filter ) = @_;
2548 if (exists $filter->{'groupname'}) {
2549 my $groups = $self->{'groups'};
2550 my $group_name = $filter->{'groupname'};
2553 if (exists $groups->{$group_name}) {
2554 $group = $groups->{$group_name};
2557 $group = $groups->{$group_name} = $filter->create_group();
2560 $group->add($filter);
2563 push @{$self->{'ungrouped'}}, $filter;
2572 return ref($self) . " - $self";
2578 my $ungrouped = $self->{'ungrouped'};
2580 return join(', ', map { "($_)" } @{$ungrouped});
2584 package App
::Ack
::Filter
::IsGroup
;
2589 our @ISA = 'App::Ack::Filter';
2592 use File
::Spec
3.00 ();
2603 my ( $self, $filter ) = @_;
2605 $self->{data
}->{ $filter->{filename
} } = 1;
2609 my ( $self, $resource ) = @_;
2611 my $data = $self->{'data'};
2612 my $base = (File
::Spec-
>splitpath($resource->name))[2];
2614 return exists $data->{$base};
2620 return ref($self) . " - $self";
2626 return join(' ', keys %{$self->{data
}});
2630 package App
::Ack
::Filter
::ExtensionGroup
;
2635 our @ISA = 'App::Ack::Filter';
2638 use File
::Spec
3.00 ();
2649 my ( $self, $filter ) = @_;
2651 my $data = $self->{'data'};
2652 my $extensions = $filter->{'extensions'};
2654 foreach my $ext (@{$extensions}) {
2655 $data->{lc $ext} = 1;
2660 my ( $self, $resource ) = @_;
2662 if ($resource->name =~ /[.]([^.]*)$/) {
2663 return exists $self->{'data'}->{lc $1};
2672 return ref($self) . " - $self";
2678 my $data = $self->{'data'};
2680 return join(' ', map { ".$_" } (keys %$data));
2692 # XXX Don't make this so brute force
2693 # See also: https://github.com/petdance/ack2/issues/89
2695 use Getopt
::Long
2.35 ();
2699 our $VERSION = '2.10';
2700 # Check http://beyondgrep.com/ for updates
2702 # These are all our globals.
2705 $App::Ack
::orig_program_name
= $0;
2706 $0 = join(' ', 'ack', $0);
2707 if ( $App::Ack
::VERSION
ne $main::VERSION
) {
2708 App
::Ack
::die( "Program/library version mismatch\n\t$0 is $main::VERSION\n\t$INC{'App/Ack.pm'} is $App::Ack::VERSION" );
2711 # Do preliminary arg checking;
2712 my $env_is_usable = 1;
2713 for my $arg ( @ARGV ) {
2714 last if ( $arg eq '--' );
2716 # Get the --thpppt, --bar, --cathy checking out of the way.
2717 $arg =~ /^--th[pt]+t+$/ and App
::Ack
::_thpppt
($arg);
2718 $arg eq '--bar' and App
::Ack
::_bar
();
2719 $arg eq '--cathy' and App
::Ack
::_cathy
();
2721 # See if we want to ignore the environment. (Don't tell Al Gore.)
2722 $arg eq '--env' and $env_is_usable = 1;
2723 $arg eq '--noenv' and $env_is_usable = 0;
2726 if ( !$env_is_usable ) {
2727 my @keys = ( 'ACKRC', grep { /^ACK_/ } keys %ENV );
2732 Getopt
::Long
::Configure
('default', 'no_auto_help', 'no_auto_version');
2733 Getopt
::Long
::Configure
('pass_through', 'no_auto_abbrev');
2734 Getopt
::Long
::GetOptions
(
2735 'help' => sub { App
::Ack
::show_help
(); exit; },
2736 'version' => sub { App
::Ack
::print_version_statement
(); exit; },
2737 'man' => sub { App
::Ack
::show_man
(); exit; },
2739 Getopt
::Long
::Configure
('default', 'no_auto_help', 'no_auto_version');
2742 App
::Ack
::show_help
();
2749 sub _compile_descend_filter
{
2752 my $idirs = $opt->{idirs
};
2753 my $dont_ignore_dirs = $opt->{no_ignore_dirs
};
2755 # if we have one or more --noignore-dir directives, we can't ignore
2756 # entire subdirectory hierarchies, so we return an "accept all"
2757 # filter and scrutinize the files more in _compile_file_filter
2758 return if $dont_ignore_dirs;
2759 return unless $idirs && @{$idirs};
2763 foreach my $idir (@{$idirs}) {
2764 if ( $idir =~ /^(\w+):(.*)/ ) {
2766 $ignore_dirs{$2} = 1;
2769 Carp
::croak
( 'Non-is filters are not yet supported for --ignore-dir' );
2773 Carp
::croak
( qq{Invalid filter specification "$idir"} );
2778 return !exists $ignore_dirs{$_} && !exists $ignore_dirs{$File::Next
::dir
};
2782 sub _compile_file_filter
{
2783 my ( $opt, $start ) = @_;
2785 my $ifiles = $opt->{ifiles
};
2788 my $ifiles_filters = App
::Ack
::Filter
::Collection-
>new();
2790 foreach my $filter_spec (@{$ifiles}) {
2791 if ( $filter_spec =~ /^(\w+):(.+)/ ) {
2792 my ($how,$what) = ($1,$2);
2793 my $filter = App
::Ack
::Filter-
>create_filter($how, split(/,/, $what));
2794 $ifiles_filters->add($filter);
2797 Carp
::croak
( qq{Invalid filter specification "$filter_spec"} );
2801 my $filters = $opt->{'filters'} || [];
2802 my $direct_filters = App
::Ack
::Filter
::Collection-
>new();
2803 my $inverse_filters = App
::Ack
::Filter
::Collection-
>new();
2805 foreach my $filter (@{$filters}) {
2806 if ($filter->is_inverted()) {
2807 # We want to check if files match the uninverted filters
2808 $inverse_filters->add($filter->invert());
2811 $direct_filters->add($filter);
2815 my %is_member_of_starting_set = map { (get_file_id
($_) => 1) } @{$start};
2817 my $ignore_dir_list = $opt->{idirs
};
2818 my $dont_ignore_dir_list = $opt->{no_ignore_dirs
};
2821 my %dont_ignore_dir_set;
2823 foreach my $filter (@{ $ignore_dir_list }) {
2824 if ( $filter =~ /^(\w+):(.*)/ ) {
2826 $ignore_dir_set{ $2 } = 1;
2828 Carp
::croak
( 'Non-is filters are not yet supported for --ignore-dir' );
2831 Carp
::croak
( qq{Invalid filter specification "$filter"} );
2834 foreach my $filter (@{ $dont_ignore_dir_list }) {
2835 if ( $filter =~ /^(\w+):(.*)/ ) {
2837 $dont_ignore_dir_set{ $2 } = 1;
2839 Carp
::croak
( 'Non-is filters are not yet supported for --ignore-dir' );
2842 Carp
::croak
( qq{Invalid filter specification "$filter"} );
2847 # ack always selects files that are specified on the command
2848 # line, regardless of filetype. If you want to ack a JPEG,
2849 # and say "ack foo whatever.jpg" it will do it for you.
2850 return 1 if $is_member_of_starting_set{ get_file_id
($File::Next
::name
) };
2852 if ( $dont_ignore_dir_list ) {
2853 my ( undef, $dirname ) = File
::Spec-
>splitpath($File::Next
::name
);
2854 my @dirs = File
::Spec-
>splitdir($dirname);
2856 my $is_ignoring = 0;
2858 foreach my $dir ( @dirs ) {
2859 if ( $ignore_dir_set{ $dir } ) {
2862 elsif ( $dont_ignore_dir_set{ $dir } ) {
2866 if ( $is_ignoring ) {
2871 # Ignore named pipes found in directory searching. Named
2872 # pipes created by subprocesses get specified on the command
2873 # line, so the rule of "always select whatever is on the
2874 # command line" wins.
2875 return 0 if -p
$File::Next
::name
;
2877 # we can't handle unreadable filenames; report them
2879 if ( $App::Ack
::report_bad_filenames
) {
2880 App
::Ack
::warn( "${File::Next::name}: cannot open file for reading" );
2885 my $resource = App
::Ack
::Resource
::Basic-
>new($File::Next
::name
);
2886 return 0 if ! $resource;
2887 if ( $ifiles_filters->filter($resource) ) {
2891 my $match_found = $direct_filters->filter($resource);
2893 # Don't bother invoking inverse filters unless we consider the current resource a match
2894 if ( $match_found && $inverse_filters->filter( $resource ) ) {
2897 return $match_found;
2902 my $resource = shift;
2905 my @types = filetypes
( $resource );
2906 my $types = join( ',', @types );
2907 my $arrow = @types ? ' => ' : ' =>';
2908 App
::Ack
::print( $resource->name, $arrow, join( ',', @types ), $ors );
2913 # Set default colors, load Term::ANSIColor
2915 eval 'use Term::ANSIColor 1.10 ()';
2916 eval 'use Win32::Console::ANSI' if $App::Ack
::is_windows
;
2918 $ENV{ACK_COLOR_MATCH
} ||= 'black on_yellow';
2919 $ENV{ACK_COLOR_FILENAME
} ||= 'bold green';
2920 $ENV{ACK_COLOR_LINENO
} ||= 'bold yellow';
2926 my ( $resource ) = @_;
2930 foreach my $k (keys %App::Ack
::mappings
) {
2931 my $filters = $App::Ack
::mappings
{$k};
2933 foreach my $filter (@{$filters}) {
2934 # clone the resource
2935 my $clone = $resource->clone;
2936 if ( $filter->filter($clone) ) {
2943 # http://search.cpan.org/dist/Perl-Critic/lib/Perl/Critic/Policy/Subroutines/ProhibitReturnSort.pm
2944 @matches = sort @matches;
2948 # Returns a (fairly) unique identifier for a file.
2949 # Use this function to compare two files to see if they're
2950 # equal (ie. the same file, but with a different path/links/etc).
2952 my ( $filename ) = @_;
2954 if ( $App::Ack
::is_windows
) {
2955 return File
::Next
::reslash
( $filename );
2958 # XXX is this the best method? it always hits the FS
2959 if( my ( $dev, $inode ) = (stat($filename))[0, 1] ) {
2960 return join(':', $dev, $inode);
2963 # XXX this could be better
2969 # Returns a regex object based on a string and command-line options.
2970 # Dies when the regex $str is undefined (i.e. not given on command line).
2976 defined $str or App
::Ack
::die( 'No regular expression found.' );
2978 $str = quotemeta( $str ) if $opt->{Q
};
2980 $str = "\\b$str" if $str =~ /^\w/;
2981 $str = "$str\\b" if $str =~ /\w$/;
2984 my $regex_is_lc = $str eq lc $str;
2985 if ( $opt->{i
} || ($opt->{smart_case
} && $regex_is_lc) ) {
2989 my $re = eval { qr/$str/ };
2991 die "Invalid regex '$str':\n $@";
3000 my @before_ctx_lines;
3001 my @after_ctx_lines;
3004 my $has_printed_something;
3007 $has_printed_something = 0;
3010 sub print_matches_in_resource
{
3011 my ( $resource, $opt ) = @_;
3013 my $passthru = $opt->{passthru
};
3014 my $max_count = $opt->{m
} || -1;
3016 my $filename = $resource->name;
3017 my $break = $opt->{break};
3018 my $heading = $opt->{heading
};
3019 my $ors = $opt->{print0
} ? "\0" : "\n";
3020 my $color = $opt->{color
};
3021 my $print_filename = $opt->{show_filename
};
3023 my $has_printed_for_this_resource = 0;
3027 local $opt->{before_context
} = $opt->{output
} ? 0 : $opt->{before_context
};
3028 local $opt->{after_context
} = $opt->{output
} ? 0 : $opt->{after_context
};
3030 my $n_before_ctx_lines = $opt->{before_context
} || 0;
3031 my $n_after_ctx_lines = $opt->{after_context
} || 0;
3033 @after_ctx_lines = @before_ctx_lines = ();
3035 my $fh = $resource->open();
3037 if ( $App::Ack
::report_bad_filenames
) {
3038 App
::Ack
::warn( "$filename: $!" );
3043 my $display_filename = $filename;
3044 if ( $print_filename && $heading && $color ) {
3045 $display_filename = Term
::ANSIColor
::colored
($display_filename, $ENV{ACK_COLOR_FILENAME
});
3048 # check for context before the main loop, so we don't
3049 # pay for it if we don't need it
3050 if ( $n_before_ctx_lines || $n_after_ctx_lines ) {
3051 my $current_line = <$fh>; # prime the first line of input
3053 while ( defined $current_line ) {
3054 while ( (@after_ctx_lines < $n_after_ctx_lines) && defined($_ = <$fh>) ) {
3055 push @after_ctx_lines, $_;
3058 local $_ = $current_line;
3059 my $former_dot_period = $.;
3060 $. -= @after_ctx_lines;
3062 if ( does_match
($opt, $_) ) {
3063 if ( !$has_printed_for_this_resource ) {
3064 if ( $break && $has_printed_something ) {
3065 App
::Ack
::print_blank_line
();
3067 if ( $print_filename && $heading ) {
3068 App
::Ack
::print_filename
( $display_filename, $ors );
3071 print_line_with_context
($opt, $filename, $_, $.);
3072 $has_printed_for_this_resource = 1;
3076 elsif ( $passthru ) {
3077 chomp; # XXX proper newline handling?
3078 # XXX inline this call?
3079 if ( $break && !$has_printed_for_this_resource && $has_printed_something ) {
3080 App
::Ack
::print_blank_line
();
3082 print_line_with_options
($opt, $filename, $_, $., ':');
3083 $has_printed_for_this_resource = 1;
3085 last unless $max_count != 0;
3087 # I tried doing this with local(), but for some reason,
3088 # $. continued to have its new value after the exit of the
3089 # enclosing block. I'm guessing that $. has some extra
3090 # magic associated with it or something. If someone can
3091 # tell me why this happened, I would love to know!
3092 $. = $former_dot_period; # XXX this won't happen on an exception
3094 if ( $n_before_ctx_lines ) {
3095 push @before_ctx_lines, $current_line;
3096 shift @before_ctx_lines while @before_ctx_lines > $n_before_ctx_lines;
3098 if ( $n_after_ctx_lines ) {
3099 $current_line = shift @after_ctx_lines;
3102 $current_line = <$fh>;
3110 if ( does_match
($opt, $_) ) {
3111 if ( !$has_printed_for_this_resource ) {
3112 if ( $break && $has_printed_something ) {
3113 App
::Ack
::print_blank_line
();
3115 if ( $print_filename && $heading ) {
3116 App
::Ack
::print_filename
( $display_filename, $ors );
3119 print_line_with_context
($opt, $filename, $_, $.);
3120 $has_printed_for_this_resource = 1;
3124 elsif ( $passthru ) {
3125 chomp; # XXX proper newline handling?
3126 if ( $break && !$has_printed_for_this_resource && $has_printed_something ) {
3127 App
::Ack
::print_blank_line
();
3129 print_line_with_options
($opt, $filename, $_, $., ':');
3130 $has_printed_for_this_resource = 1;
3132 last unless $max_count != 0;
3136 $is_iterating = 0; # XXX this won't happen on an exception
3137 # then again, do we care? ack doesn't really
3138 # handle exceptions anyway.
3143 sub print_line_with_options
{
3144 my ( $opt, $filename, $line, $line_no, $separator ) = @_;
3146 $has_printed_something = 1;
3148 my $print_filename = $opt->{show_filename
};
3149 my $print_column = $opt->{column
};
3150 my $ors = $opt->{print0
} ? "\0" : "\n";
3151 my $heading = $opt->{heading
};
3152 my $output_expr = $opt->{output
};
3153 my $color = $opt->{color
};
3158 $filename = Term
::ANSIColor
::colored
($filename,
3159 $ENV{ACK_COLOR_FILENAME
});
3160 $line_no = Term
::ANSIColor
::colored
($line_no,
3161 $ENV{ACK_COLOR_LINENO
});
3164 if($print_filename) {
3166 push @line_parts, $line_no;
3169 push @line_parts, $filename, $line_no;
3172 if( $print_column ) {
3173 push @line_parts, get_match_column
();
3176 if( $output_expr ) {
3177 while ( $line =~ /$opt->{regex}/og ) {
3178 my $output = eval $output_expr;
3179 App
::Ack
::print( join( $separator, @line_parts, $output ), $ors );
3184 $line =~ /$opt->{regex}/o; # this match is redundant, but we need
3185 # to perfom it in order to get if
3186 # capture groups are set
3188 if ( @+ > 1 ) { # if we have captures
3189 while ( $line =~ /$opt->{regex}/og ) {
3190 my $offset = 0; # additional offset for when we add stuff
3191 my $previous_match_end = 0;
3193 for ( my $i = 1; $i < @+; $i++ ) {
3194 my ( $match_start, $match_end ) = ( $-[$i], $+[$i] );
3196 next unless defined($match_start);
3197 next if $match_start < $previous_match_end;
3199 my $substring = substr( $line,
3200 $offset + $match_start, $match_end - $match_start );
3201 my $substitution = Term
::ANSIColor
::colored
( $substring,
3202 $ENV{ACK_COLOR_MATCH
} );
3204 substr( $line, $offset + $match_start,
3205 $match_end - $match_start, $substitution );
3207 $previous_match_end = $match_end; # offsets do not need to be applied
3208 $offset += length( $substitution ) - length( $substring );
3211 pos($line) = $+[0] + $offset;
3215 my $matched = 0; # flag; if matched, need to escape afterwards
3217 while ( $line =~ /$opt->{regex}/og ) {
3220 my ( $match_start, $match_end ) = ($-[0], $+[0]);
3221 next unless defined($match_start);
3223 my $substring = substr( $line, $match_start,
3224 $match_end - $match_start );
3225 my $substitution = Term
::ANSIColor
::colored
( $substring,
3226 $ENV{ACK_COLOR_MATCH
} );
3228 substr( $line, $match_start, $match_end - $match_start,
3231 pos($line) = $match_end +
3232 (length( $substitution ) - length( $substring ));
3234 # XXX why do we do this?
3235 $line .= "\033[0m\033[K" if $matched;
3239 push @line_parts, $line;
3240 App
::Ack
::print( join( $separator, @line_parts ), $ors );
3247 my ( $resource, $opt, $cb ) = @_;
3251 local $opt->{before_context
} = $opt->{output
} ? 0 : $opt->{before_context
};
3252 local $opt->{after_context
} = $opt->{output
} ? 0 : $opt->{after_context
};
3254 my $n_before_ctx_lines = $opt->{before_context
} || 0;
3255 my $n_after_ctx_lines = $opt->{after_context
} || 0;
3257 @after_ctx_lines = @before_ctx_lines = ();
3259 my $fh = $resource->open();
3261 if ( $App::Ack
::report_bad_filenames
) {
3262 # XXX direct access to filename
3263 App
::Ack
::warn( "$resource->{filename}: $!" );
3268 # check for context before the main loop, so we don't
3269 # pay for it if we don't need it
3270 if ( $n_before_ctx_lines || $n_after_ctx_lines ) {
3271 my $current_line = <$fh>; # prime the first line of input
3273 while ( defined $current_line ) {
3274 while ( (@after_ctx_lines < $n_after_ctx_lines) && defined($_ = <$fh>) ) {
3275 push @after_ctx_lines, $_;
3278 local $_ = $current_line;
3279 my $former_dot_period = $.;
3280 $. -= @after_ctx_lines;
3282 last unless $cb->();
3284 # I tried doing this with local(), but for some reason,
3285 # $. continued to have its new value after the exit of the
3286 # enclosing block. I'm guessing that $. has some extra
3287 # magic associated with it or something. If someone can
3288 # tell me why this happened, I would love to know!
3289 $. = $former_dot_period; # XXX this won't happen on an exception
3291 if ( $n_before_ctx_lines ) {
3292 push @before_ctx_lines, $current_line;
3293 shift @before_ctx_lines while @before_ctx_lines > $n_before_ctx_lines;
3295 if ( $n_after_ctx_lines ) {
3296 $current_line = shift @after_ctx_lines;
3299 $current_line = <$fh>;
3307 last unless $cb->();
3311 $is_iterating = 0; # XXX this won't happen on an exception
3312 # then again, do we care? ack doesn't really
3313 # handle exceptions anyway.
3319 if ( not $is_iterating ) {
3320 Carp
::croak
( 'get_context() called outside of iterate()' );
3324 scalar(@before_ctx_lines) ? \
@before_ctx_lines : undef,
3325 scalar(@after_ctx_lines) ? \
@after_ctx_lines : undef,
3334 my $previous_file_processed;
3335 my $previous_line_printed;
3338 $is_first_match = 1;
3339 $previous_line_printed = -1;
3342 sub print_line_with_context
{
3343 my ( $opt, $filename, $matching_line, $line_no ) = @_;
3345 my $heading = $opt->{heading
};
3347 if( !defined($previous_file_processed) ||
3348 $previous_file_processed ne $filename ) {
3349 $previous_file_processed = $filename;
3350 $previous_line_printed = -1;
3353 $is_first_match = 1;
3357 my $ors = $opt->{print0
} ? "\0" : "\n";
3358 my $match_word = $opt->{w
};
3359 my $is_tracking_context = $opt->{after_context
} || $opt->{before_context
};
3360 my $output_expr = $opt->{output
};
3362 $matching_line =~ s/[\r\n]+$//g;
3364 my ( $before_context, $after_context ) = get_context
();
3366 if ( $before_context ) {
3367 my $first_line = $. - @{$before_context};
3369 if ( $first_line <= $previous_line_printed ) {
3370 splice @{$before_context}, 0, $previous_line_printed - $first_line + 1;
3371 $first_line = $. - @{$before_context};
3373 if ( @{$before_context} ) {
3374 my $offset = @{$before_context};
3376 if( !$is_first_match && $previous_line_printed != $first_line - 1 ) {
3377 App
::Ack
::print('--', $ors);
3379 foreach my $line (@{$before_context}) {
3380 my $context_line_no = $. - $offset;
3381 if ( $context_line_no <= $previous_line_printed ) {
3386 print_line_with_options
($opt, $filename, $line, $context_line_no, '-');
3387 $previous_line_printed = $context_line_no;
3393 if ( $. > $previous_line_printed ) {
3394 if( $is_tracking_context && !$is_first_match && $previous_line_printed != $. - 1 ) {
3395 App
::Ack
::print('--', $ors);
3398 print_line_with_options
($opt, $filename, $matching_line, $line_no, ':');
3399 $previous_line_printed = $.;
3402 if($after_context) {
3404 foreach my $line (@{$after_context}) {
3406 if ( $previous_line_printed >= $. + $offset ) {
3411 my $separator = ($opt->{regex
} && does_match
( $opt, $line )) ? ':' : '-';
3412 print_line_with_options
($opt, $filename, $line, $. + $offset, $separator);
3413 $previous_line_printed = $. + $offset;
3418 $is_first_match = 0;
3427 my $match_column_number;
3429 # does_match() MUST have an $opt->{regex} set.
3432 my ( $opt, $line ) = @_;
3434 $match_column_number = undef;
3437 return ( $line !~ /$opt->{regex}/o );
3440 if ( $line =~ /$opt->{regex}/o ) {
3441 # @- = @LAST_MATCH_START
3442 # @+ = @LAST_MATCH_END
3443 $match_column_number = $-[0] + 1;
3452 sub get_match_column
{
3453 return $match_column_number;
3458 sub resource_has_match
{
3459 my ( $resource, $opt ) = @_;
3462 my $fh = $resource->open();
3464 if ( $App::Ack
::report_bad_filenames
) {
3465 # XXX direct access to filename
3466 App
::Ack
::warn( "$resource->{filename}: $!" );
3470 my $opt_v = $opt->{v
};
3471 my $re = $opt->{regex
};
3473 if (/$re/o xor $opt_v) {
3484 sub count_matches_in_resource
{
3485 my ( $resource, $opt ) = @_;
3488 my $fh = $resource->open();
3490 if ( $App::Ack
::report_bad_filenames
) {
3491 # XXX direct access to filename
3492 App
::Ack
::warn( "$resource->{filename}: $!" );
3496 my $opt_v = $opt->{v
};
3497 my $re = $opt->{regex
};
3499 ++$nmatches if (/$re/o xor $opt_v);
3508 my @arg_sources = App
::Ack
::ConfigLoader
::retrieve_arg_sources
();
3510 my $opt = App
::Ack
::ConfigLoader
::process_args
( @arg_sources );
3512 $App::Ack
::report_bad_filenames
= !$opt->{dont_report_bad_filenames
};
3514 if ( $opt->{flush
} ) {
3518 if ( not defined $opt->{color
} ) {
3519 my $windows_color = 1;
3520 if ( $App::Ack
::is_windows
) {
3521 $windows_color = eval { require Win32
::Console
::ANSI
; }
3523 $opt->{color
} = !App
::Ack
::output_to_pipe
() && $windows_color;
3525 if ( not defined $opt->{heading
} and not defined $opt->{break} ) {
3526 $opt->{heading
} = $opt->{break} = !App
::Ack
::output_to_pipe
();
3529 if ( defined($opt->{H
}) || defined($opt->{h
}) ) {
3530 $opt->{show_filename
}= $opt->{H
} && !$opt->{h
};
3533 if ( my $output = $opt->{output
} ) {
3534 $output =~ s{\\}{\\\\}g;
3535 $output =~ s{"}{\\"}g;
3536 $opt->{output
} = qq{"$output"};
3540 if ( $App::Ack
::is_filter_mode
&& !$opt->{files_from
} ) { # probably -x
3541 $resources = App
::Ack
::Resources-
>from_stdin( $opt );
3542 my $regex = $opt->{regex
};
3543 $regex = shift @ARGV if not defined $regex;
3544 $opt->{regex
} = build_regex
( $regex, $opt );
3547 if ( $opt->{f
} || $opt->{lines
} ) {
3548 if ( $opt->{regex
} ) {
3549 App
::Ack
::warn( "regex ($opt->{regex}) specified with -f or --lines" );
3550 App
::Ack
::exit_from_ack
( 0 ); # XXX the 0 is misleading
3554 my $regex = $opt->{regex
};
3555 $regex = shift @ARGV if not defined $regex;
3556 $opt->{regex
} = build_regex
( $regex, $opt );
3559 if ( not defined $opt->{files_from
} ) {
3562 if ( !exists($opt->{show_filename
}) ) {
3563 unless(@start == 1 && !(-d
$start[0])) {
3564 $opt->{show_filename
} = 1;
3568 if ( defined $opt->{files_from
} ) {
3569 $resources = App
::Ack
::Resources-
>from_file( $opt, $opt->{files_from
} );
3570 exit 1 unless $resources;
3573 @start = ('.') unless @start;
3574 foreach my $target (@start) {
3575 if ( !-e
$target && $App::Ack
::report_bad_filenames
) {
3576 App
::Ack
::warn( "$target: No such file or directory" );
3580 $opt->{file_filter
} = _compile_file_filter
($opt, \
@start);
3581 $opt->{descend_filter
} = _compile_descend_filter
($opt);
3583 $resources = App
::Ack
::Resources-
>from_argv( $opt, \
@start );
3586 App
::Ack
::set_up_pager
( $opt->{pager
} ) if defined $opt->{pager
};
3588 my $print_filenames = $opt->{show_filename
};
3589 my $max_count = $opt->{m
};
3590 my $ors = $opt->{print0
} ? "\0" : "\n";
3591 my $only_first = $opt->{1};
3594 my $total_count = 0;
3596 while ( my $resource = $resources->next ) {
3597 # XXX this variable name combined with what we're trying
3598 # to do makes no sense.
3600 # XXX Combine the -f and -g functions
3602 # XXX printing should probably happen inside of App::Ack
3603 if ( $opt->{show_types
} ) {
3604 show_types
( $resource, $ors );
3607 App
::Ack
::print( $resource->name, $ors );
3610 last RESOURCES
if defined($max_count) && $nmatches >= $max_count;
3612 elsif ( $opt->{g
} ) {
3613 my $is_match = ( $resource->name =~ /$opt->{regex}/o );
3614 if ( $opt->{v
} ? !$is_match : $is_match ) {
3615 if ( $opt->{show_types
} ) {
3616 show_types
( $resource, $ors );
3619 App
::Ack
::print( $resource->name, $ors );
3622 last RESOURCES
if defined($max_count) && $nmatches >= $max_count;
3625 elsif ( $opt->{lines
} ) {
3626 my $print_filename = $opt->{show_filename
};
3627 my $passthru = $opt->{passthru
};
3630 foreach my $line ( @{ $opt->{lines
} } ) {
3631 my @lines = split /,/, $line;
3637 @line_numbers{@lines} = (1) x
@lines;
3640 my $filename = $resource->name;
3642 local $opt->{color
} = 0;
3644 iterate
($resource, $opt, sub {
3647 if ( $line_numbers{$.} ) {
3648 print_line_with_context
($opt, $filename, $_, $.);
3650 elsif ( $passthru ) {
3651 print_line_with_options
($opt, $filename, $_, $., ':');
3656 elsif ( $opt->{count
} ) {
3657 my $matches_for_this_file = count_matches_in_resource
( $resource, $opt );
3659 unless ( $opt->{show_filename
} ) {
3660 $total_count += $matches_for_this_file;
3664 if ( !$opt->{l
} || $matches_for_this_file > 0) {
3665 if ( $print_filenames ) {
3666 App
::Ack
::print( $resource->name, ':', $matches_for_this_file, $ors );
3669 App
::Ack
::print( $matches_for_this_file, $ors );
3673 elsif ( $opt->{l
} || $opt->{L
} ) {
3674 my $is_match = resource_has_match
( $resource, $opt );
3676 if ( $opt->{L
} ? !$is_match : $is_match ) {
3677 App
::Ack
::print( $resource->name, $ors );
3680 last RESOURCES
if $only_first;
3681 last RESOURCES
if defined($max_count) && $nmatches >= $max_count;
3685 $nmatches += print_matches_in_resource
( $resource, $opt );
3686 if ( $nmatches && $only_first ) {
3692 if ( $opt->{count
} && !$opt->{show_filename
} ) {
3693 App
::Ack
::print( $total_count, "\n" );
3696 close $App::Ack
::fh
;
3697 App
::Ack
::exit_from_ack
( $nmatches );
3704 ack - grep-like text finder
3708 ack [options] PATTERN [FILE...]
3709 ack -f [options] [DIRECTORY...]
3713 Ack is designed as a replacement for 99% of the uses of F<grep>.
3715 Ack searches the named input FILEs (or standard input if no files
3716 are named, or the file name - is given) for lines containing a match
3717 to the given PATTERN. By default, ack prints the matching lines.
3719 PATTERN is a Perl regular expression. Perl regular expressions
3720 are commonly found in other programming languages, but for the particulars
3721 of their behavior, please consult
3722 L<http://perldoc.perl.org/perlreref.html|perlreref>. If you don't know
3723 how to use regular expression but are interested in learning, you may
3724 consult L<http://perldoc.perl.org/perlretut.html|perlretut>. If you do not
3725 need or want ack to use regular expressions, please see the
3726 C<-Q>/C<--literal> option.
3728 Ack can also list files that would be searched, without actually
3729 searching them, to let you take advantage of ack's file-type filtering
3732 =head1 FILE SELECTION
3734 If files are not specified for searching, either on the command
3735 line or piped in with the C<-x> option, I<ack> delves into
3736 subdirectories selecting files for searching.
3738 I<ack> is intelligent about the files it searches. It knows about
3739 certain file types, based on both the extension on the file and,
3740 in some cases, the contents of the file. These selections can be
3741 made with the B<--type> option.
3743 With no file selection, I<ack> searches through regular files that
3744 are not explicitly excluded by B<--ignore-dir> and B<--ignore-file>
3745 options, either present in F<ackrc> files or on the command line.
3747 The default options for I<ack> ignore certain files and directories. These
3752 =item * Backup files: Files matching F<#*#> or ending with F<~>.
3754 =item * Coredumps: Files matching F<core.\d+>
3756 =item * Version control directories like F<.svn> and F<.git>.
3760 Run I<ack> with the C<--dump> option to see what settings are set.
3762 However, I<ack> always searches the files given on the command line,
3763 no matter what type. If you tell I<ack> to search in a coredump,
3764 it will search in a coredump.
3766 =head1 DIRECTORY SELECTION
3768 I<ack> descends through the directory tree of the starting directories
3769 specified. If no directories are specified, the current working directory is
3770 used. However, it will ignore the shadow directories used by
3771 many version control systems, and the build directories used by the
3772 Perl MakeMaker system. You may add or remove a directory from this
3773 list with the B<--[no]ignore-dir> option. The option may be repeated
3774 to add/remove multiple directories from the ignore list.
3776 For a complete list of directories that do not get searched, run
3779 =head1 WHEN TO USE GREP
3781 I<ack> trumps I<grep> as an everyday tool 99% of the time, but don't
3782 throw I<grep> away, because there are times you'll still need it.
3784 E.g., searching through huge files looking for regexes that can be
3785 expressed with I<grep> syntax should be quicker with I<grep>.
3787 If your script or parent program uses I<grep> C<--quiet> or C<--silent>
3788 or needs exit 2 on IO error, use I<grep>.
3796 Specifies an ackrc file to load after all others; see L</"ACKRC LOCATION SEMANTICS">.
3798 =item B<-A I<NUM>>, B<--after-context=I<NUM>>
3800 Print I<NUM> lines of trailing context after matching lines.
3802 =item B<-B I<NUM>>, B<--before-context=I<NUM>>
3804 Print I<NUM> lines of leading context before matching lines.
3806 =item B<--[no]break>
3808 Print a break between results from different files. On by default
3809 when used interactively.
3811 =item B<-C [I<NUM>]>, B<--context[=I<NUM>]>
3813 Print I<NUM> lines (default 2) of context around matching lines.
3815 =item B<-c>, B<--count>
3817 Suppress normal output; instead print a count of matching lines for
3818 each input file. If B<-l> is in effect, it will only show the
3819 number of lines for each file that has lines matching. Without
3820 B<-l>, some line counts may be zeroes.
3822 If combined with B<-h> (B<--no-filename>) ack outputs only one total
3825 =item B<--[no]color>, B<--[no]colour>
3827 B<--color> highlights the matching text. B<--nocolor> suppresses
3828 the color. This is on by default unless the output is redirected.
3830 On Windows, this option is off by default unless the
3831 L<Win32::Console::ANSI> module is installed or the C<ACK_PAGER_COLOR>
3832 environment variable is used.
3834 =item B<--color-filename=I<color>>
3836 Sets the color to be used for filenames.
3838 =item B<--color-match=I<color>>
3840 Sets the color to be used for matches.
3842 =item B<--color-lineno=I<color>>
3844 Sets the color to be used for line numbers.
3846 =item B<--[no]column>
3848 Show the column number of the first match. This is helpful for
3849 editors that can place your cursor at a given position.
3851 =item B<--create-ackrc>
3853 Dumps the default ack options to standard output. This is useful for
3854 when you want to customize the defaults.
3858 Writes the list of options loaded and where they came from to standard
3859 output. Handy for debugging.
3863 B<--noenv> disables all environment processing. No F<.ackrc> is
3864 read and all environment variables are ignored. By default, F<ack>
3865 considers F<.ackrc> and settings in the environment.
3869 B<--flush> flushes output immediately. This is off by default
3870 unless ack is running interactively (when output goes to a pipe or
3875 Only print the files that would be searched, without actually doing
3876 any searching. PATTERN must not be specified, or it will be taken
3877 as a path to search.
3879 =item B<--files-from=I<FILE>>
3881 The list of files to be searched is specified in I<FILE>. The list of
3882 files are separated by newlines. If I<FILE> is C<->, the list is loaded
3883 from standard input.
3885 =item B<--[no]filter>
3887 Forces ack to act as if it were receiving input via a pipe.
3889 =item B<--[no]follow>
3891 Follow or don't follow symlinks, other than whatever starting files
3892 or directories were specified on the command line.
3894 This is off by default.
3896 =item B<-g I<PATTERN>>
3898 Print files where the relative path + filename matches I<PATTERN>.
3900 =item B<--[no]group>
3902 B<--group> groups matches by file name. This is the default
3903 when used interactively.
3905 B<--nogroup> prints one result per line, like grep. This is the
3906 default when output is redirected.
3908 =item B<-H>, B<--with-filename>
3910 Print the filename for each match. This is the default unless searching
3911 a single explicitly specified file.
3913 =item B<-h>, B<--no-filename>
3915 Suppress the prefixing of filenames on output when multiple files are
3918 =item B<--[no]heading>
3920 Print a filename heading above each file's results. This is the default
3921 when used interactively.
3923 =item B<--help>, B<-?>
3925 Print a short help statement.
3927 =item B<--help-types>, B<--help=types>
3929 Print all known types.
3931 =item B<-i>, B<--ignore-case>
3933 Ignore case distinctions in PATTERN
3935 =item B<--ignore-ack-defaults>
3937 Tells ack to completely ignore the default definitions provided with ack.
3938 This is useful in combination with B<--create-ackrc> if you I<really> want
3941 =item B<--[no]ignore-dir=I<DIRNAME>>, B<--[no]ignore-directory=I<DIRNAME>>
3943 Ignore directory (as CVS, .svn, etc are ignored). May be used
3944 multiple times to ignore multiple directories. For example, mason
3945 users may wish to include B<--ignore-dir=data>. The B<--noignore-dir>
3946 option allows users to search directories which would normally be
3947 ignored (perhaps to research the contents of F<.svn/props> directories).
3949 The I<DIRNAME> must always be a simple directory name. Nested
3950 directories like F<foo/bar> are NOT supported. You would need to
3951 specify B<--ignore-dir=foo> and then no files from any foo directory
3952 are taken into account by ack unless given explicitly on the command
3955 =item B<--ignore-file=I<FILTERTYPE:FILTERARGS>>
3957 Ignore files matching I<FILTERTYPE:FILTERARGS>. The filters are specified
3958 identically to file type filters as seen in L</"Defining your own types">.
3960 =item B<-k>, B<--known-types>
3962 Limit selected files to those with types that ack knows about. This is
3963 equivalent to the default behavior found in ack 1.
3965 =item B<--lines=I<NUM>>
3967 Only print line I<NUM> of each file. Multiple lines can be given with multiple
3968 B<--lines> options or as a comma separated list (B<--lines=3,5,7>). B<--lines=4-7>
3969 also works. The lines are always output in ascending order, no matter the
3970 order given on the command line.
3972 =item B<-l>, B<--files-with-matches>
3974 Only print the filenames of matching files, instead of the matching text.
3976 =item B<-L>, B<--files-without-matches>
3978 Only print the filenames of files that do I<NOT> match.
3980 =item B<--match I<PATTERN>>
3982 Specify the I<PATTERN> explicitly. This is helpful if you don't want to put the
3983 regex as your first argument, e.g. when executing multiple searches over the
3986 # search for foo and bar in given files
3987 ack file1 t/file* --match foo
3988 ack file1 t/file* --match bar
3990 =item B<-m=I<NUM>>, B<--max-count=I<NUM>>
3992 Stop reading a file after I<NUM> matches.
3996 Print this manual page.
3998 =item B<-n>, B<--no-recurse>
4000 No descending into subdirectories.
4004 Show only the part of each line matching PATTERN (turns off text
4007 =item B<--output=I<expr>>
4009 Output the evaluation of I<expr> for each line (turns off text
4011 If PATTERN matches more than once then a line is output for each non-overlapping match.
4012 For more information please see the section L</"Examples of F<--output>">.
4014 =item B<--pager=I<program>>, B<--nopager>
4016 B<--pager> directs ack's output through I<program>. This can also be specified
4017 via the C<ACK_PAGER> and C<ACK_PAGER_COLOR> environment variables.
4019 Using --pager does not suppress grouping and coloring like piping
4020 output on the command-line does.
4022 B<--nopager> cancels any setting in ~/.ackrc, C<ACK_PAGER> or C<ACK_PAGER_COLOR>.
4023 No output will be sent through a pager.
4027 Prints all lines, whether or not they match the expression. Highlighting
4028 will still work, though, so it can be used to highlight matches while
4029 still seeing the entire file, as in:
4031 # Watch a log file, and highlight a certain IP address
4032 $ tail -f ~/access.log | ack --passthru 123.45.67.89
4036 Only works in conjunction with -f, -g, -l or -c (filename output). The filenames
4037 are output separated with a null byte instead of the usual newline. This is
4038 helpful when dealing with filenames that contain whitespace, e.g.
4040 # remove all files of type html
4041 ack -f --html --print0 | xargs -0 rm -f
4043 =item B<-Q>, B<--literal>
4045 Quote all metacharacters in PATTERN, it is treated as a literal.
4047 =item B<-r>, B<-R>, B<--recurse>
4049 Recurse into sub-directories. This is the default and just here for
4050 compatibility with grep. You can also use it for turning B<--no-recurse> off.
4054 Suppress error messages about nonexistent or unreadable files. This is taken
4057 =item B<--[no]smart-case>, B<--no-smart-case>
4059 Ignore case in the search strings if PATTERN contains no uppercase
4060 characters. This is similar to C<smartcase> in vim. This option is
4061 off by default, and ignored if C<-i> is specified.
4063 B<-i> always overrides this option.
4065 =item B<--sort-files>
4067 Sorts the found files lexicographically. Use this if you want your file
4068 listings to be deterministic between runs of I<ack>.
4070 =item B<--show-types>
4072 Outputs the filetypes that ack associates with each file.
4074 Works with B<-f> and B<-g> options.
4076 =item B<--type=[no]TYPE>
4078 Specify the types of files to include or exclude from a search.
4079 TYPE is a filetype, like I<perl> or I<xml>. B<--type=perl> can
4080 also be specified as B<--perl>, and B<--type=noperl> can be done
4083 If a file is of both type "foo" and "bar", specifying --foo and
4084 --nobar will exclude the file, because an exclusion takes precedence
4087 Type specifications can be repeated and are ORed together.
4089 See I<ack --help=types> for a list of valid types.
4091 =item B<--type-add I<TYPE>:I<FILTER>:I<FILTERARGS>>
4093 Files with the given FILTERARGS applied to the given FILTER
4094 are recognized as being of (the existing) type TYPE.
4095 See also L</"Defining your own types">.
4098 =item B<--type-set I<TYPE>:I<FILTER>:I<FILTERARGS>>
4100 Files with the given FILTERARGS applied to the given FILTER are recognized as
4101 being of type TYPE. This replaces an existing definition for type TYPE. See
4102 also L</"Defining your own types">.
4104 =item B<--type-del I<TYPE>>
4106 The filters associated with TYPE are removed from Ack, and are no longer considered
4109 =item B<-v>, B<--invert-match>
4111 Invert match: select non-matching lines
4115 Display version and copyright information.
4117 =item B<-w>, B<--word-regexp>
4119 Force PATTERN to match only whole words. The PATTERN is wrapped with
4120 C<\b> metacharacters.
4124 An abbreviation for B<--files-from=->; the list of files to search are read
4125 from standard input, with one line per file.
4129 Stops after reporting first match of any kind. This is different
4130 from B<--max-count=1> or B<-m1>, where only one match per file is
4131 shown. Also, B<-1> works with B<-f> and B<-g>, where B<-m> does
4136 Display the all-important Bill The Cat logo. Note that the exact
4137 spelling of B<--thpppppt> is not important. It's checked against
4138 a regular expression.
4142 Check with the admiral for traps.
4146 Chocolate, Chocolate, Chocolate!
4150 =head1 THE .ackrc FILE
4152 The F<.ackrc> file contains command-line options that are prepended
4153 to the command line before processing. Multiple options may live
4154 on multiple lines. Lines beginning with a # are ignored. A F<.ackrc>
4155 might look like this:
4157 # Always sort the files
4160 # Always color, even if piping to a another program
4163 # Use "less -r" as my pager
4166 Note that arguments with spaces in them do not need to be quoted,
4167 as they are not interpreted by the shell. Basically, each I<line>
4168 in the F<.ackrc> file is interpreted as one element of C<@ARGV>.
4170 F<ack> looks in several locations for F<.ackrc> files; the searching
4171 process is detailed in L</"ACKRC LOCATION SEMANTICS">. These
4172 files are not considered if B<--noenv> is specified on the command line.
4174 =head1 Defining your own types
4176 ack allows you to define your own types in addition to the predefined
4177 types. This is done with command line options that are best put into
4178 an F<.ackrc> file - then you do not have to define your types over and
4179 over again. In the following examples the options will always be shown
4180 on one command line so that they can be easily copy & pasted.
4182 I<ack --perl foo> searches for foo in all perl files. I<ack --help=types>
4183 tells you, that perl files are files ending
4184 in .pl, .pm, .pod or .t. So what if you would like to include .xs
4185 files as well when searching for --perl files? I<ack --type-add perl:ext:xs --perl foo>
4186 does this for you. B<--type-add> appends
4187 additional extensions to an existing type.
4189 If you want to define a new type, or completely redefine an existing
4190 type, then use B<--type-set>. I<ack --type-set eiffel:ext:e,eiffel> defines
4191 the type I<eiffel> to include files with
4192 the extensions .e or .eiffel. So to search for all eiffel files
4193 containing the word Bertrand use I<ack --type-set eiffel:ext:e,eiffel --eiffel Bertrand>.
4194 As usual, you can also write B<--type=eiffel>
4195 instead of B<--eiffel>. Negation also works, so B<--noeiffel> excludes
4196 all eiffel files from a search. Redefining also works: I<ack --type-set cc:ext:c,h>
4197 and I<.xs> files no longer belong to the type I<cc>.
4199 When defining your own types in the F<.ackrc> file you have to use
4202 --type-set=eiffel:ext:e,eiffel
4204 or writing on separate lines
4209 The following does B<NOT> work in the F<.ackrc> file:
4211 --type-set eiffel:ext:e,eiffel
4214 In order to see all currently defined types, use I<--help-types>, e.g.
4215 I<ack --type-set backup:ext:bak --type-add perl:ext:perl --help-types>
4217 In addition to filtering based on extension (like ack 1.x allowed), ack 2
4218 offers additional filter types. The generic syntax is
4219 I<--type-set TYPE:FILTER:FILTERARGS>; I<FILTERARGS> depends on the value
4224 =item is:I<FILENAME>
4226 I<is> filters match the target filename exactly. It takes exactly one
4227 argument, which is the name of the file to match.
4231 --type-set make:is:Makefile
4233 =item ext:I<EXTENSION>[,I<EXTENSION2>[,...]]
4235 I<ext> filters match the extension of the target file against a list
4236 of extensions. No leading dot is needed for the extensions.
4240 --type-set perl:ext:pl,pm,t
4242 =item match:I<PATTERN>
4244 I<match> filters match the target filename against a regular expression.
4245 The regular expression is made case insensitive for the search.
4249 --type-set make:match:/(gnu)?makefile/
4251 =item firstlinematch:I<PATTERN>
4253 I<firstlinematch> matches the first line of the target file against a
4254 regular expression. Like I<match>, the regular expression is made
4259 --type-add perl:firstlinematch:/perl/
4263 More filter types may be made available in the future.
4265 =head1 ENVIRONMENT VARIABLES
4267 For commonly-used ack options, environment variables can make life
4268 much easier. These variables are ignored if B<--noenv> is specified
4269 on the command line.
4275 Specifies the location of the user's F<.ackrc> file. If this file doesn't
4276 exist, F<ack> looks in the default location.
4280 This variable specifies default options to be placed in front of
4281 any explicit options on the command line.
4283 =item ACK_COLOR_FILENAME
4285 Specifies the color of the filename when it's printed in B<--group>
4286 mode. By default, it's "bold green".
4288 The recognized attributes are clear, reset, dark, bold, underline,
4289 underscore, blink, reverse, concealed black, red, green, yellow,
4290 blue, magenta, on_black, on_red, on_green, on_yellow, on_blue,
4291 on_magenta, on_cyan, and on_white. Case is not significant.
4292 Underline and underscore are equivalent, as are clear and reset.
4293 The color alone sets the foreground color, and on_color sets the
4296 This option can also be set with B<--color-filename>.
4298 =item ACK_COLOR_MATCH
4300 Specifies the color of the matching text when printed in B<--color>
4301 mode. By default, it's "black on_yellow".
4303 This option can also be set with B<--color-match>.
4305 See B<ACK_COLOR_FILENAME> for the color specifications.
4307 =item ACK_COLOR_LINENO
4309 Specifies the color of the line number when printed in B<--color>
4310 mode. By default, it's "bold yellow".
4312 This option can also be set with B<--color-lineno>.
4314 See B<ACK_COLOR_FILENAME> for the color specifications.
4318 Specifies a pager program, such as C<more>, C<less> or C<most>, to which
4319 ack will send its output.
4321 Using C<ACK_PAGER> does not suppress grouping and coloring like
4322 piping output on the command-line does, except that on Windows
4323 ack will assume that C<ACK_PAGER> does not support color.
4325 C<ACK_PAGER_COLOR> overrides C<ACK_PAGER> if both are specified.
4327 =item ACK_PAGER_COLOR
4329 Specifies a pager program that understands ANSI color sequences.
4330 Using C<ACK_PAGER_COLOR> does not suppress grouping and coloring
4331 like piping output on the command-line does.
4333 If you are not on Windows, you never need to use C<ACK_PAGER_COLOR>.
4337 =head1 ACK & OTHER TOOLS
4339 =head2 Vim integration
4341 F<ack> integrates easily with the Vim text editor. Set this in your
4342 F<.vimrc> to use F<ack> instead of F<grep>:
4346 That example uses C<-k> to search through only files of the types ack
4347 knows about, but you may use other default flags. Now you can search
4348 with F<ack> and easily step through the results in Vim:
4350 :grep Dumper perllib
4352 Miles Sterrett has written a Vim plugin for F<ack> which allows you to use
4353 C<:Ack> instead of C<:grep>, as well as several other advanced features.
4355 L<https://github.com/mileszs/ack.vim>
4357 =head2 Emacs integration
4359 Phil Jackson put together an F<ack.el> extension that "provides a
4360 simple compilation mode ... has the ability to guess what files you
4361 want to search for based on the major-mode."
4363 L<http://www.shellarchive.co.uk/content/emacs.html>
4365 =head2 TextMate integration
4367 Pedro Melo is a TextMate user who writes "I spend my day mostly
4368 inside TextMate, and the built-in find-in-project sucks with large
4369 projects. So I hacked a TextMate command that was using find +
4370 grep to use ack. The result is the Search in Project with ack, and
4371 you can find it here:
4372 L<http://www.simplicidade.org/notes/archives/2008/03/search_in_proje.html>"
4374 =head2 Shell and Return Code
4376 For greater compatibility with I<grep>, I<ack> in normal use returns
4377 shell return or exit code of 0 only if something is found and 1 if
4380 (Shell exit code 1 is C<$?=256> in perl with C<system> or backticks.)
4382 The I<grep> code 2 for errors is not used.
4384 If C<-f> or C<-g> are specified, then 0 is returned if at least one
4385 file is found. If no files are found, then 1 is returned.
4389 =head1 DEBUGGING ACK PROBLEMS
4391 If ack gives you output you're not expecting, start with a few simple steps.
4393 =head2 Use B<--noenv>
4395 Your environment variables and F<.ackrc> may be doing things you're
4396 not expecting, or forgotten you specified. Use B<--noenv> to ignore
4397 your environment and F<.ackrc>.
4399 =head2 Use B<-f> to see what files have been selected
4401 Ack's B<-f> was originally added as a debugging tool. If ack is
4402 not finding matches you think it should find, run F<ack -f> to see
4403 what files have been selected. You can also add the C<--show-types>
4404 options to show the type of each file selected.
4406 =head2 Use B<--dump>
4408 This lists the ackrc files that are loaded and the options loaded
4410 So for example you can find a list of directories that do not get searched or where filetypes are defined.
4414 =head2 Use the F<.ackrc> file.
4416 The F<.ackrc> is the place to put all your options you use most of
4417 the time but don't want to remember. Put all your --type-add and
4418 --type-set definitions in it. If you like --smart-case, set it
4419 there, too. I also set --sort-files there.
4421 =head2 Use F<-f> for working with big codesets
4423 Ack does more than search files. C<ack -f --perl> will create a
4424 list of all the Perl files in a tree, ideal for sending into F<xargs>.
4427 # Change all "this" to "that" in all Perl files in a tree.
4428 ack -f --perl | xargs perl -p -i -e's/this/that/g'
4432 perl -p -i -e's/this/that/g' $(ack -f --perl)
4434 =head2 Use F<-Q> when in doubt about metacharacters
4436 If you're searching for something with a regular expression
4437 metacharacter, most often a period in a filename or IP address, add
4438 the -Q to avoid false positives without all the backslashing. See
4439 the following example for more...
4441 =head2 Use ack to watch log files
4443 Here's one I used the other day to find trouble spots for a website
4444 visitor. The user had a problem loading F<troublesome.gif>, so I
4445 took the access log and scanned it with ack twice.
4447 ack -Q aa.bb.cc.dd /path/to/access.log | ack -Q -B5 troublesome.gif
4449 The first ack finds only the lines in the Apache log for the given
4450 IP. The second finds the match on my troublesome GIF, and shows
4451 the previous five lines from the log in each case.
4453 =head2 Examples of F<--output>
4455 Following variables are useful in the expansion string:
4461 The whole string matched by PATTERN.
4463 =item C<$1>, C<$2>, ...
4465 The contents of the 1st, 2nd ... bracketed group in PATTERN.
4469 The string before the match.
4473 The string after the match.
4477 For more details and other variables see
4478 L<http://perldoc.perl.org/perlvar.html#Variables-related-to-regular-expressions|perlvar>.
4480 This example shows how to add text around a particular pattern
4481 (in this case adding _ around word with "e")
4483 ack2.pl "\w*e\w*" quick.txt --output="$`_$&_$'"
4484 _The_ quick brown fox jumps over the lazy dog
4485 The quick brown fox jumps _over_ the lazy dog
4486 The quick brown fox jumps over _the_ lazy dog
4488 This shows how to pick out particular parts of a match using ( ) within regular expression.
4490 ack '=head(\d+)\s+(.*)' --output=' $1 : $2'
4491 input file contains "=head1 NAME"
4494 =head2 Share your knowledge
4496 Join the ack-users mailing list. Send me your tips and I may add
4501 =head2 Why isn't ack finding a match in (some file)?
4503 Probably because it's of a type that ack doesn't recognize. ack's
4504 searching behavior is driven by filetype. B<If ack doesn't know
4505 what kind of file it is, ack ignores the file.>
4507 Use the C<-f> switch to see a list of files that ack will search
4508 for you. You can use the C<--show-types> switch to show which type
4509 ack thinks each file is.
4511 =head2 Wouldn't it be great if F<ack> did search & replace?
4513 No, ack will always be read-only. Perl has a perfectly good way
4514 to do search & replace in files, using the C<-i>, C<-p> and C<-n>
4517 You can certainly use ack to select your files to update. For
4518 example, to change all "foo" to "bar" in all PHP files, you can do
4519 this from the Unix shell:
4521 $ perl -i -p -e's/foo/bar/g' $(ack -f --php)
4523 =head2 Can I make ack recognize F<.xyz> files?
4525 Yes! Please see L</"Defining your own types">. If you think
4526 that F<ack> should recognize a type by default, please see
4529 =head2 There's already a program/package called ack.
4533 =head2 Why is it called ack if it's called ack-grep?
4535 The name of the program is "ack". Some packagers have called it
4536 "ack-grep" when creating packages because there's already a package
4537 out there called "ack" that has nothing to do with this ack.
4539 I suggest you make a symlink named F<ack> that points to F<ack-grep>
4540 because one of the crucial benefits of ack is having a name that's
4541 so short and simple to type.
4543 To do that, run this with F<sudo> or as root:
4545 ln -s /usr/bin/ack-grep /usr/bin/ack
4547 Alternatively, you could use a shell alias:
4555 =head2 What does F<ack> mean?
4557 Nothing. I wanted a name that was easy to type and that you could
4558 pronounce as a single syllable.
4560 =head2 Can I do multi-line regexes?
4562 No, ack does not support regexes that match multiple lines. Doing
4563 so would require reading in the entire file at a time.
4565 If you want to see lines near your match, use the C<--A>, C<--B>
4566 and C<--C> switches for displaying context.
4568 =head2 Why is ack telling me I have an invalid option when searching for C<+foo>?
4570 ack treats command line options beginning with C<+> or C<-> as options; if you
4571 would like to search for these, you may prefix your search term with C<--> or
4572 use the C<--match> option. (However, don't forget that C<+> is a regular
4573 expression metacharacter!)
4575 =head2 Why does C<"ack '.{40000,}'"> fail? Isn't that a valid regex?
4577 The Perl language limits the repetition quanitifier to 32K. You
4578 can search for C<.{32767}> but not C<.{32768}>.
4580 =head1 ACKRC LOCATION SEMANTICS
4582 Ack can load its configuration from many sources. This list
4583 specifies the sources Ack looks for configuration; each one
4584 that is found is loaded in the order specified here, and
4585 each one overrides options set in any of the sources preceding
4586 it. (For example, if I set --sort-files in my user ackrc, and
4587 --nosort-files on the command line, the command line takes
4594 Defaults are loaded from App::Ack::ConfigDefaults. This can be omitted
4595 using C<--ignore-ack-defaults>.
4597 =item * Global ackrc
4599 Options are then loaded from the global ackrc. This is located at
4600 C</etc/ackrc> on Unix-like systems, and
4601 C<C:\Documents and Settings\All Users\Application Data\ackrc> on Windows.
4602 This can be omitted using C<--noenv>.
4606 Options are then loaded from the user's ackrc. This is located at
4607 C<$HOME/.ackrc> on Unix-like systems, and
4608 C<C:\Documents and Settings\$USER\Application Data\ackrc>. If a different
4609 ackrc is desired, it may be overridden with the C<$ACKRC> environment
4611 This can be omitted using C<--noenv>.
4613 =item * Project ackrc
4615 Options are then loaded from the project ackrc. The project ackrc is
4616 the first ackrc file with the name C<.ackrc> or C<_ackrc>, first searching
4617 in the current directory, then the parent directory, then the grandparent
4618 directory, etc. This can be omitted using C<--noenv>.
4622 The C<--ackrc> option may be included on the command line to specify an
4623 ackrc file that can override all others. It is consulted even if C<--noenv>
4628 Options are then loaded from the environment variable C<ACK_OPTIONS>. This can
4629 be omitted using C<--noenv>.
4631 =item * Command line
4633 Options are then loaded from the command line.
4637 =head1 DIFFERENCES BETWEEN ACK 1.X AND ACK 2.X
4639 A lot of changes were made for ack 2; here is a list of them.
4641 =head2 GENERAL CHANGES
4647 When no selectors are specified, ack 1.x only searches through files that
4648 it can map to a file type. ack 2.x, by contrast, will search through
4649 every regular, non-binary file that is not explicitly ignored via
4650 B<--ignore-file> or B<--ignore-dir>. This is similar to the behavior of the
4651 B<-a/--all> option in ack 1.x.
4655 A more flexible filter system has been added, so that more powerful file types
4656 may be created by the user. For details, please consult
4657 L</"Defining your own types">.
4661 ack now loads multiple ackrc files; see L</"ACKRC LOCATION SEMANTICS"> for
4666 ack's default filter definitions aren't special; you may tell ack to
4667 completely disregard them if you don't like them.
4671 =head2 REMOVED OPTIONS
4677 Because of the change in default search behavior, the B<-a/--all> and
4678 B<-u/--unrestricted> options have been removed. In addition, the
4679 B<-k/--known-types> option was added to cause ack to behave with
4680 the default search behavior of ack 1.x.
4684 The B<-G> option has been removed. Two regular expressions on the
4685 command line was considered too confusing; to simulate B<-G>'s functionality,
4686 you may use the new B<-x> option to pipe filenames from one invocation of
4691 The B<--binary> option has been removed.
4695 The B<--skipped> option has been removed.
4699 The B<--text> option has been removed.
4703 The B<--invert-file-match> option has been removed. Instead, you may
4704 use B<-v> with B<-g>.
4708 =head2 CHANGED OPTIONS
4714 The options that modify the regular expression's behavior (B<-i>, B<-w>,
4715 B<-Q>, and B<-v>) may now be used with B<-g>.
4719 =head2 ADDED OPTIONS
4725 B<--files-from> was added so that a user may submit a list of filenames as
4726 a list of files to search.
4730 B<-x> was added to tell ack to accept a list of filenames via standard input;
4731 this list is the list of filenames that will be used for the search.
4735 B<-s> was added to tell ack to suppress error messages about non-existent or
4740 B<--ignore-directory> and B<--noignore-directory> were added as aliases for
4741 B<--ignore-dir> and B<--noignore-dir> respectively.
4745 B<--ignore-file> was added so that users may specify patterns of files to
4746 ignore (ex. /.*~$/).
4750 B<--dump> was added to allow users to easily find out which options are
4755 B<--create-ackrc> was added so that users may create custom ackrc files based
4756 on the default settings loaded by ack, and so that users may easily view those
4761 B<--type-del> was added to selectively remove file type definitions.
4765 B<--ignore-ack-defaults> was added so that users may ignore ack's default
4766 options in favor of their own.
4770 B<--bar> was added so ack users may consult Admiral Ackbar.
4776 Andy Lester, C<< <andy at petdance.com> >>
4780 Please report any bugs or feature requests to the issues list at
4781 Github: L<https://github.com/petdance/ack2/issues>
4785 All enhancement requests MUST first be posted to the ack-users
4786 mailing list at L<http://groups.google.com/group/ack-users>. I
4787 will not consider a request without it first getting seen by other
4788 ack users. This includes requests for new filetypes.
4790 There is a list of enhancements I want to make to F<ack> in the ack
4791 issues list at Github: L<https://github.com/petdance/ack2/issues>
4793 Patches are always welcome, but patches with tests get the most
4798 Support for and information about F<ack> can be found at:
4802 =item * The ack homepage
4804 L<http://beyondgrep.com/>
4806 =item * The ack-users mailing list
4808 L<http://groups.google.com/group/ack-users>
4810 =item * The ack issues list at Github
4812 L<https://github.com/petdance/ack2/issues>
4814 =item * AnnoCPAN: Annotated CPAN documentation
4816 L<http://annocpan.org/dist/ack>
4818 =item * CPAN Ratings
4820 L<http://cpanratings.perl.org/d/ack>
4824 L<http://search.cpan.org/dist/ack>
4826 =item * Git source repository
4828 L<https://github.com/petdance/ack2>
4832 =head1 ACKNOWLEDGEMENTS
4834 How appropriate to have I<ack>nowledgements!
4836 Thanks to everyone who has contributed to ack in any way, including
4870 Eric Van Dewoestine,
4879 Christopher J. Madsen,
4891 GE<aacute>bor SzabE<oacute>,
4894 E<AElig>var ArnfjE<ouml>rE<eth> Bjarmason,
4898 Mark Leighton Fisher,
4904 Nilson Santos F. Jr,
4909 Ask BjE<oslash>rn Hansen,
4913 Slaven ReziE<0x107>,
4923 =head1 COPYRIGHT & LICENSE
4925 Copyright 2005-2013 Andy Lester.
4927 This program is free software; you can redistribute it and/or modify
4928 it under the terms of the Artistic License v2.0.
4930 See http://www.perlfoundation.org/artistic_license_2_0 or the LICENSE.md
4931 file that comes with the ack distribution.