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 # XXX Don't make this so brute force 
  19 # See also: https://github.com/petdance/ack2/issues/89 
  21 use Getopt
::Long 
2.35 (); 
  25 our $VERSION = '2.04'; 
  26 # Check http://beyondgrep.com/ for updates 
  28 # These are all our globals. 
  31     $App::Ack
::orig_program_name 
= $0; 
  32     $0 = join(' ', 'ack', $0); 
  33     if ( $App::Ack
::VERSION 
ne $main::VERSION 
) { 
  34         App
::Ack
::die( "Program/library version mismatch\n\t$0 is $main::VERSION\n\t$INC{'App/Ack.pm'} is $App::Ack::VERSION" ); 
  37     # Do preliminary arg checking; 
  38     my $env_is_usable = 1; 
  40         last if ( $_ eq '--' ); 
  42         # Get the --thpppt and --bar checking out of the way. 
  43         /^--th[pt]+t+$/ && App
::Ack
::_thpppt
($_); 
  44         /^--bar$/ && App
::Ack
::_bar
(); 
  46         # See if we want to ignore the environment. (Don't tell Al Gore.) 
  47         if ( /^--(no)?env$/ ) { 
  48             $env_is_usable = defined $1 ? 0 : 1; 
  51     if ( !$env_is_usable ) { 
  52         my @keys = ( 'ACKRC', grep { /^ACK_/ } keys %ENV ); 
  57     Getopt
::Long
::Configure
('default', 'no_auto_help', 'no_auto_version'); 
  58     Getopt
::Long
::Configure
('pass_through', 'no_auto_abbrev'); 
  59     Getopt
::Long
::GetOptions
( 
  60         'help'       => sub { App
::Ack
::show_help
(); exit; }, 
  61         'version'    => sub { App
::Ack
::print_version_statement
(); exit; }, 
  62         'man'        => sub { App
::Ack
::show_man
(); exit; }, 
  64     Getopt
::Long
::Configure
('default', 'no_auto_help', 'no_auto_version'); 
  67         App
::Ack
::show_help
(); 
  74 sub _compile_descend_filter 
{ 
  77     my $idirs            = $opt->{idirs
}; 
  78     my $dont_ignore_dirs = $opt->{no_ignore_dirs
}; 
  80     # if we have one or more --noignore-dir directives, we can't ignore 
  81     # entire subdirectory hierarchies, so we return an "accept all" 
  82     # filter and scrutinize the files more in _compile_file_filter 
  83     return if $dont_ignore_dirs; 
  84     return unless $idirs && @{$idirs}; 
  88     foreach my $idir (@{$idirs}) { 
  89         if ( $idir =~ /^(\w+):(.*)/ ) { 
  94                 Carp
::croak
( 'Non-is filters are not yet supported for --ignore-dir' ); 
  98             Carp
::croak
( qq{Invalid filter specification "$idir"} ); 
 103         return !exists $ignore_dirs{$_} && !exists $ignore_dirs{$File::Next
::dir
}; 
 107 sub _compile_file_filter 
{ 
 108     my ( $opt, $start ) = @_; 
 110     my $ifiles = $opt->{ifiles
}; 
 113     my @ifiles_filters = map { 
 116         if ( /^(\w+):(.+)/ ) { 
 117             my ($how,$what) = ($1,$2); 
 118             $filter = App
::Ack
::Filter-
>create_filter($how, split(/,/, $what)); 
 121             Carp
::croak
( qq{Invalid filter specification "$_"} ); 
 126     my $filters         = $opt->{'filters'} || []; 
 127     my $inverse_filters = [ grep {  $_->is_inverted() } @{$filters} ]; 
 128     @{$filters}         =   grep { !$_->is_inverted() } @{$filters}; 
 130     my %is_member_of_starting_set = map { (get_file_id
($_) => 1) } @{$start}; 
 132     my $ignore_dir_list      = $opt->{idirs
}; 
 133     my $dont_ignore_dir_list = $opt->{no_ignore_dirs
}; 
 136     my %dont_ignore_dir_set; 
 138     foreach my $filter (@{ $ignore_dir_list }) { 
 139         if ( $filter =~ /^(\w+):(.*)/ ) { 
 141                 $ignore_dir_set{ $2 } = 1; 
 143                 Carp
::croak
( 'Non-is filters are not yet supported for --ignore-dir' ); 
 146             Carp
::croak
( qq{Invalid filter specification "$filter"} ); 
 149     foreach my $filter (@{ $dont_ignore_dir_list }) { 
 150         if ( $filter =~ /^(\w+):(.*)/ ) { 
 152                 $dont_ignore_dir_set{ $2 } = 1; 
 154                 Carp
::croak
( 'Non-is filters are not yet supported for --ignore-dir' ); 
 157             Carp
::croak
( qq{Invalid filter specification "$filter"} ); 
 162         # ack always selects files that are specified on the command 
 163         # line, regardless of filetype.  If you want to ack a JPEG, 
 164         # and say "ack foo whatever.jpg" it will do it for you. 
 165         return 1 if $is_member_of_starting_set{ get_file_id
($File::Next
::name
) }; 
 167         if ( $dont_ignore_dir_list ) { 
 168             my ( undef, $dirname ) = File
::Spec-
>splitpath($File::Next
::name
); 
 169             my @dirs               = File
::Spec-
>splitdir($dirname); 
 173             foreach my $dir ( @dirs ) { 
 174                 if ( $ignore_dir_set{ $dir } ) { 
 177                 elsif ( $dont_ignore_dir_set{ $dir } ) { 
 181             if ( $is_ignoring ) { 
 186         # Ignore named pipes found in directory searching.  Named 
 187         # pipes created by subprocesses get specified on the command 
 188         # line, so the rule of "always select whatever is on the 
 189         # command line" wins. 
 190         return 0 if -p 
$File::Next
::name
; 
 192         # we can't handle unreadable filenames; report them 
 194             if ( $App::Ack
::report_bad_filenames 
) { 
 195                 App
::Ack
::warn( "${File::Next::name}: cannot open file for reading" ); 
 200         my $resource = App
::Ack
::Resource
::Basic-
>new($File::Next
::name
); 
 201         return 0 if ! $resource; 
 202         foreach my $filter (@ifiles_filters) { 
 203             return 0 if $filter->filter($resource); 
 209             foreach my $filter (@{$filters}) { 
 210                 if ($filter->filter($resource)) { 
 216         # Don't bother invoking inverse filters unless we consider the current resource a match 
 217         if ( $match_found && @{$inverse_filters} ) { 
 218             foreach my $filter ( @{$inverse_filters} ) { 
 219                 if ( not $filter->filter( $resource ) ) { 
 230     my $resource = shift; 
 233     my @types = filetypes
( $resource ); 
 234     my $types = join( ',', @types ); 
 235     my $arrow = @types ? ' => ' : ' =>'; 
 236     App
::Ack
::print( $resource->name, $arrow, join( ',', @types ), $ors ); 
 241 # Set default colors, load Term::ANSIColor 
 243     eval 'use Term::ANSIColor 1.10 ()'; 
 245     $ENV{ACK_COLOR_MATCH
}    ||= 'black on_yellow'; 
 246     $ENV{ACK_COLOR_FILENAME
} ||= 'bold green'; 
 247     $ENV{ACK_COLOR_LINENO
}   ||= 'bold yellow'; 
 252 # inefficient, but functional 
 254     my ( $resource ) = @_; 
 258     foreach my $k (keys %App::Ack
::mappings
) { 
 259         my $filters = $App::Ack
::mappings
{$k}; 
 261         foreach my $filter (@{$filters}) { 
 263             my $clone = $resource->clone; 
 264             if ( $filter->filter($clone) ) { 
 271     return sort @matches; 
 274 # returns a (fairly) unique identifier for a file 
 275 # use this function to compare two files to see if they're 
 276 # equal (ie. the same file, but with a different path/links/etc) 
 278     my ( $filename ) = @_; 
 280     if ( $App::Ack
::is_windows 
) { 
 281         return File
::Next
::reslash
( $filename ); 
 284         # XXX is this the best method? it always hits the FS 
 285         if( my ( $dev, $inode ) = (stat($filename))[0, 1] ) { 
 286             return join(':', $dev, $inode); 
 289             # XXX this could be better 
 295 # Returns a regex object based on a string and command-line options. 
 296 # Dies when the regex $str is undefinied (i.e. not given on command line). 
 302     defined $str or App
::Ack
::die( 'No regular expression found.' ); 
 304     $str = quotemeta( $str ) if $opt->{Q
}; 
 306         $str = "\\b$str" if $str =~ /^\w/; 
 307         $str = "$str\\b" if $str =~ /\w$/; 
 310     my $regex_is_lc = $str eq lc $str; 
 311     if ( $opt->{i
} || ($opt->{smart_case
} && $regex_is_lc) ) { 
 315     my $re = eval { qr/$str/ }; 
 317         die "Invalid regex '$str':\n  $@"; 
 326 my @before_ctx_lines; 
 330 my $has_printed_something; 
 333     $has_printed_something = 0; 
 336 sub print_matches_in_resource 
{ 
 337     my ( $resource, $opt ) = @_; 
 339     my $passthru       = $opt->{passthru
}; 
 340     my $max_count      = $opt->{m
} || -1; 
 342     my $filename       = $resource->name; 
 343     my $break          = $opt->{break}; 
 344     my $heading        = $opt->{heading
}; 
 345     my $ors            = $opt->{print0
} ? "\0" : "\n"; 
 346     my $color          = $opt->{color
}; 
 347     my $print_filename = $opt->{show_filename
}; 
 349     my $has_printed_for_this_resource = 0; 
 353     local $opt->{before_context
} = $opt->{output
} ? 0 : $opt->{before_context
}; 
 354     local $opt->{after_context
}  = $opt->{output
} ? 0 : $opt->{after_context
}; 
 356     my $n_before_ctx_lines = $opt->{before_context
} || 0; 
 357     my $n_after_ctx_lines  = $opt->{after_context
}  || 0; 
 359     @after_ctx_lines = @before_ctx_lines = (); 
 361     my $fh = $resource->open(); 
 363         if ( $App::Ack
::report_bad_filenames 
) { 
 364             App
::Ack
::warn( "$filename: $!" ); 
 369     my $display_filename = $filename; 
 370     if ( $print_filename && $heading && $color ) { 
 371         $display_filename = Term
::ANSIColor
::colored
($display_filename, $ENV{ACK_COLOR_FILENAME
}); 
 374     # check for context before the main loop, so we don't 
 375     # pay for it if we don't need it 
 376     if ( $n_before_ctx_lines || $n_after_ctx_lines ) { 
 377         my $current_line = <$fh>; # prime the first line of input 
 379         while ( defined $current_line ) { 
 380             while ( (@after_ctx_lines < $n_after_ctx_lines) && defined($_ = <$fh>) ) { 
 381                 push @after_ctx_lines, $_; 
 384             local $_ = $current_line; 
 385             my $former_dot_period = $.; 
 386             $. -= @after_ctx_lines; 
 388             if ( does_match
($opt, $_) ) { 
 389                 if ( !$has_printed_for_this_resource ) { 
 390                     if ( $break && $has_printed_something ) { 
 391                         App
::Ack
::print_blank_line
(); 
 393                     if ( $print_filename && $heading ) { 
 394                         App
::Ack
::print_filename
( $display_filename, $ors ); 
 397                 print_line_with_context
($opt, $filename, $_, $.); 
 398                 $has_printed_for_this_resource = 1; 
 402             elsif ( $passthru ) { 
 403                 chomp; # XXX proper newline handling? 
 404                 # XXX inline this call? 
 405                 if ( $break && !$has_printed_for_this_resource && $has_printed_something ) { 
 406                     App
::Ack
::print_blank_line
(); 
 408                 print_line_with_options
($opt, $filename, $_, $., ':'); 
 409                 $has_printed_for_this_resource = 1; 
 411             last unless $max_count != 0; 
 413             # I tried doing this with local(), but for some reason, 
 414             # $. continued to have its new value after the exit of the 
 415             # enclosing block.  I'm guessing that $. has some extra 
 416             # magic associated with it or something.  If someone can 
 417             # tell me why this happened, I would love to know! 
 418             $. = $former_dot_period; # XXX this won't happen on an exception 
 420             if ( $n_before_ctx_lines ) { 
 421                 push @before_ctx_lines, $current_line; 
 422                 shift @before_ctx_lines while @before_ctx_lines > $n_before_ctx_lines; 
 424             if ( $n_after_ctx_lines ) { 
 425                 $current_line = shift @after_ctx_lines; 
 428                 $current_line = <$fh>; 
 436             if ( does_match
($opt, $_) ) { 
 437                 if ( !$has_printed_for_this_resource ) { 
 438                     if ( $break && $has_printed_something ) { 
 439                         App
::Ack
::print_blank_line
(); 
 441                     if ( $print_filename && $heading ) { 
 442                         App
::Ack
::print_filename
( $display_filename, $ors ); 
 445                 print_line_with_context
($opt, $filename, $_, $.); 
 446                 $has_printed_for_this_resource = 1; 
 450             elsif ( $passthru ) { 
 451                 chomp; # XXX proper newline handling? 
 452                 if ( $break && !$has_printed_for_this_resource && $has_printed_something ) { 
 453                     App
::Ack
::print_blank_line
(); 
 455                 print_line_with_options
($opt, $filename, $_, $., ':'); 
 456                 $has_printed_for_this_resource = 1; 
 458             last unless $max_count != 0; 
 462     $is_iterating = 0; # XXX this won't happen on an exception 
 463                        #     then again, do we care? ack doesn't really 
 464                        #     handle exceptions anyway. 
 469 sub print_line_with_options 
{ 
 470     my ( $opt, $filename, $line, $line_no, $separator ) = @_; 
 472     $has_printed_something = 1; 
 474     my $print_filename = $opt->{show_filename
}; 
 475     my $print_column   = $opt->{column
}; 
 476     my $ors            = $opt->{print0
} ? "\0" : "\n"; 
 477     my $heading        = $opt->{heading
}; 
 478     my $output_expr    = $opt->{output
}; 
 479     my $color          = $opt->{color
}; 
 484         $filename = Term
::ANSIColor
::colored
($filename, 
 485             $ENV{ACK_COLOR_FILENAME
}); 
 486         $line_no  = Term
::ANSIColor
::colored
($line_no, 
 487             $ENV{ACK_COLOR_LINENO
}); 
 490     if($print_filename) { 
 492             push @line_parts, $line_no; 
 495             push @line_parts, $filename, $line_no; 
 498         if( $print_column ) { 
 499             push @line_parts, get_match_column
(); 
 503         while ( $line =~ /$opt->{regex}/og ) { 
 504             my $output = eval $output_expr; 
 505             App
::Ack
::print( join( $separator, @line_parts, $output ), $ors ); 
 510             my @capture_indices = get_capture_indices
(); 
 511             if( @capture_indices ) { 
 512                 my $offset = 0; # additional offset for when we add stuff 
 514                 foreach my $index_pair ( @capture_indices ) { 
 515                     my ( $match_start, $match_end ) = @{$index_pair}; 
 517                     my $substring = substr( $line, 
 518                         $offset + $match_start, $match_end - $match_start ); 
 519                     my $substitution = Term
::ANSIColor
::colored
( $substring, 
 520                         $ENV{ACK_COLOR_MATCH
} ); 
 522                     substr( $line, $offset + $match_start, 
 523                         $match_end - $match_start, $substitution ); 
 525                     $offset += length( $substitution ) - length( $substring ); 
 529                 my $matched = 0; # flag; if matched, need to escape afterwards 
 531                 while ( $line =~ /$opt->{regex}/og ) { 
 534                     my ( $match_start, $match_end ) = ($-[0], $+[0]); 
 536                     my $substring = substr( $line, $match_start, 
 537                         $match_end - $match_start ); 
 538                     my $substitution = Term
::ANSIColor
::colored
( $substring, 
 539                         $ENV{ACK_COLOR_MATCH
} ); 
 541                     substr( $line, $match_start, $match_end - $match_start, 
 544                     pos($line) = $match_end + 
 545                     (length( $substitution ) - length( $substring )); 
 547                 $line .= "\033[0m\033[K" if $matched; 
 551         push @line_parts, $line; 
 552         App
::Ack
::print( join( $separator, @line_parts ), $ors ); 
 559     my ( $resource, $opt, $cb ) = @_; 
 563     local $opt->{before_context
} = $opt->{output
} ? 0 : $opt->{before_context
}; 
 564     local $opt->{after_context
}  = $opt->{output
} ? 0 : $opt->{after_context
}; 
 566     my $n_before_ctx_lines = $opt->{before_context
} || 0; 
 567     my $n_after_ctx_lines  = $opt->{after_context
}  || 0; 
 569     @after_ctx_lines = @before_ctx_lines = (); 
 571     my $fh = $resource->open(); 
 573         if ( $App::Ack
::report_bad_filenames 
) { 
 574             # XXX direct access to filename 
 575             App
::Ack
::warn( "$resource->{filename}: $!" ); 
 580     # check for context before the main loop, so we don't 
 581     # pay for it if we don't need it 
 582     if ( $n_before_ctx_lines || $n_after_ctx_lines ) { 
 583         my $current_line = <$fh>; # prime the first line of input 
 585         while ( defined $current_line ) { 
 586             while ( (@after_ctx_lines < $n_after_ctx_lines) && defined($_ = <$fh>) ) { 
 587                 push @after_ctx_lines, $_; 
 590             local $_ = $current_line; 
 591             my $former_dot_period = $.; 
 592             $. -= @after_ctx_lines; 
 596             # I tried doing this with local(), but for some reason, 
 597             # $. continued to have its new value after the exit of the 
 598             # enclosing block.  I'm guessing that $. has some extra 
 599             # magic associated with it or something.  If someone can 
 600             # tell me why this happened, I would love to know! 
 601             $. = $former_dot_period; # XXX this won't happen on an exception 
 603             if ( $n_before_ctx_lines ) { 
 604                 push @before_ctx_lines, $current_line; 
 605                 shift @before_ctx_lines while @before_ctx_lines > $n_before_ctx_lines; 
 607             if ( $n_after_ctx_lines ) { 
 608                 $current_line = shift @after_ctx_lines; 
 611                 $current_line = <$fh>; 
 623     $is_iterating = 0; # XXX this won't happen on an exception 
 624                        #     then again, do we care? ack doesn't really 
 625                        #     handle exceptions anyway. 
 631     if ( not $is_iterating ) { 
 632         Carp
::croak
( 'get_context() called outside of iterate()' ); 
 636         scalar(@before_ctx_lines) ? \
@before_ctx_lines : undef, 
 637         scalar(@after_ctx_lines)  ? \
@after_ctx_lines  : undef, 
 646 my $previous_file_processed; 
 647 my $previous_line_printed; 
 651     $previous_line_printed = -1; 
 654 sub print_line_with_context 
{ 
 655     my ( $opt, $filename, $matching_line, $line_no ) = @_; 
 657     my $heading = $opt->{heading
}; 
 659     if( !defined($previous_file_processed) || 
 660       $previous_file_processed ne $filename ) { 
 661         $previous_file_processed = $filename; 
 662         $previous_line_printed   = -1; 
 669     my $ors                 = $opt->{print0
} ? "\0" : "\n"; 
 670     my $match_word          = $opt->{w
}; 
 671     my $is_tracking_context = $opt->{after_context
} || $opt->{before_context
}; 
 672     my $output_expr         = $opt->{output
}; 
 674     $matching_line =~ s/[\r\n]+$//g; 
 676     my ( $before_context, $after_context ) = get_context
(); 
 678     if ( $before_context ) { 
 679         my $first_line = $. - @{$before_context}; 
 681         if ( $first_line <= $previous_line_printed ) { 
 682             splice @{$before_context}, 0, $previous_line_printed - $first_line + 1; 
 683             $first_line = $. - @{$before_context}; 
 685         if ( @{$before_context} ) { 
 686             my $offset = @{$before_context}; 
 688             if( !$is_first_match && $previous_line_printed != $first_line - 1 ) { 
 689                 App
::Ack
::print('--', $ors); 
 691             foreach my $line (@{$before_context}) { 
 692                 my $context_line_no = $. - $offset; 
 693                 if ( $context_line_no <= $previous_line_printed ) { 
 698                 print_line_with_options
($opt, $filename, $line, $context_line_no, '-'); 
 699                 $previous_line_printed = $context_line_no; 
 705     if ( $. > $previous_line_printed ) { 
 706         if( $is_tracking_context && !$is_first_match && $previous_line_printed != $. - 1 ) { 
 707             App
::Ack
::print('--', $ors); 
 710         print_line_with_options
($opt, $filename, $matching_line, $line_no, ':'); 
 711         $previous_line_printed = $.; 
 716         foreach my $line (@{$after_context}) { 
 718             if ( $previous_line_printed >= $. + $offset ) { 
 723             my $separator = ($opt->{regex
} && does_match
( $opt, $line )) ? ':' : '-'; 
 724             print_line_with_options
($opt, $filename, $line, $. + $offset, $separator); 
 725             $previous_line_printed = $. + $offset; 
 740 my $match_column_number; 
 742 # does_match() MUST have an $opt->{regex} set. 
 745     my ( $opt, $line ) = @_; 
 747     $match_column_number = undef; 
 748     @capture_indices     = (); 
 751         return ( $line !~ /$opt->{regex}/o ); 
 754         if ( $line =~ /$opt->{regex}/o ) { 
 755             # @- = @LAST_MATCH_START 
 756             # @+ = @LAST_MATCH_END 
 757             $match_column_number = $-[0] + 1; 
 760                 @capture_indices = map { 
 772 sub get_capture_indices 
{ 
 773     return @capture_indices; 
 776 sub get_match_column 
{ 
 777     return $match_column_number; 
 782 sub resource_has_match 
{ 
 783     my ( $resource, $opt ) = @_; 
 786     my $fh = $resource->open(); 
 788         if ( $App::Ack
::report_bad_filenames 
) { 
 789             # XXX direct access to filename 
 790             App
::Ack
::warn( "$resource->{filename}: $!" ); 
 794         my $opt_v = $opt->{v
}; 
 795         my $re    = $opt->{regex
}; 
 797             if (/$re/o xor $opt_v) { 
 808 sub count_matches_in_resource 
{ 
 809     my ( $resource, $opt ) = @_; 
 812     my $fh = $resource->open(); 
 814         if ( $App::Ack
::report_bad_filenames 
) { 
 815             # XXX direct access to filename 
 816             App
::Ack
::warn( "$resource->{filename}: $!" ); 
 820         my $opt_v = $opt->{v
}; 
 821         my $re    = $opt->{regex
}; 
 823             ++$nmatches if (/$re/o xor $opt_v); 
 832     my @arg_sources = App
::Ack
::ConfigLoader
::retrieve_arg_sources
(); 
 834     my $opt = App
::Ack
::ConfigLoader
::process_args
( @arg_sources ); 
 836     $App::Ack
::report_bad_filenames 
= !$opt->{dont_report_bad_filenames
}; 
 838     if ( $opt->{flush
} ) { 
 842     if ( not defined $opt->{color
} ) { 
 843         $opt->{color
} = !App
::Ack
::output_to_pipe
() && !$App::Ack
::is_windows
; 
 845     if ( not defined $opt->{heading
} and not defined $opt->{break}  ) { 
 846         $opt->{heading
} = $opt->{break} = !App
::Ack
::output_to_pipe
(); 
 849     if ( defined($opt->{H
}) || defined($opt->{h
}) ) { 
 850         $opt->{show_filename
}= $opt->{H
} && !$opt->{h
}; 
 853     if ( my $output = $opt->{output
} ) { 
 854         $output        =~ s{\\}{\\\\}g; 
 855         $output        =~ s{"}{\\"}g; 
 856         $opt->{output
} = qq{"$output"}; 
 860     if ( $App::Ack
::is_filter_mode 
&& !$opt->{files_from
} ) { # probably -x 
 861         $resources    = App
::Ack
::Resources-
>from_stdin( $opt ); 
 862         my $regex = $opt->{regex
}; 
 863         $regex = shift @ARGV if not defined $regex; 
 864         $opt->{regex
} = build_regex
( $regex, $opt ); 
 867         if ( $opt->{f
} || $opt->{lines
} ) { 
 868             if ( $opt->{regex
} ) { 
 869                 App
::Ack
::warn( "regex ($opt->{regex}) specified with -f or --lines" ); 
 870                 App
::Ack
::exit_from_ack
( 0 ); # XXX the 0 is misleading 
 874             my $regex = $opt->{regex
}; 
 875             $regex = shift @ARGV if not defined $regex; 
 876             $opt->{regex
} = build_regex
( $regex, $opt ); 
 879         if ( not defined $opt->{files_from
} ) { 
 882         if ( !exists($opt->{show_filename
}) ) { 
 883             unless(@start == 1 && !(-d 
$start[0])) { 
 884                 $opt->{show_filename
} = 1; 
 888         if ( defined $opt->{files_from
} ) { 
 889             $resources = App
::Ack
::Resources-
>from_file( $opt, $opt->{files_from
} ); 
 890             exit 1 unless $resources; 
 893             @start = ('.') unless @start; 
 894             foreach my $target (@start) { 
 895                 if ( !-e 
$target && $App::Ack
::report_bad_filenames
) { 
 896                     App
::Ack
::warn( "$target: No such file or directory" ); 
 900             $opt->{file_filter
}    = _compile_file_filter
($opt, \
@start); 
 901             $opt->{descend_filter
} = _compile_descend_filter
($opt); 
 903             $resources = App
::Ack
::Resources-
>from_argv( $opt, \
@start ); 
 906     App
::Ack
::set_up_pager
( $opt->{pager
} ) if defined $opt->{pager
}; 
 908     my $print_filenames = $opt->{show_filename
}; 
 909     my $max_count       = $opt->{m
}; 
 910     my $ors             = $opt->{print0
} ? "\0" : "\n"; 
 911     my $only_first      = $opt->{1}; 
 916     while ( my $resource = $resources->next ) { 
 917         # XXX this variable name combined with what we're trying 
 918         # to do makes no sense. 
 920         # XXX Combine the -f and -g functions 
 922             # XXX printing should probably happen inside of App::Ack 
 923             if ( $opt->{show_types
} ) { 
 924                 show_types
( $resource, $ors ); 
 927                 App
::Ack
::print( $resource->name, $ors ); 
 930             last RESOURCES 
if defined($max_count) && $nmatches >= $max_count; 
 932         elsif ( $opt->{g
} ) { 
 933             my $is_match = ( $resource->name =~ /$opt->{regex}/o ); 
 934             if ( $opt->{v
} ? !$is_match : $is_match ) { 
 935                 if ( $opt->{show_types
} ) { 
 936                     show_types
( $resource, $ors ); 
 939                     App
::Ack
::print( $resource->name, $ors ); 
 942                 last RESOURCES 
if defined($max_count) && $nmatches >= $max_count; 
 945         elsif ( $opt->{lines
} ) { 
 946             my $print_filename = $opt->{show_filename
}; 
 947             my $passthru       = $opt->{passthru
}; 
 950             foreach my $line ( @{ $opt->{lines
} } ) { 
 951                 my @lines             = split /,/, $line; 
 957                 @line_numbers{@lines} = (1) x 
@lines; 
 960             my $filename = $resource->name; 
 962             local $opt->{color
} = 0; 
 964             iterate
($resource, $opt, sub { 
 967                 if ( $line_numbers{$.} ) { 
 968                     print_line_with_context
($opt, $filename, $_, $.); 
 970                 elsif ( $passthru ) { 
 971                     print_line_with_options
($opt, $filename, $_, $., ':'); 
 976         elsif ( $opt->{count
} ) { 
 977             my $matches_for_this_file = count_matches_in_resource
( $resource, $opt ); 
 979             unless ( $opt->{show_filename
} ) { 
 980                 $total_count += $matches_for_this_file; 
 984             if ( !$opt->{l
} || $matches_for_this_file > 0) { 
 985                 if ( $print_filenames ) { 
 986                     App
::Ack
::print( $resource->name, ':', $matches_for_this_file, $ors ); 
 989                     App
::Ack
::print( $matches_for_this_file, $ors ); 
 993         elsif ( $opt->{l
} || $opt->{L
} ) { 
 994             my $is_match = resource_has_match
( $resource, $opt ); 
 996             if ( $opt->{L
} ? !$is_match : $is_match ) { 
 997                 App
::Ack
::print( $resource->name, $ors ); 
1000                 last RESOURCES 
if $only_first; 
1001                 last RESOURCES 
if defined($max_count) && $nmatches >= $max_count; 
1005             $nmatches += print_matches_in_resource
( $resource, $opt ); 
1006             if ( $nmatches && $only_first ) { 
1012     if ( $opt->{count
} && !$opt->{show_filename
} ) { 
1013         App
::Ack
::print( $total_count, "\n" ); 
1016     close $App::Ack
::fh
; 
1017     App
::Ack
::exit_from_ack
( $nmatches ); 
1024 ack - grep-like text finder 
1028     ack [options] PATTERN [FILE...] 
1029     ack -f [options] [DIRECTORY...] 
1033 Ack is designed as a replacement for 99% of the uses of F<grep>. 
1035 Ack searches the named input FILEs (or standard input if no files 
1036 are named, or the file name - is given) for lines containing a match 
1037 to the given PATTERN.  By default, ack prints the matching lines. 
1039 PATTERN is a Perl regular expression.  Perl regular expressions 
1040 are commonly found in other programming languages, but for the particulars 
1041 of their behavior, please consult 
1042 L<http://perldoc.perl.org/perlreref.html|perlreref>.  If you don't know 
1043 how to use regular expression but are interested in learning, you may 
1044 consult L<http://perldoc.perl.org/perlretut.html|perlretut>.  If you do not 
1045 need or want ack to use regular expressions, please see the 
1046 C<-Q>/C<--literal> option. 
1048 Ack can also list files that would be searched, without actually 
1049 searching them, to let you take advantage of ack's file-type filtering 
1052 =head1 FILE SELECTION 
1054 If files are not specified for searching, either on the command 
1055 line or piped in with the C<-x> option, I<ack> delves into 
1056 subdirectories selecting files for searching. 
1058 I<ack> is intelligent about the files it searches.  It knows about 
1059 certain file types, based on both the extension on the file and, 
1060 in some cases, the contents of the file.  These selections can be 
1061 made with the B<--type> option. 
1063 With no file selection, I<ack> searches through regular files that 
1064 are not explicitly excluded by B<--ignore-dir> and B<--ignore-file> 
1065 options, either present in F<ackrc> files or on the command line. 
1067 The default options for I<ack> ignore certain files and directories.  These 
1072 =item * Backup files: Files matching F<#*#> or ending with F<~>. 
1074 =item * Coredumps: Files matching F<core.\d+> 
1076 =item * Version control directories like F<.svn> and F<.git>. 
1080 Run I<ack> with the C<--dump> option to see what settings are set. 
1082 However, I<ack> always searches the files given on the command line, 
1083 no matter what type.  If you tell I<ack> to search in a coredump, 
1084 it will search in a coredump. 
1086 =head1 DIRECTORY SELECTION 
1088 I<ack> descends through the directory tree of the starting directories 
1089 specified.  If no directories are specified, the current working directory is 
1090 used.  However, it will ignore the shadow directories used by 
1091 many version control systems, and the build directories used by the 
1092 Perl MakeMaker system.  You may add or remove a directory from this 
1093 list with the B<--[no]ignore-dir> option. The option may be repeated 
1094 to add/remove multiple directories from the ignore list. 
1096 For a complete list of directories that do not get searched, run 
1099 =head1 WHEN TO USE GREP 
1101 I<ack> trumps I<grep> as an everyday tool 99% of the time, but don't 
1102 throw I<grep> away, because there are times you'll still need it. 
1104 E.g., searching through huge files looking for regexes that can be 
1105 expressed with I<grep> syntax should be quicker with I<grep>. 
1107 If your script or parent program uses I<grep> C<--quiet> or C<--silent> 
1108 or needs exit 2 on IO error, use I<grep>. 
1114 =item B<-A I<NUM>>, B<--after-context=I<NUM>> 
1116 Print I<NUM> lines of trailing context after matching lines. 
1118 =item B<-B I<NUM>>, B<--before-context=I<NUM>> 
1120 Print I<NUM> lines of leading context before matching lines. 
1122 =item B<--[no]break> 
1124 Print a break between results from different files. On by default 
1125 when used interactively. 
1127 =item B<-C [I<NUM>]>, B<--context[=I<NUM>]> 
1129 Print I<NUM> lines (default 2) of context around matching lines. 
1131 =item B<-c>, B<--count> 
1133 Suppress normal output; instead print a count of matching lines for 
1134 each input file.  If B<-l> is in effect, it will only show the 
1135 number of lines for each file that has lines matching.  Without 
1136 B<-l>, some line counts may be zeroes. 
1138 If combined with B<-h> (B<--no-filename>) ack outputs only one total 
1141 =item B<--[no]color>, B<--[no]colour> 
1143 B<--color> highlights the matching text.  B<--nocolor> supresses 
1144 the color.  This is on by default unless the output is redirected. 
1146 On Windows, this option is off by default unless the 
1147 L<Win32::Console::ANSI> module is installed or the C<ACK_PAGER_COLOR> 
1148 environment variable is used. 
1150 =item B<--color-filename=I<color>> 
1152 Sets the color to be used for filenames. 
1154 =item B<--color-match=I<color>> 
1156 Sets the color to be used for matches. 
1158 =item B<--color-lineno=I<color>> 
1160 Sets the color to be used for line numbers. 
1162 =item B<--[no]column> 
1164 Show the column number of the first match.  This is helpful for 
1165 editors that can place your cursor at a given position. 
1167 =item B<--create-ackrc> 
1169 Dumps the default ack options to standard output.  This is useful for 
1170 when you want to customize the defaults. 
1174 Writes the list of options loaded and where they came from to standard 
1175 output.  Handy for debugging. 
1179 B<--noenv> disables all environment processing. No F<.ackrc> is 
1180 read and all environment variables are ignored. By default, F<ack> 
1181 considers F<.ackrc> and settings in the environment. 
1185 B<--flush> flushes output immediately.  This is off by default 
1186 unless ack is running interactively (when output goes to a pipe or 
1191 Only print the files that would be searched, without actually doing 
1192 any searching.  PATTERN must not be specified, or it will be taken 
1193 as a path to search. 
1195 =item B<--files-from=I<FILE>> 
1197 The list of files to be searched is specified in I<FILE>.  The list of 
1198 files are seperated by newlines.  If I<FILE> is C<->, the list is loaded 
1199 from standard input. 
1201 =item B<--[no]filter> 
1203 Forces ack to act as if it were recieving input via a pipe. 
1205 =item B<--[no]follow> 
1207 Follow or don't follow symlinks, other than whatever starting files 
1208 or directories were specified on the command line. 
1210 This is off by default. 
1212 =item B<-g I<PATTERN>> 
1214 Print files where the relative path + filename matches I<PATTERN>. 
1216 =item B<--[no]group> 
1218 B<--group> groups matches by file name.  This is the default 
1219 when used interactively. 
1221 B<--nogroup> prints one result per line, like grep.  This is the 
1222 default when output is redirected. 
1224 =item B<-H>, B<--with-filename> 
1226 Print the filename for each match. This is the default unless searching 
1227 a single explicitly specified file. 
1229 =item B<-h>, B<--no-filename> 
1231 Suppress the prefixing of filenames on output when multiple files are 
1234 =item B<--[no]heading> 
1236 Print a filename heading above each file's results.  This is the default 
1237 when used interactively. 
1239 =item B<--help>, B<-?> 
1241 Print a short help statement. 
1243 =item B<--help-types>, B<--help=types> 
1245 Print all known types. 
1247 =item B<-i>, B<--ignore-case> 
1249 Ignore case distinctions in PATTERN 
1251 =item B<--ignore-ack-defaults> 
1253 Tells ack to completely ignore the default definitions provided with ack. 
1254 This is useful in combination with B<--create-ackrc> if you I<really> want 
1257 =item B<--[no]ignore-dir=I<DIRNAME>>, B<--[no]ignore-directory=I<DIRNAME>> 
1259 Ignore directory (as CVS, .svn, etc are ignored). May be used 
1260 multiple times to ignore multiple directories. For example, mason 
1261 users may wish to include B<--ignore-dir=data>. The B<--noignore-dir> 
1262 option allows users to search directories which would normally be 
1263 ignored (perhaps to research the contents of F<.svn/props> directories). 
1265 The I<DIRNAME> must always be a simple directory name. Nested 
1266 directories like F<foo/bar> are NOT supported. You would need to 
1267 specify B<--ignore-dir=foo> and then no files from any foo directory 
1268 are taken into account by ack unless given explicitly on the command 
1271 =item B<--ignore-file=I<FILTERTYPE:FILTERARGS>> 
1273 Ignore files matching I<FILTERTYPE:FILTERARGS>.  The filters are specified 
1274 identically to file type filters as seen in L</"Defining your own types">. 
1276 =item B<-k>, B<--known-types> 
1278 Limit selected files to those with types that ack knows about.  This is 
1279 equivalent to the default behavior found in ack 1. 
1281 =item B<--lines=I<NUM>> 
1283 Only print line I<NUM> of each file. Multiple lines can be given with multiple 
1284 B<--lines> options or as a comma separated list (B<--lines=3,5,7>). B<--lines=4-7> 
1285 also works. The lines are always output in ascending order, no matter the 
1286 order given on the command line. 
1288 =item B<-l>, B<--files-with-matches> 
1290 Only print the filenames of matching files, instead of the matching text. 
1292 =item B<-L>, B<--files-without-matches> 
1294 Only print the filenames of files that do I<NOT> match. 
1296 =item B<--match I<PATTERN>> 
1298 Specify the I<PATTERN> explicitly. This is helpful if you don't want to put the 
1299 regex as your first argument, e.g. when executing multiple searches over the 
1302     # search for foo and bar in given files 
1303     ack file1 t/file* --match foo 
1304     ack file1 t/file* --match bar 
1306 =item B<-m=I<NUM>>, B<--max-count=I<NUM>> 
1308 Stop reading a file after I<NUM> matches. 
1312 Print this manual page. 
1314 =item B<-n>, B<--no-recurse> 
1316 No descending into subdirectories. 
1320 Show only the part of each line matching PATTERN (turns off text 
1323 =item B<--output=I<expr>> 
1325 Output the evaluation of I<expr> for each line (turns off text 
1327 If PATTERN matches more than once then a line is output for each non-overlapping match. 
1328 For more information please see the section L</"Examples of F<--output>">. 
1330 =item B<--pager=I<program>>, B<--nopager> 
1332 B<--pager> directs ack's output through I<program>.  This can also be specified 
1333 via the C<ACK_PAGER> and C<ACK_PAGER_COLOR> environment variables. 
1335 Using --pager does not suppress grouping and coloring like piping 
1336 output on the command-line does. 
1338 B<--nopager> cancels any setting in ~/.ackrc, C<ACK_PAGER> or C<ACK_PAGER_COLOR>. 
1339 No output will be sent through a pager. 
1343 Prints all lines, whether or not they match the expression.  Highlighting 
1344 will still work, though, so it can be used to highlight matches while 
1345 still seeing the entire file, as in: 
1347     # Watch a log file, and highlight a certain IP address 
1348     $ tail -f ~/access.log | ack --passthru 123.45.67.89 
1352 Only works in conjunction with -f, -g, -l or -c (filename output). The filenames 
1353 are output separated with a null byte instead of the usual newline. This is 
1354 helpful when dealing with filenames that contain whitespace, e.g. 
1356     # remove all files of type html 
1357     ack -f --html --print0 | xargs -0 rm -f 
1359 =item B<-Q>, B<--literal> 
1361 Quote all metacharacters in PATTERN, it is treated as a literal. 
1363 =item B<-r>, B<-R>, B<--recurse> 
1365 Recurse into sub-directories. This is the default and just here for 
1366 compatibility with grep. You can also use it for turning B<--no-recurse> off. 
1370 Suppress error messages about nonexistent or unreadable files.  This is taken 
1373 =item B<--[no]smart-case>, B<--no-smart-case> 
1375 Ignore case in the search strings if PATTERN contains no uppercase 
1376 characters. This is similar to C<smartcase> in vim. This option is 
1377 off by default, and ignored if C<-i> is specified. 
1379 B<-i> always overrides this option. 
1381 =item B<--sort-files> 
1383 Sorts the found files lexicographically.  Use this if you want your file 
1384 listings to be deterministic between runs of I<ack>. 
1386 =item B<--show-types> 
1388 Outputs the filetypes that ack associates with each file. 
1390 Works with B<-f> and B<-g> options. 
1392 =item B<--type=[no]TYPE> 
1394 Specify the types of files to include or exclude from a search. 
1395 TYPE is a filetype, like I<perl> or I<xml>.  B<--type=perl> can 
1396 also be specified as B<--perl>, and B<--type=noperl> can be done 
1399 If a file is of both type "foo" and "bar", specifying --foo and 
1400 --nobar will exclude the file, because an exclusion takes precedence 
1403 Type specifications can be repeated and are ORed together. 
1405 See I<ack --help=types> for a list of valid types. 
1407 =item B<--type-add I<TYPE>:I<FILTER>:I<FILTERARGS>> 
1409 Files with the given FILTERARGS applied to the given FILTER 
1410 are recognized as being of (the existing) type TYPE. 
1411 See also L</"Defining your own types">. 
1414 =item B<--type-set I<TYPE>:I<FILTER>:I<FILTERARGS>> 
1416 Files with the given FILTERARGS applied to the given FILTER are recognized as 
1417 being of type TYPE. This replaces an existing definition for type TYPE.  See 
1418 also L</"Defining your own types">. 
1420 =item B<--type-del I<TYPE>> 
1422 The filters associated with TYPE are removed from Ack, and are no longer considered 
1425 =item B<-v>, B<--invert-match> 
1427 Invert match: select non-matching lines 
1431 Display version and copyright information. 
1433 =item B<-w>, B<--word-regexp> 
1435 Force PATTERN to match only whole words.  The PATTERN is wrapped with 
1436 C<\b> metacharacters. 
1440 An abbreviation for B<--files-from=->; the list of files to search are read 
1441 from standard input, with one line per file. 
1445 Stops after reporting first match of any kind.  This is different 
1446 from B<--max-count=1> or B<-m1>, where only one match per file is 
1447 shown.  Also, B<-1> works with B<-f> and B<-g>, where B<-m> does 
1452 Display the all-important Bill The Cat logo.  Note that the exact 
1453 spelling of B<--thpppppt> is not important.  It's checked against 
1454 a regular expression. 
1458 Check with the admiral for traps. 
1462 =head1 THE .ackrc FILE 
1464 The F<.ackrc> file contains command-line options that are prepended 
1465 to the command line before processing.  Multiple options may live 
1466 on multiple lines.  Lines beginning with a # are ignored.  A F<.ackrc> 
1467 might look like this: 
1469     # Always sort the files 
1472     # Always color, even if piping to a another program 
1475     # Use "less -r" as my pager 
1478 Note that arguments with spaces in them do not need to be quoted, 
1479 as they are not interpreted by the shell. Basically, each I<line> 
1480 in the F<.ackrc> file is interpreted as one element of C<@ARGV>. 
1482 F<ack> looks in several locations for F<.ackrc> files; the searching 
1483 process is detailed in L</"ACKRC LOCATION SEMANTICS">.  These 
1484 files are not considered if B<--noenv> is specified on the command line. 
1486 =head1 Defining your own types 
1488 ack allows you to define your own types in addition to the predefined 
1489 types. This is done with command line options that are best put into 
1490 an F<.ackrc> file - then you do not have to define your types over and 
1491 over again. In the following examples the options will always be shown 
1492 on one command line so that they can be easily copy & pasted. 
1494 I<ack --perl foo> searches for foo in all perl files. I<ack --help=types> 
1495 tells you, that perl files are files ending 
1496 in .pl, .pm, .pod or .t. So what if you would like to include .xs 
1497 files as well when searching for --perl files? I<ack --type-add perl:ext:xs --perl foo> 
1498 does this for you. B<--type-add> appends 
1499 additional extensions to an existing type. 
1501 If you want to define a new type, or completely redefine an existing 
1502 type, then use B<--type-set>. I<ack --type-set eiffel:ext:e,eiffel> defines 
1503 the type I<eiffel> to include files with 
1504 the extensions .e or .eiffel. So to search for all eiffel files 
1505 containing the word Bertrand use I<ack --type-set eiffel:ext:e,eiffel --eiffel Bertrand>. 
1506 As usual, you can also write B<--type=eiffel> 
1507 instead of B<--eiffel>. Negation also works, so B<--noeiffel> excludes 
1508 all eiffel files from a search. Redefining also works: I<ack --type-set cc:ext:c,h> 
1509 and I<.xs> files no longer belong to the type I<cc>. 
1511 When defining your own types in the F<.ackrc> file you have to use 
1514   --type-set=eiffel:ext:e,eiffel 
1516 or writing on separate lines 
1521 The following does B<NOT> work in the F<.ackrc> file: 
1523   --type-set eiffel:ext:e,eiffel 
1526 In order to see all currently defined types, use I<--help-types>, e.g. 
1527 I<ack --type-set backup:ext:bak --type-add perl:ext:perl --help-types> 
1529 In addition to filtering based on extension (like ack 1.x allowed), ack 2 
1530 offers additional filter types.  The generic syntax is 
1531 I<--type-set TYPE:FILTER:FILTERARGS>; I<FILTERARGS> depends on the value 
1536 =item is:I<FILENAME> 
1538 I<is> filters match the target filename exactly.  It takes exactly one 
1539 argument, which is the name of the file to match. 
1543     --type-set make:is:Makefile 
1545 =item ext:I<EXTENSION>[,I<EXTENSION2>[,...]] 
1547 I<ext> filters match the extension of the target file against a list 
1548 of extensions.  No leading dot is needed for the extensions. 
1552     --type-set perl:ext:pl,pm,t 
1554 =item match:I<PATTERN> 
1556 I<match> filters match the target filename against a regular expression. 
1557 The regular expression is made case insensitive for the search. 
1561     --type-set make:match:/(gnu)?makefile/ 
1563 =item firstlinematch:I<PATTERN> 
1565 I<firstlinematch> matches the first line of the target file against a 
1566 regular expression.  Like I<match>, the regular expression is made 
1571     --type-add perl:firstlinematch:/perl/ 
1575 More filter types may be made available in the future. 
1577 =head1 ENVIRONMENT VARIABLES 
1579 For commonly-used ack options, environment variables can make life 
1580 much easier.  These variables are ignored if B<--noenv> is specified 
1581 on the command line. 
1587 Specifies the location of the user's F<.ackrc> file.  If this file doesn't 
1588 exist, F<ack> looks in the default location. 
1592 This variable specifies default options to be placed in front of 
1593 any explicit options on the command line. 
1595 =item ACK_COLOR_FILENAME 
1597 Specifies the color of the filename when it's printed in B<--group> 
1598 mode.  By default, it's "bold green". 
1600 The recognized attributes are clear, reset, dark, bold, underline, 
1601 underscore, blink, reverse, concealed black, red, green, yellow, 
1602 blue, magenta, on_black, on_red, on_green, on_yellow, on_blue, 
1603 on_magenta, on_cyan, and on_white.  Case is not significant. 
1604 Underline and underscore are equivalent, as are clear and reset. 
1605 The color alone sets the foreground color, and on_color sets the 
1608 This option can also be set with B<--color-filename>. 
1610 =item ACK_COLOR_MATCH 
1612 Specifies the color of the matching text when printed in B<--color> 
1613 mode.  By default, it's "black on_yellow". 
1615 This option can also be set with B<--color-match>. 
1617 See B<ACK_COLOR_FILENAME> for the color specifications. 
1619 =item ACK_COLOR_LINENO 
1621 Specifies the color of the line number when printed in B<--color> 
1622 mode.  By default, it's "bold yellow". 
1624 This option can also be set with B<--color-lineno>. 
1626 See B<ACK_COLOR_FILENAME> for the color specifications. 
1630 Specifies a pager program, such as C<more>, C<less> or C<most>, to which 
1631 ack will send its output. 
1633 Using C<ACK_PAGER> does not suppress grouping and coloring like 
1634 piping output on the command-line does, except that on Windows 
1635 ack will assume that C<ACK_PAGER> does not support color. 
1637 C<ACK_PAGER_COLOR> overrides C<ACK_PAGER> if both are specified. 
1639 =item ACK_PAGER_COLOR 
1641 Specifies a pager program that understands ANSI color sequences. 
1642 Using C<ACK_PAGER_COLOR> does not suppress grouping and coloring 
1643 like piping output on the command-line does. 
1645 If you are not on Windows, you never need to use C<ACK_PAGER_COLOR>. 
1649 =head1 ACK & OTHER TOOLS 
1651 =head2 Vim integration 
1653 F<ack> integrates easily with the Vim text editor. Set this in your 
1654 F<.vimrc> to use F<ack> instead of F<grep>: 
1658 That example uses C<-k> to search through only files of the types ack 
1659 knows about, but you may use other default flags. Now you can search 
1660 with F<ack> and easily step through the results in Vim: 
1662   :grep Dumper perllib 
1664 Miles Sterrett has written a Vim plugin for F<ack> which allows you to use 
1665 C<:Ack> instead of C<:grep>, as well as several other advanced features. 
1667 L<https://github.com/mileszs/ack.vim> 
1669 =head2 Emacs integration 
1671 Phil Jackson put together an F<ack.el> extension that "provides a 
1672 simple compilation mode ... has the ability to guess what files you 
1673 want to search for based on the major-mode." 
1675 L<http://www.shellarchive.co.uk/content/emacs.html> 
1677 =head2 TextMate integration 
1679 Pedro Melo is a TextMate user who writes "I spend my day mostly 
1680 inside TextMate, and the built-in find-in-project sucks with large 
1681 projects.  So I hacked a TextMate command that was using find + 
1682 grep to use ack.  The result is the Search in Project with ack, and 
1683 you can find it here: 
1684 L<http://www.simplicidade.org/notes/archives/2008/03/search_in_proje.html>" 
1686 =head2 Shell and Return Code 
1688 For greater compatibility with I<grep>, I<ack> in normal use returns 
1689 shell return or exit code of 0 only if something is found and 1 if 
1692 (Shell exit code 1 is C<$?=256> in perl with C<system> or backticks.) 
1694 The I<grep> code 2 for errors is not used. 
1696 If C<-f> or C<-g> are specified, then 0 is returned if at least one 
1697 file is found.  If no files are found, then 1 is returned. 
1701 =head1 DEBUGGING ACK PROBLEMS 
1703 If ack gives you output you're not expecting, start with a few simple steps. 
1705 =head2 Use B<--noenv> 
1707 Your environment variables and F<.ackrc> may be doing things you're 
1708 not expecting, or forgotten you specified.  Use B<--noenv> to ignore 
1709 your environment and F<.ackrc>. 
1711 =head2 Use B<-f> to see what files have been selected 
1713 Ack's B<-f> was originally added as a debugging tool.  If ack is 
1714 not finding matches you think it should find, run F<ack -f> to see 
1715 what files have been selected.  You can also add the C<--show-types> 
1716 options to show the type of each file selected. 
1718 =head2 Use B<--dump> 
1720 This lists the ackrc files that are loaded and the options loaded 
1722 So for example you can find a list of directories that do not get searched or where filetypes are defined. 
1726 =head2 Use the F<.ackrc> file. 
1728 The F<.ackrc> is the place to put all your options you use most of 
1729 the time but don't want to remember.  Put all your --type-add and 
1730 --type-set definitions in it.  If you like --smart-case, set it 
1731 there, too.  I also set --sort-files there. 
1733 =head2 Use F<-f> for working with big codesets 
1735 Ack does more than search files.  C<ack -f --perl> will create a 
1736 list of all the Perl files in a tree, ideal for sending into F<xargs>. 
1739     # Change all "this" to "that" in all Perl files in a tree. 
1740     ack -f --perl | xargs perl -p -i -e's/this/that/g' 
1744     perl -p -i -e's/this/that/g' $(ack -f --perl) 
1746 =head2 Use F<-Q> when in doubt about metacharacters 
1748 If you're searching for something with a regular expression 
1749 metacharacter, most often a period in a filename or IP address, add 
1750 the -Q to avoid false positives without all the backslashing.  See 
1751 the following example for more... 
1753 =head2 Use ack to watch log files 
1755 Here's one I used the other day to find trouble spots for a website 
1756 visitor.  The user had a problem loading F<troublesome.gif>, so I 
1757 took the access log and scanned it with ack twice. 
1759     ack -Q aa.bb.cc.dd /path/to/access.log | ack -Q -B5 troublesome.gif 
1761 The first ack finds only the lines in the Apache log for the given 
1762 IP.  The second finds the match on my troublesome GIF, and shows 
1763 the previous five lines from the log in each case. 
1765 =head2 Examples of F<--output> 
1767 Following variables are useful in the expansion string: 
1773 The whole string matched by PATTERN. 
1775 =item C<$1>, C<$2>, ... 
1777 The contents of the 1st, 2nd ... bracketed group in PATTERN. 
1781 The string before the match. 
1785 The string after the match. 
1789 For more details and other variables see 
1790 L<http://perldoc.perl.org/perlvar.html#Variables-related-to-regular-expressions|perlvar>. 
1792 This example shows how to add text around a particular pattern 
1793 (in this case adding _ around word with "e") 
1795     ack2.pl "\w*e\w*" quick.txt --output="$`_$&_$'" 
1796     _The_ quick brown fox jumps over the lazy dog 
1797     The quick brown fox jumps _over_ the lazy dog 
1798     The quick brown fox jumps over _the_ lazy dog 
1800 This shows how to pick out particular parts of a match using ( ) within regular expression. 
1802   ack '=head(\d+)\s+(.*)' --output=' $1 : $2' 
1803   input file contains "=head1 NAME" 
1806 =head2 Share your knowledge 
1808 Join the ack-users mailing list.  Send me your tips and I may add 
1813 =head2 Why isn't ack finding a match in (some file)? 
1815 Probably because it's of a type that ack doesn't recognize.  ack's 
1816 searching behavior is driven by filetype.  B<If ack doesn't know 
1817 what kind of file it is, ack ignores the file.> 
1819 Use the C<-f> switch to see a list of files that ack will search 
1822 If you want ack to search files that it doesn't recognize, use the 
1825 If you want ack to search every file, even ones that it always 
1826 ignores like coredumps and backup files, use the C<-u> switch. 
1828 =head2 Why does ack ignore unknown files by default? 
1830 ack is designed by a programmer, for programmers, for searching 
1831 large trees of code.  Most codebases have a lot files in them which 
1832 aren't source files (like compiled object files, source control 
1833 metadata, etc), and grep wastes a lot of time searching through all 
1834 of those as well and returning matches from those files. 
1836 That's why ack's behavior of not searching things it doesn't recognize 
1837 is one of its greatest strengths: the speed you get from only 
1838 searching the things that you want to be looking at. 
1840 =head2 Wouldn't it be great if F<ack> did search & replace? 
1842 No, ack will always be read-only.  Perl has a perfectly good way 
1843 to do search & replace in files, using the C<-i>, C<-p> and C<-n> 
1846 You can certainly use ack to select your files to update.  For 
1847 example, to change all "foo" to "bar" in all PHP files, you can do 
1848 this from the Unix shell: 
1850     $ perl -i -p -e's/foo/bar/g' $(ack -f --php) 
1852 =head2 Can you make ack recognize F<.xyz> files? 
1854 Yes!  Please see L</"Defining your own types">.  If you think 
1855 that F<ack> should recognize a type by default, please see 
1858 =head2 There's already a program/package called ack. 
1862 =head2 Why is it called ack if it's called ack-grep? 
1864 The name of the program is "ack".  Some packagers have called it 
1865 "ack-grep" when creating packages because there's already a package 
1866 out there called "ack" that has nothing to do with this ack. 
1868 I suggest you make a symlink named F<ack> that points to F<ack-grep> 
1869 because one of the crucial benefits of ack is having a name that's 
1870 so short and simple to type. 
1872 To do that, run this with F<sudo> or as root: 
1874    ln -s /usr/bin/ack-grep /usr/bin/ack 
1876 Alternatively, you could use a shell alias: 
1884 =head2 What does F<ack> mean? 
1886 Nothing.  I wanted a name that was easy to type and that you could 
1887 pronounce as a single syllable. 
1889 =head2 Can I do multi-line regexes? 
1891 No, ack does not support regexes that match multiple lines.  Doing 
1892 so would require reading in the entire file at a time. 
1894 If you want to see lines near your match, use the C<--A>, C<--B> 
1895 and C<--C> switches for displaying context. 
1897 =head2 Why is ack telling me I have an invalid option when searching for C<+foo>? 
1899 ack treats command line options beginning with C<+> or C<-> as options; if you 
1900 would like to search for these, you may prefix your search term with C<--> or 
1901 use the C<--match> option.  (However, don't forget that C<+> is a regular 
1902 expression metacharacter!) 
1904 =head1 ACKRC LOCATION SEMANTICS 
1906 Ack can load its configuration from many sources.  This list 
1907 specifies the sources Ack looks for configuration; each one 
1908 that is found is loaded in the order specified here, and 
1909 each one overrides options set in any of the sources preceding 
1910 it.  (For example, if I set --sort-files in my user ackrc, and 
1911 --nosort-files on the command line, the command line takes 
1918 Defaults are loaded from App::Ack::ConfigDefaults.  This can be omitted 
1919 using C<--ignore-ack-defaults>. 
1921 =item * Global ackrc 
1923 Options are then loaded from the global ackrc.  This is located at 
1924 C</etc/ackrc> on Unix-like systems, and 
1925 C<C:\Documents and Settings\All Users\Application Data> on Windows. 
1926 This can be omitted using C<--noenv>. 
1930 Options are then loaded from the user's ackrc.  This is located at 
1931 C<$HOME/.ackrc> on Unix-like systems, and 
1932 C<C:\Documents and Settings\$USER\Application Data>.  If a different 
1933 ackrc is desired, it may be overriden with the C<$ACKRC> environment 
1935 This can be omitted using C<--noenv>. 
1937 =item * Project ackrc 
1939 Options are then loaded from the project ackrc.  The project ackrc is 
1940 the first ackrc file with the name C<.ackrc> or C<_ackrc>, first searching 
1941 in the current directory, then the parent directory, then the grandparent 
1942 directory, etc.  This can be omitted using C<--noenv>. 
1946 Options are then loaded from the enviroment variable C<ACK_OPTIONS>.  This can 
1947 be omitted using C<--noenv>. 
1949 =item * Command line 
1951 Options are then loaded from the command line. 
1955 =head1 DIFFERENCES BETWEEN ACK 1.X AND ACK 2.X 
1957 A lot of changes were made for ack 2; here is a list of them. 
1959 =head2 GENERAL CHANGES 
1965 When no selectors are specified, ack 1.x only searches through files that 
1966 it can map to a file type.  ack 2.x, by constrast, will search through 
1967 every regular, non-binary file that is not explicitly ignored via 
1968 B<--ignore-file> or B<--ignore-dir>.  This is similar to the behavior of the 
1969 B<-a/--all> option in ack 1.x. 
1973 A more flexible filter system has been added, so that more powerful file types 
1974 may be created by the user.  For details, please consult 
1975 L</"Defining your own types">. 
1979 ack now loads multiple ackrc files; see L</"ACKRC LOCATION SEMANTICS"> for 
1984 ack's default filter definitions aren't special; you may tell ack to 
1985 completely disregard them if you don't like them. 
1989 =head2 REMOVED OPTIONS 
1995 Because of the change in default search behavior, the B<-a/--all> and 
1996 B<-u/--unrestricted> options have been removed.  In addition, the 
1997 B<-k/--known-types> option was added to cause ack to behave with 
1998 the default search behavior of ack 1.x. 
2002 The B<-G> option has been removed.  Two regular expressions on the 
2003 command line was considered too confusing; to simulate B<-G>'s functionality, 
2004 you may use the new B<-x> option to pipe filenames from one invocation of 
2009 The B<--binary> option has been removed. 
2013 The B<--skipped> option has been removed. 
2017 The B<--text> option has been removed. 
2021 The B<--invert-file-match> option has been removed.  Instead, you may 
2022 use B<-v> with B<-g>. 
2026 =head2 CHANGED OPTIONS 
2032 The options that modify the regular expression's behavior (B<-i>, B<-w>, 
2033 B<-Q>, and B<-v>) may now be used with B<-g>. 
2037 =head2 ADDED OPTIONS 
2043 B<--files-from> was added so that a user may submit a list of filenames as 
2044 a list of files to search. 
2048 B<-x> was added to tell ack to accept a list of filenames via standard input; 
2049 this list is the list of filenames that will be used for the search. 
2053 B<-s> was added to tell ack to suppress error messages about non-existent or 
2058 B<--ignore-directory> and B<--noignore-directory> were added as aliases for 
2059 B<--ignore-dir> and B<--noignore-dir> respectively. 
2063 B<--ignore-file> was added so that users may specify patterns of files to 
2064 ignore (ex. /.*~$/). 
2068 B<--dump> was added to allow users to easily find out which options are 
2073 B<--create-ackrc> was added so that users may create custom ackrc files based 
2074 on the default settings loaded by ack, and so that users may easily view those 
2079 B<--type-del> was added to selectively remove file type definitions. 
2083 B<--ignore-ack-defaults> was added so that users may ignore ack's default 
2084 options in favor of their own. 
2088 B<--bar> was added so ack users may consult Admiral Ackbar. 
2094 Andy Lester, C<< <andy at petdance.com> >> 
2098 Please report any bugs or feature requests to the issues list at 
2099 Github: L<https://github.com/petdance/ack2/issues> 
2103 All enhancement requests MUST first be posted to the ack-users 
2104 mailing list at L<http://groups.google.com/group/ack-users>.  I 
2105 will not consider a request without it first getting seen by other 
2106 ack users.  This includes requests for new filetypes. 
2108 There is a list of enhancements I want to make to F<ack> in the ack 
2109 issues list at Github: L<https://github.com/petdance/ack2/issues> 
2111 Patches are always welcome, but patches with tests get the most 
2116 Support for and information about F<ack> can be found at: 
2120 =item * The ack homepage 
2122 L<http://beyondgrep.com/> 
2124 =item * The ack-users mailing list 
2126 L<http://groups.google.com/group/ack-users> 
2128 =item * The ack issues list at Github 
2130 L<https://github.com/petdance/ack2/issues> 
2132 =item * AnnoCPAN: Annotated CPAN documentation 
2134 L<http://annocpan.org/dist/ack> 
2136 =item * CPAN Ratings 
2138 L<http://cpanratings.perl.org/d/ack> 
2142 L<http://search.cpan.org/dist/ack> 
2144 =item * Git source repository 
2146 L<https://github.com/petdance/ack2> 
2150 =head1 ACKNOWLEDGEMENTS 
2152 How appropriate to have I<ack>nowledgements! 
2154 Thanks to everyone who has contributed to ack in any way, including 
2177 Eric Van Dewoestine, 
2186 Christopher J. Madsen, 
2198 GE<aacute>bor SzabE<oacute>, 
2201 E<AElig>var ArnfjE<ouml>rE<eth> Bjarmason, 
2205 Mark Leighton Fisher, 
2211 Nilson Santos F. Jr, 
2216 Ask BjE<oslash>rn Hansen, 
2220 Slaven ReziE<0x107>, 
2230 =head1 COPYRIGHT & LICENSE 
2232 Copyright 2005-2013 Andy Lester. 
2234 This program is free software; you can redistribute it and/or modify 
2235 it under the terms of the Artistic License v2.0. 
2237 See http://www.perlfoundation.org/artistic_license_2_0 or the LICENSE.md 
2238 file that comes with the ack distribution. 
2247 our $VERSION = '1.12'; 
2253 our $name; # name of the current file 
2254 our $dir;  # dir of the current file 
2256 our %files_defaults; 
2261         file_filter     
=> undef, 
2262         descend_filter  
=> undef, 
2263         error_handler   
=> sub { CORE
::die @_ }, 
2264         warning_handler 
=> sub { CORE
::warn @_ }, 
2265         sort_files      
=> undef, 
2266         follow_symlinks 
=> 1, 
2269     %skip_dirs = map {($_,1)} (File
::Spec-
>curdir, File
::Spec-
>updir); 
2274     die _bad_invocation
() if @_ && defined($_[0]) && ($_[0] eq __PACKAGE__
); 
2276     my ($parms,@queue) = _setup
( \
%files_defaults, @_ ); 
2277     my $filter = $parms->{file_filter
}; 
2281             my ($dirname,$file,$fullpath) = splice( @queue, 0, 3 ); 
2282             if ( -f 
$fullpath || -p 
$fullpath || $fullpath =~ m{^/dev/fd} ) { 
2285                     local $File::Next
::dir 
= $dirname; 
2286                     local $File::Next
::name 
= $fullpath; 
2287                     next if not $filter->(); 
2289                 return wantarray ? ($dirname,$file,$fullpath) : $fullpath; 
2292                 unshift( @queue, _candidate_files
( $parms, $fullpath ) ); 
2306     die _bad_invocation
() if @_ && defined($_[0]) && ($_[0] eq __PACKAGE__
); 
2308     my ($parms,@queue) = _setup
( \
%files_defaults, @_ ); 
2309     my $err  = $parms->{error_handler
}; 
2310     my $warn = $parms->{error_handler
}; 
2312     my $filename = $queue[1]; 
2314     if ( !defined($filename) ) { 
2315         $err->( 'Must pass a filename to from_file()' ); 
2320     if ( $filename eq '-' ) { 
2324         if ( !open( $fh, '<', $filename ) ) { 
2325             $err->( "Unable to open $filename: $!" ); 
2329     my $filter = $parms->{file_filter
}; 
2332         local $/ = $parms->{nul_separated
} ? "\x00" : $/; 
2333         while ( my $fullpath = <$fh> ) { 
2335             next unless $fullpath =~ /./; 
2336             if ( not ( -f 
$fullpath || -p _ 
) ) { 
2337                 $warn->( "$fullpath: No such file" ); 
2341             my ($volume,$dirname,$file) = File
::Spec-
>splitpath( $fullpath ); 
2344                 local $File::Next
::dir  
= $dirname; 
2345                 local $File::Next
::name 
= $fullpath; 
2346                 next if not $filter->(); 
2348             return wantarray ? ($dirname,$file,$fullpath) : $fullpath; 
2356 sub _bad_invocation 
{ 
2357     my $good = (caller(1))[3]; 
2359     $bad =~ s/(.+)::/$1->/; 
2360     return "$good must not be invoked as $bad"; 
2363 sub sort_standard
($$)   { return $_[0]->[1] cmp $_[1]->[1] } 
2364 sub sort_reverse
($$)    { return $_[1]->[1] cmp $_[0]->[1] } 
2369     my @parts = split( /\//, $path ); 
2371     return $path if @parts < 2; 
2373     return File
::Spec-
>catfile( @parts ); 
2379     my $defaults = shift; 
2380     my $passed_parms = ref $_[0] eq 'HASH' ? {%{+shift}} : {}; # copy parm hash 
2382     my %passed_parms = %{$passed_parms}; 
2385     for my $key ( keys %{$defaults} ) { 
2387             exists $passed_parms{$key} 
2388                 ? delete $passed_parms{$key} 
2389                 : $defaults->{$key}; 
2392     # Any leftover keys are bogus 
2393     for my $badkey ( keys %passed_parms ) { 
2394         my $sub = (caller(1))[3]; 
2395         $parms->{error_handler
}->( "Invalid option passed to $sub(): $badkey" ); 
2398     # If it's not a code ref, assume standard sort 
2399     if ( $parms->{sort_files
} && ( ref($parms->{sort_files
}) ne 'CODE' ) ) { 
2400         $parms->{sort_files
} = \
&sort_standard
; 
2405         my $start = reslash
( $_ ); 
2407             push @queue, ($start,undef,$start); 
2410             push @queue, (undef,$start,$start); 
2414     return ($parms,@queue); 
2418 sub _candidate_files 
{ 
2420     my $dirname = shift; 
2423     if ( !opendir $dh, $dirname ) { 
2424         $parms->{error_handler
}->( "$dirname: $!" ); 
2429     my $descend_filter = $parms->{descend_filter
}; 
2430     my $follow_symlinks = $parms->{follow_symlinks
}; 
2431     my $sort_sub = $parms->{sort_files
}; 
2433     for my $file ( grep { !exists $skip_dirs{$_} } readdir $dh ) { 
2436         # Only do directory checking if we have a descend_filter 
2437         my $fullpath = File
::Spec-
>catdir( $dirname, $file ); 
2438         if ( !$follow_symlinks ) { 
2439             next if -l 
$fullpath; 
2443         if ( $descend_filter ) { 
2444             if ( $has_stat ? (-d _
) : (-d 
$fullpath) ) { 
2445                 local $File::Next
::dir 
= $fullpath; 
2447                 next if not $descend_filter->(); 
2451             push( @newfiles, [ $dirname, $file, $fullpath ] ); 
2454             push( @newfiles, $dirname, $file, $fullpath ); 
2460         return map { @{$_} } sort $sort_sub @newfiles; 
2467 1; # End of File::Next 
2479     $COPYRIGHT = 'Copyright 2005-2013 Andy Lester.'; 
2480     $GIT_REVISION = q{8f405b7}; 
2495 our $is_filter_mode; 
2496 our $output_to_pipe; 
2502 use File
::Spec 
1.00015 (); 
2505     # These have to be checked before any filehandle diddling. 
2506     $output_to_pipe  = not -t 
*STDOUT
; 
2507     $is_filter_mode = -p STDIN
; 
2509     $is_cygwin       = ($^O eq 'cygwin'); 
2510     $is_windows      = ($^O =~ /MSWin32/); 
2511     $dir_sep_chars   = $is_windows ? quotemeta( '\\/' ) : quotemeta( File
::Spec-
>catfile( '', '' ) ); 
2516 sub remove_dir_sep 
{ 
2518     $path =~ s/[$dir_sep_chars]$//; 
2526     return CORE
::warn( _my_program
(), ': ', @_, "\n" ); 
2531     return CORE
::die( _my_program
(), ': ', @_, "\n" ); 
2535     require File
::Basename
; 
2536     return File
::Basename
::basename
( $0 ); 
2541 sub filetypes_supported 
{ 
2542     return keys %mappings; 
2546     my $y = q{_   /|,\\'!.x',=(www)=,   U   }; 
2547     $y =~ tr/,x!w/\nOo_/; 
2552     my $y = _get_thpppt
(); 
2553     App
::Ack
::print( "$y ack $_[0]!\n" ); 
2561  3~!I#7#I"7#I!?!+!="+"="+!:! 
2562  2?#I!7!I!?#I!7!I"+"=%+"=# 
2563  1?"+!?*+!=#~"=!+#?"="+! 
2564  0?"+!?"I"?&+!="~!=!~"=!+%="+" 
2565  /I!+!?)+!?!+!=$~!=!~!="+!="+"?!="?! 
2567  ,,!?%I"?(+$=$~!=#:"~$:!~! 
2568  ,I!?!I!?"I"?!+#?"+!?!+#="~$:!~!:!~!:!,!:!,":#~! 
2569  +I!?&+!="+!?#+$=!~":!~!:!~!:!,!:#,!:!,%:" 
2570  *+!I!?!+$=!+!=!+!?$+#=!~":!~":#,$:",#:!,!:! 
2571  *I!?"+!?!+!=$+!?#+#=#~":$,!:",!:!,&:" 
2572  )I!?$=!~!=#+"?!+!=!+!=!~!="~!:!~":!,'.!,%:!~! 
2573  (=!?"+!?!=!~$?"+!?!+!=#~"=",!="~$,$.",#.!:!=! 
2574  (I"+"="~"=!+&=!~"=!~!,!~!+!=!?!+!?!=!I!?!+"=!.",!.!,":! 
2575  %I$?!+!?!=%+!~!+#~!=!~#:#=!~!+!~!=#:!,%.!,!.!:" 
2576  $I!?!=!?!I!+!?"+!=!~!=!~!?!I!?!=!+!=!~#:",!~"=!~!:"~!=!:",&:" '-/ 
2577  $?!+!I!?"+"=!+"~!,!:"+#~#:#,"=!~"=!,!~!,!.",!:".!:! */! !I!t!'!s! !a! !g!r!e!p!!! !/! 
2578  $+"=!+!?!+"~!=!:!~!:"I!+!,!~!=!:!~!,!:!,$:!~".&:"~!,# (-/ 
2579  %~!=!~!=!:!.!+"~!:!,!.!,!~!=!:$.!,":!,!.!:!~!,!:!=!.#="~!,!:" ./! 
2580  %=!~!?!+"?"+!=!~",!.!:!?!~!.!:!,!:!,#.!,!:","~!:!=!~!=!:",!~! ./! 
2581  %+"~":!~!=#~!:!~!,!.!~!:",!~!=!~!.!:!,!.",!:!,":!=":!.!,!:!7! -/! 
2582  %~",!:".#:!=!:!,!:"+!:!~!:!.!,!~!,!.#,!.!,$:"~!,":"~!=! */! 
2583  &=!~!=#+!=!~",!.!:",#:#,!.",+:!,!.",!=!+!?! 
2584  &~!=!~!=!~!:"~#:",!.!,#~!:!.!+!,!.",$.",$.#,!+!I!?! 
2585  &~!="~!:!~":!~",!~!=!~":!,!:!~!,!:!,&.$,#."+!?!I!?!I! 
2586  &~!=!~!=!+!,!:!~!:!=!,!:!~&:$,!.!,".!,".!,#."~!+!?$I! 
2587  &~!=!~!="~!=!:!~":!,!~%:#,!:",!.!,#.",#I!7"I!?!+!?"I" 
2588  &+!I!7!:#~"=!~!:!,!:"~$.!=!.!,!~!,$.#,!~!7!I#?!+!?"I"7! 
2589  %7#?!+!~!:!=!~!=!~":!,!:"~":#.!,)7#I"?"I!7& 
2590  %7#I!=":!=!~!:"~$:"~!:#,!:!,!:!~!:#,!7#I!?#7) 
2591  $7$+!,!~!=#~!:!~!:!~$:#,!.!~!:!=!,":!7#I"?#7+=!?! 
2592  $7#I!~!,!~#=!~!:"~!:!,!:!,#:!=!~",":!7$I!?#I!7*+!=!+" 
2593  "I!7$I!,":!,!.!=":$,!:!,$:$7$I!+!?"I!7+?"I!7!I!7!,! 
2594  !,!7%I!:",!."~":!,&.!,!:!~!I!7$I!+!?"I!7,?!I!7',! 
2595  !7(,!.#~":!,%.!,!7%I!7!?#I"7,+!?!7* 
2596 7+:!,!~#,"=!7'I!?#I"7/+!7+ 
2597 77I!+!7!?!7!I"71+!7, 
2600     $x =~ s/(.)(.)/$1x(ord($2)-32)/eg; 
2601     App
::Ack
::print( $x ); 
2607     my $help_arg = shift || 0; 
2609     return show_help_types
() if $help_arg =~ /^types?/; 
2611     App
::Ack
::print( <<"END_OF_HELP" ); 
2612 Usage: ack [OPTION]... PATTERN [FILES OR DIRECTORIES] 
2614 Search for PATTERN in each source file in the tree from the current 
2615 directory on down.  If any files or directories are specified, then 
2616 only those files and directories are checked.  ack may also search 
2617 STDIN, but only if no file or directory arguments are specified, 
2618 or if one of them is "-". 
2620 Default switches may be specified in ACK_OPTIONS environment variable or 
2621 an .ackrc file. If you want no dependency on the environment, turn it 
2624 Example: ack -i select 
2627   -i, --ignore-case             Ignore case distinctions in PATTERN 
2628   --[no]smart-case              Ignore case distinctions in PATTERN, 
2629                                 only if PATTERN contains no upper case. 
2630                                 Ignored if -i is specified 
2631   -v, --invert-match            Invert match: select non-matching lines 
2632   -w, --word-regexp             Force PATTERN to match only whole words 
2633   -Q, --literal                 Quote all metacharacters; PATTERN is literal 
2636   --lines=NUM                   Only print line(s) NUM of each file 
2637   -l, --files-with-matches      Only print filenames containing matches 
2638   -L, --files-without-matches   Only print filenames with no matches 
2639   --output=expr                 Output the evaluation of expr for each line 
2640                                 (turns off text highlighting) 
2641   -o                            Show only the part of a line matching PATTERN 
2642                                 Same as --output='\$&' 
2643   --passthru                    Print all lines, whether matching or not 
2644   --match PATTERN               Specify PATTERN explicitly. 
2645   -m, --max-count=NUM           Stop searching in each file after NUM matches 
2646   -1                            Stop searching after one match of any kind 
2647   -H, --with-filename           Print the filename for each match (default: 
2648                                 on unless explicitly searching a single file) 
2649   -h, --no-filename             Suppress the prefixing filename on output 
2650   -c, --count                   Show number of lines matching per file 
2651   --[no]column                  Show the column number of the first match 
2653   -A NUM, --after-context=NUM   Print NUM lines of trailing context after matching 
2655   -B NUM, --before-context=NUM  Print NUM lines of leading context before matching 
2657   -C [NUM], --context[=NUM]     Print NUM lines (default 2) of output context. 
2659   --print0                      Print null byte as separator between filenames, 
2660                                 only works with -f, -g, -l, -L or -c. 
2662   -s                            Suppress error messages about nonexistent or 
2667   --pager=COMMAND               Pipes all ack output through COMMAND.  For example, 
2668                                 --pager="less -R".  Ignored if output is redirected. 
2669   --nopager                     Do not send output through a pager.  Cancels any 
2670                                 setting in ~/.ackrc, ACK_PAGER or ACK_PAGER_COLOR. 
2671   --[no]heading                 Print a filename heading above each file's results. 
2672                                 (default: on when used interactively) 
2673   --[no]break                   Print a break between results from different files. 
2674                                 (default: on when used interactively) 
2675   --group                       Same as --heading --break 
2676   --nogroup                     Same as --noheading --nobreak 
2677   --[no]color                   Highlight the matching text (default: on unless 
2678                                 output is redirected, or on Windows) 
2679   --[no]colour                  Same as --[no]color 
2680   --color-filename=COLOR 
2682   --color-lineno=COLOR          Set the color for filenames, matches, and line numbers. 
2683   --flush                       Flush output immediately, even when ack is used 
2684                                 non-interactively (when output goes to a pipe or 
2689   -f                            Only print the files selected, without searching. 
2690                                 The PATTERN must not be specified. 
2691   -g                            Same as -f, but only select files matching PATTERN. 
2692   --sort-files                  Sort the found files lexically. 
2693   --show-types                  Show which types each file has. 
2694   --files-from=FILE             Read the list of files to search from FILE. 
2695   -x                            Read the list of files to search from STDIN. 
2697 File inclusion/exclusion: 
2698   --[no]ignore-dir=name         Add/Remove directory from the list of ignored dirs 
2699   --[no]ignore-directory=name   Synonym for ignore-dir 
2700   --ignore-file=filter          Add filter for ignoring files 
2701   -r, -R, --recurse             Recurse into subdirectories (ack's default behavior) 
2702   -n, --no-recurse              No descending into subdirectories 
2703   --[no]follow                  Follow symlinks.  Default is off. 
2704   -k, --known-types             Include only files with types that ack recognizes. 
2706   --type=X                      Include only X files, where X is a recognized filetype. 
2707   --type=noX                    Exclude X files. 
2708                                 See "ack --help-types" for supported filetypes. 
2710 File type specification: 
2711   --type-set TYPE:FILTER:FILTERARGS 
2712                                 Files with the given FILTERARGS applied to the given 
2713                                 FILTER are recognized as being of type TYPE. This 
2714                                 replaces an existing definition for type TYPE. 
2715   --type-add TYPE:FILTER:FILTERARGS 
2716                                 Files with the given FILTERARGS applied to the given 
2717                                 FILTER are recognized as being of type TYPE. 
2718   --type-del TYPE               Removes all filters associated with TYPE. 
2722   --[no]env                     Ignore environment variables and global ackrc files.  --env is legal but redundant. 
2723   --ackrc=filename              Specify an ackrc file to use 
2724   --ignore-ack-defaults         Ignore the default definitions that ack includes. 
2725   --create-ackrc                Outputs a default ackrc for your customization to standard output. 
2726   --help, -?                    This help 
2727   --help-types                  Display all known types 
2728   --dump                        Dump information on which options are loaded from which RC files 
2729   --[no]filter                  Force ack to treat standard input as a pipe (--filter) or tty (--nofilter) 
2731   --version                     Display version & copyright 
2732   --thpppt                      Bill the Cat 
2733   --bar                         The warning admiral 
2735 Exit status is 0 if match, 1 if no match. 
2737 This is version $VERSION of ack. 
2745 sub show_help_types 
{ 
2746     App
::Ack
::print( <<'END_OF_HELP' ); 
2747 Usage: ack [OPTION]... PATTERN [FILES OR DIRECTORIES] 
2749 The following is the list of filetypes supported by ack.  You can 
2750 specify a file type with the --type=TYPE format, or the --TYPE 
2751 format.  For example, both --type=perl and --perl work. 
2753 Note that some extensions may appear in multiple types.  For example, 
2754 .pod files are both Perl and Parrot. 
2758     my @types = filetypes_supported
(); 
2761         $maxlen = length if $maxlen < length; 
2763     for my $type ( sort @types ) { 
2764         next if $type =~ /^-/; # Stuff to not show 
2765         my $ext_list = $mappings{$type}; 
2767         if ( ref $ext_list ) { 
2768             $ext_list = join( '; ', map { $_->to_string } @{$ext_list} ); 
2770         App
::Ack
::print( sprintf( "    --[no]%-*.*s %s\n", $maxlen, $maxlen, $type, $ext_list ) ); 
2779     Pod
::Usage
::pod2usage
({ 
2780         -input   
=> $App::Ack
::orig_program_name
, 
2789 sub get_version_statement 
{ 
2792     my $copyright = get_copyright
(); 
2793     my $this_perl = $Config::Config
{perlpath
}; 
2795         my $ext = $Config::Config
{_exe
}; 
2796         $this_perl .= $ext unless $this_perl =~ m/$ext$/i; 
2798     my $ver = sprintf( '%vd', $^V ); 
2800     my $git_revision = $GIT_REVISION ? " (git commit $GIT_REVISION)" : ''; 
2802     return <<"END_OF_VERSION"; 
2803 ack ${VERSION}${git_revision} 
2804 Running under Perl $ver at $this_perl 
2808 This program is free software.  You may modify or distribute it 
2809 under the terms of the Artistic License v2.0. 
2814 sub print_version_statement 
{ 
2815     App
::Ack
::print( get_version_statement
() ); 
2826 # print subs added in order to make it easy for a third party 
2827 # module (such as App::Wack) to redefine the display methods 
2828 # and show the results in a different way. 
2829 sub print                   { print {$fh} @_; return; } 
2830 sub print_first_filename    
{ App
::Ack
::print( $_[0], "\n" ); return; } 
2831 sub print_blank_line        
{ App
::Ack
::print( "\n" ); return; } 
2832 sub print_separator         
{ App
::Ack
::print( "--\n" ); return; } 
2833 sub print_filename          
{ App
::Ack
::print( $_[0], $_[1] ); return; } 
2834 sub print_line_no           
{ App
::Ack
::print( $_[0], $_[1] ); return; } 
2835 sub print_column_no         
{ App
::Ack
::print( $_[0], $_[1] ); return; } 
2837     my $filename = shift; 
2838     my $nmatches = shift; 
2841     my $show_filename = shift; 
2843     if ($show_filename) { 
2844         App
::Ack
::print( $filename ); 
2845         App
::Ack
::print( ':', $nmatches ) if $count; 
2848         App
::Ack
::print( $nmatches ) if $count; 
2850     App
::Ack
::print( $ors ); 
2856     my $filename = shift; 
2858     my $show_filename = shift; 
2860     if ($show_filename) { 
2861         App
::Ack
::print( $filename, ':0', $ors ); 
2864         App
::Ack
::print( '0', $ors ); 
2871     my $command = shift; 
2873     return if App
::Ack
::output_to_pipe
(); 
2876     if ( not open( $pager, '|-', $command ) ) { 
2877         App
::Ack
::die( qq{Unable to pipe to pager "$command": $!} ); 
2885 sub output_to_pipe 
{ 
2886     return $output_to_pipe; 
2891     my $nmatches = shift; 
2893     my $rc = $nmatches ? 0 : 1; 
2899 1; # End of App::Ack 
2900 package App
::Ack
::Resource
; 
2910     Carp
::confess
( 'Must be overloaded' ); 
2934 sub needs_line_scan 
{ 
2959 package App
::Ack
::Resources
; 
2972     my $self = bless {}, $class; 
2974     my $file_filter    = undef; 
2975     my $descend_filter = $opt->{descend_filter
}; 
2978         $descend_filter = sub { 
2984         File
::Next
::files
( { 
2985             file_filter     
=> $opt->{file_filter
}, 
2986             descend_filter  
=> $descend_filter, 
2987             error_handler   
=> sub { my $msg = shift; App
::Ack
::warn( $msg ) }, 
2988             sort_files      
=> $opt->{sort_files
}, 
2989             follow_symlinks 
=> $opt->{follow
}, 
3002         File
::Next
::from_file
( { 
3003             error_handler   
=> sub { my $msg = shift; App
::Ack
::warn( $msg ) }, 
3004             warning_handler 
=> sub { my $msg = shift; App
::Ack
::warn( $msg ) }, 
3005             sort_files      
=> $opt->{sort_files
}, 
3006         }, $file ) or return undef; 
3013 # This is for reading input lines from STDIN, not the list of files from STDIN 
3018     my $self  = bless {}, $class; 
3020     my $has_been_called = 0; 
3022     $self->{iter
} = sub { 
3023         if ( !$has_been_called ) { 
3024             $has_been_called = 1; 
3036     my $file = $self->{iter
}->() or return; 
3038     return App
::Ack
::Resource
::Basic-
>new( $file ); 
3042 package App
::Ack
::Resource
::Basic
; 
3051     our @ISA = 'App::Ack::Resource'; 
3057     my $filename = shift; 
3060         filename 
=> $filename, 
3065     if ( $self->{filename
} eq '-' ) { 
3066         $self->{fh
}     = *STDIN
; 
3067         $self->{opened
} = 1; 
3075     return $_[0]->{filename
}; 
3080 sub needs_line_scan 
{ 
3084     return 1 if $opt->{v
}; 
3086     my $size = -s 
$self->{fh
}; 
3090     elsif ( $size > 100_000 ) { 
3095     my $rc = sysread( $self->{fh
}, $buffer, $size ); 
3096     if ( !defined($rc) && $App::Ack
::report_bad_filenames 
) { 
3097         App
::Ack
::warn( "$self->{filename}: $!" ); 
3100     return 0 unless $rc && ( $rc == $size ); 
3102     my $regex = $opt->{regex
}; 
3103     return $buffer =~ /$regex/m; 
3110     # return if we haven't opened the file yet 
3111     if ( !defined($self->{fh
}) ) { 
3115     if( !seek( $self->{fh
}, 0, 0 ) && $App::Ack
::report_bad_filenames 
) { 
3116         App
::Ack
::warn( "$self->{filename}: $!" ); 
3126     # return if we haven't opened the file yet 
3127     if ( !defined($self->{fh
}) ) { 
3131     if ( !close($self->{fh
}) && $App::Ack
::report_bad_filenames 
) { 
3132         App
::Ack
::warn( $self->name() . ": $!" ); 
3135     $self->{opened
} = 0; 
3144     return __PACKAGE__-
>new($self->name); 
3150     my $fh = $self->open(); 
3152     unless(exists $self->{firstliney
}) { 
3154         my $rc     = sysread( $fh, $buffer, 250 ); 
3155         unless($rc) { # XXX handle this better? 
3158         $buffer =~ s/[\r\n].*//s; 
3159         $self->{firstliney
} = $buffer; 
3165     return $self->{firstliney
}; 
3171     return $self->{fh
} if $self->{opened
}; 
3173     unless ( open $self->{fh
}, '<', $self->{filename
} ) { 
3177     $self->{opened
} = 1; 
3183 package App
::Ack
::Filter
; 
3188     '""' => 'to_string'; 
3196     my ( undef, $type, @args ) = @_; 
3198     if ( my $package = $filter_types{$type} ) { 
3199         return $package->new(@args); 
3201     Carp
::croak 
"Unknown filter type '$type'"; 
3205 sub register_filter 
{ 
3206     my ( undef, $type, $package ) = @_; 
3208     $filter_types{$type} = $package; 
3217     return App
::Ack
::Filter
::Inverse-
>new( $self ); 
3229     return '(unimplemented to_string)'; 
3240 package App
::Ack
::Filter
::Extension
; 
3245     our @ISA = 'App::Ack::Filter'; 
3249     my ( $class, @extensions ) = @_; 
3251     my $exts = join('|', map { "\Q$_\E"} @extensions); 
3252     my $re   = qr/[.](?:$exts)$/i; 
3255         extensions 
=> \
@extensions, 
3261     my ( $self, $resource ) = @_; 
3263     my $re = $self->{'regex'}; 
3265     return $resource->name =~ /$re/; 
3271     my $re = $self->{'regex'}; 
3273     return ref($self) . " - $re"; 
3279     my $exts = $self->{'extensions'}; 
3281     return join(' ', map { ".$_" } @{$exts}); 
3285     App
::Ack
::Filter-
>register_filter(ext 
=> __PACKAGE__
); 
3289 package App
::Ack
::Filter
::FirstLineMatch
; 
3294     our @ISA = 'App::Ack::Filter'; 
3298     my ( $class, $re ) = @_; 
3300     $re =~ s{^/|/$}{}g; # XXX validate? 
3308 # This test reads the first 250 characters of a file, then just uses the 
3309 # first line found in that. This prevents reading something  like an entire 
3310 # .min.js file (which might be only one "line" long) into memory. 
3313     my ( $self, $resource ) = @_; 
3315     my $re = $self->{'regex'}; 
3317     my $line = $resource->firstliney; 
3319     return $line =~ /$re/; 
3325     my $re = $self->{'regex'}; 
3327     return ref($self) . " - $re"; 
3333     (my $re = $self->{regex
}) =~ s{\([^:]*:(.*)\)$}{$1}; 
3335     return "first line matches /$re/"; 
3339     App
::Ack
::Filter-
>register_filter(firstlinematch 
=> __PACKAGE__
); 
3343 package App
::Ack
::Filter
::Is
; 
3348     our @ISA = 'App::Ack::Filter'; 
3351 use File
::Spec 
3.00 (); 
3354     my ( $class, $filename ) = @_; 
3357         filename 
=> $filename, 
3362     my ( $self, $resource ) = @_; 
3364     my $filename = $self->{'filename'}; 
3365     my $base     = (File
::Spec-
>splitpath($resource->name))[2]; 
3367     return $base eq $filename; 
3373     my $filename = $self->{'filename'}; 
3375     return ref($self) . " - $filename"; 
3381     my $filename = $self->{'filename'}; 
3385     App
::Ack
::Filter-
>register_filter(is => __PACKAGE__
); 
3389 package App
::Ack
::Filter
::Match
; 
3394     our @ISA = 'App::Ack::Filter'; 
3397 use File
::Spec 
3.00; 
3400     my ( $class, $re ) = @_; 
3402     $re =~ s{^/|/$}{}g; # XXX validate? 
3411     my ( $self, $resource ) = @_; 
3413     my $re   = $self->{'regex'}; 
3414     my $base = (File
::Spec-
>splitpath($resource->name))[2]; 
3416     return $base =~ /$re/; 
3422     my $re = $self->{'regex'}; 
3424     print ref($self) . " - $re"; 
3430     my $re = $self->{'regex'}; 
3432     return "filename matches $re"; 
3436     App
::Ack
::Filter-
>register_filter(match 
=> __PACKAGE__
); 
3440 package App
::Ack
::Filter
::Default
; 
3445     our @ISA = 'App::Ack::Filter'; 
3451     return bless {}, $class; 
3455     my ( $self, $resource ) = @_; 
3457     return -T 
$resource->name; 
3461 package App
::Ack
::Filter
::Inverse
; 
3466     our @ISA = 'App::Ack::Filter'; 
3470     my ( $class, $filter ) = @_; 
3478     my ( $self, $resource ) = @_; 
3480     my $filter = $self->{'filter'}; 
3481     return !$filter->filter( $resource ); 
3487     return $self->{'filter'}; 
3497     my $filter = $self->{'filter'}; 
3503 package App
::Ack
::ConfigFinder
; 
3510 use File
::Spec 
3.00; 
3512 use if ($^O =~ /MSWin32/ ? 1 : 0), "Win32"; 
3520     $is_win = $^O =~ /MSWin32/, 
3522     return bless {}, $class; 
3525 sub _remove_redundancies 
{ 
3526     my ( @configs ) = @_; 
3529         # inode stat always returns 0 on windows, 
3530         # so just check filenames 
3533         foreach my $path (@configs) { 
3534             push @uniq, $path unless $seen{$path}; 
3543         my %dev_and_inode_seen; 
3545         foreach my $path ( @configs ) { 
3546             my ( $dev, $inode ) = (stat $path)[0, 1]; 
3548             if( defined($dev) ) { 
3549                 if( $dev_and_inode_seen{"$dev:$inode"} ) { 
3553                     $dev_and_inode_seen{"$dev:$inode"} = 1; 
3558         return grep { defined() } @configs; 
3563 sub _check_for_ackrc 
{ 
3564     return unless defined $_[0]; 
3566     my @files = grep { -f 
} 
3567                 map { File
::Spec-
>catfile(@_, $_) } 
3570     die File
::Spec-
>catdir(@_) . " contains both .ackrc and _ackrc.\n" . 
3571         "Please remove one of those files.\n" 
3574     return wantarray ? @files : $files[0]; 
3575 } # end _check_for_ackrc 
3578 sub find_config_files 
{ 
3582         push @config_files, map { File
::Spec-
>catfile($_, 'ackrc') } ( 
3583             Win32
::GetFolderPath
(Win32
::CSIDL_COMMON_APPDATA
()), 
3584             Win32
::GetFolderPath
(Win32
::CSIDL_APPDATA
()), 
3588         push @config_files, '/etc/ackrc'; 
3592     if ( $ENV{'ACKRC'} && -f 
$ENV{'ACKRC'} ) { 
3593         push @config_files, $ENV{'ACKRC'}; 
3596         push @config_files, _check_for_ackrc
($ENV{'HOME'}); 
3599     my @dirs = File
::Spec-
>splitdir(Cwd
::getcwd
()); 
3601         my $ackrc = _check_for_ackrc
(@dirs); 
3602         if(defined $ackrc) { 
3603             push @config_files, $ackrc; 
3609     # XXX we only test for existence here, so if the file is 
3610     #     deleted out from under us, this will fail later. =( 
3611     return _remove_redundancies
( @config_files ); 
3618     return unless defined $file && -e 
$file; 
3622     open( my $fh, '<', $file ) or App
::Ack
::die( "Unable to read $file: $!" ); 
3623     while ( my $line = <$fh> ) { 
3628         next if $line eq ''; 
3629         next if $line =~ /^#/; 
3631         push( @lines, $line ); 
3639 package App
::Ack
::ConfigLoader
; 
3645 use Getopt
::Long 
2.35 (); 
3646 use Text
::ParseWords 
3.1 (); 
3649 my @INVALID_COMBINATIONS; 
3652     my @context  = qw( -A -B -C --after-context --before-context --context ); 
3653     my @pretty   = qw( --heading --group --break ); 
3654     my @filename = qw( -h -H --with-filename --no-filename ); 
3656     @INVALID_COMBINATIONS = ( 
3658         [qw(-l)]                 => [@context, @pretty, @filename, qw(-L -o --passthru --output --max-count --column -f -g --show-types)], 
3659         [qw(-L)]                 => [@context, @pretty, @filename, qw(-l -o --passthru --output --max-count --column -f -g --show-types -c --count)], 
3660         [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)], 
3661         [qw(-o)]                 => [@context, qw(--output -c --count --column --column -f --show-types)], 
3662         [qw(--passthru)]         => [@context, qw(--output --column -m --max-count -1 -c --count -f -g)], 
3663         [qw(--output)]           => [@context, qw(-c --count -f -g)], 
3664         [qw(--match)]            => [qw(-f -g)], 
3665         [qw(-m --max-count)]     => [qw(-1 -f -g -c --count)], 
3666         [qw(-h --no-filename)]   => [qw(-H --with-filename -f -g --group --heading)], 
3667         [qw(-H --with-filename)] => [qw(-h --no-filename -f -g)], 
3668         [qw(-c --count)]         => [@context, @pretty, qw(--column -f -g)], 
3669         [qw(--column)]           => [qw(-f -g)], 
3670         [@context]               => [qw(-f -g)], 
3671         [qw(-f)]                 => [qw(-g), @pretty], 
3672         [qw(-g)]                 => [qw(-f), @pretty], 
3676 sub process_filter_spec 
{ 
3679     if ( $spec =~ /^(\w+):(\w+):(.*)/ ) { 
3680         my ( $type_name, $ext_type, $arguments ) = ( $1, $2, $3 ); 
3682         return ( $type_name, 
3683             App
::Ack
::Filter-
>create_filter($ext_type, split(/,/, $arguments)) ); 
3685     elsif ( $spec =~ /^(\w+)=(.*)/ ) { # Check to see if we have ack1-style argument specification. 
3686         my ( $type_name, $extensions ) = ( $1, $2 ); 
3688         my @extensions = split(/,/, $extensions); 
3689         foreach my $extension ( @extensions ) { 
3690             $extension =~ s/^[.]//; 
3693         return ( $type_name, App
::Ack
::Filter-
>create_filter('ext', @extensions) ); 
3696         Carp
::croak 
"invalid filter specification '$spec'"; 
3700 sub process_filetypes 
{ 
3701     my ( $opt, $arg_sources ) = @_; 
3703     Getopt
::Long
::Configure
('default', 'no_auto_help', 'no_auto_version'); # start with default options, minus some annoying ones 
3704     Getopt
::Long
::Configure
( 
3709     my %additional_specs; 
3711     my $add_spec = sub { 
3712         my ( undef, $spec ) = @_; 
3714         my ( $name, $filter ) = process_filter_spec
($spec); 
3716         push @{ $App::Ack
::mappings
{$name} }, $filter; 
3718         $additional_specs{$name . '!'} = sub { 
3719             my ( undef, $value ) = @_; 
3721             my @filters = @{ $App::Ack
::mappings
{$name} }; 
3723                 @filters = map { $_->invert() } @filters; 
3726             push @{ $opt->{'filters'} }, @filters; 
3730     my $set_spec = sub { 
3731         my ( undef, $spec ) = @_; 
3733         my ( $name, $filter ) = process_filter_spec
($spec); 
3735         $App::Ack
::mappings
{$name} = [ $filter ]; 
3737         $additional_specs{$name . '!'} = sub { 
3738             my ( undef, $value ) = @_; 
3740             my @filters = @{ $App::Ack
::mappings
{$name} }; 
3742                 @filters = map { $_->invert() } @filters; 
3745             push @{ $opt->{'filters'} }, @filters; 
3749     my $delete_spec = sub { 
3750         my ( undef, $name ) = @_; 
3752         delete $App::Ack
::mappings
{$name}; 
3753         delete $additional_specs{$name . '!'}; 
3756     my %type_arg_specs = ( 
3757         'type-add=s' => $add_spec, 
3758         'type-set=s' => $set_spec, 
3759         'type-del=s' => $delete_spec, 
3762     for ( my $i = 0; $i < @{$arg_sources}; $i += 2) { 
3763         my ( $source_name, $args ) = @{$arg_sources}[ $i, $i + 1]; 
3766             # $args are modified in place, so no need to munge $arg_sources 
3767             local @ARGV = @{$args}; 
3768             Getopt
::Long
::GetOptions
(%type_arg_specs); 
3772             ( undef, $arg_sources->[$i + 1] ) = 
3773                 Getopt
::Long
::GetOptionsFromString
($args, %type_arg_specs); 
3777     $additional_specs{'k|known-types'} = sub { 
3778         my ( undef, $value ) = @_; 
3780         my @filters = map { @{$_} } values(%App::Ack
::mappings
); 
3782         push @{ $opt->{'filters'} }, @filters; 
3785     return \
%additional_specs; 
3788 sub removed_option 
{ 
3789     my ( $option, $explanation ) = @_; 
3791     $explanation ||= ''; 
3793         warn "Option '$option' is not valid in ack 2\n$explanation"; 
3799     my ( $opt, $extra_specs ) = @_; 
3801     my $dash_a_explanation = <<EOT; 
3802 This is because we now have -k/--known-types which makes it only select files 
3803 of known types, rather than any text file (which is the behavior of ack 1.x). 
3807         1                   => sub { $opt->{1} = $opt->{m
} = 1 }, 
3808         'A|after-context=i' => \
$opt->{after_context
}, 
3809         'B|before-context=i' 
3810                             => \
$opt->{before_context
}, 
3811         'C|context:i'       => sub { shift; my $val = shift; $opt->{before_context
} = $opt->{after_context
} = ($val || 2) }, 
3812         'a'                 => removed_option
('-a', $dash_a_explanation), 
3813         'all'               => removed_option
('--all', $dash_a_explanation), 
3814         'break!'            => \
$opt->{break}, 
3815         c                   
=> \
$opt->{count
}, 
3816         'color|colour!'     => \
$opt->{color
}, 
3817         'color-match=s'     => \
$ENV{ACK_COLOR_MATCH
}, 
3818         'color-filename=s'  => \
$ENV{ACK_COLOR_FILENAME
}, 
3819         'color-lineno=s'    => \
$ENV{ACK_COLOR_LINENO
}, 
3820         'column!'           => \
$opt->{column
}, 
3821         count               
=> \
$opt->{count
}, 
3822         'create-ackrc'      => sub { print "$_\n" for ( '--ignore-ack-defaults', App
::Ack
::ConfigDefault
::options
() ); exit; }, 
3824             my ( undef, $value ) = @_; 
3827                 $opt->{noenv_seen
} = 1; 
3831         'files-from=s'      => \
$opt->{files_from
}, 
3832         'filter!'           => \
$App::Ack
::is_filter_mode
, 
3833         flush               
=> \
$opt->{flush
}, 
3834         'follow!'           => \
$opt->{follow
}, 
3836         G                   
=> removed_option
('-G'), 
3837         'group!'            => sub { shift; $opt->{heading
} = $opt->{break} = shift }, 
3838         'heading!'          => \
$opt->{heading
}, 
3839         'h|no-filename'     => \
$opt->{h
}, 
3840         'H|with-filename'   => \
$opt->{H
}, 
3841         'i|ignore-case'     => \
$opt->{i
}, 
3842         'ignore-directory|ignore-dir=s' # XXX Combine this version with the negated version below 
3844                                 my ( undef, $dir ) = @_; 
3846                                 $dir = App
::Ack
::remove_dir_sep
( $dir ); 
3847                                 if ( $dir !~ /^(?:is|match):/ ) { 
3848                                     $dir = 'is:' . $dir; 
3850                                 push @{ $opt->{idirs
} }, $dir; 
3852         'ignore-file=s'    => sub { 
3853                                     my ( undef, $file ) = @_; 
3854                                     push @{ $opt->{ifiles
} }, $file; 
3856         'lines=s'           => sub { shift; my $val = shift; push @{$opt->{lines
}}, $val }, 
3857         'l|files-with-matches' 
3859         'L|files-without-matches' 
3861         'm|max-count=i'     => \
$opt->{m
}, 
3862         'match=s'           => \
$opt->{regex
}, 
3863         'n|no-recurse'      => \
$opt->{n
}, 
3864         o                   
=> sub { $opt->{output
} = '$&' }, 
3865         'output=s'          => \
$opt->{output
}, 
3866         'pager=s'           => \
$opt->{pager
}, 
3867         'noignore-directory|noignore-dir=s' 
3869                                 my ( undef, $dir ) = @_; 
3871                                 # XXX can you do --noignore-dir=match,...? 
3872                                 $dir = App
::Ack
::remove_dir_sep
( $dir ); 
3873                                 if ( $dir !~ /^(?:is|match):/ ) { 
3874                                     $dir = 'is:' . $dir; 
3876                                 if ( $dir !~ /^(?:is|match):/ ) { 
3877                                     Carp
::croak
("invalid noignore-directory argument: '$dir'"); 
3880                                 @{ $opt->{idirs
} } = grep { 
3882                                 } @{ $opt->{idirs
} }; 
3884                                 push @{ $opt->{no_ignore_dirs
} }, $dir; 
3886         'nopager'           => sub { $opt->{pager
} = undef }, 
3887         'passthru'          => \
$opt->{passthru
}, 
3888         'print0'            => \
$opt->{print0
}, 
3889         'Q|literal'         => \
$opt->{Q
}, 
3890         'r|R|recurse'       => sub { $opt->{n
} = 0 }, 
3891         's'                 => \
$opt->{dont_report_bad_filenames
}, 
3892         'show-types'        => \
$opt->{show_types
}, 
3893         'smart-case!'       => \
$opt->{smart_case
}, 
3894         'sort-files'        => \
$opt->{sort_files
}, 
3896             my ( $getopt, $value ) = @_; 
3899             if ( $value =~ s/^no// ) { 
3903             my $callback = $extra_specs->{ $value . '!' }; 
3906                 $callback->( $getopt, $cb_value ); 
3909                 Carp
::croak
( "Unknown type '$value'" ); 
3912         'u'                 => removed_option
('-u'), 
3913         'unrestricted'      => removed_option
('--unrestricted'), 
3914         'v|invert-match'    => \
$opt->{v
}, 
3915         'w|word-regexp'     => \
$opt->{w
}, 
3916         'x'                 => sub { $opt->{files_from
} = '-' }, 
3918         'version'           => sub { App
::Ack
::print_version_statement
(); exit; }, 
3919         'help|?:s'          => sub { shift; App
::Ack
::show_help
(@_); exit; }, 
3920         'help-types'        => sub { App
::Ack
::show_help_types
(); exit; }, 
3921         'man'               => sub { App
::Ack
::show_man
(); exit; }, 
3922         $extra_specs ? %{$extra_specs} : (), 
3927     my ( $opt, $extra_specs, $arg_sources ) = @_; 
3929     Getopt
::Long
::Configure
('default', 'no_auto_help', 'no_auto_version'); # start with default options, minus some annoying ones 
3930     Getopt
::Long
::Configure
( 
3936     my $is_help_types_active; 
3938     for ( my $i = 0; $i < @{$arg_sources}; $i += 2 ) { 
3939         my ( $source_name, $args ) = @{$arg_sources}[ $i, $i + 1 ]; 
3941         if ( $source_name eq 'ARGV' ) { 
3942             $argv_source = $args; 
3947     if ( $argv_source ) { # this *should* always be true, but you never know... 
3948         my @copy = @{$argv_source}; 
3949         local @ARGV = @copy; 
3951         Getopt
::Long
::Configure
('pass_through'); 
3953         Getopt
::Long
::GetOptions
( 
3954             'help-types' => \
$is_help_types_active, 
3957         Getopt
::Long
::Configure
('no_pass_through'); 
3960     my $arg_specs = get_arg_spec
($opt, $extra_specs); 
3962     for ( my $i = 0; $i < @{$arg_sources}; $i += 2) { 
3963         my ($source_name, $args) = @{$arg_sources}[$i, $i + 1]; 
3967             local @ARGV = @{$args}; 
3968             $ret = Getopt
::Long
::GetOptions
( %{$arg_specs} ); 
3972             ( $ret, $arg_sources->[$i + 1] ) = 
3973                 Getopt
::Long
::GetOptionsFromString
( $args, %{$arg_specs} ); 
3976             if ( !$is_help_types_active ) { 
3977                 my $where = $source_name eq 'ARGV' ? 'on command line' : "in $source_name"; 
3978                 App
::Ack
::die( "Invalid option $where" ); 
3981         if ( $opt->{noenv_seen
} ) { 
3982             App
::Ack
::die( "--noenv found in $source_name" ); 
3986     # XXX We need to check on a -- in the middle of a non-ARGV source 
3991 sub should_dump_options 
{ 
3992     my ( $sources ) = @_; 
3994     for(my $i = 0; $i < @{$sources}; $i += 2) { 
3995         my ( $name, $options ) = @{$sources}[$i, $i + 1]; 
3996         if($name eq 'ARGV') { 
3998             local @ARGV = @{$options}; 
3999             Getopt
::Long
::Configure
('default', 'pass_through', 'no_auto_help', 'no_auto_version'); 
4000             Getopt
::Long
::GetOptions
( 
4003             @{$options} = @ARGV; 
4010 sub explode_sources 
{ 
4011     my ( $sources ) = @_; 
4015     Getopt
::Long
::Configure
('default', 'pass_through', 'no_auto_help', 'no_auto_version'); 
4018     my $arg_spec = get_arg_spec
(\
%opt); 
4020     my $add_type = sub { 
4021         my ( undef, $arg ) = @_; 
4024         if ( $arg =~ /(\w+)=/) { 
4025             $arg_spec->{$1} = sub {}; 
4028             ( $arg ) = split /:/, $arg; 
4029             $arg_spec->{$arg} = sub {}; 
4033     my $del_type = sub { 
4034         my ( undef, $arg ) = @_; 
4036         delete $arg_spec->{$arg}; 
4039     for(my $i = 0; $i < @{$sources}; $i += 2) { 
4040         my ( $name, $options ) = @{$sources}[$i, $i + 1]; 
4041         if ( ref($options) ne 'ARRAY' ) { 
4042             $sources->[$i + 1] = $options = 
4043                 [ Text
::ParseWords
::shellwords
($options) ]; 
4045         for ( my $j = 0; $j < @{$options}; $j++ ) { 
4046             next unless $options->[$j] =~ /^-/; 
4047             my @chunk = ( $options->[$j] ); 
4048             push @chunk, $options->[$j] while ++$j < @{$options} && $options->[$j] !~ /^-/; 
4052             local @ARGV = @chunk; 
4053             Getopt
::Long
::GetOptions
( 
4054                 'type-add=s' => $add_type, 
4055                 'type-set=s' => $add_type, 
4056                 'type-del=s' => $del_type, 
4058             Getopt
::Long
::GetOptions
( %{$arg_spec} ); 
4060             push @new_sources, $name, \
@copy; 
4064     return \
@new_sources; 
4070     my $first_a = $a->[0]; 
4071     my $first_b = $b->[0]; 
4073     $first_a =~ s/^--?//; 
4074     $first_b =~ s/^--?//; 
4076     return $first_a cmp $first_b; 
4080     my ( $sources ) = @_; 
4082     $sources = explode_sources
($sources); 
4087     for(my $i = 0; $i < @{$sources}; $i += 2) { 
4088         my ( $name, $contents ) = @{$sources}[$i, $i + 1]; 
4089         if ( not $opts_by_source{$name} ) { 
4090             $opts_by_source{$name} = []; 
4091             push @source_names, $name; 
4093         push @{$opts_by_source{$name}}, $contents; 
4096     foreach my $name (@source_names) { 
4097         my $contents = $opts_by_source{$name}; 
4100         print '=' x 
length($name), "\n"; 
4101         print '  ', join(' ', @{$_}), "\n" foreach sort { compare_opts
($a, $b) } @{$contents}; 
4107 sub remove_default_options_if_needed 
{ 
4108     my ( $sources ) = @_; 
4112     foreach my $index ( 0 .. $#$sources ) { 
4113         if ( $sources->[$index] eq 'Defaults' ) { 
4114             $default_index = $index; 
4119     return $sources unless defined $default_index; 
4121     my $should_remove = 0; 
4123     Getopt
::Long
::Configure
('default', 'no_auto_help', 'no_auto_version'); # start with default options, minus some annoying ones 
4124     Getopt
::Long
::Configure
( 
4130     foreach my $index ( $default_index + 2 .. $#$sources ) { 
4131         next if $index % 2 != 0; 
4133         my ( $name, $args ) = @{$sources}[ $index, $index + 1 ]; 
4136             local @ARGV = @{$args}; 
4137             Getopt
::Long
::GetOptions
( 
4138                 'ignore-ack-defaults' => \
$should_remove, 
4143             ( undef, $sources->[$index + 1] ) = Getopt
::Long
::GetOptionsFromString
($args, 
4144                 'ignore-ack-defaults' => \
$should_remove, 
4149     Getopt
::Long
::Configure
('default'); 
4150     Getopt
::Long
::Configure
('default', 'no_auto_help', 'no_auto_version'); 
4152     return $sources unless $should_remove; 
4154     my @copy = @{$sources}; 
4155     splice @copy, $default_index, 2; 
4159 sub check_for_mutually_exclusive_options 
{ 
4160     my ( $arg_sources ) = @_; 
4162     my %mutually_exclusive_with; 
4163     my @copy = @{$arg_sources}; 
4165     for(my $i = 0; $i < @INVALID_COMBINATIONS; $i += 2) { 
4166         my ( $lhs, $rhs ) = @INVALID_COMBINATIONS[ $i, $i + 1 ]; 
4168         foreach my $l_opt ( @{$lhs} ) { 
4169             foreach my $r_opt ( @{$rhs} ) { 
4170                 push @{ $mutually_exclusive_with{ $l_opt } }, $r_opt; 
4171                 push @{ $mutually_exclusive_with{ $r_opt } }, $l_opt; 
4179         my ( $source_name, $args ) = splice @copy, 0, 2; 
4180         $args = ref($args) ? [ @{$args} ] : [ Text
::ParseWords
::shellwords
($args) ]; 
4182         foreach my $opt ( @{$args} ) { 
4183             next unless $opt =~ /^[-+]/; 
4184             last if $opt eq '--'; 
4186             if( $opt =~ /^(.*)=/ ) { 
4189             elsif ( $opt =~ /^(-[^-]).+/ ) { 
4193             $set_opts{ $opt } = 1; 
4195             my $mutex_opts = $mutually_exclusive_with{ $opt }; 
4197             next unless $mutex_opts; 
4199             foreach my $mutex_opt ( @{$mutex_opts} ) { 
4200                 if($set_opts{ $mutex_opt }) { 
4201                     die "Options '$mutex_opt' and '$opt' are mutually exclusive\n"; 
4209     my $arg_sources = \
@_; 
4213     check_for_mutually_exclusive_options
($arg_sources); 
4215     $arg_sources = remove_default_options_if_needed
($arg_sources); 
4217     if ( should_dump_options
($arg_sources) ) { 
4218         dump_options
($arg_sources); 
4222     my $type_specs = process_filetypes
(\
%opt, $arg_sources); 
4223     process_other
(\
%opt, $type_specs, $arg_sources); 
4224     while ( @{$arg_sources} ) { 
4225         my ( $source_name, $args ) = splice( @{$arg_sources}, 0, 2 ); 
4227         # All of our sources should be transformed into an array ref 
4229             if ( $source_name eq 'ARGV' ) { 
4233                 Carp
::croak 
"source '$source_name' has extra arguments!"; 
4237             Carp
::croak 
'The impossible has occurred!'; 
4240     my $filters = ($opt{filters
} ||= []); 
4242     # throw the default filter in if no others are selected 
4243     if ( not grep { !$_->is_inverted() } @{$filters} ) { 
4244         push @{$filters}, App
::Ack
::Filter
::Default-
>new(); 
4250 sub retrieve_arg_sources 
{ 
4256     Getopt
::Long
::Configure
('default', 'no_auto_help', 'no_auto_version'); 
4257     Getopt
::Long
::Configure
('pass_through'); 
4258     Getopt
::Long
::Configure
('no_auto_abbrev'); 
4260     Getopt
::Long
::GetOptions
( 
4262         'ackrc=s' => \
$ackrc, 
4265     Getopt
::Long
::Configure
('default', 'no_auto_help', 'no_auto_version'); 
4270         my $finder = App
::Ack
::ConfigFinder-
>new; 
4271         @files  = $finder->find_config_files; 
4274         # we explicitly use open so we get a nice error message 
4275         # XXX this is a potential race condition! 
4276         if(open my $fh, '<', $ackrc) { 
4280             die "Unable to load ackrc '$ackrc': $!" 
4282         push( @files, $ackrc ); 
4285     push @arg_sources, Defaults 
=> [ App
::Ack
::ConfigDefault
::options
() ]; 
4287     foreach my $file ( @files) { 
4288         my @lines = App
::Ack
::ConfigFinder
::read_rcfile
($file); 
4289         push ( @arg_sources, $file, \
@lines ) if @lines; 
4292     if ( $ENV{ACK_OPTIONS
} && !$noenv ) { 
4293         push( @arg_sources, 'ACK_OPTIONS' => $ENV{ACK_OPTIONS
} ); 
4296     push( @arg_sources, 'ARGV' => [ @ARGV ] ); 
4298     return @arg_sources; 
4301 1; # End of App::Ack::ConfigLoader 
4302 package App
::Ack
::ConfigDefault
; 
4308     my @options = split( /\n/, _options_block
() ); 
4309     @options = grep { /./ && !/^#/ } @options; 
4314 sub _options_block 
{ 
4316 # This is the default ackrc for ack 2.0 
4318 # There are four different ways to match 
4320 # is:  Match the filename exactly 
4322 # ext: Match the extension of the filename exactly 
4324 # match: Match the filename against a Perl regular expression 
4326 # firstlinematch: Match the first 250 characters of the first line 
4327 #   of text against a Perl regular expression.  This is only for 
4328 #   the --type-add option. 
4331 # Directories to ignore 
4333 --ignore-directory=is:.bzr 
4336 --ignore-directory=is:.cdv 
4339 --ignore-directory=is:~.dep 
4340 --ignore-directory=is:~.dot 
4341 --ignore-directory=is:~.nib 
4342 --ignore-directory=is:~.plst 
4345 --ignore-directory=is:.git 
4348 --ignore-directory=is:.hg 
4351 --ignore-directory=is:.pc 
4354 --ignore-directory=is:.svn 
4357 --ignore-directory=is:_MTN 
4360 --ignore-directory=is:CVS 
4363 --ignore-directory=is:RCS 
4366 --ignore-directory=is:SCCS 
4369 --ignore-directory=is:_darcs 
4372 --ignore-directory=is:_sgbak 
4375 --ignore-directory=is:autom4te.cache 
4377 # Perl module building 
4378 --ignore-directory=is:blib 
4379 --ignore-directory=is:_build 
4381 # Perl Devel::Cover module's output directory 
4382 --ignore-directory=is:cover_db 
4388 --ignore-file=ext:bak 
4389 --ignore-file=match:/~$/ 
4392 --ignore-file=match:/^#.+#$/ 
4395 --ignore-file=match:/[._].*\.swp$/ 
4398 --ignore-file=match:/core\.\d+$/ 
4400 # minified Javascript 
4401 --ignore-file=match:/[.]min[.]js$/ 
4402 --ignore-file=match:/[.]js[.]min$/ 
4405 --ignore-file=match:/[.]min[.]css$/ 
4406 --ignore-file=match:/[.]css[.]min$/ 
4411 # Perl http://perl.org/ 
4412 --type-add=perl:ext:pl,pm,pod,t 
4413 --type-add=perl:firstlinematch:/^#!.*\bperl/ 
4415 # Makefiles http://www.gnu.org/s/make/ 
4416 --type-add=make:ext:mk 
4417 --type-add=make:ext:mak 
4418 --type-add=make:is:makefile 
4419 --type-add=make:is:Makefile 
4420 --type-add=make:is:GNUmakefile 
4422 # Rakefiles http://rake.rubyforge.org/ 
4423 --type-add=rake:is:Rakefile 
4425 # CMake http://www.cmake.org/ 
4426 --type-add=cmake:is:CMakeLists.txt 
4427 --type-add=cmake:ext:cmake 
4430 --type-add=actionscript:ext:as,mxml 
4432 # Ada http://www.adaic.org/ 
4433 --type-add=ada:ext:ada,adb,ads 
4435 # ASP http://msdn.microsoft.com/en-us/library/aa286483.aspx 
4436 --type-add=asp:ext:asp 
4438 # ASP.Net http://www.asp.net/ 
4439 --type-add=aspx:ext:master,ascx,asmx,aspx,svc 
4442 --type-add=asm:ext:asm,s 
4445 --type-add=batch:ext:bat,cmd 
4447 # ColdFusion http://en.wikipedia.org/wiki/ColdFusion 
4448 --type-add=cfmx:ext:cfc,cfm,cfml 
4450 # Clojure http://clojure.org/ 
4451 --type-add=clojure:ext:clj 
4454 # .xs are Perl C files 
4455 --type-add=cc:ext:c,h,xs 
4461 --type-add=cpp:ext:cpp,cc,cxx,m,hpp,hh,h,hxx 
4464 --type-add=csharp:ext:cs 
4466 # CSS http://www.w3.org/Style/CSS/ 
4467 --type-add=css:ext:css 
4469 # Dart http://www.dartlang.org/ 
4470 --type-add=dart:ext:dart 
4472 # Delphi http://en.wikipedia.org/wiki/Embarcadero_Delphi 
4473 --type-add=delphi:ext:pas,int,dfm,nfm,dof,dpk,dproj,groupproj,bdsgroup,bdsproj 
4475 # Emacs Lisp http://www.gnu.org/software/emacs 
4476 --type-add=elisp:ext:el 
4478 # Erlang http://www.erlang.org/ 
4479 --type-add=erlang:ext:erl,hrl 
4481 # Fortran http://en.wikipedia.org/wiki/Fortran 
4482 --type-add=fortran:ext:f,f77,f90,f95,f03,for,ftn,fpp 
4484 # Google Go http://golang.org/ 
4485 --type-add=go:ext:go 
4487 # Groovy http://groovy.codehaus.org/ 
4488 --type-add=groovy:ext:groovy,gtmpl,gpp,grunit,gradle 
4490 # Haskell http://www.haskell.org/ 
4491 --type-add=haskell:ext:hs,lhs 
4494 --type-add=html:ext:htm,html 
4496 # Java http://www.oracle.com/technetwork/java/index.html 
4497 --type-add=java:ext:java,properties 
4500 --type-add=js:ext:js 
4502 # JSP http://www.oracle.com/technetwork/java/javaee/jsp/index.html 
4503 --type-add=jsp:ext:jsp,jspx,jhtm,jhtml 
4505 # Common Lisp http://common-lisp.net/ 
4506 --type-add=lisp:ext:lisp,lsp 
4508 # Lua http://www.lua.org/ 
4509 --type-add=lua:ext:lua 
4512 --type-add=objc:ext:m,h 
4515 --type-add=objcpp:ext:mm,h 
4517 # OCaml http://caml.inria.fr/ 
4518 --type-add=ocaml:ext:ml,mli 
4520 # Parrot http://www.parrot.org/ 
4521 --type-add=parrot:ext:pir,pasm,pmc,ops,pod,pg,tg 
4523 # PHP http://www.php.net/ 
4524 --type-add=php:ext:php,phpt,php3,php4,php5,phtml 
4525 --type-add=php:firstlinematch:/^#!.*\bphp/ 
4527 # Plone http://plone.org/ 
4528 --type-add=plone:ext:pt,cpt,metadata,cpy,py 
4530 # Python http://www.python.org/ 
4531 --type-add=python:ext:py 
4532 --type-add=python:firstlinematch:/^#!.*\bpython/ 
4534 # R http://www.r-project.org/ 
4537 # Ruby http://www.ruby-lang.org/ 
4538 --type-add=ruby:ext:rb,rhtml,rjs,rxml,erb,rake,spec 
4539 --type-add=ruby:is:Rakefile 
4540 --type-add=ruby:firstlinematch:/^#!.*\bruby/ 
4542 # Rust http://www.rust-lang.org/ 
4543 --type-add=rust:ext:rs 
4545 # Scala http://www.scala-lang.org/ 
4546 --type-add=scala:ext:scala 
4548 # Scheme http://groups.csail.mit.edu/mac/projects/scheme/ 
4549 --type-add=scheme:ext:scm,ss 
4552 --type-add=shell:ext:sh,bash,csh,tcsh,ksh,zsh,fish 
4553 --type-add=shell:firstlinematch:/^#!.*\b(?:ba|t?c|k|z|fi)?sh\b/ 
4555 # Smalltalk http://www.smalltalk.org/ 
4556 --type-add=smalltalk:ext:st 
4558 # SQL http://www.iso.org/iso/catalogue_detail.htm?csnumber=45498 
4559 --type-add=sql:ext:sql,ctl 
4561 # Tcl http://www.tcl.tk/ 
4562 --type-add=tcl:ext:tcl,itcl,itk 
4564 # LaTeX http://www.latex-project.org/ 
4565 --type-add=tex:ext:tex,cls,sty 
4567 # Template Toolkit http://template-toolkit.org/ 
4568 --type-add=tt:ext:tt,tt2,ttml 
4571 --type-add=vb:ext:bas,cls,frm,ctl,vb,resx 
4574 --type-add=verilog:ext:v,vh,sv 
4576 # VHDL http://www.eda.org/twiki/bin/view.cgi/P1076/WebHome 
4577 --type-add=vhdl:ext:vhd,vhdl 
4579 # Vim http://www.vim.org/ 
4580 --type-add=vim:ext:vim 
4582 # XML http://www.w3.org/TR/REC-xml/ 
4583 --type-add=xml:ext:xml,dtd,xsl,xslt,ent 
4584 --type-add=xml:firstlinematch:/<[?]xml/ 
4586 # YAML http://yaml.org/ 
4587 --type-add=yaml:ext:yaml,yml