]> git.wincent.com - docvim.git/blob - tests/fixtures/shared/integration-ferret-plugin.vim
Share integration tests inputs across output types
[docvim.git] / tests / fixtures / shared / integration-ferret-plugin.vim
1 " Copyright 2015-present Greg Hurrell. All rights reserved.
2 " Licensed under the terms of the BSD 2-clause license.
3
4 ""
5 " @plugin ferret Ferret plug-in for Vim
6 "
7 " # Intro
8 "
9 " > "ferret (verb)<br />
10 " > (ferret something out) search tenaciously for and find something: she had
11 " > the ability to ferret out the facts."
12 "
13 "                                                               *ferret-features*
14 " Ferret improves Vim's multi-file search in four ways:
15 "
16 " ## 1. Powerful multi-file search
17 "
18 " Ferret provides an |:Ack| command for searching across multiple files using
19 " The Silver Searcher (https://github.com/ggreer/the_silver_searcher), Ack
20 " (http://beyondgrep.com/), or Grep (http://www.gnu.org/software/grep/). Support
21 " for passing options through to the underlying search command exists, along
22 " with the ability to use full regular expression syntax without doing special
23 " escaping.
24 "
25 " Shortcut mappings are provided to start an |:Ack| search (<leader>a) or to
26 " search for the word currently under the cursor (<leader>s).
27 "
28 " Results are normally displayed in the |quickfix| window, but Ferret also
29 " provides a |:Lack| command that behaves like |:Ack| but uses the
30 " |location-list| instead, and a <leader>l mapping as a shortcut to |:Lack|.
31 "
32 " Finally, Ferret offers integration with dispatch.vim
33 " (https://github.com/tpope/vim-dispatch), which enables asynchronous searching
34 " despite the fact that Vim itself is single-threaded.
35 "
36 " ## 2. Streamlined multi-file replace
37 "
38 " The companion to |:Ack| is |:Acks| (mnemonic: "Ack substitute", accessible via
39 " shortcut <leader>r), which allows you to run a multi-file replace across all
40 " the files placed in the |quickfix| window by a previous invocation of |:Ack|.
41 "
42 " ## 3. Quickfix listing enhancements
43 "
44 " The |quickfix| listing itself is enhanced with settings to improve its
45 " usability, and natural mappings that allow quick removal of items from the
46 " list (for example, you can reduce clutter in the listing by removing lines
47 " that you don't intend to make changes to).
48 "
49 " Additionally, Vim's |:cn|, |:cp|, |:cnf| and |:cpf| commands are tweaked to
50 " make it easier to immediately identify matches by centering them within the
51 " viewport.
52 "
53 " ## 4. Easy operations on files in the quickfix listing
54 "
55 " Finally, Ferret provides a |:Qargs| command that puts the files currently in
56 " the |quickfix| listing into the |:args| list, where they can be operated on in
57 " bulk via the |:argdo| command. This is what's used under the covers by |:Acks|
58 " to do its work.
59 "
60 "
61 " # Installation
62 "
63 " To install Ferret, use your plug-in management system of choice.
64 "
65 " If you don't have a "plug-in management system of choice", I recommend
66 " Pathogen (https://github.com/tpope/vim-pathogen) due to its simplicity and
67 " robustness. Assuming that you have Pathogen installed and configured, and that
68 " you want to install Ferret into `~/.vim/bundle`, you can do so with:
69 "
70 " ```
71 " git clone https://github.com/wincent/ferret.git ~/.vim/bundle/ferret
72 " ```
73 "
74 " Alternatively, if you use a Git submodule for each Vim plug-in, you could do
75 " the following after `cd`-ing into the top-level of your Git superproject:
76 "
77 " ```
78 " git submodule add https://github.com/wincent/ferret.git ~/vim/bundle/ferret
79 " git submodule init
80 " ```
81 "
82 " To generate help tags under Pathogen, you can do so from inside Vim with:
83 "
84 " ```
85 " :call pathogen#helptags()
86 " ```
87 "
88 " @mappings
89 "
90 " ## Circumstances where mappings do not get set up
91 "
92 " Note that Ferret will not try to set up the <leader> mappings if any of the
93 " following are true:
94 "
95 " - A mapping for already exists.
96 " - An alternative mapping for the same functionality has already been set up
97 "   from a |.vimrc|.
98 " - The mapping has been suppressed by setting |g:FerretMap| to 1 in your
99 "   |.vimrc|.
100 "
101 " ## Mappings specific to the quickfix window
102 "
103 " Additionally, Ferret will set up special mappings in |quickfix| listings,
104 " unless prevented from doing so by |g:FerretQFMap|:
105 "
106 " - `d` (|visual-mode|): delete visual selection
107 " - `dd` (|Normal-mode|): delete current line
108 " - `d`{motion} (|Normal-mode|): delete range indicated by {motion}
109 "
110 "
111 " @footer
112 "
113 " # Custom autocommands
114 "
115 "                                                *FerretWillWrite* *FerretDidWrite*
116 " For maximum compatibility with other plug-ins, Ferret runs the following
117 " "User" autocommands before and after running the file writing operations
118 " during |:Acks|:
119 "
120 " - FerretWillWrite
121 " - FerretDidWrite
122 "
123 " For example, to call a pair of custom functions in response to these events,
124 " you might do:
125 "
126 " ```
127 " autocmd! User FerretWillWrite
128 " autocmd User FerretWillWrite call CustomWillWrite()
129 " autocmd! User FerretDidWrite
130 " autocmd User FerretDidWrite call CustomDidWrite()
131 " ```
132 "
133 "
134 " # Overrides
135 "
136 " Ferret overrides the 'grepformat' and 'grepprg' settings, preferentially
137 " setting `ag`, `ack` or `grep` as the 'grepprg' (in that order) and configuring
138 " a suitable 'grepformat'.
139 "
140 " Additionally, Ferret includes an |ftplugin| for the |quickfix| listing that
141 " adjusts a number of settings to improve the usability of search results.
142 "
143 " @indent
144 "                                                                 *ferret-nolist*
145 "   'nolist'
146 "
147 "   Turned off to reduce visual clutter in the search results, and because
148 "   'list' is most useful in files that are being actively edited, which is not
149 "   the case for |quickfix| results.
150 "
151 "                                                       *ferret-norelativenumber*
152 "   'norelativenumber'
153 "
154 "   Turned off, because it is more useful to have a sense of absolute progress
155 "   through the results list than to have the ability to jump to nearby results
156 "   (especially seeing as the most common operations are moving to the next or
157 "   previous file, which are both handled nicely by |:cnf| and |:cpf|
158 "   respectively).
159 "
160 "                                                                 *ferret-nowrap*
161 "   'nowrap'
162 "
163 "   Turned off to avoid ugly wrapping that makes the results list hard to read,
164 "   and because in search results, the most relevant information is the
165 "   filename, which is on the left and is usually visible even without wrapping.
166 "
167 "                                                                 *ferret-number*
168 "   'number'
169 "
170 "   Turned on to give a sense of absolute progress through the results.
171 "
172 "                                                              *ferret-scrolloff*
173 "   'scrolloff'
174 "
175 "   Set to 0 because the |quickfix| listing is usually small by default, so
176 "   trying to keep the current line away from the edge of the viewpoint is
177 "   futile; by definition it is usually near the edge.
178 "
179 "                                                           *ferret-nocursorline*
180 "   'nocursorline'
181 "
182 "   Turned off to reduce visual clutter.
183 "
184 " @dedent
185 "
186 " To prevent any of these |quickfix|-specific overrides from being set up, you
187 " can set |g:FerretQFOptions| to 0 in your |.vimrc|:
188 "
189 " ```
190 " let g:FerretQFOptions=0
191 " ```
192 "
193 "
194 " # Troubleshooting
195 "
196 "                                                                 *ferret-quotes*
197 " ## Ferret fails to find patterns containing spaces
198 "
199 " As described in the documentation for |:Ack|, the search pattern is passed
200 " through as-is to the underlying search command, and no escaping is required
201 " other than preceding spaces by a single backslash.
202 "
203 " So, to find "foo bar", you would search like:
204 "
205 " ```
206 " :Ack foo\ bar
207 " ```
208 "
209 " Unescaped spaces in the search are treated as argument separators, so a
210 " command like the following means pass the `-w` option through, search for
211 " pattern "foo", and limit search to the "bar" directory:
212 "
213 " ```
214 " :Ack -w foo bar
215 " ```
216 "
217 " Note that including quotes will not do what you intend.
218 "
219 " ```
220 " " Search for '"foo' in the 'bar"' directory:
221 " :Ack "foo bar"
222 "
223 " " Search for "'foo' in the "bar'" directory:
224 " :Ack 'foo bar'
225 " ```
226 "
227 " This approach to escaping is taken in order to make it straightfoward to use
228 " powerful Perl-compatible regular expression syntax in an unambiguous way
229 " without having to worry about shell escaping rules:
230 "
231 " ```
232 " :Ack \blog\((['"]).*?\1\) -i --ignore-dir=src/vendor src dist build
233 " ```
234 "
235 "
236 " # FAQ
237 "
238 " ## Why do Ferret commands start with "Ack", "Lack" and so on?
239 "
240 " Ferret was originally the thinnest of wrappers (7 lines of code in my
241 " |.vimrc|) around `ack`. The earliest traces of it can be seen in the initial
242 " commit to my dotfiles repo in May, 2009 (https://wt.pe/h).
243 "
244 " So, even though Ferret has a new name now and actually prefers `ag` over `ack`
245 " when available, I prefer to keep the command names intact and benefit from
246 " years of accumulated muscle-memory.
247 "
248 "
249 "
250 " # Related
251 "
252 " Just as Ferret aims to improve the multi-file search and replace experience,
253 " Loupe does the same for within-file searching:
254 "
255 "   https://github.com/wincent/loupe
256 "
257 "
258 " # Website
259 "
260 " The official Ferret source code repo is at:
261 "
262 "   http://git.wincent.com/ferret.git
263 "
264 " A mirror exists at:
265 "
266 "   https://github.com/wincent/ferret
267 "
268 " Official releases are listed at:
269 "
270 "   http://www.vim.org/scripts/script.php?script_id=5220
271 "
272 "
273 " # License
274 "
275 " Copyright 2015-present Greg Hurrell. All rights reserved.
276 "
277 " Redistribution and use in source and binary forms, with or without
278 " modification, are permitted provided that the following conditions are met:
279 "
280 " 1. Redistributions of source code must retain the above copyright notice,
281 "    this list of conditions and the following disclaimer.
282 " 2. Redistributions in binary form must reproduce the above copyright notice,
283 "    this list of conditions and the following disclaimer in the documentation
284 "    and/or other materials provided with the distribution.
285 "
286 " THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
287 " AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
288 " IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
289 " ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
290 " LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
291 " CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
292 " SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
293 " INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
294 " CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
295 " ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
296 " POSSIBILITY OF SUCH DAMAGE.
297 "
298 "
299 " # Development
300 "
301 " ## Contributing patches
302 "
303 " Patches can be sent via mail to greg@hurrell.net, or as GitHub pull requests
304 " at: https://github.com/wincent/ferret/pulls
305 "
306 " ## Cutting a new release
307 "
308 " At the moment the release process is manual:
309 "
310 " - Perform final sanity checks and manual testing
311 " - Update the |ferret-history| section of the documentation
312 " - Verify clean work tree:
313 "
314 " ```
315 " git status
316 " ```
317 "
318 " - Tag the release:
319 "
320 " ```
321 " git tag -s -m "$VERSION release" $VERSION
322 " ```
323 "
324 " - Publish the code:
325 "
326 " ```
327 " git push origin master --follow-tags
328 " git push github master --follow-tags
329 " ```
330 "
331 " - Produce the release archive:
332 "
333 " ```
334 " git archive -o ferret-$VERSION.zip HEAD -- .
335 " ```
336 "
337 " - Upload to http://www.vim.org/scripts/script.php?script_id=5220
338 "
339 "
340 " # Authors
341 "
342 " Ferret is written and maintained by Greg Hurrell <greg@hurrell.net>.
343 "
344 " The idea for vim-dispatch integration was taken from Miles Sterrett's ack.vim
345 " plug-in (https://github.com/mileszs/ack.vim).
346 "
347 " Other contributors that have submitted patches include (in alphabetical
348 " order):
349 "
350 " - Daniel Silva
351 " - Joe Lencioni
352 " - Nelo-Thara Wallus
353 " - Vaibhav Sagar
354 "
355 "
356 " # History
357 "
358 " 0.3.1 (not yet released)
359 "
360 " - Fix broken |:Qargs| command (patch from Daniel Silva).
361 "
362 " 0.3 (24 July 2015)
363 "
364 " - Added highlighting of search pattern and related |g:FerretHlsearch| option
365 "   (patch from Nelo-Thara Wallus).
366 " - Add better error reporting for failed or incorrect searches.
367 "
368 " 0.2 (16 July 2015)
369 "
370 " - Added |FerretDidWrite| and |FerretWillWrite| autocommands (patch from Joe
371 "   Lencioni).
372 " - Add |<Plug>(FerretAcks)| mapping (patch from Nelo-Thara Wallus).
373 "
374 " 0.1 (8 July 2015)
375 "
376 " - Initial release, extracted from my dotfiles
377 "   (https://github.com/wincent/wincent).
378
379 ""
380 " @option g:FerretLoaded any
381 "
382 " To prevent Ferret from being loaded, set |g:FerretLoaded| to any value in your
383 " |.vimrc|. For example:
384 "
385 " ```
386 " let g:FerretLoaded=1
387 " ```
388 if exists('g:FerretLoaded') || &compatible || v:version < 700
389   finish
390 endif
391 let g:FerretLoaded = 1
392
393 " Temporarily set 'cpoptions' to Vim default as per `:h use-cpo-save`.
394 let s:cpoptions = &cpoptions
395 set cpoptions&vim
396
397 if executable('ag') " The Silver Searcher: faster than ack.
398   let s:ackprg = 'ag --column --nocolor --nogroup'
399 elseif executable('ack') " Ack: better than grep.
400   let s:ackprg = 'ack --column'
401 elseif executable('grep') " Grep: it's just grep.
402   let s:ackprg = &grepprg " default is: grep -n $* /dev/null
403 endif
404
405 if !empty(s:ackprg)
406   let &grepprg=s:ackprg
407   set grepformat=%f:%l:%c:%m
408 endif
409
410 if has('autocmd')
411   augroup Ferret
412     autocmd!
413     autocmd QuickFixCmdPost [^l]* nested cwindow
414     autocmd QuickFixCmdPost l* nested lwindow
415   augroup END
416 endif
417
418 ""
419 " @command :Ack {pattern} {options}
420 "
421 " Searches for {pattern} in all the files under the current directory (see
422 " |:pwd|), unless otherwise overridden via {options}, and displays the results
423 " in the |quickfix| listing.
424 "
425 " `ag` (The Silver Searcher) will be used preferentially if present on the
426 " system, because it is faster, falling back to `ack` and then `grep` as needed.
427 "
428 " If dispatch.vim is installed the search process will run asynchronously via
429 " the |:Make| command, otherwise it will be run synchronously via |:cexpr|.
430 " Asynchronous searches are preferred because they do not block, despite the
431 " fact that Vim itself is single threaded. The |g:FerretDispatch| option can be
432 " used to prevent the use of dispatch.vim.
433 "
434 " The {pattern} is passed through as-is to the underlying search program, and no
435 " escaping is required other than preceding spaces by a single backslash. For
436 " example, to search for "\bfoo[0-9]{2} bar\b" (ie. using `ag`'s Perl-style
437 " regular expression syntax), you could do:
438 "
439 " ```
440 " :Ack \bfoo[0-9]{2}\ bar\b
441 " ```
442 "
443 " Likewise, {options} are passed through. In this example, we pass the `-w`
444 " option (to search on word boundaries), and scope the search to the "foo" and
445 " "bar" subdirectories: >
446 "
447 " ```
448 " :Ack -w something foo bar
449 " ```
450 "
451 " As a convenience <leader>a is set-up (|<Plug>(FerretAck)|) as a shortcut to
452 " enter |Cmdline-mode| with `:Ack` inserted on the |Cmdline|. Likewise <leader>s
453 " (|<Plug>(FerretAckWord)|) is a shortcut for running |:Ack| with the word
454 " currently under the cursor.
455 command! -nargs=+ -complete=file Ack call ferret#private#ack(<q-args>)
456
457 ""
458 " @command :Lack {pattern} {options}
459 "
460 " Just like |:Ack|, but instead of using the |quickfix| listing, which is global
461 " across an entire Vim instance, it uses the |location-list|, which is a
462 " per-window construct.
463 "
464 " Note that |:Lack| always runs synchronously via |:cexpr|, because dispatch.vim
465 " doesn't currently support the |location-list|.
466 command! -nargs=+ -complete=file Lack call ferret#private#lack(<q-args>)
467
468 ""
469 " @command :Acks /{pattern}/{replacement}/
470 "
471 " Takes all of the files currently in the |quickfix| listing and performs a
472 " substitution of all instances of {pattern} (a standard Vim search |pattern|)
473 " by {replacement}.
474 "
475 " A typical sequence consists of an |:Ack| invocation to populate the |quickfix|
476 " listing and then |:Acks| (mnemonic: "Ack substitute") to perform replacements.
477 " For example, to replace "foo" with "bar" across all files in the current
478 " directory:
479 "
480 " ```
481 " :Ack foo
482 " :Acks /foo/bar/
483 " ```
484 command! -nargs=1 Acks call ferret#private#acks(<q-args>)
485
486 ""
487 " @option g:FerretMap boolean 1
488 "
489 " Controls whether to set up the Ferret mappings, such as |<Plug>(FerretAck)|
490 " (see |ferret-mappings| for a full list). To prevent any mapping from being
491 " configured, set to 0:
492 "
493 " ```
494 " let g:FerretMap=0
495 " ```
496 let s:map=get(g:, 'FerretMap', 1)
497 if s:map
498   if !hasmapto('<Plug>(FerretAck)') && maparg('<leader>a', 'n') ==# ''
499     ""
500     " @mapping <Plug>(FerretAck)
501     "
502     " Ferret maps <leader>a to |<Plug>(FerretAck)|, which triggers the |:Ack|
503     " command. To use an alternative mapping instead, create a different one in
504     " your |.vimrc| instead using |:nmap|:
505     "
506     " ```
507     " " Instead of <leader>a, use <leader>x.
508     " nmap <leader>x <Plug>(FerretAck)
509     " ```
510     nmap <unique> <leader>a <Plug>(FerretAck)
511   endif
512   nnoremap <Plug>(FerretAck) :Ack<space>
513
514   if !hasmapto('<Plug>FerretLack') && maparg('<leader>l', 'n') ==# ''
515     ""
516     " @mapping <Plug>(FerretLack)
517     "
518     " Ferret maps <leader>l to |<Plug>(FerretLack)|, which triggers the |:Lack|
519     " command. To use an alternative mapping instead, create a different one in
520     " your |.vimrc| instead using |:nmap|:
521     "
522     " ```
523     " " Instead of <leader>l, use <leader>y.
524     " nmap <leader>y <Plug>(FerretLack)
525     " ```
526     nmap <unique> <leader>l <Plug>(FerretLack)
527   endif
528   nnoremap <Plug>(FerretLack) :Lack<space>
529
530   if !hasmapto('<Plug>(FerretAckWord)') && maparg('<leader>s', 'n') ==# ''
531     " Call :Ack with word currently under cursor (mnemonic: selection).
532
533
534     ""
535     " @mapping <Plug>(FerretAckWord)
536     "
537     " Ferret maps <leader>s (mnemonix: "selection) to |<Plug>(FerretAckWord)|,
538     " which uses |:Ack| to search for the word currently under the cursor. To
539     " use an alternative mapping instead, create a different one in your
540     " |.vimrc| instead using |:nmap|:
541     "
542     " ```
543     " " Instead of <leader>s, use <leader>z.
544     " nmap <leader>z <Plug>(FerretAckWord)
545     " ```
546     nmap <unique> <leader>s <Plug>(FerretAckWord)
547   endif
548   nnoremap <Plug>(FerretAckWord) :Ack <C-r><C-w><CR>
549
550   if !hasmapto('<Plug>(FerretAcks)') && maparg('<leader>r', 'n') ==# ''
551     ""
552     " @mapping *<Plug>(FerretAcks)*
553     "
554     " Ferret maps <leader>r (mnemonic: "replace") to |<Plug>(FerretAcks)|, which
555     " triggers the |:Acks| command and fills the prompt with the last search
556     " term from Ferret. to use an alternative mapping instead, create a
557     " different one in your |.vimrc| instead using |:nmap|:
558     "
559     " ```
560     " " Instead of <leader>r, use <leader>u.
561     " nmap <leader>u <Plug>(FerretAcks)
562     " ```
563     nmap <unique> <leader>r <Plug>(FerretAcks)
564   endif
565   nnoremap <Plug>(FerretAcks)
566         \ :Acks <c-r>=(exists('g:ferret_lastsearch') ? '/' . g:ferret_lastsearch . '//' : ' ')<CR><Left>
567 endif
568
569 ""
570 " @command :Qargs
571 "
572 " This is a utility function that is used by the |:Acks| command but is also
573 " generally useful enough to warrant being exposed publicly.
574 "
575 " It takes the files currently in the |quickfix| listing and sets them as
576 " |:args| so that they can be operated on en masse via the |:argdo| command.
577 command! -bar Qargs execute 'args' ferret#private#qargs()
578
579 ""
580 " @option g:FerretQFCommands boolean 1
581 "
582 " Controls whether to set up custom versions of the |quickfix| commands, |:cn|,
583 " |:cnf|, |:cp| an |:cpf|. These overrides vertically center the match within
584 " the viewport on each jump. To prevent the custom versions from being
585 " configured, set to 0:
586 "
587 " ```
588 " let g:FerretQFCommands=0
589 " ```
590 let s:commands=get(g:, 'FerretQFCommands', 1)
591 if s:commands
592   " Keep quickfix result centered, if possible, when jumping from result to result.
593   cabbrev <silent> <expr> cn ((getcmdtype() == ':' && getcmdpos() == 3) ? 'cn <bar> normal zz' : 'cn')
594   cabbrev <silent> <expr> cnf ((getcmdtype() == ':' && getcmdpos() == 4) ? 'cnf <bar> normal zz' : 'cnf')
595   cabbrev <silent> <expr> cp ((getcmdtype() == ':' && getcmdpos() == 3) ? 'cp <bar> normal zz' : 'cp')
596   cabbrev <silent> <expr> cpf ((getcmdtype() == ':' && getcmdpos() == 4) ? 'cpf <bar> normal zz' : 'cpf')
597 endif
598
599 " Restore 'cpoptions' to its former value.
600 let &cpoptions = s:cpoptions
601 unlet s:cpoptions