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.