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