]>
Tony Duckles's Git Repositories (git.nynim.org) - dotfiles.git/blob - bin/ack
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/ack
8 # and submit patches against the individual files
15 our $VERSION = '1.92';
16 # Check http://betterthangrep.com/ for updates
18 # These are all our globals.
22 if ( $App::Ack
::VERSION
ne $main::VERSION
) {
23 App
::Ack
::die( "Program/library version mismatch\n\t$0 is $main::VERSION\n\t$INC{'App/Ack.pm'} is $App::Ack::VERSION" );
26 # Do preliminary arg checking;
27 my $env_is_usable = 1;
29 last if ( $_ eq '--' );
31 # Priorities! Get the --thpppt checking out of the way.
32 /^--th[pt]+t+$/ && App
::Ack
::_thpppt
($_);
34 # See if we want to ignore the environment. (Don't tell Al Gore.)
35 if ( $_ eq '--noenv' ) {
36 my @keys = ( 'ACKRC', grep { /^ACK_/ } keys %ENV );
41 unshift( @ARGV, App
::Ack
::read_ackrc
() ) if $env_is_usable;
42 App
::Ack
::load_colors
();
44 if ( exists $ENV{ACK_SWITCHES
} ) {
45 App
::Ack
::warn( 'ACK_SWITCHES is no longer supported. Use ACK_OPTIONS.' );
49 App
::Ack
::show_help
();
57 my $opt = App
::Ack
::get_command_line_options
();
59 $| = 1 if $opt->{flush
}; # Unbuffer the output if flush mode
61 if ( App
::Ack
::input_from_pipe
() ) {
62 # We're going into filter mode
64 $opt->{$_} and App
::Ack
::die( "Can't use -$_ when acting as a filter." );
66 $opt->{show_filename
} = 0;
67 $opt->{regex
} = App
::Ack
::build_regex
( defined $opt->{regex
} ? $opt->{regex
} : shift @ARGV, $opt );
68 if ( my $nargs = @ARGV ) {
69 my $s = $nargs == 1 ? '' : 's';
70 App
::Ack
::warn( "Ignoring $nargs argument$s on the command-line while acting as a filter." );
72 my $res = App
::Ack
::Resource
::Basic-
>new( '-' );
73 App
::Ack
::search_resource
( $res, $opt );
78 my $file_matching = $opt->{f
} || $opt->{lines
};
79 if ( !$file_matching ) {
80 @ARGV or App
::Ack
::die( 'No regular expression found.' );
81 $opt->{regex
} = App
::Ack
::build_regex
( defined $opt->{regex
} ? $opt->{regex
} : shift @ARGV, $opt );
84 # check that all regexes do compile fine
85 App
::Ack
::check_regex
( $_ ) for ( $opt->{regex
}, $opt->{G
} );
87 my $what = App
::Ack
::get_starting_points
( \
@ARGV, $opt );
88 my $iter = App
::Ack
::get_iterator
( $what, $opt );
89 App
::Ack
::filetype_setup
();
93 App
::Ack
::set_up_pager
( $opt->{pager
} ) if defined $opt->{pager
};
95 $nmatches = App
::Ack
::print_files
( $iter, $opt );
97 elsif ( $opt->{l
} || $opt->{count
} ) {
98 $nmatches = App
::Ack
::print_files_with_matches
( $iter, $opt );
101 $nmatches = App
::Ack
::print_matches
( $iter, $opt );
104 exit ($nmatches ? 0 : 1);
109 ack - grep-like text finder
113 ack [options] PATTERN [FILE...]
114 ack -f [options] [DIRECTORY...]
118 Ack is designed as a replacement for 99% of the uses of F<grep>.
120 Ack searches the named input FILEs (or standard input if no files are
121 named, or the file name - is given) for lines containing a match to the
122 given PATTERN. By default, ack prints the matching lines.
124 Ack can also list files that would be searched, without actually searching
125 them, to let you take advantage of ack's file-type filtering capabilities.
127 =head1 FILE SELECTION
129 I<ack> is intelligent about the files it searches. It knows about
130 certain file types, based on both the extension on the file and,
131 in some cases, the contents of the file. These selections can be
132 made with the B<--type> option.
134 With no file selections, I<ack> only searches files of types that
135 it recognizes. If you have a file called F<foo.wango>, and I<ack>
136 doesn't know what a .wango file is, I<ack> won't search it.
138 The B<-a> option tells I<ack> to select all files, regardless of
141 Some files will never be selected by I<ack>, even with B<-a>,
146 =item * Backup files: Files matching F<#*#> or ending with F<~>.
148 =item * Coredumps: Files matching F<core.\d+>
152 However, I<ack> always searches the files given on the command line,
153 no matter what type. Furthermore, by specifying the B<-u> option all
154 files will be searched.
156 =head1 DIRECTORY SELECTION
158 I<ack> descends through the directory tree of the starting directories
159 specified. However, it will ignore the shadow directories used by
160 many version control systems, and the build directories used by the
161 Perl MakeMaker system. You may add or remove a directory from this
162 list with the B<--[no]ignore-dir> option. The option may be repeated
163 to add/remove multiple directories from the ignore list.
165 For a complete list of directories that do not get searched, run
168 =head1 WHEN TO USE GREP
170 I<ack> trumps I<grep> as an everyday tool 99% of the time, but don't
171 throw I<grep> away, because there are times you'll still need it.
173 E.g., searching through huge files looking for regexes that can be
174 expressed with I<grep> syntax should be quicker with I<grep>.
176 If your script or parent program uses I<grep> C<--quiet> or
177 C<--silent> or needs exit 2 on IO error, use I<grep>.
183 =item B<-a>, B<--all>
185 Operate on all files, regardless of type (but still skip directories
186 like F<blib>, F<CVS>, etc.)
188 =item B<-A I<NUM>>, B<--after-context=I<NUM>>
190 Print I<NUM> lines of trailing context after matching lines.
192 =item B<-B I<NUM>>, B<--before-context=I<NUM>>
194 Print I<NUM> lines of leading context before matching lines.
196 =item B<-C [I<NUM>]>, B<--context[=I<NUM>]>
198 Print I<NUM> lines (default 2) of context around matching lines.
200 =item B<-c>, B<--count>
202 Suppress normal output; instead print a count of matching lines for
203 each input file. If B<-l> is in effect, it will only show the
204 number of lines for each file that has lines matching. Without
205 B<-l>, some line counts may be zeroes.
207 =item B<--color>, B<--nocolor>
209 B<--color> highlights the matching text. B<--nocolor> supresses
210 the color. This is on by default unless the output is redirected.
212 On Windows, this option is off by default unless the
213 L<Win32::Console::ANSI> module is installed or the C<ACK_PAGER_COLOR>
214 environment variable is used.
216 =item B<--color-filename=I<color>>
218 Sets the color to be used for filenames.
220 =item B<--color-match=I<color>>
222 Sets the color to be used for matches.
226 Show the column number of the first match. This is helpful for editors
227 that can place your cursor at a given position.
229 =item B<--env>, B<--noenv>
231 B<--noenv> disables all environment processing. No F<.ackrc> is read
232 and all environment variables are ignored. By default, F<ack> considers
233 F<.ackrc> and settings in the environment.
237 B<--flush> flushes output immediately. This is off by default
238 unless ack is running interactively (when output goes to a pipe
243 Only print the files that would be searched, without actually doing
244 any searching. PATTERN must not be specified, or it will be taken as
247 =item B<--follow>, B<--nofollow>
249 Follow or don't follow symlinks, other than whatever starting files
250 or directories were specified on the command line.
252 This is off by default.
256 Only paths matching I<REGEX> are included in the search. The entire
257 path and filename are matched against I<REGEX>, and I<REGEX> is a
258 Perl regular expression, not a shell glob.
260 The options B<-i>, B<-w>, B<-v>, and B<-Q> do not apply to this I<REGEX>.
264 Print files where the relative path + filename matches I<REGEX>. This option is
265 a convenience shortcut for B<-f> B<-G I<REGEX>>.
267 The options B<-i>, B<-w>, B<-v>, and B<-Q> do not apply to this I<REGEX>.
269 =item B<--group>, B<--nogroup>
271 B<--group> groups matches by file name with. This is the default when
274 B<--nogroup> prints one result per line, like grep. This is the default
275 when output is redirected.
277 =item B<-H>, B<--with-filename>
279 Print the filename for each match.
281 =item B<-h>, B<--no-filename>
283 Suppress the prefixing of filenames on output when multiple files are
288 Print a short help statement.
290 =item B<-i>, B<--ignore-case>
292 Ignore case in the search strings.
294 This applies only to the PATTERN, not to the regexes given for the B<-g>
297 =item B<--[no]ignore-dir=DIRNAME>
299 Ignore directory (as CVS, .svn, etc are ignored). May be used multiple times
300 to ignore multiple directories. For example, mason users may wish to include
301 B<--ignore-dir=data>. The B<--noignore-dir> option allows users to search
302 directories which would normally be ignored (perhaps to research the contents
303 of F<.svn/props> directories).
305 =item B<--line=I<NUM>>
307 Only print line I<NUM> of each file. Multiple lines can be given with multiple
308 B<--line> options or as a comma separated list (B<--line=3,5,7>). B<--line=4-7>
309 also works. The lines are always output in ascending order, no matter the
310 order given on the command line.
312 =item B<-l>, B<--files-with-matches>
314 Only print the filenames of matching files, instead of the matching text.
316 =item B<-L>, B<--files-without-matches>
318 Only print the filenames of files that do I<NOT> match. This is equivalent
319 to specifying B<-l> and B<-v>.
321 =item B<--match I<REGEX>>
323 Specify the I<REGEX> explicitly. This is helpful if you don't want to put the
324 regex as your first argument, e.g. when executing multiple searches over the
327 # search for foo and bar in given files
328 ack file1 t/file* --match foo
329 ack file1 t/file* --match bar
331 =item B<-m=I<NUM>>, B<--max-count=I<NUM>>
333 Stop reading a file after I<NUM> matches.
337 Print this manual page.
341 No descending into subdirectories.
345 Show only the part of each line matching PATTERN (turns off text
348 =item B<--output=I<expr>>
350 Output the evaluation of I<expr> for each line (turns off text
353 =item B<--pager=I<program>>
355 Direct ack's output through I<program>. This can also be specified
356 via the C<ACK_PAGER> and C<ACK_PAGER_COLOR> environment variables.
358 Using --pager does not suppress grouping and coloring like piping
359 output on the command-line does.
363 Prints all lines, whether or not they match the expression. Highlighting
364 will still work, though, so it can be used to highlight matches while
365 still seeing the entire file, as in:
367 # Watch a log file, and highlight a certain IP address
368 $ tail -f ~/access.log | ack --passthru 123.45.67.89
372 Only works in conjunction with -f, -g, -l or -c (filename output). The filenames
373 are output separated with a null byte instead of the usual newline. This is
374 helpful when dealing with filenames that contain whitespace, e.g.
376 # remove all files of type html
377 ack -f --html --print0 | xargs -0 rm -f
379 =item B<-Q>, B<--literal>
381 Quote all metacharacters in PATTERN, it is treated as a literal.
383 This applies only to the PATTERN, not to the regexes given for the B<-g>
386 =item B<--smart-case>, B<--no-smart-case>
388 Ignore case in the search strings if PATTERN contains no uppercase
389 characters. This is similar to C<smartcase> in vim. This option is
392 B<-i> always overrides this option.
394 This applies only to the PATTERN, not to the regexes given for the
395 B<-g> and B<-G> options.
397 =item B<--sort-files>
399 Sorts the found files lexically. Use this if you want your file
400 listings to be deterministic between runs of I<ack>.
404 Display the all-important Bill The Cat logo. Note that the exact
405 spelling of B<--thpppppt> is not important. It's checked against
406 a regular expression.
408 =item B<--type=TYPE>, B<--type=noTYPE>
410 Specify the types of files to include or exclude from a search.
411 TYPE is a filetype, like I<perl> or I<xml>. B<--type=perl> can
412 also be specified as B<--perl>, and B<--type=noperl> can be done
415 If a file is of both type "foo" and "bar", specifying --foo and
416 --nobar will exclude the file, because an exclusion takes precedence
419 Type specifications can be repeated and are ORed together.
421 See I<ack --help=types> for a list of valid types.
423 =item B<--type-add I<TYPE>=I<.EXTENSION>[,I<.EXT2>[,...]]>
425 Files with the given EXTENSION(s) are recognized as being of (the
426 existing) type TYPE. See also L</"Defining your own types">.
429 =item B<--type-set I<TYPE>=I<.EXTENSION>[,I<.EXT2>[,...]]>
431 Files with the given EXTENSION(s) are recognized as being of type
432 TYPE. This replaces an existing definition for type TYPE. See also
433 L</"Defining your own types">.
435 =item B<-u>, B<--unrestricted>
437 All files and directories (including blib/, core.*, ...) are searched,
438 nothing is skipped. When both B<-u> and B<--ignore-dir> are used, the
439 B<--ignore-dir> option has no effect.
441 =item B<-v>, B<--invert-match>
443 Invert match: select non-matching lines
445 This applies only to the PATTERN, not to the regexes given for the B<-g>
450 Display version and copyright information.
452 =item B<-w>, B<--word-regexp>
454 Force PATTERN to match only whole words. The PATTERN is wrapped with
455 C<\b> metacharacters.
457 This applies only to the PATTERN, not to the regexes given for the B<-g>
462 Stops after reporting first match of any kind. This is different
463 from B<--max-count=1> or B<-m1>, where only one match per file is
464 shown. Also, B<-1> works with B<-f> and B<-g>, where B<-m> does
469 =head1 THE .ackrc FILE
471 The F<.ackrc> file contains command-line options that are prepended
472 to the command line before processing. Multiple options may live
473 on multiple lines. Lines beginning with a # are ignored. A F<.ackrc>
474 might look like this:
476 # Always sort the files
479 # Always color, even if piping to a another program
482 # Use "less -r" as my pager
485 Note that arguments with spaces in them do not need to be quoted,
486 as they are not interpreted by the shell. Basically, each I<line>
487 in the F<.ackrc> file is interpreted as one element of C<@ARGV>.
489 F<ack> looks in your home directory for the F<.ackrc>. You can
490 specify another location with the F<ACKRC> variable, below.
492 If B<--noenv> is specified on the command line, the F<.ackrc> file
495 =head1 Defining your own types
497 ack allows you to define your own types in addition to the predefined
498 types. This is done with command line options that are best put into
499 an F<.ackrc> file - then you do not have to define your types over and
500 over again. In the following examples the options will always be shown
501 on one command line so that they can be easily copy & pasted.
503 I<ack --perl foo> searches for foo in all perl files. I<ack --help=types>
504 tells you, that perl files are files ending
505 in .pl, .pm, .pod or .t. So what if you would like to include .xs
506 files as well when searching for --perl files? I<ack --type-add perl=.xs --perl foo>
507 does this for you. B<--type-add> appends
508 additional extensions to an existing type.
510 If you want to define a new type, or completely redefine an existing
511 type, then use B<--type-set>. I<ack --type-set
512 eiffel=.e,.eiffel> defines the type I<eiffel> to include files with
513 the extensions .e or .eiffel. So to search for all eiffel files
514 containing the word Bertrand use I<ack --type-set eiffel=.e,.eiffel --eiffel Bertrand>.
515 As usual, you can also write B<--type=eiffel>
516 instead of B<--eiffel>. Negation also works, so B<--noeiffel> excludes
517 all eiffel files from a search. Redefining also works: I<ack --type-set cc=.c,.h>
518 and I<.xs> files no longer belong to the type I<cc>.
520 When defining your own types in the F<.ackrc> file you have to use
523 --type-set=eiffel=.e,.eiffel
525 or writing on separate lines
530 The following does B<NOT> work in the F<.ackrc> file:
532 --type-set eiffel=.e,.eiffel
535 In order to see all currently defined types, use I<--help types>, e.g.
536 I<ack --type-set backup=.bak --type-add perl=.perl --help types>
544 The types 'skipped', 'make', 'binary' and 'text' are considered "builtin" and
549 The shebang line recognition of the types 'perl', 'ruby', 'php', 'python',
550 'shell' and 'xml' cannot be redefined by I<--type-set>, it is always
551 active. However, the shebang line is only examined for files where the
552 extension is not recognised. Therefore it is possible to say
553 I<ack --type-set perl=.perl --type-set foo=.pl,.pm,.pod,.t --perl --nofoo> and
554 only find your shiny new I<.perl> files (and all files with unrecognized extension
555 and perl on the shebang line).
559 =head1 ENVIRONMENT VARIABLES
561 For commonly-used ack options, environment variables can make life much easier.
562 These variables are ignored if B<--noenv> is specified on the command line.
568 Specifies the location of the F<.ackrc> file. If this file doesn't
569 exist, F<ack> looks in the default location.
573 This variable specifies default options to be placed in front of
574 any explicit options on the command line.
576 =item ACK_COLOR_FILENAME
578 Specifies the color of the filename when it's printed in B<--group>
579 mode. By default, it's "bold green".
581 The recognized attributes are clear, reset, dark, bold, underline,
582 underscore, blink, reverse, concealed black, red, green, yellow,
583 blue, magenta, on_black, on_red, on_green, on_yellow, on_blue,
584 on_magenta, on_cyan, and on_white. Case is not significant.
585 Underline and underscore are equivalent, as are clear and reset.
586 The color alone sets the foreground color, and on_color sets the
589 This option can also be set with B<--color-filename>.
591 =item ACK_COLOR_MATCH
593 Specifies the color of the matching text when printed in B<--color>
594 mode. By default, it's "black on_yellow".
596 This option can also be set with B<--color-match>.
598 See B<ACK_COLOR_FILENAME> for the color specifications.
602 Specifies a pager program, such as C<more>, C<less> or C<most>, to which
603 ack will send its output.
605 Using C<ACK_PAGER> does not suppress grouping and coloring like
606 piping output on the command-line does, except that on Windows
607 ack will assume that C<ACK_PAGER> does not support color.
609 C<ACK_PAGER_COLOR> overrides C<ACK_PAGER> if both are specified.
611 =item ACK_PAGER_COLOR
613 Specifies a pager program that understands ANSI color sequences.
614 Using C<ACK_PAGER_COLOR> does not suppress grouping and coloring
615 like piping output on the command-line does.
617 If you are not on Windows, you never need to use C<ACK_PAGER_COLOR>.
621 =head1 ACK & OTHER TOOLS
623 =head2 Vim integration
625 F<ack> integrates easily with the Vim text editor. Set this in your
626 F<.vimrc> to use F<ack> instead of F<grep>:
630 That examples uses C<-a> to search through all files, but you may
631 use other default flags. Now you can search with F<ack> and easily
632 step through the results in Vim:
636 =head2 Emacs integration
638 Phil Jackson put together an F<ack.el> extension that "provides a
639 simple compilation mode ... has the ability to guess what files you
640 want to search for based on the major-mode."
642 L<http://www.shellarchive.co.uk/content/emacs.html>
644 =head2 TextMate integration
646 Pedro Melo is a TextMate user who writes "I spend my day mostly
647 inside TextMate, and the built-in find-in-project sucks with large
648 projects. So I hacked a TextMate command that was using find +
649 grep to use ack. The result is the Search in Project with ack, and
650 you can find it here:
651 L<http://www.simplicidade.org/notes/archives/2008/03/search_in_proje.html>"
653 =head2 Shell and Return Code
655 For greater compatibility with I<grep>, I<ack> in normal use returns
656 shell return or exit code of 0 only if something is found and 1 if
659 (Shell exit code 1 is C<$?=256> in perl with C<system> or backticks.)
661 The I<grep> code 2 for errors is not used.
663 If C<-f> or C<-g> are specified, then 0 is returned if at least one
664 file is found. If no files are found, then 1 is returned.
668 =head1 DEBUGGING ACK PROBLEMS
670 If ack gives you output you're not expecting, start with a few simple steps.
672 =head2 Use B<--noenv>
674 Your environment variables and F<.ackrc> may be doing things you're
675 not expecting, or forgotten you specified. Use B<--noenv> to ignore
676 your environment and F<.ackrc>.
678 =head2 Use B<-f> to see what files you're scanning
680 The reason I created B<-f> in the first place was as a debugging
681 tool. If ack is not finding matches you think it should find, run
682 F<ack -f> to see what files are being checked.
686 =head2 Use the F<.ackrc> file.
688 The F<.ackrc> is the place to put all your options you use most of
689 the time but don't want to remember. Put all your --type-add and
690 --type-set definitions in it. If you like --smart-case, set it
691 there, too. I also set --sort-files there.
693 =head2 Use F<-f> for working with big codesets
695 Ack does more than search files. C<ack -f --perl> will create a
696 list of all the Perl files in a tree, ideal for sending into F<xargs>.
699 # Change all "this" to "that" in all Perl files in a tree.
700 ack -f --perl | xargs perl -p -i -e's/this/that/g'
704 perl -p -i -e's/this/thatg/' $(ack -f --perl)
706 =head2 Use F<-Q> when in doubt about metacharacters
708 If you're searching for something with a regular expression
709 metacharacter, most often a period in a filename or IP address, add
710 the -Q to avoid false positives without all the backslashing. See
711 the following example for more...
713 =head2 Use ack to watch log files
715 Here's one I used the other day to find trouble spots for a website
716 visitor. The user had a problem loading F<troublesome.gif>, so I
717 took the access log and scanned it with ack twice.
719 ack -Q aa.bb.cc.dd /path/to/access.log | ack -Q -B5 troublesome.gif
721 The first ack finds only the lines in the Apache log for the given
722 IP. The second finds the match on my troublesome GIF, and shows
723 the previous five lines from the log in each case.
725 =head2 Share your knowledge
727 Join the ack-users mailing list. Send me your tips and I may add
732 =head2 Why isn't ack finding a match in (some file)?
734 Probably because it's of a type that ack doesn't recognize.
736 ack's searching behavior is driven by filetype. If ack doesn't
737 know what kind of file it is, ack ignores it.
739 If you want ack to search files that it doesn't recognize, use the
742 If you want ack to search every file, even ones that it always
743 ignores like coredumps and backup files, use the C<-u> switch.
745 =head2 Why does ack ignore unknown files by default?
747 ack is designed by a programmer, for programmers, for searching
748 large trees of code. Most codebases have a lot files in them which
749 aren't source files (like compiled object files, source control
750 metadata, etc), and grep wastes a lot of time searching through all
751 of those as well and returning matches from those files.
753 That's why ack's behavior of not searching things it doesn't recognize
754 is one of its greatest strengths: the speed you get from only
755 searching the things that you want to be looking at.
757 =head2 Wouldn't it be great if F<ack> did search & replace?
759 No, ack will always be read-only. Perl has a perfectly good way
760 to do search & replace in files, using the C<-i>, C<-p> and C<-n>
763 You can certainly use ack to select your files to update. For
764 example, to change all "foo" to "bar" in all PHP files, you can do
765 this form the Unix shell:
767 $ perl -i -p -e's/foo/bar/g' $(ack -f --php)
769 =head2 Can you make ack recognize F<.xyz> files?
771 That's an enhancement. Please see the section in the manual about
774 =head2 There's already a program/package called ack.
778 =head2 Why is it called ack if it's called ack-grep?
780 The name of the program is "ack". Some packagers have called it
781 "ack-grep" when creating packages because there's already a package
782 out there called "ack" that has nothing to do with this ack.
784 I suggest you rename your ack-grep install to "ack" because one of
785 the crucial benefits of ack is having a name that's so short and
790 Andy Lester, C<< <andy at petdance.com> >>
794 Please report any bugs or feature requests to the issues list at
795 Github: L<http://github.com/petdance/ack/issues>
799 All enhancement requests MUST first be posted to the ack-users
800 mailing list at L<http://groups.google.com/group/ack-users>. I
801 will not consider a request without it first getting seen by other
802 ack users. This includes requests for new filetypes.
804 There is a list of enhancements I want to make to F<ack> in the ack
805 issues list at Github: L<http://github.com/petdance/ack/issues>
807 Patches are always welcome, but patches with tests get the most
812 Support for and information about F<ack> can be found at:
816 =item * The ack homepage
818 L<http://betterthangrep.com/>
820 =item * The ack issues list at Github
822 L<http://github.com/petdance/ack/issues>
824 =item * AnnoCPAN: Annotated CPAN documentation
826 L<http://annocpan.org/dist/ack>
830 L<http://cpanratings.perl.org/d/ack>
834 L<http://search.cpan.org/dist/ack>
836 =item * Git source repository
838 L<http://github.com/petdance/ack>
842 =head1 ACKNOWLEDGEMENTS
844 How appropriate to have I<ack>nowledgements!
846 Thanks to everyone who has contributed to ack in any way, including
863 Christopher J. Madsen,
875 GE<aacute>bor SzabE<oacute>,
878 E<AElig>var ArnfjE<ouml>rE<eth> Bjarmason,
882 Mark Leighton Fisher,
893 Ask BjE<oslash>rn Hansen,
906 =head1 COPYRIGHT & LICENSE
908 Copyright 2005-2009 Andy Lester.
910 This program is free software; you can redistribute it and/or modify
911 it under the terms of either:
915 =item * the GNU General Public License as published by the Free
916 Software Foundation; either version 1, or (at your option) any later
919 =item * the Artistic License version 2.0.
930 our $VERSION = '1.06';
937 our $name; # name of the current file
938 our $dir; # dir of the current file
945 file_filter
=> undef,
946 descend_filter
=> undef,
947 error_handler
=> sub { CORE
::die @_ },
949 follow_symlinks
=> 1,
951 %skip_dirs = map {($_,1)} (File
::Spec-
>curdir, File
::Spec-
>updir);
956 ($_[0] eq __PACKAGE__
) && die 'File::Next::files must not be invoked as File::Next->files';
958 my ($parms,@queue) = _setup
( \
%files_defaults, @_ );
959 my $filter = $parms->{file_filter
};
963 my ($dir,$file,$fullpath) = splice( @queue, 0, 3 );
964 if ( -f
$fullpath ) {
967 local $File::Next
::dir
= $dir;
968 local $File::Next
::name
= $fullpath;
969 next if not $filter->();
971 return wantarray ? ($dir,$file,$fullpath) : $fullpath;
974 unshift( @queue, _candidate_files
( $parms, $fullpath ) );
988 sub sort_standard
($$) { return $_[0]->[1] cmp $_[1]->[1] }
989 sub sort_reverse
($$) { return $_[1]->[1] cmp $_[0]->[1] }
994 my @parts = split( /\//, $path );
996 return $path if @parts < 2;
998 return File
::Spec-
>catfile( @parts );
1004 my $defaults = shift;
1005 my $passed_parms = ref $_[0] eq 'HASH' ? {%{+shift}} : {}; # copy parm hash
1007 my %passed_parms = %{$passed_parms};
1010 for my $key ( keys %{$defaults} ) {
1012 exists $passed_parms{$key}
1013 ? delete $passed_parms{$key}
1014 : $defaults->{$key};
1017 # Any leftover keys are bogus
1018 for my $badkey ( keys %passed_parms ) {
1019 my $sub = (caller(1))[3];
1020 $parms->{error_handler
}->( "Invalid option passed to $sub(): $badkey" );
1023 # If it's not a code ref, assume standard sort
1024 if ( $parms->{sort_files
} && ( ref($parms->{sort_files
}) ne 'CODE' ) ) {
1025 $parms->{sort_files
} = \
&sort_standard
;
1030 my $start = reslash
( $_ );
1032 push @queue, ($start,undef,$start);
1035 push @queue, (undef,$start,$start);
1039 return ($parms,@queue);
1043 sub _candidate_files
{
1048 if ( !opendir $dh, $dir ) {
1049 $parms->{error_handler
}->( "$dir: $!" );
1054 my $descend_filter = $parms->{descend_filter
};
1055 my $follow_symlinks = $parms->{follow_symlinks
};
1056 my $sort_sub = $parms->{sort_files
};
1058 for my $file ( grep { !exists $skip_dirs{$_} } readdir $dh ) {
1061 # Only do directory checking if we have a descend_filter
1062 my $fullpath = File
::Spec-
>catdir( $dir, $file );
1063 if ( !$follow_symlinks ) {
1064 next if -l
$fullpath;
1068 if ( $descend_filter ) {
1069 if ( $has_stat ? (-d _
) : (-d
$fullpath) ) {
1070 local $File::Next
::dir
= $fullpath;
1072 next if not $descend_filter->();
1076 push( @newfiles, [ $dir, $file, $fullpath ] );
1079 push( @newfiles, $dir, $file, $fullpath );
1085 return map { @{$_} } sort $sort_sub @newfiles;
1092 1; # End of File::Next
1105 $COPYRIGHT = 'Copyright 2005-2009 Andy Lester.';
1120 our $input_from_pipe;
1121 our $output_to_pipe;
1128 use File
::Glob
':glob';
1129 use Getopt
::Long
();
1134 '.cdv' => 'Codeville',
1135 '~.dep' => 'Interface Builder',
1136 '~.dot' => 'Interface Builder',
1137 '~.nib' => 'Interface Builder',
1138 '~.plst' => 'Interface Builder',
1140 '.hg' => 'Mercurial',
1142 '.svn' => 'Subversion',
1143 blib
=> 'Perl module building',
1148 _sgbak
=> 'Vault/Fortress',
1149 'autom4te.cache' => 'autoconf',
1150 'cover_db' => 'Devel::Cover',
1151 _build
=> 'Module::Build',
1155 actionscript
=> [qw( as mxml )],
1156 ada
=> [qw( ada adb ads )],
1157 asm
=> [qw( asm s )],
1158 batch
=> [qw( bat cmd )],
1159 binary
=> q{Binary files, as defined by Perl's -B op (default: off)},
1160 cc
=> [qw( c h xs )],
1161 cfmx
=> [qw( cfc cfm cfml )],
1162 cpp
=> [qw( cpp cc cxx m hpp hh h hxx )],
1163 csharp
=> [qw( cs )],
1165 elisp
=> [qw( el )],
1166 erlang
=> [qw( erl hrl )],
1167 fortran
=> [qw( f f77 f90 f95 f03 for ftn fpp )],
1168 haskell
=> [qw( hs lhs )],
1170 html
=> [qw( htm html shtml xhtml )],
1171 java
=> [qw( java properties )],
1173 jsp
=> [qw( jsp jspx jhtm jhtml )],
1174 lisp
=> [qw( lisp lsp )],
1176 make
=> q{Makefiles},
1177 mason
=> [qw( mas mhtml mpl mtxt )],
1178 objc
=> [qw( m h )],
1179 objcpp
=> [qw( mm h )],
1180 ocaml
=> [qw( ml mli )],
1181 parrot
=> [qw( pir pasm pmc ops pod pg tg )],
1182 perl
=> [qw( pl pm pod t )],
1183 php
=> [qw( php phpt php3 php4 php5 phtml)],
1184 plone
=> [qw( pt cpt metadata cpy py )],
1185 python
=> [qw( py )],
1186 rake
=> q{Rakefiles},
1187 ruby
=> [qw( rb rhtml rjs rxml erb rake )],
1188 scala
=> [qw( scala )],
1189 scheme
=> [qw( scm ss )],
1190 shell
=> [qw( sh bash csh tcsh ksh zsh )],
1191 skipped
=> q{Files, but not directories, normally skipped by ack (default: off)},
1192 smalltalk
=> [qw( st )],
1193 sql
=> [qw( sql ctl )],
1194 tcl
=> [qw( tcl itcl itk )],
1195 tex
=> [qw( tex cls sty )],
1196 text
=> q{Text files, as defined by Perl's -T op (default: off)},
1197 tt
=> [qw( tt tt2 ttml )],
1198 vb
=> [qw( bas cls frm ctl vb resx )],
1200 yaml
=> [qw( yaml yml )],
1201 xml
=> [qw( xml dtd xslt ent )],
1204 while ( my ($type,$exts) = each %mappings ) {
1206 for my $ext ( @{$exts} ) {
1207 push( @{$types{$ext}}, $type );
1212 # These have to be checked before any filehandle diddling.
1213 $output_to_pipe = not -t
*STDOUT
;
1214 $input_from_pipe = -p STDIN
;
1216 $is_cygwin = ($^O eq 'cygwin');
1217 $is_windows = ($^O =~ /MSWin32/);
1218 $dir_sep_chars = $is_windows ? quotemeta( '\\/' ) : quotemeta( File
::Spec-
>catfile( '', '' ) );
1223 my @files = ( $ENV{ACKRC
} );
1226 ? ( $ENV{HOME
}, $ENV{USERPROFILE
} )
1227 : ( '~', $ENV{HOME
} );
1228 for my $dir ( grep { defined } @dirs ) {
1229 for my $file ( '.ackrc', '_ackrc' ) {
1230 push( @files, bsd_glob
( "$dir/$file", GLOB_TILDE
) );
1233 for my $filename ( @files ) {
1234 if ( defined $filename && -e
$filename ) {
1235 open( my $fh, '<', $filename ) or App
::Ack
::die( "$filename: $!\n" );
1236 my @lines = grep { /./ && !/^\s*#/ } <$fh>;
1238 close $fh or App
::Ack
::die( "$filename: $!\n" );
1248 sub get_command_line_options
{
1250 pager
=> $ENV{ACK_PAGER_COLOR
} || $ENV{ACK_PAGER
},
1253 my $getopt_specs = {
1254 1 => sub { $opt{1} = $opt{m
} = 1 },
1255 'A|after-context=i' => \
$opt{after_context
},
1256 'B|before-context=i' => \
$opt{before_context
},
1257 'C|context:i' => sub { shift; my $val = shift; $opt{before_context
} = $opt{after_context
} = ($val || 2) },
1258 'a|all-types' => \
$opt{all
},
1259 'break!' => \
$opt{break},
1261 'color|colour!' => \
$opt{color
},
1262 'color-match=s' => \
$ENV{ACK_COLOR_MATCH
},
1263 'color-filename=s' => \
$ENV{ACK_COLOR_FILENAME
},
1264 'column!' => \
$opt{column
},
1265 count
=> \
$opt{count
},
1266 'env!' => sub { }, # ignore this option, it is handled beforehand
1268 flush
=> \
$opt{flush
},
1269 'follow!' => \
$opt{follow
},
1270 'g=s' => sub { shift; $opt{G
} = shift; $opt{f
} = 1 },
1272 'group!' => sub { shift; $opt{heading
} = $opt{break} = shift },
1273 'heading!' => \
$opt{heading
},
1274 'h|no-filename' => \
$opt{h
},
1275 'H|with-filename' => \
$opt{H
},
1276 'i|ignore-case' => \
$opt{i
},
1277 'lines=s' => sub { shift; my $val = shift; push @{$opt{lines
}}, $val },
1278 'l|files-with-matches' => \
$opt{l
},
1279 'L|files-without-matches' => sub { $opt{l
} = $opt{v
} = 1 },
1280 'm|max-count=i' => \
$opt{m
},
1281 'match=s' => \
$opt{regex
},
1282 'n|no-recurse' => \
$opt{n
},
1283 o
=> sub { $opt{output
} = '$&' },
1284 'output=s' => \
$opt{output
},
1285 'pager=s' => \
$opt{pager
},
1286 'nopager' => sub { $opt{pager
} = undef },
1287 'passthru' => \
$opt{passthru
},
1288 'print0' => \
$opt{print0
},
1289 'Q|literal' => \
$opt{Q
},
1290 'r|R|recurse' => sub {},
1291 'smart-case!' => \
$opt{smart_case
},
1292 'sort-files' => \
$opt{sort_files
},
1293 'u|unrestricted' => \
$opt{u
},
1294 'v|invert-match' => \
$opt{v
},
1295 'w|word-regexp' => \
$opt{w
},
1297 'ignore-dirs=s' => sub { shift; my $dir = remove_dir_sep
( shift ); $ignore_dirs{$dir} = '--ignore-dirs' },
1298 'noignore-dirs=s' => sub { shift; my $dir = remove_dir_sep
( shift ); delete $ignore_dirs{$dir} },
1300 'version' => sub { print_version_statement
(); exit 1; },
1301 'help|?:s' => sub { shift; show_help
(@_); exit; },
1302 'help-types'=> sub { show_help_types
(); exit; },
1303 'man' => sub { require Pod
::Usage
; Pod
::Usage
::pod2usage
({-verbose
=> 2}); exit; },
1306 # Whatever --type=xxx they specify, set it manually in the hash
1309 my $wanted = ($type =~ s/^no//) ? 0 : 1; # must not be undef later
1311 if ( exists $type_wanted{ $type } ) {
1312 $type_wanted{ $type } = $wanted;
1315 App
::Ack
::die( qq{Unknown --type "$type"} );
1320 # Stick any default switches at the beginning, so they can be overridden
1321 # by the command line switches.
1322 unshift @ARGV, split( ' ', $ENV{ACK_OPTIONS
} ) if defined $ENV{ACK_OPTIONS
};
1324 # first pass through options, looking for type definitions
1325 def_types_from_ARGV
();
1327 for my $i ( filetypes_supported
() ) {
1328 $getopt_specs->{ "$i!" } = \
$type_wanted{ $i };
1332 my $parser = Getopt
::Long
::Parser-
>new();
1333 $parser->configure( 'bundling', 'no_ignore_case', );
1334 $parser->getoptions( %{$getopt_specs} ) or
1335 App
::Ack
::die( 'See ack --help, ack --help-types or ack --man for options.' );
1337 my $to_screen = not output_to_pipe
();
1340 color
=> $to_screen,
1342 break => $to_screen,
1343 heading
=> $to_screen,
1344 before_context
=> 0,
1347 if ( $is_windows && $defaults{color
} && not $ENV{ACK_PAGER_COLOR
} ) {
1348 if ( $ENV{ACK_PAGER
} || not eval { require Win32
::Console
::ANSI
} ) {
1349 $defaults{color
} = 0;
1352 if ( $to_screen && $ENV{ACK_PAGER_COLOR
} ) {
1353 $defaults{color
} = 1;
1356 while ( my ($key,$value) = each %defaults ) {
1357 if ( not defined $opt{$key} ) {
1358 $opt{$key} = $value;
1362 if ( defined $opt{m
} && $opt{m
} <= 0 ) {
1363 App
::Ack
::die( '-m must be greater than zero' );
1366 for ( qw( before_context after_context ) ) {
1367 if ( defined $opt{$_} && $opt{$_} < 0 ) {
1368 App
::Ack
::die( "--$_ may not be negative" );
1372 if ( defined( my $val = $opt{output
} ) ) {
1373 $opt{output
} = eval qq[ sub { "$val" } ];
1375 if ( defined( my $l = $opt{lines
} ) ) {
1376 # --line=1 --line=5 is equivalent to --line=1,5
1377 my @lines = split( /,/, join( ',', @{$l} ) );
1379 # --line=1-3 is equivalent to --line=1,2,3
1383 my ($from, $to) = split /-/, $_;
1384 if ( $from > $to ) {
1385 App
::Ack
::warn( "ignoring --line=$from-$to" );
1389 @ret = ( $from .. $to );
1400 @uniq{ @lines } = ();
1401 $opt{lines
} = [ sort { $a <=> $b } keys %uniq ]; # numerical sort and each line occurs only once!
1404 # happens if there are only ignored --line directives
1405 App
::Ack
::die( 'All --line options are invalid.' );
1413 sub def_types_from_ARGV
{
1416 my $parser = Getopt
::Long
::Parser-
>new();
1417 # pass_through => leave unrecognized command line arguments alone
1418 # no_auto_abbrev => otherwise -c is expanded and not left alone
1419 $parser->configure( 'no_ignore_case', 'pass_through', 'no_auto_abbrev' );
1420 $parser->getoptions(
1421 'type-set=s' => sub { shift; push @typedef, ['c', shift] },
1422 'type-add=s' => sub { shift; push @typedef, ['a', shift] },
1423 ) or App
::Ack
::die( 'See ack --help or ack --man for options.' );
1425 for my $td (@typedef) {
1426 my ($type, $ext) = split /=/, $td->[1];
1428 if ( $td->[0] eq 'c' ) {
1430 if ( exists $mappings{$type} ) {
1431 # can't redefine types 'make', 'skipped', 'text' and 'binary'
1432 App
::Ack
::die( qq{--type-set: Builtin type "$type" cannot be changed.} )
1433 if ref $mappings{$type} ne 'ARRAY';
1441 # can't append to types 'make', 'skipped', 'text' and 'binary'
1442 App
::Ack
::die( qq{--type-add: Builtin type "$type" cannot be changed.} )
1443 if exists $mappings{$type} && ref $mappings{$type} ne 'ARRAY';
1445 App
::Ack
::warn( qq{--type-add: Type "$type" does not exist, creating with "$ext" ...} )
1446 unless exists $mappings{$type};
1449 my @exts = split /,/, $ext;
1452 if ( !exists $mappings{$type} || ref($mappings{$type}) eq 'ARRAY' ) {
1453 push @{$mappings{$type}}, @exts;
1454 for my $e ( @exts ) {
1455 push @{$types{$e}}, $type;
1459 App
::Ack
::die( qq{Cannot append to type "$type".} );
1470 App
::Ack
::die( qq{Internal error: Cannot delete builtin type "$type".} )
1471 unless ref $mappings{$type} eq 'ARRAY';
1473 delete $mappings{$type};
1474 delete $type_wanted{$type};
1475 for my $ext ( keys %types ) {
1476 $types{$ext} = [ grep { $_ ne $type } @{$types{$ext}} ];
1481 sub ignoredir_filter
{
1482 return !exists $ignore_dirs{$_};
1486 sub remove_dir_sep
{
1488 $path =~ s/[$dir_sep_chars]$//;
1494 use constant TEXT
=> 'text';
1497 my $filename = shift;
1499 my $basename = $filename;
1500 $basename =~ s{.*[$dir_sep_chars]}{};
1502 return 'skipped' unless is_searchable
( $basename );
1504 my $lc_basename = lc $basename;
1505 return ('make',TEXT
) if $lc_basename eq 'makefile';
1506 return ('rake','ruby',TEXT
) if $lc_basename eq 'rakefile';
1508 # If there's an extension, look it up
1509 if ( $filename =~ m{\.([^\.$dir_sep_chars]+)$}o ) {
1510 my $ref = $types{lc $1};
1511 return (@{$ref},TEXT
) if $ref;
1514 # At this point, we can't tell from just the name. Now we have to
1515 # open it and look inside.
1517 return unless -e
$filename;
1518 # From Elliot Shank:
1519 # I can't see any reason that -r would fail on these-- the ACLs look
1520 # fine, and no program has any of them open, so the busted Windows
1521 # file locking model isn't getting in there. If I comment the if
1522 # statement out, everything works fine
1523 # So, for cygwin, don't bother trying to check for readability.
1524 if ( !$is_cygwin ) {
1525 if ( !-r
$filename ) {
1526 App
::Ack
::warn( "$filename: Permission denied" );
1531 return 'binary' if -B
$filename;
1533 # If there's no extension, or we don't recognize it, check the shebang line
1535 if ( !open( $fh, '<', $filename ) ) {
1536 App
::Ack
::warn( "$filename: $!" );
1542 if ( $header =~ /^#!/ ) {
1543 return ($1,TEXT
) if $header =~ /\b(ruby|p(?:erl|hp|ython))\b/;
1544 return ('shell',TEXT
) if $header =~ /\b(?:ba|t?c|k|z)?sh\b/;
1547 return ('xml',TEXT
) if $header =~ /\Q<?xml /i;
1555 my $filename = shift;
1557 # If these are updated, update the --help message
1558 return if $filename =~ /[.]bak$/;
1559 return if $filename =~ /~$/;
1560 return if $filename =~ m{^#.*#$}o;
1561 return if $filename =~ m{^core\.\d+$}o;
1562 return if $filename =~ m{[._].*\.swp$}o;
1572 $str = quotemeta( $str ) if $opt->{Q
};
1574 $str = "\\b$str" if $str =~ /^\w/;
1575 $str = "$str\\b" if $str =~ /\w$/;
1578 my $regex_is_lc = $str eq lc $str;
1579 if ( $opt->{i
} || ($opt->{smart_case
} && $regex_is_lc) ) {
1590 return unless defined $regex;
1592 eval { qr/$regex/ };
1594 (my $error = $@) =~ s/ at \S+ line \d+.*//;
1596 App
::Ack
::die( "Invalid regex '$regex':\n $error" );
1606 return CORE
::warn( _my_program
(), ': ', @_, "\n" );
1611 return CORE
::die( _my_program
(), ': ', @_, "\n" );
1615 require File
::Basename
;
1616 return File
::Basename
::basename
( $0 );
1621 sub filetypes_supported
{
1622 return keys %mappings;
1626 my $y = q{_ /|,\\'!.x',=(www)=, U };
1627 $y =~ tr/,x!w/\nOo_/;
1632 my $y = _get_thpppt
();
1633 App
::Ack
::print( "$y ack $_[0]!\n" );
1639 $str =~ s/[^a-z]//g;
1646 my $help_arg = shift || 0;
1648 return show_help_types
() if $help_arg =~ /^types?/;
1650 my $ignore_dirs = _listify
( sort { _key
($a) cmp _key
($b) } keys %ignore_dirs );
1652 App
::Ack
::print( <<"END_OF_HELP" );
1653 Usage: ack [OPTION]... PATTERN [FILE]
1655 Search for PATTERN in each source file in the tree from cwd on down.
1656 If [FILES] is specified, then only those files/directories are checked.
1657 ack may also search STDIN, but only if no FILE are specified, or if
1658 one of FILES is "-".
1660 Default switches may be specified in ACK_OPTIONS environment variable or
1661 an .ackrc file. If you want no dependency on the environment, turn it
1664 Example: ack -i select
1667 -i, --ignore-case Ignore case distinctions in PATTERN
1668 --[no]smart-case Ignore case distinctions in PATTERN,
1669 only if PATTERN contains no upper case
1670 Ignored if -i is specified
1671 -v, --invert-match Invert match: select non-matching lines
1672 -w, --word-regexp Force PATTERN to match only whole words
1673 -Q, --literal Quote all metacharacters; PATTERN is literal
1676 --line=NUM Only print line(s) NUM of each file
1677 -l, --files-with-matches
1678 Only print filenames containing matches
1679 -L, --files-without-matches
1680 Only print filenames with no matches
1681 -o Show only the part of a line matching PATTERN
1682 (turns off text highlighting)
1683 --passthru Print all lines, whether matching or not
1684 --output=expr Output the evaluation of expr for each line
1685 (turns off text highlighting)
1686 --match PATTERN Specify PATTERN explicitly.
1687 -m, --max-count=NUM Stop searching in each file after NUM matches
1688 -1 Stop searching after one match of any kind
1689 -H, --with-filename Print the filename for each match
1690 -h, --no-filename Suppress the prefixing filename on output
1691 -c, --count Show number of lines matching per file
1692 --column Show the column number of the first match
1694 -A NUM, --after-context=NUM
1695 Print NUM lines of trailing context after matching
1697 -B NUM, --before-context=NUM
1698 Print NUM lines of leading context before matching
1700 -C [NUM], --context[=NUM]
1701 Print NUM lines (default 2) of output context.
1703 --print0 Print null byte as separator between filenames,
1704 only works with -f, -g, -l, -L or -c.
1707 --pager=COMMAND Pipes all ack output through COMMAND. For example,
1708 --pager="less -R". Ignored if output is redirected.
1709 --nopager Do not send output through a pager. Cancels any
1710 setting in ~/.ackrc, ACK_PAGER or ACK_PAGER_COLOR.
1711 --[no]heading Print a filename heading above each file's results.
1712 (default: on when used interactively)
1713 --[no]break Print a break between results from different files.
1714 (default: on when used interactively)
1715 --group Same as --heading --break
1716 --nogroup Same as --noheading --nobreak
1717 --[no]color Highlight the matching text (default: on unless
1718 output is redirected, or on Windows)
1719 --[no]colour Same as --[no]color
1720 --color-filename=COLOR
1721 --color-match=COLOR Set the color for matches and filenames.
1722 --flush Flush output immediately, even when ack is used
1723 non-interactively (when output goes to a pipe or
1727 -f Only print the files found, without searching.
1728 The PATTERN must not be specified.
1729 -g REGEX Same as -f, but only print files matching REGEX.
1730 --sort-files Sort the found files lexically.
1732 File inclusion/exclusion:
1733 -a, --all-types All file types searched;
1734 Ignores CVS, .svn and other ignored directories
1735 -u, --unrestricted All files and directories searched
1736 --[no]ignore-dir=name Add/Remove directory from the list of ignored dirs
1737 -r, -R, --recurse Recurse into subdirectories (ack's default behavior)
1738 -n, --no-recurse No descending into subdirectories
1739 -G REGEX Only search files that match REGEX
1741 --perl Include only Perl files.
1742 --type=perl Include only Perl files.
1743 --noperl Exclude Perl files.
1744 --type=noperl Exclude Perl files.
1745 See "ack --help type" for supported filetypes.
1747 --type-set TYPE=.EXTENSION[,.EXT2[,...]]
1748 Files with the given EXTENSION(s) are recognized as
1749 being of type TYPE. This replaces an existing
1750 definition for type TYPE.
1751 --type-add TYPE=.EXTENSION[,.EXT2[,...]]
1752 Files with the given EXTENSION(s) are recognized as
1753 being of (the existing) type TYPE
1755 --[no]follow Follow symlinks. Default is off.
1757 Directories ignored by default:
1760 Files not checked for type:
1761 /~\$/ - Unix backup files
1762 /#.+#\$/ - Emacs swap files
1763 /[._].*\\.swp\$/ - Vi(m) swap files
1764 /core\\.\\d+\$/ - core dumps
1767 --noenv Ignore environment variables and ~/.ackrc
1770 --version Display version & copyright
1771 --thpppt Bill the Cat
1773 Exit status is 0 if match, 1 if no match.
1775 This is version $VERSION of ack.
1783 sub show_help_types
{
1784 App
::Ack
::print( <<'END_OF_HELP' );
1785 Usage: ack [OPTION]... PATTERN [FILES]
1787 The following is the list of filetypes supported by ack. You can
1788 specify a file type with the --type=TYPE format, or the --TYPE
1789 format. For example, both --type=perl and --perl work.
1791 Note that some extensions may appear in multiple types. For example,
1792 .pod files are both Perl and Parrot.
1796 my @types = filetypes_supported
();
1799 $maxlen = length if $maxlen < length;
1801 for my $type ( sort @types ) {
1802 next if $type =~ /^-/; # Stuff to not show
1803 my $ext_list = $mappings{$type};
1805 if ( ref $ext_list ) {
1806 $ext_list = join( ' ', map { ".$_" } @{$ext_list} );
1808 App
::Ack
::print( sprintf( " --[no]%-*.*s %s\n", $maxlen, $maxlen, $type, $ext_list ) );
1817 return '' if !@whats;
1819 my $end = pop @whats;
1820 my $str = @whats ? join( ', ', @whats ) . " and $end" : $end;
1824 $Text::Wrap
::columns
= 75;
1825 return Text
::Wrap
::wrap
( '', ' ', $str );
1829 sub get_version_statement
{
1832 my $copyright = get_copyright
();
1833 my $this_perl = $Config::Config
{perlpath
};
1835 my $ext = $Config::Config
{_exe
};
1836 $this_perl .= $ext unless $this_perl =~ m/$ext$/i;
1838 my $ver = sprintf( '%vd', $^V );
1840 return <<"END_OF_VERSION";
1842 Running under Perl $ver at $this_perl
1846 This program is free software; you can redistribute it and/or modify
1847 it under the terms of either: the GNU General Public License as
1848 published by the Free Software Foundation; or the Artistic License.
1853 sub print_version_statement
{
1854 App
::Ack
::print( get_version_statement
() );
1866 eval 'use Term::ANSIColor ()';
1868 $ENV{ACK_COLOR_MATCH
} ||= 'black on_yellow';
1869 $ENV{ACK_COLOR_FILENAME
} ||= 'bold green';
1875 sub is_interesting
{
1880 for my $type ( filetypes
( $File::Next
::name
) ) {
1881 if ( defined $type_wanted{$type} ) {
1882 if ( $type_wanted{$type} ) {
1896 # print subs added in order to make it easy for a third party
1897 # module (such as App::Wack) to redefine the display methods
1898 # and show the results in a different way.
1899 sub print { print {$fh} @_ }
1900 sub print_first_filename
{ App
::Ack
::print( $_[0], "\n" ) }
1901 sub print_blank_line
{ App
::Ack
::print( "\n" ) }
1902 sub print_separator
{ App
::Ack
::print( "--\n" ) }
1903 sub print_filename
{ App
::Ack
::print( $_[0], $_[1] ) }
1904 sub print_line_no
{ App
::Ack
::print( $_[0], $_[1] ) }
1905 sub print_column_no
{ App
::Ack
::print( $_[0], $_[1] ) }
1907 my $filename = shift;
1908 my $nmatches = shift;
1912 App
::Ack
::print( $filename );
1913 App
::Ack
::print( ':', $nmatches ) if $count;
1914 App
::Ack
::print( $ors );
1918 my $filename = shift;
1921 App
::Ack
::print( $filename, ':0', $ors );
1929 my $display_filename;
1933 my $last_output_line; # number of the last line that has been output
1934 my $any_output; # has there been any output for the current file yet
1935 my $context_overall_output_count; # has there been any output at all
1937 sub search_resource
{
1941 $filename = $res->name();
1944 my $passthru = $opt->{passthru
};
1945 my $max = $opt->{m
};
1948 $display_filename = undef;
1950 # for --line processing
1953 if ( defined $opt->{lines
} ) {
1955 @lines = ( @{$opt->{lines
}}, -1 );
1956 undef $regex; # Don't match when printing matching line
1959 $regex = qr/$opt->{regex}/;
1962 # for context processing
1963 $last_output_line = -1;
1965 my $before_context = $opt->{before_context
};
1966 my $after_context = $opt->{after_context
};
1968 $keep_context = ($before_context || $after_context) && !$passthru;
1971 my $before_starts_at_line;
1972 my $after = 0; # number of lines still to print after a match
1974 while ( $res->next_text ) {
1975 # XXX Optimize away the case when there are no more @lines to find.
1976 # XXX $has_lines, $passthru and $v never change. Optimize.
1978 ? $. != $lines[0] # $lines[0] should be a scalar
1979 : $v ? m/$regex/ : !m/$regex/ ) {
1981 App
::Ack
::print( $_ );
1985 if ( $keep_context ) {
1987 print_match_or_context
( $opt, 0, $., $-[0], $+[0], $_ );
1990 elsif ( $before_context ) {
1992 if ( @before >= $before_context ) {
1994 ++$before_starts_at_line;
1998 $before_starts_at_line = $.;
2002 last if $max && ( $nmatches >= $max ) && !$after;
2009 # print an empty line as a divider before first line in each file (not before the first file)
2010 if ( !$any_output && $opt->{show_filename
} && $opt->{break} && defined( $context_overall_output_count ) ) {
2011 App
::Ack
::print_blank_line
();
2014 shift @lines if $has_lines;
2016 if ( $res->is_binary ) {
2017 App
::Ack
::print( "Binary file $filename matches\n" );
2020 if ( $keep_context ) {
2022 print_match_or_context
( $opt, 0, $before_starts_at_line, $-[0], $+[0], @before );
2024 $before_starts_at_line = 0;
2026 if ( $max && $nmatches > $max ) {
2030 $after = $after_context;
2033 print_match_or_context
( $opt, 1, $., $-[0], $+[0], $_ );
2035 last if $max && ( $nmatches >= $max ) && !$after;
2039 } # search_resource()
2043 sub print_match_or_context
{
2044 my $opt = shift; # opts array
2045 my $is_match = shift; # is there a match on the line?
2046 my $line_no = shift;
2047 my $match_start = shift;
2048 my $match_end = shift;
2050 my $color = $opt->{color
};
2051 my $heading = $opt->{heading
};
2052 my $show_filename = $opt->{show_filename
};
2053 my $show_column = $opt->{column
};
2055 if ( $show_filename ) {
2056 if ( not defined $display_filename ) {
2059 ? Term
::ANSIColor
::colored
( $filename, $ENV{ACK_COLOR_FILENAME
} )
2061 if ( $heading && !$any_output ) {
2062 App
::Ack
::print_first_filename
($display_filename);
2067 my $sep = $is_match ? ':' : '-';
2068 my $output_func = $opt->{output
};
2070 if ( $keep_context && !$output_func ) {
2071 if ( ( $last_output_line != $line_no - 1 ) &&
2072 ( $any_output || ( !$heading && defined( $context_overall_output_count ) ) ) ) {
2073 App
::Ack
::print_separator
();
2075 # to ensure separators between different files when --noheading
2077 $last_output_line = $line_no;
2080 if ( $show_filename ) {
2081 App
::Ack
::print_filename
($display_filename, $sep) if not $heading;
2082 App
::Ack
::print_line_no
($line_no, $sep);
2085 if ( $output_func ) {
2086 while ( /$regex/go ) {
2087 App
::Ack
::print( $output_func->() . "\n" );
2091 if ( $color && $is_match && $regex &&
2092 s/$regex/Term::ANSIColor::colored( substr($_, $-[0], $+[0] - $-[0]), $ENV{ACK_COLOR_MATCH} )/eg ) {
2093 # At the end of the line reset the color and remove newline
2094 s/[\r\n]*\z/\e[0m\e[K/;
2097 # remove any kind of newline at the end of the line
2100 if ( $show_column ) {
2101 App
::Ack
::print_column_no
( $match_start+1, $sep );
2103 App
::Ack
::print($_ . "\n");
2106 ++$context_overall_output_count;
2111 } # print_match_or_context()
2113 } # scope around search_resource() and print_match_or_context()
2117 sub search_and_list
{
2122 my $count = $opt->{count
};
2123 my $ors = $opt->{print0
} ? "\0" : "\n"; # output record separator
2125 my $regex = qr/$opt->{regex}/;
2128 while ( $res->next_text ) {
2130 return 0 unless $count;
2138 while ( $res->next_text ) {
2147 App
::Ack
::print_count
( $res->name, $nmatches, $ors, $count );
2149 elsif ( $count && !$opt->{l
} ) {
2150 App
::Ack
::print_count0
( $res->name, $ors );
2153 return $nmatches ? 1 : 0;
2154 } # search_and_list()
2158 sub filetypes_supported_set
{
2159 return grep { defined $type_wanted{$_} && ($type_wanted{$_} == 1) } filetypes_supported
();
2168 my $ors = $opt->{print0
} ? "\0" : "\n";
2171 while ( defined ( my $file = $iter->() ) ) {
2172 App
::Ack
::print $file, $ors;
2181 sub print_files_with_matches
{
2186 while ( defined ( my $filename = $iter->() ) ) {
2187 my $repo = App
::Ack
::Repository
::Basic-
>new( $filename );
2189 while ( $res = $repo->next_resource() ) {
2190 $nmatches += search_and_list
( $res, $opt );
2192 last if $nmatches && $opt->{1};
2205 $opt->{show_filename
} = 0 if $opt->{h
};
2206 $opt->{show_filename
} = 1 if $opt->{H
};
2209 while ( defined ( my $filename = $iter->() ) ) {
2211 my $tarballs_work = 0;
2212 if ( $tarballs_work && $filename =~ /\.tar\.gz$/ ) {
2213 App
::Ack
::die( 'Not working here yet' );
2214 require App
::Ack
::Repository
::Tar
; # XXX Error checking
2215 $repo = App
::Ack
::Repository
::Tar-
>new( $filename );
2218 $repo = App
::Ack
::Repository
::Basic-
>new( $filename );
2222 while ( my $res = $repo->next_resource() ) {
2223 my $needs_line_scan;
2224 if ( $opt->{regex
} && !$opt->{passthru
} ) {
2225 $needs_line_scan = $res->needs_line_scan( $opt );
2226 if ( $needs_line_scan ) {
2231 $needs_line_scan = 1;
2233 if ( $needs_line_scan ) {
2234 $nmatches += search_resource
( $res, $opt );
2238 last if $nmatches && $opt->{1};
2245 sub filetype_setup
{
2246 my $filetypes_supported_set = filetypes_supported_set
();
2247 # If anyone says --no-whatever, we assume all other types must be on.
2248 if ( !$filetypes_supported_set ) {
2249 for my $i ( keys %type_wanted ) {
2250 $type_wanted{$i} = 1 unless ( defined( $type_wanted{$i} ) || $i eq 'binary' || $i eq 'text' || $i eq 'skipped' );
2257 EXPAND_FILENAMES_SCOPE
: {
2260 sub expand_filenames
{
2266 foreach my $pattern ( @{$argv} ) {
2267 my @results = bsd_glob
( $pattern );
2269 if (@results == 0) {
2270 @results = $pattern; # Glob didn't match, pass it thru unchanged
2272 elsif ( (@results > 1) or ($results[0] ne $pattern) ) {
2273 if (not defined $filter) {
2274 eval 'require Win32::File;';
2279 $filter = Win32
::File
::HIDDEN
()|Win32
::File
::SYSTEM
();
2281 } # end unless we've tried to load Win32::File
2283 # Filter out hidden and system files:
2284 @results = grep { not(Win32
::File
::GetAttributes
($_, $attr) and $attr & $filter) } @results;
2285 App
::Ack
::warn( "$pattern: Matched only hidden files" ) unless @results;
2286 } # end if we can filter by file attributes
2287 } # end elsif this pattern got expanded
2289 push @files, @results;
2290 } # end foreach pattern
2293 } # end expand_filenames
2294 } # EXPAND_FILENAMES_SCOPE
2298 sub get_starting_points
{
2305 @what = @{ $is_windows ? expand_filenames
($argv) : $argv };
2306 $_ = File
::Next
::reslash
( $_ ) for @what;
2308 # Show filenames unless we've specified one single file
2309 $opt->{show_filename
} = (@what > 1) || (!-f
$what[0]);
2312 @what = '.'; # Assume current directory
2313 $opt->{show_filename
} = 1;
2316 for my $start_point (@what) {
2317 App
::Ack
::warn( "$start_point: No such file or directory" ) unless -e
$start_point;
2328 # Starting points are always searched, no matter what
2329 my %starting_point = map { ($_ => 1) } @{$what};
2331 my $g_regex = defined $opt->{G
} ? qr/$opt->{G}/ : undef;
2336 = $opt->{u
} ? sub { $File::Next
::name
=~ /$g_regex/ } # XXX Maybe this should be a 1, no?
2337 : $opt->{all
} ? sub { $starting_point{ $File::Next
::name
} || ( $File::Next
::name
=~ /$g_regex/ && is_searchable
( $_ ) ) }
2338 : sub { $starting_point{ $File::Next
::name
} || ( $File::Next
::name
=~ /$g_regex/ && is_interesting
( @_ ) ) }
2343 = $opt->{u
} ? sub {1}
2344 : $opt->{all
} ? sub { $starting_point{ $File::Next
::name
} || is_searchable
( $_ ) }
2345 : sub { $starting_point{ $File::Next
::name
} || is_interesting
( @_ ) }
2350 = $opt->{n
} ? sub {0}
2351 : $opt->{u
} ? sub {1}
2352 : \
&ignoredir_filter
;
2355 File
::Next
::files
( {
2356 file_filter
=> $file_filter,
2357 descend_filter
=> $descend_filter,
2358 error_handler
=> sub { my $msg = shift; App
::Ack
::warn( $msg ) },
2359 sort_files
=> $opt->{sort_files
},
2360 follow_symlinks
=> $opt->{follow
},
2367 my $command = shift;
2369 return if App
::Ack
::output_to_pipe
();
2372 if ( not open( $pager, '|-', $command ) ) {
2373 App
::Ack
::die( qq{Unable to pipe to pager "$command": $!} );
2381 sub input_from_pipe
{
2382 return $input_from_pipe;
2387 sub output_to_pipe
{
2388 return $output_to_pipe;
2393 1; # End of App::Ack
2394 package App
::Ack
::Repository
;
2402 Carp
::confess
( 'Must be overloaded' );
2421 package App
::Ack
::Resource
;
2429 Carp
::confess
( 'Must be overloaded' );
2449 sub needs_line_scan
{
2469 package App
::Ack
::Plugin
::Basic
;
2473 package App
::Ack
::Resource
::Basic
;
2480 our @ISA = qw( App::Ack::Resource );
2485 my $filename = shift;
2488 filename
=> $filename,
2490 could_be_binary
=> undef,
2495 if ( $self->{filename
} eq '-' ) {
2496 $self->{fh
} = *STDIN
;
2497 $self->{could_be_binary
} = 0;
2500 if ( !open( $self->{fh
}, '<', $self->{filename
} ) ) {
2501 App
::Ack
::warn( "$self->{filename}: $!" );
2504 $self->{could_be_binary
} = 1;
2514 return $self->{filename
};
2521 if ( $self->{could_be_binary
} ) {
2522 return -B
$self->{filename
};
2530 sub needs_line_scan
{
2534 return 1 if $opt->{v
};
2536 my $size = -s
$self->{fh
};
2540 elsif ( $size > 100_000 ) {
2545 my $rc = sysread( $self->{fh
}, $buffer, $size );
2546 if ( not defined $rc ) {
2547 App
::Ack
::warn( "$self->{filename}: $!" );
2550 return 0 unless $rc && ( $rc == $size );
2552 my $regex = $opt->{regex
};
2553 return $buffer =~ /$regex/m;
2560 seek( $self->{fh
}, 0, 0 )
2561 or App
::Ack
::warn( "$self->{filename}: $!" );
2568 if ( defined ($_ = readline $_[0]->{fh
}) ) {
2569 $. = ++$_[0]->{line
};
2580 if ( not close $self->{fh
} ) {
2581 App
::Ack
::warn( $self->name() . ": $!" );
2587 package App
::Ack
::Repository
::Basic
;
2590 our @ISA = qw( App::Ack::Repository );
2598 my $filename = shift;
2601 filename
=> $filename,
2612 return if $self->{nexted
};
2613 $self->{nexted
} = 1;
2615 return App
::Ack
::Resource
::Basic-
>new( $self->{filename
} );