1 *ferret.txt* Ferret plug-in for Vim *ferret*
3 CONTENTS *ferret-contents*
5 1. Intro |ferret-intro|
6 2. Installation |ferret-installation|
7 3. Commands |ferret-commands|
8 4. Mappings |ferret-mappings|
9 5. Options |ferret-options|
10 6. Custom autocommands |ferret-custom-autocommands|
11 7. Overrides |ferret-overrides|
12 8. Troubleshooting |ferret-troubleshooting|
14 10. Related |ferret-related|
15 11. Website |ferret-website|
16 12. License |ferret-license|
17 13. Development |ferret-development|
18 14. Authors |ferret-authors|
19 15. History |ferret-history|
24 (ferret something out) search tenaciously for and find something: she
25 had the ability to ferret out the facts."
29 Ferret improves Vim's multi-file search in four ways:
31 1. Powerful multi-file search ~
33 Ferret provides an |:Ack| command for searching across multiple files using
34 The Silver Searcher (https://github.com/ggreer/the_silver_searcher), or Ack
35 (http://beyondgrep.com/). Support for passing options through to the
36 underlying search command exists, along with the ability to use full regular
37 expression syntax without doing special escaping. On Vim version 8 or
38 higher, searches are performed asynchronously (without blocking the UI).
40 Shortcut mappings are provided to start an |:Ack| search (<leader>a) or to
41 search for the word currently under the cursor (<leader>s).
43 Results are normally displayed in the |quickfix| window, but Ferret also
44 provides a |:Lack| command that behaves like |:Ack| but uses the |location-list|
45 instead, and a <leader>l mapping as a shortcut to |:Lack|.
47 |:Back| and |:Black| are analogous to |:Ack| and |:Lack|, but scoped to search
48 within currently open buffers only.
50 Finally, Ferret offers integration with dispatch.vim
51 (https://github.com/tpope/vim-dispatch), which enables asynchronous
52 searching on older versions of Vim (prior to version 8), despite the fact
53 that Vim itself is single-threaded.
55 2. Streamlined multi-file replace ~
57 The companion to |:Ack| is |:Acks| (mnemonic: "Ack substitute", accessible via
58 shortcut <leader>r), which allows you to run a multi-file replace across all
59 the files placed in the |quickfix| window by a previous invocation of |:Ack| (or
62 3. Quickfix listing enhancements ~
64 The |quickfix| listing itself is enhanced with settings to improve its
65 usability, and natural mappings that allow quick removal of items from the
66 list (for example, you can reduce clutter in the listing by removing lines
67 that you don't intend to make changes to).
69 Additionally, Vim's |:cn|, |:cp|, |:cnf| and |:cpf| commands are tweaked to make it
70 easier to immediately identify matches by centering them within the viewport.
72 4. Easy operations on files in the quickfix listing ~
74 Finally, Ferret provides a |:Qargs| command that puts the files currently in
75 the |quickfix| listing into the |:args| list, where they can be operated on in
76 bulk via the |:argdo| command. This is what's used under the covers by |:Acks|
79 INSTALLATION *ferret-installation*
81 To install Ferret, use your plug-in management system of choice.
83 If you don't have a "plug-in management system of choice", I recommend
84 Pathogen (https://github.com/tpope/vim-pathogen) due to its simplicity and
85 robustness. Assuming that you have Pathogen installed and configured, and
86 that you want to install Ferret into `~/.vim/bundle`, you can do so with:
88 git clone https://github.com/wincent/ferret.git ~/.vim/bundle/ferret
90 Alternatively, if you use a Git submodule for each Vim plug-in, you could do
91 the following after `cd`-ing into the top-level of your Git superproject:
93 git submodule add https://github.com/wincent/ferret.git ~/vim/bundle/ferret
96 To generate help tags under Pathogen, you can do so from inside Vim with:
98 :call pathogen#helptags()
100 COMMANDS *ferret-commands*
103 :Ack {pattern} {options} ~
105 Searches for {pattern} in all the files under the current directory (see
106 |:pwd|), unless otherwise overridden via {options}, and displays the results
107 in the |quickfix| listing.
109 `rg` (ripgrep) then `ag` (The Silver Searcher) will be used preferentially if
110 present on the system, because they are faster, falling back to `ack`/`ack-grep`
113 On newer versions of Vim (version 8 and above), the search process runs
114 asynchronously in the background and does not block the UI.
116 On older Vim versions (prior to version 8), if dispatch.vim is installed the
117 search process will run asynchronously via the |:Make| command, otherwise it
118 will be run synchronously via |:cexpr|. The |g:FerretDispatch| option can be
119 used to prevent the use of dispatch.vim.
121 Asynchronous searches are preferred because they do not block, despite the
122 fact that Vim itself is single threaded.
124 The {pattern} is passed through as-is to the underlying search program, and
125 no escaping is required other than preceding spaces by a single backslash.
126 For example, to search for "\bfoo[0-9]{2} bar\b" (ie. using `ag`'s Perl-style
127 regular expression syntax), you could do:
129 :Ack \bfoo[0-9]{2}\ bar\b
131 Likewise, {options} are passed through. In this example, we pass the `-w`
132 option (to search on word boundaries), and scope the search to the "foo" and
133 "bar" subdirectories: >
135 :Ack -w something foo bar
137 As a convenience <leader>a is set-up (|<Plug>(FerretAck)|) as a shortcut to
138 enter |Cmdline-mode| with `:Ack` inserted on the |Cmdline|. Likewise <leader>s
139 (|<Plug>(FerretAckWord)|) is a shortcut for running |:Ack| with the word
140 currently under the cursor.
143 :Ack! {pattern} {options} ~
145 Like |:Ack|, but returns all results irrespective of the value of
146 |g:FerretMaxResults|.
149 :Lack {pattern} {options} ~
151 Just like |:Ack|, but instead of using the |quickfix| listing, which is global
152 across an entire Vim instance, it uses the |location-list|, which is a
153 per-window construct.
155 Note that |:Lack| always runs synchronously via |:cexpr|, because dispatch.vim
156 doesn't currently support the |location-list|.
159 :Lack! {pattern} {options} ~
161 Like |:Lack|, but returns all results irrespective of the value of
162 |g:FerretMaxResults|.
165 :Back {pattern} {options} ~
167 Like |:Ack|, but searches only listed buffers. Note that the search is still
168 delegated to the underlying |'grepprg'| (`rg`, `ag`, `ack` or `ack-grep`), which means
169 that only buffers written to disk will be searched. If no buffers are
170 written to disk, then |:Back| behaves exactly like |:Ack| and will search all
171 files in the current directory.
174 :Back! {pattern} {options} ~
176 Like |:Back|, but returns all results irrespective of the value of
177 |g:FerretMaxResults|.
180 :Black {pattern} {options} ~
182 Like |:Lack|, but searches only listed buffers. As with |:Back|, the search is
183 still delegated to the underlying |'grepprg'| (`rg`, `ag`, `ack` or `ack-grep`), which
184 means that only buffers written to disk will be searched. Likewise, If no
185 buffers are written to disk, then |:Black| behaves exactly like |:Lack| and will
186 search all files in the current directory.
189 :Black! {pattern} {options} ~
191 Like |:Black|, but returns all results irrespective of the value of
192 |g:FerretMaxResults|.
195 :Acks /{pattern}/{replacement}/ ~
197 Takes all of the files currently in the |quickfix| listing and performs a
198 substitution of all instances of {pattern} (a standard Vim search |pattern|)
201 A typical sequence consists of an |:Ack| invocation to populate the |quickfix|
202 listing and then |:Acks| (mnemonic: "Ack substitute") to perform replacements.
203 For example, to replace "foo" with "bar" across all files in the current
212 This is a utility function that is used internally when running on older
213 versions of Vim (prior to version 8) but is also generally useful enough to
214 warrant being exposed publicly.
216 It takes the files currently in the |quickfix| listing and sets them as |:args|
217 so that they can be operated on en masse via the |:argdo| command.
219 MAPPINGS *ferret-mappings*
221 Circumstances where mappings do not get set up ~
223 Note that Ferret will not try to set up the <leader> mappings if any of the
226 - A mapping for already exists.
227 - An alternative mapping for the same functionality has already been set up
229 - The mapping has been suppressed by setting |g:FerretMap| to 1 in your |.vimrc|.
231 Mappings specific to the quickfix window ~
233 Additionally, Ferret will set up special mappings in |quickfix| listings,
234 unless prevented from doing so by |g:FerretQFMap|:
236 - `d` (|visual-mode|): delete visual selection
237 - `dd` (|Normal-mode|): delete current line
238 - `d`{motion} (|Normal-mode|): delete range indicated by {motion}
242 Ferret maps <leader>a to |<Plug>(FerretAck)|, which triggers the |:Ack| command.
243 To use an alternative mapping instead, create a different one in your |.vimrc|
244 instead using |:nmap|:
246 " Instead of <leader>a, use <leader>x.
247 nmap <leader>x <Plug>(FerretAck)
251 Ferret maps <leader>l to |<Plug>(FerretLack)|, which triggers the |:Lack|
252 command. To use an alternative mapping instead, create a different one in
253 your |.vimrc| instead using |:nmap|:
255 " Instead of <leader>l, use <leader>y.
256 nmap <leader>y <Plug>(FerretLack)
259 *<Plug>(FerretAckWord)*
260 Ferret maps <leader>s (mnemonix: "selection) to |<Plug>(FerretAckWord)|, which
261 uses |:Ack| to search for the word currently under the cursor. To use an
262 alternative mapping instead, create a different one in your |.vimrc| instead
265 " Instead of <leader>s, use <leader>z.
266 nmap <leader>z <Plug>(FerretAckWord)
270 Ferret maps <leader>r (mnemonic: "replace") to |<Plug>(FerretAcks)|, which
271 triggers the |:Acks| command and fills the prompt with the last search term
272 from Ferret. to use an alternative mapping instead, create a different one
273 in your |.vimrc| instead using |:nmap|:
275 " Instead of <leader>r, use <leader>u.
276 nmap <leader>u <Plug>(FerretAcks)
278 OPTIONS *ferret-options*
282 |g:FerretDispatch| boolean (default: 1)
284 Controls whether to use vim-dispatch (and specifically, |:Make|) to run |:Ack|
285 searches asynchronously, when available. To prevent vim-dispatch from being
288 let g:FerretDispatch=0
290 Note that on sufficiently recent versions of Vim with |+job| support, Ferret
291 will first try to use |+job|, falling back to vim-dispatch and consulting
292 |g:FerretDispatch| only if |g:FerretJob| is set to 0.
296 |g:FerretJob| boolean (default: 1)
298 Controls whether to use Vim's |+job| feature, when available, to run searches
299 asynchronously. To prevent |+job| from being used, set to 0, in which case
300 Ferret will fall back to vim-dispatch (see also: |g:FerretDispatch|):
306 |g:FerretHlsearch| boolean (default: none)
308 Controls whether Ferret should attempt to highlight the search pattern when
309 running |:Ack| or |:Lack|. If left unset, Ferret will respect the current
310 'hlsearch' setting. To force highlighting on or off irrespective of
311 'hlsearch', set |g:FerretHlsearch| to 1 (on) or 0 (off):
313 let g:FerretHlsearch=0
317 |g:FerretExecutable| string (default: "rg,ag,ack,ack-grep")
319 Ferret will preferentially use `rg`, `ag` and finally `ack`/`ack-grep` (in that
320 order, using the first found executable), however you can force your
321 preference for a specific tool to be used by setting an override in your
322 |.vimrc|. Valid values are a comma-separated list of "rg", "ag", "ack" or
323 "ack-grep". If no requested executable exists, Ferret will fall-back to the
324 next in the default list.
328 " Prefer `ag` over `rg`.
329 let g:FerretExecutable='ag,rg'
333 |g:FerretMaxResults| number (default: 100000)
335 Controls the maximum number of results Ferret will attempt to gather before
336 displaying the results. Note that this only applies when searching
337 asynchronously; that is, on recent versions of Vim with |+job| support and
338 when |g:FerretJob| is not set to 0.
340 The intent of this option is to prevent runaway search processes that
341 produce huge volumes of output (for example, searching for a common string
342 like "test" inside a |$HOME| directory containing millions of files) from
345 In the event that Ferret aborts a search that has hit the |g:FerretMaxResults|
346 limit, a message will be printed prompting users to run the search again
347 with |:Ack!| or |:Lack!| if they want to bypass the limit.
351 |g:FerretQFOptions| boolean (default: 1)
353 Controls whether to set up setting overrides for |quickfix| windows. These are
354 various settings, such as |norelativenumber|, |nolist| and |nowrap|, that are
355 intended to make the |quickfix| window, which is typically very small relative
356 to other windows, more usable.
358 A full list of overridden settings can be found in |ferret-overrides|.
360 To prevent the custom settings from being applied, set |g:FerretQFOptions| to
363 let g:FerretQFOptions=0
367 |g:FerretQFMap| boolean (default: 1)
369 Controls whether to set up mappings in the |quickfix| results window for
370 deleting results. The mappings include:
372 - `d` (|visual-mode|): delete visual selection
373 - `dd` (|Normal-mode|): delete current line
374 - `d`{motion} (|Normal-mode|): delete range indicated by {motion}
376 To prevent these mappings from being set up, set to 0:
382 |g:FerretLoaded| any (default: none)
384 To prevent Ferret from being loaded, set |g:FerretLoaded| to any value in your
385 |.vimrc|. For example:
391 |g:FerretLazyInit| boolean (default: 1)
393 In order to minimize impact on Vim start-up time Ferret will initialize
394 itself lazily on first use by default. If you wish to force immediate
395 initialization (for example, to cause |'grepprg'| and |'grepformat'| to be set
396 as soon as Vim launches), then set |g:FerretLazyInit| to 0 in your |.vimrc|:
398 let g:FerrerLazyInit=0
402 |g:FerretMap| boolean (default: 1)
404 Controls whether to set up the Ferret mappings, such as |<Plug>(FerretAck)|
405 (see |ferret-mappings| for a full list). To prevent any mapping from being
406 configured, set to 0:
412 |g:FerretQFCommands| boolean (default: 1)
414 Controls whether to set up custom versions of the |quickfix| commands, |:cn|,
415 |:cnf|, |:cp| an |:cpf|. These overrides vertically center the match within the
416 viewport on each jump. To prevent the custom versions from being configured,
419 let g:FerretQFCommands=0
423 |g:FerretFormat| string (default: "%f:%l:%c:%m")
425 Sets the '|grepformat|' used by Ferret.
427 CUSTOM AUTOCOMMANDS *ferret-custom-autocommands*
430 *FerretDidWrite* *FerretWillWrite*
431 For maximum compatibility with other plug-ins, Ferret runs the following
432 "User" autocommands before and after running the file writing operations
438 For example, to call a pair of custom functions in response to these events,
441 autocmd! User FerretWillWrite
442 autocmd User FerretWillWrite call CustomWillWrite()
443 autocmd! User FerretDidWrite
444 autocmd User FerretDidWrite call CustomDidWrite()
446 OVERRIDES *ferret-overrides*
448 Ferret overrides the 'grepformat' and 'grepprg' settings, preferentially
449 setting `rg`, `ag`, `ack` or `ack-grep` as the 'grepprg' (in that order) and
450 configuring a suitable 'grepformat'.
452 Additionally, Ferret includes an |ftplugin| for the |quickfix| listing that
453 adjusts a number of settings to improve the usability of search results.
459 Turned off to reduce visual clutter in the search results, and because
460 'list' is most useful in files that are being actively edited, which is not
461 the case for |quickfix| results.
464 *ferret-norelativenumber*
467 Turned off, because it is more useful to have a sense of absolute progress
468 through the results list than to have the ability to jump to nearby results
469 (especially seeing as the most common operations are moving to the next or
470 previous file, which are both handled nicely by |:cnf| and |:cpf| respectively).
476 Turned off to avoid ugly wrapping that makes the results list hard to read,
477 and because in search results, the most relevant information is the
478 filename, which is on the left and is usually visible even without wrapping.
484 Turned on to give a sense of absolute progress through the results.
490 Set to 0 because the |quickfix| listing is usually small by default, so trying
491 to keep the current line away from the edge of the viewpoint is futile; by
492 definition it is usually near the edge.
495 *ferret-nocursorline*
498 Turned off to reduce visual clutter.
500 To prevent any of these |quickfix|-specific overrides from being set up, you
501 can set |g:FerretQFOptions| to 0 in your |.vimrc|:
503 let g:FerretQFOptions=0
505 TROUBLESHOOTING *ferret-troubleshooting*
509 Ferret fails to find patterns containing spaces ~
511 As described in the documentation for |:Ack|, the search pattern is passed
512 through as-is to the underlying search command, and no escaping is required
513 other than preceding spaces by a single backslash.
515 So, to find "foo bar", you would search like:
519 Unescaped spaces in the search are treated as argument separators, so a
520 command like the following means pass the `-w` option through, search for
521 pattern "foo", and limit search to the "bar" directory:
525 Note that including quotes will not do what you intend.
527 " Search for '"foo' in the 'bar"' directory:
530 " Search for "'foo' in the "bar'" directory:
533 This approach to escaping is taken in order to make it straightfoward to use
534 powerful Perl-compatible regular expression syntax in an unambiguous way
535 without having to worry about shell escaping rules:
537 :Ack \blog\((['"]).*?\1\) -i --ignore-dir=src/vendor src dist build
541 Why do Ferret commands start with "Ack", "Lack" and so on? ~
543 Ferret was originally the thinnest of wrappers (7 lines of code in my
544 |.vimrc|) around `ack`. The earliest traces of it can be seen in the initial
545 commit to my dotfiles repo in May, 2009 (https://wt.pe/h).
547 So, even though Ferret has a new name now and actually prefers `rg` then `ag`
548 over `ack`/`ack-grep` when available, I prefer to keep the command names intact
549 and benefit from years of accumulated muscle-memory.
551 RELATED *ferret-related*
553 Just as Ferret aims to improve the multi-file search and replace experience,
554 Loupe does the same for within-file searching:
556 https://github.com/wincent/loupe
558 WEBSITE *ferret-website*
560 The official Ferret source code repo is at:
562 http://git.wincent.com/ferret.git
566 https://github.com/wincent/ferret
568 Official releases are listed at:
570 http://www.vim.org/scripts/script.php?script_id=5220
572 LICENSE *ferret-license*
574 Copyright 2015-present Greg Hurrell. All rights reserved.
576 Redistribution and use in source and binary forms, with or without
577 modification, are permitted provided that the following conditions are met:
579 1. Redistributions of source code must retain the above copyright notice,
580 this list of conditions and the following disclaimer.
582 2. Redistributions in binary form must reproduce the above copyright notice,
583 this list of conditions and the following disclaimer in the documentation
584 and/or other materials provided with the distribution.
586 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
587 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
588 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
589 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
590 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
591 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
592 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
593 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
594 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
595 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
596 POSSIBILITY OF SUCH DAMAGE.
598 DEVELOPMENT *ferret-development*
600 Contributing patches ~
602 Patches can be sent via mail to greg@hurrell.net, or as GitHub pull requests
603 at: https://github.com/wincent/ferret/pulls
605 Cutting a new release ~
607 At the moment the release process is manual:
609 - Perform final sanity checks and manual testing
610 - Update the |ferret-history| section of the documentation
611 - Verify clean work tree:
617 git tag -s -m "$VERSION release" $VERSION
621 git push origin master --follow-tags
622 git push github master --follow-tags
624 - Produce the release archive:
626 git archive -o ferret-$VERSION.zip HEAD -- .
628 - Upload to http://www.vim.org/scripts/script.php?script_id=5220
630 AUTHORS *ferret-authors*
632 Ferret is written and maintained by Greg Hurrell <greg@hurrell.net>.
634 The idea for vim-dispatch integration was taken from Miles Sterrett's
635 ack.vim plug-in (https://github.com/mileszs/ack.vim).
637 Other contributors that have submitted patches include (in alphabetical
647 HISTORY *ferret-history*
649 master (not yet released) ~
651 - Improvements to the handling of very large result sets (due to wide lines
653 - Added |g:FerretLazyInit|.
654 - Added missing documentation for |g:FerretJob|.
655 - Added |g:FerretMaxResults|.
656 - Added feature-detection for `rg` and `ag`, allowing Ferret to gracefully work
657 with older versions of those tools that do not support all desired
658 command-line switches.
660 1.4 (21 January 2017) ~
662 - Drop broken support for `grep`, printing a prompt to install `rg`, `ag`, or
663 `ack`/`ack-grep` instead.
664 - If an `ack` executable is not found, search for `ack-grep`, which is the name
665 used on Debian-derived distros.
667 1.3 (8 January 2017) ~
669 - Reset |'errorformat'| before each search (fixes issue #31).
670 - Added |:Back| and |:Black| commands, analogous to |:Ack| and |:Lack| but scoped to
671 search within currently open buffers only.
672 - Change |:Acks| to use |:cfdo| when available rather than |:Qargs| and |:argdo|, to
673 avoid polluting the |arglist|.
674 - Remove superfluous |QuickFixCmdPost| autocommands, resolving clash with
675 Neomake plug-in (patch from Tom Dooner, #36).
676 - Add support for searching with ripgrep (`rg`).
680 - Add optional support for running searches asynchronously using Vim's |+job|
681 feature (enabled by default in sufficiently recent versions of Vim); see
682 |g:FerretJob|, |:FerretCancelAsync| and |:FerretPullAsync|.
684 1.1.1 (7 March 2016) ~
686 - Fix another edge case when searching for patterns containing "#", only
687 manifesting under dispatch.vim.
691 - Fix edge case when searching for strings of the form "<foo>".
692 - Fix edge case when searching for patterns containing "#" and "%".
693 - Provide completion for `ag` and `ack` options when using |:Ack| and |:Lack|.
694 - Fix display of error messages under dispatch.vim.
696 1.0 (28 December 2015) ~
698 - Fix broken |:Qargs| command (patch from Daniel Silva).
699 - Add |g:FerretQFHandler| and |g:FerretLLHandler| options (patch from Daniel
701 - Make |<Plug>| mappings accessible even |g:FerretMap| is set to 0.
702 - Fix failure to report filename when using `ack` and explicitly scoping
703 search to a single file (patch from Daniel Silva).
704 - When using `ag`, report multiple matches per line instead of just the first
705 (patch from Daniel Silva).
706 - Improve content and display of error messages.
710 - Added highlighting of search pattern and related |g:FerretHlsearch| option
711 (patch from Nelo-Thara Wallus).
712 - Add better error reporting for failed or incorrect searches.
716 - Added |FerretDidWrite| and |FerretWillWrite| autocommands (patch from Joe
718 - Add |<Plug>(FerretAcks)| mapping (patch from Nelo-Thara Wallus).
722 - Initial release, extracted from my dotfiles
723 (https://github.com/wincent/wincent).