--- /dev/null
+#!/bin/sh
+
+for TYPE in tests/fixtures/*; do
+ if [ $TYPE != "tests/fixtures/shared" ]; then
+ (
+ echo "In $TYPE:"
+ cd $TYPE
+ for TEST in ../shared/integration-*; do
+ echo "Linking: $TEST"
+ ln -sf $TEST
+ done
+ )
+ fi
+done
+++ /dev/null
-" Copyright 2015-present Greg Hurrell. All rights reserved.
-" Licensed under the terms of the BSD 2-clause license.
-
-""
-" @option g:FerretQFOptions boolean 1
-"
-" Controls whether to set up setting overrides for |quickfix| windows. These are
-" various settings, such as |norelativenumber|, |nolist| and |nowrap|, that are
-" intended to make the |quickfix| window, which is typically very small relative
-" to other windows, more usable.
-"
-" A full list of overridden settings can be found in |ferret-overrides|.
-"
-" To prevent the custom settings from being applied, set |g:FerretQFOptions|
-" to 0:
-"
-" ```
-" let g:FerretQFOptions=0
-" ```
-let s:options=get(g:, 'FerretQFOptions', 1)
-if s:options
- setlocal nolist
- if exists('+relativenumber')
- setlocal norelativenumber
- endif
- setlocal nowrap
- setlocal number
-
- " Want to set scrolloff only for the qf window, but it is a global option.
- let s:original_scrolloff=&scrolloff
- set scrolloff=0
-
- if has('autocmd')
- augroup FerretQF
- autocmd!
- autocmd BufLeave <buffer> execute 'set scrolloff=' . s:original_scrolloff
- autocmd BufEnter <buffer> set scrolloff=0 | setlocal nocursorline
- augroup END
- endif
-endif
-
-""
-" @option g:FerretQFMap boolean 1
-"
-" Controls whether to set up mappings in the |quickfix| results window for
-" deleting results. The mappings include:
-"
-" - `d` (|visual-mode|): delete visual selection
-" - `dd` (|Normal-mode|): delete current line
-" - `d`{motion} (|Normal-mode|): delete range indicated by {motion}
-"
-" To prevent these mappings from being set up, set to 0:
-"
-" ```
-" let g:FerretQFMap=0
-" ```
-let s:map=get(g:, 'FerretQFMap', 1)
-if s:map
- " Make it easy to remove entries from the quickfix listing.
- " TODO: distinguish between quickfix and location list
- nnoremap <buffer> <silent> d :set operatorfunc=ferret#private#qf_delete_motion<CR>g@
- nnoremap <buffer> <silent> dd :call ferret#private#qf_delete()<CR>
- vnoremap <buffer> <silent> d :call ferret#private#qf_delete()<CR>
-endif
--- /dev/null
+../shared/integration-ferret-ftplugin-qf.vim
\ No newline at end of file
+++ /dev/null
-" Copyright 2015-present Greg Hurrell. All rights reserved.
-" Licensed under the terms of the BSD 2-clause license.
-
-""
-" @plugin ferret Ferret plug-in for Vim
-"
-" # Intro
-"
-" > "ferret (verb)<br />
-" > (ferret something out) search tenaciously for and find something: she had
-" > the ability to ferret out the facts."
-"
-" *ferret-features*
-" Ferret improves Vim's multi-file search in four ways:
-"
-" ## 1. Powerful multi-file search
-"
-" Ferret provides an |:Ack| command for searching across multiple files using
-" The Silver Searcher (https://github.com/ggreer/the_silver_searcher), Ack
-" (http://beyondgrep.com/), or Grep (http://www.gnu.org/software/grep/). Support
-" for passing options through to the underlying search command exists, along
-" with the ability to use full regular expression syntax without doing special
-" escaping.
-"
-" Shortcut mappings are provided to start an |:Ack| search (<leader>a) or to
-" search for the word currently under the cursor (<leader>s).
-"
-" Results are normally displayed in the |quickfix| window, but Ferret also
-" provides a |:Lack| command that behaves like |:Ack| but uses the
-" |location-list| instead, and a <leader>l mapping as a shortcut to |:Lack|.
-"
-" Finally, Ferret offers integration with dispatch.vim
-" (https://github.com/tpope/vim-dispatch), which enables asynchronous searching
-" despite the fact that Vim itself is single-threaded.
-"
-" ## 2. Streamlined multi-file replace
-"
-" The companion to |:Ack| is |:Acks| (mnemonic: "Ack substitute", accessible via
-" shortcut <leader>r), which allows you to run a multi-file replace across all
-" the files placed in the |quickfix| window by a previous invocation of |:Ack|.
-"
-" ## 3. Quickfix listing enhancements
-"
-" The |quickfix| listing itself is enhanced with settings to improve its
-" usability, and natural mappings that allow quick removal of items from the
-" list (for example, you can reduce clutter in the listing by removing lines
-" that you don't intend to make changes to).
-"
-" Additionally, Vim's |:cn|, |:cp|, |:cnf| and |:cpf| commands are tweaked to
-" make it easier to immediately identify matches by centering them within the
-" viewport.
-"
-" ## 4. Easy operations on files in the quickfix listing
-"
-" Finally, Ferret provides a |:Qargs| command that puts the files currently in
-" the |quickfix| listing into the |:args| list, where they can be operated on in
-" bulk via the |:argdo| command. This is what's used under the covers by |:Acks|
-" to do its work.
-"
-"
-" # Installation
-"
-" To install Ferret, use your plug-in management system of choice.
-"
-" If you don't have a "plug-in management system of choice", I recommend
-" Pathogen (https://github.com/tpope/vim-pathogen) due to its simplicity and
-" robustness. Assuming that you have Pathogen installed and configured, and that
-" you want to install Ferret into `~/.vim/bundle`, you can do so with:
-"
-" ```
-" git clone https://github.com/wincent/ferret.git ~/.vim/bundle/ferret
-" ```
-"
-" Alternatively, if you use a Git submodule for each Vim plug-in, you could do
-" the following after `cd`-ing into the top-level of your Git superproject:
-"
-" ```
-" git submodule add https://github.com/wincent/ferret.git ~/vim/bundle/ferret
-" git submodule init
-" ```
-"
-" To generate help tags under Pathogen, you can do so from inside Vim with:
-"
-" ```
-" :call pathogen#helptags()
-" ```
-"
-" @mappings
-"
-" ## Circumstances where mappings do not get set up
-"
-" Note that Ferret will not try to set up the <leader> mappings if any of the
-" following are true:
-"
-" - A mapping for already exists.
-" - An alternative mapping for the same functionality has already been set up
-" from a |.vimrc|.
-" - The mapping has been suppressed by setting |g:FerretMap| to 1 in your
-" |.vimrc|.
-"
-" ## Mappings specific to the quickfix window
-"
-" Additionally, Ferret will set up special mappings in |quickfix| listings,
-" unless prevented from doing so by |g:FerretQFMap|:
-"
-" - `d` (|visual-mode|): delete visual selection
-" - `dd` (|Normal-mode|): delete current line
-" - `d`{motion} (|Normal-mode|): delete range indicated by {motion}
-"
-"
-" @footer
-"
-" # Custom autocommands
-"
-" *FerretWillWrite* *FerretDidWrite*
-" For maximum compatibility with other plug-ins, Ferret runs the following
-" "User" autocommands before and after running the file writing operations
-" during |:Acks|:
-"
-" - FerretWillWrite
-" - FerretDidWrite
-"
-" For example, to call a pair of custom functions in response to these events,
-" you might do:
-"
-" ```
-" autocmd! User FerretWillWrite
-" autocmd User FerretWillWrite call CustomWillWrite()
-" autocmd! User FerretDidWrite
-" autocmd User FerretDidWrite call CustomDidWrite()
-" ```
-"
-"
-" # Overrides
-"
-" Ferret overrides the 'grepformat' and 'grepprg' settings, preferentially
-" setting `ag`, `ack` or `grep` as the 'grepprg' (in that order) and configuring
-" a suitable 'grepformat'.
-"
-" Additionally, Ferret includes an |ftplugin| for the |quickfix| listing that
-" adjusts a number of settings to improve the usability of search results.
-"
-" @indent
-" *ferret-nolist*
-" 'nolist'
-"
-" Turned off to reduce visual clutter in the search results, and because
-" 'list' is most useful in files that are being actively edited, which is not
-" the case for |quickfix| results.
-"
-" *ferret-norelativenumber*
-" 'norelativenumber'
-"
-" Turned off, because it is more useful to have a sense of absolute progress
-" through the results list than to have the ability to jump to nearby results
-" (especially seeing as the most common operations are moving to the next or
-" previous file, which are both handled nicely by |:cnf| and |:cpf|
-" respectively).
-"
-" *ferret-nowrap*
-" 'nowrap'
-"
-" Turned off to avoid ugly wrapping that makes the results list hard to read,
-" and because in search results, the most relevant information is the
-" filename, which is on the left and is usually visible even without wrapping.
-"
-" *ferret-number*
-" 'number'
-"
-" Turned on to give a sense of absolute progress through the results.
-"
-" *ferret-scrolloff*
-" 'scrolloff'
-"
-" Set to 0 because the |quickfix| listing is usually small by default, so
-" trying to keep the current line away from the edge of the viewpoint is
-" futile; by definition it is usually near the edge.
-"
-" *ferret-nocursorline*
-" 'nocursorline'
-"
-" Turned off to reduce visual clutter.
-"
-" @dedent
-"
-" To prevent any of these |quickfix|-specific overrides from being set up, you
-" can set |g:FerretQFOptions| to 0 in your |.vimrc|:
-"
-" ```
-" let g:FerretQFOptions=0
-" ```
-"
-"
-" # Troubleshooting
-"
-" *ferret-quotes*
-" ## Ferret fails to find patterns containing spaces
-"
-" As described in the documentation for |:Ack|, the search pattern is passed
-" through as-is to the underlying search command, and no escaping is required
-" other than preceding spaces by a single backslash.
-"
-" So, to find "foo bar", you would search like:
-"
-" ```
-" :Ack foo\ bar
-" ```
-"
-" Unescaped spaces in the search are treated as argument separators, so a
-" command like the following means pass the `-w` option through, search for
-" pattern "foo", and limit search to the "bar" directory:
-"
-" ```
-" :Ack -w foo bar
-" ```
-"
-" Note that including quotes will not do what you intend.
-"
-" ```
-" " Search for '"foo' in the 'bar"' directory:
-" :Ack "foo bar"
-"
-" " Search for "'foo' in the "bar'" directory:
-" :Ack 'foo bar'
-" ```
-"
-" This approach to escaping is taken in order to make it straightfoward to use
-" powerful Perl-compatible regular expression syntax in an unambiguous way
-" without having to worry about shell escaping rules:
-"
-" ```
-" :Ack \blog\((['"]).*?\1\) -i --ignore-dir=src/vendor src dist build
-" ```
-"
-"
-" # FAQ
-"
-" ## Why do Ferret commands start with "Ack", "Lack" and so on?
-"
-" Ferret was originally the thinnest of wrappers (7 lines of code in my
-" |.vimrc|) around `ack`. The earliest traces of it can be seen in the initial
-" commit to my dotfiles repo in May, 2009 (https://wt.pe/h).
-"
-" So, even though Ferret has a new name now and actually prefers `ag` over `ack`
-" when available, I prefer to keep the command names intact and benefit from
-" years of accumulated muscle-memory.
-"
-"
-"
-" # Related
-"
-" Just as Ferret aims to improve the multi-file search and replace experience,
-" Loupe does the same for within-file searching:
-"
-" https://github.com/wincent/loupe
-"
-"
-" # Website
-"
-" The official Ferret source code repo is at:
-"
-" http://git.wincent.com/ferret.git
-"
-" A mirror exists at:
-"
-" https://github.com/wincent/ferret
-"
-" Official releases are listed at:
-"
-" http://www.vim.org/scripts/script.php?script_id=5220
-"
-"
-" # License
-"
-" Copyright 2015-present Greg Hurrell. All rights reserved.
-"
-" Redistribution and use in source and binary forms, with or without
-" modification, are permitted provided that the following conditions are met:
-"
-" 1. Redistributions of source code must retain the above copyright notice,
-" this list of conditions and the following disclaimer.
-" 2. Redistributions in binary form must reproduce the above copyright notice,
-" this list of conditions and the following disclaimer in the documentation
-" and/or other materials provided with the distribution.
-"
-" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-" ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
-" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-" POSSIBILITY OF SUCH DAMAGE.
-"
-"
-" # Development
-"
-" ## Contributing patches
-"
-" Patches can be sent via mail to greg@hurrell.net, or as GitHub pull requests
-" at: https://github.com/wincent/ferret/pulls
-"
-" ## Cutting a new release
-"
-" At the moment the release process is manual:
-"
-" - Perform final sanity checks and manual testing
-" - Update the |ferret-history| section of the documentation
-" - Verify clean work tree:
-"
-" ```
-" git status
-" ```
-"
-" - Tag the release:
-"
-" ```
-" git tag -s -m "$VERSION release" $VERSION
-" ```
-"
-" - Publish the code:
-"
-" ```
-" git push origin master --follow-tags
-" git push github master --follow-tags
-" ```
-"
-" - Produce the release archive:
-"
-" ```
-" git archive -o ferret-$VERSION.zip HEAD -- .
-" ```
-"
-" - Upload to http://www.vim.org/scripts/script.php?script_id=5220
-"
-"
-" # Authors
-"
-" Ferret is written and maintained by Greg Hurrell <greg@hurrell.net>.
-"
-" The idea for vim-dispatch integration was taken from Miles Sterrett's ack.vim
-" plug-in (https://github.com/mileszs/ack.vim).
-"
-" Other contributors that have submitted patches include (in alphabetical
-" order):
-"
-" - Daniel Silva
-" - Joe Lencioni
-" - Nelo-Thara Wallus
-" - Vaibhav Sagar
-"
-"
-" # History
-"
-" 0.3.1 (not yet released)
-"
-" - Fix broken |:Qargs| command (patch from Daniel Silva).
-"
-" 0.3 (24 July 2015)
-"
-" - Added highlighting of search pattern and related |g:FerretHlsearch| option
-" (patch from Nelo-Thara Wallus).
-" - Add better error reporting for failed or incorrect searches.
-"
-" 0.2 (16 July 2015)
-"
-" - Added |FerretDidWrite| and |FerretWillWrite| autocommands (patch from Joe
-" Lencioni).
-" - Add |<Plug>(FerretAcks)| mapping (patch from Nelo-Thara Wallus).
-"
-" 0.1 (8 July 2015)
-"
-" - Initial release, extracted from my dotfiles
-" (https://github.com/wincent/wincent).
-
-""
-" @option g:FerretLoaded any
-"
-" To prevent Ferret from being loaded, set |g:FerretLoaded| to any value in your
-" |.vimrc|. For example:
-"
-" ```
-" let g:FerretLoaded=1
-" ```
-if exists('g:FerretLoaded') || &compatible || v:version < 700
- finish
-endif
-let g:FerretLoaded = 1
-
-" Temporarily set 'cpoptions' to Vim default as per `:h use-cpo-save`.
-let s:cpoptions = &cpoptions
-set cpoptions&vim
-
-if executable('ag') " The Silver Searcher: faster than ack.
- let s:ackprg = 'ag --column --nocolor --nogroup'
-elseif executable('ack') " Ack: better than grep.
- let s:ackprg = 'ack --column'
-elseif executable('grep') " Grep: it's just grep.
- let s:ackprg = &grepprg " default is: grep -n $* /dev/null
-endif
-
-if !empty(s:ackprg)
- let &grepprg=s:ackprg
- set grepformat=%f:%l:%c:%m
-endif
-
-if has('autocmd')
- augroup Ferret
- autocmd!
- autocmd QuickFixCmdPost [^l]* nested cwindow
- autocmd QuickFixCmdPost l* nested lwindow
- augroup END
-endif
-
-""
-" @command :Ack {pattern} {options}
-"
-" Searches for {pattern} in all the files under the current directory (see
-" |:pwd|), unless otherwise overridden via {options}, and displays the results
-" in the |quickfix| listing.
-"
-" `ag` (The Silver Searcher) will be used preferentially if present on the
-" system, because it is faster, falling back to `ack` and then `grep` as needed.
-"
-" If dispatch.vim is installed the search process will run asynchronously via
-" the |:Make| command, otherwise it will be run synchronously via |:cexpr|.
-" Asynchronous searches are preferred because they do not block, despite the
-" fact that Vim itself is single threaded. The |g:FerretDispatch| option can be
-" used to prevent the use of dispatch.vim.
-"
-" The {pattern} is passed through as-is to the underlying search program, and no
-" escaping is required other than preceding spaces by a single backslash. For
-" example, to search for "\bfoo[0-9]{2} bar\b" (ie. using `ag`'s Perl-style
-" regular expression syntax), you could do:
-"
-" ```
-" :Ack \bfoo[0-9]{2}\ bar\b
-" ```
-"
-" Likewise, {options} are passed through. In this example, we pass the `-w`
-" option (to search on word boundaries), and scope the search to the "foo" and
-" "bar" subdirectories: >
-"
-" ```
-" :Ack -w something foo bar
-" ```
-"
-" As a convenience <leader>a is set-up (|<Plug>(FerretAck)|) as a shortcut to
-" enter |Cmdline-mode| with `:Ack` inserted on the |Cmdline|. Likewise <leader>s
-" (|<Plug>(FerretAckWord)|) is a shortcut for running |:Ack| with the word
-" currently under the cursor.
-command! -nargs=+ -complete=file Ack call ferret#private#ack(<q-args>)
-
-""
-" @command :Lack {pattern} {options}
-"
-" Just like |:Ack|, but instead of using the |quickfix| listing, which is global
-" across an entire Vim instance, it uses the |location-list|, which is a
-" per-window construct.
-"
-" Note that |:Lack| always runs synchronously via |:cexpr|, because dispatch.vim
-" doesn't currently support the |location-list|.
-command! -nargs=+ -complete=file Lack call ferret#private#lack(<q-args>)
-
-""
-" @command :Acks /{pattern}/{replacement}/
-"
-" Takes all of the files currently in the |quickfix| listing and performs a
-" substitution of all instances of {pattern} (a standard Vim search |pattern|)
-" by {replacement}.
-"
-" A typical sequence consists of an |:Ack| invocation to populate the |quickfix|
-" listing and then |:Acks| (mnemonic: "Ack substitute") to perform replacements.
-" For example, to replace "foo" with "bar" across all files in the current
-" directory:
-"
-" ```
-" :Ack foo
-" :Acks /foo/bar/
-" ```
-command! -nargs=1 Acks call ferret#private#acks(<q-args>)
-
-""
-" @option g:FerretMap boolean 1
-"
-" Controls whether to set up the Ferret mappings, such as |<Plug>(FerretAck)|
-" (see |ferret-mappings| for a full list). To prevent any mapping from being
-" configured, set to 0:
-"
-" ```
-" let g:FerretMap=0
-" ```
-let s:map=get(g:, 'FerretMap', 1)
-if s:map
- if !hasmapto('<Plug>(FerretAck)') && maparg('<leader>a', 'n') ==# ''
- ""
- " @mapping <Plug>(FerretAck)
- "
- " Ferret maps <leader>a to |<Plug>(FerretAck)|, which triggers the |:Ack|
- " command. To use an alternative mapping instead, create a different one in
- " your |.vimrc| instead using |:nmap|:
- "
- " ```
- " " Instead of <leader>a, use <leader>x.
- " nmap <leader>x <Plug>(FerretAck)
- " ```
- nmap <unique> <leader>a <Plug>(FerretAck)
- endif
- nnoremap <Plug>(FerretAck) :Ack<space>
-
- if !hasmapto('<Plug>FerretLack') && maparg('<leader>l', 'n') ==# ''
- ""
- " @mapping <Plug>(FerretLack)
- "
- " Ferret maps <leader>l to |<Plug>(FerretLack)|, which triggers the |:Lack|
- " command. To use an alternative mapping instead, create a different one in
- " your |.vimrc| instead using |:nmap|:
- "
- " ```
- " " Instead of <leader>l, use <leader>y.
- " nmap <leader>y <Plug>(FerretLack)
- " ```
- nmap <unique> <leader>l <Plug>(FerretLack)
- endif
- nnoremap <Plug>(FerretLack) :Lack<space>
-
- if !hasmapto('<Plug>(FerretAckWord)') && maparg('<leader>s', 'n') ==# ''
- " Call :Ack with word currently under cursor (mnemonic: selection).
-
-
- ""
- " @mapping <Plug>(FerretAckWord)
- "
- " Ferret maps <leader>s (mnemonix: "selection) to |<Plug>(FerretAckWord)|,
- " which uses |:Ack| to search for the word currently under the cursor. To
- " use an alternative mapping instead, create a different one in your
- " |.vimrc| instead using |:nmap|:
- "
- " ```
- " " Instead of <leader>s, use <leader>z.
- " nmap <leader>z <Plug>(FerretAckWord)
- " ```
- nmap <unique> <leader>s <Plug>(FerretAckWord)
- endif
- nnoremap <Plug>(FerretAckWord) :Ack <C-r><C-w><CR>
-
- if !hasmapto('<Plug>(FerretAcks)') && maparg('<leader>r', 'n') ==# ''
- ""
- " @mapping *<Plug>(FerretAcks)*
- "
- " Ferret maps <leader>r (mnemonic: "replace") to |<Plug>(FerretAcks)|, which
- " triggers the |:Acks| command and fills the prompt with the last search
- " term from Ferret. to use an alternative mapping instead, create a
- " different one in your |.vimrc| instead using |:nmap|:
- "
- " ```
- " " Instead of <leader>r, use <leader>u.
- " nmap <leader>u <Plug>(FerretAcks)
- " ```
- nmap <unique> <leader>r <Plug>(FerretAcks)
- endif
- nnoremap <Plug>(FerretAcks)
- \ :Acks <c-r>=(exists('g:ferret_lastsearch') ? '/' . g:ferret_lastsearch . '//' : ' ')<CR><Left>
-endif
-
-""
-" @command :Qargs
-"
-" This is a utility function that is used by the |:Acks| command but is also
-" generally useful enough to warrant being exposed publicly.
-"
-" It takes the files currently in the |quickfix| listing and sets them as
-" |:args| so that they can be operated on en masse via the |:argdo| command.
-command! -bar Qargs execute 'args' ferret#private#qargs()
-
-""
-" @option g:FerretQFCommands boolean 1
-"
-" Controls whether to set up custom versions of the |quickfix| commands, |:cn|,
-" |:cnf|, |:cp| an |:cpf|. These overrides vertically center the match within
-" the viewport on each jump. To prevent the custom versions from being
-" configured, set to 0:
-"
-" ```
-" let g:FerretQFCommands=0
-" ```
-let s:commands=get(g:, 'FerretQFCommands', 1)
-if s:commands
- " Keep quickfix result centered, if possible, when jumping from result to result.
- cabbrev <silent> <expr> cn ((getcmdtype() == ':' && getcmdpos() == 3) ? 'cn <bar> normal zz' : 'cn')
- cabbrev <silent> <expr> cnf ((getcmdtype() == ':' && getcmdpos() == 4) ? 'cnf <bar> normal zz' : 'cnf')
- cabbrev <silent> <expr> cp ((getcmdtype() == ':' && getcmdpos() == 3) ? 'cp <bar> normal zz' : 'cp')
- cabbrev <silent> <expr> cpf ((getcmdtype() == ':' && getcmdpos() == 4) ? 'cpf <bar> normal zz' : 'cpf')
-endif
-
-" Restore 'cpoptions' to its former value.
-let &cpoptions = s:cpoptions
-unlet s:cpoptions
--- /dev/null
+../shared/integration-ferret-plugin.vim
\ No newline at end of file
+++ /dev/null
-" Copyright 2015-present Greg Hurrell. All rights reserved.
-" Licensed under the terms of the BSD 2-clause license.
-
-" Remove lines a:first through a:last from the quickfix listing.
-function! s:delete(first, last)
- let l:list=getqflist()
- let l:line=a:first
-
- while l:line >= a:first && l:line <= a:last
- " Non-dictionary items will be ignored. This effectively deletes the line.
- let l:list[l:line - 1]=0
- let l:line=l:line + 1
- endwhile
- call setqflist(l:list, 'r')
-
- " Show to next entry.
- execute 'cc ' . a:first
-
- " Move focus back to quickfix listing.
- execute "normal \<C-W>\<C-P>"
-endfunction
-
-" Returns 1 if we should/can use vim-dispatch.
-function! s:dispatch()
- ""
- " @option g:FerretDispatch boolean 1
- "
- " Controls whether to use vim-dispatch (and specifically, |:Make|) to run
- " |:Ack| searches asynchronously, when available. To prevent vim-dispatch from
- " being used, set to 0:
- "
- " ```
- " let g:FerretDispatch=0
- " ```
- let l:dispatch=get(g:, 'FerretDispatch', 1)
- return l:dispatch && exists(':Make') == 2
-endfunction
-
-" Use `input()` to show error output to user. Ideally, we would do this in a way
-" that didn't require user interaction, but this is the only reliable mechanism
-" that works for all cases. Alternatives considered:
-"
-" (1) Using `:echomsg`
-"
-" When not using vim-dispatch, the screen is getting cleared before the
-" user sees it, even with a pre-emptive `:redraw!` beforehand. Note that
-" we can get the message to linger on the screen by making it multi-line and
-" forcing Vim to show a prompt (see `:h hit-enter-prompt`), but this is not
-" reliable because the number of lines required to force the prompt will
-" vary by system, depending on the value of `'cmdheight'`.
-"
-" When using vim-dispatch, anything we output ends up getting swallowed
-" before the user sees it, because something it is doing is clearing the
-" screen. This is true no matter how many lines we output.
-"
-" (2) Writing back into the quickfix/location list
-"
-" This interacts poorly with vim-dispatch. If we write back an error message
-" and then call `:copen 1`, vim-dispatch ends up closing the listing before
-" the user sees it.
-"
-" (3) Using `:echoerr`
-"
-" This works, but presents to the user as an exception (see `:h :echoerr`).
-"
-function! s:error(message) abort
- call inputsave()
- echohl ErrorMsg
- call input(a:message . ': press ENTER to continue')
- echohl NONE
- call inputrestore()
- echo
-endfunction
-
-" Parses arguments, extracting a search pattern (which is stored in
-" g:ferret_lastsearch) and escaping space-delimited arguments for use by
-" `system()`. A string containing all the escaped arguments is returned.
-"
-" The basic strategy is to split on spaces, expand wildcards for non-option
-" arguments, shellescape each word, and join.
-"
-" To support an edge-case (the ability to search for strings with spaces in
-" them, however, we swap out escaped spaces first (subsituting the unlikely
-" "<!!S!!>") and then swap them back in at the end. This allows us to perform
-" searches like:
-"
-" :Ack -i \bFoo_?Bar\b
-" :Ack that's\ nice\ dear
-"
-" and so on...
-function! s:parse(arg) abort
- if exists('g:ferret_lastsearch')
- unlet g:ferret_lastsearch
- endif
-
- let l:escaped_spaces_replaced_with_markers=substitute(a:arg, '\\ ', '<!!S!!>', 'g')
- let l:split_on_spaces=split(l:escaped_spaces_replaced_with_markers)
- let l:expanded_args=[]
-
- for l:arg in l:split_on_spaces
- if l:arg =~# '^-'
- " Options get passed through as-is.
- call add(l:expanded_args, l:arg)
- elseif exists('g:ferret_lastsearch')
- let l:file_args=glob(l:arg, 1, 1) " Ignore 'wildignore', return a list.
- if len(l:file_args)
- call extend(l:expanded_args, l:file_args)
- else
- " Let through to `ag`/`ack`/`grep`, which will throw ENOENT.
- call add(l:expanded_args, l:arg)
- endif
- else
- " First non-option arg is considered to be search pattern.
- let g:ferret_lastsearch=substitute(l:arg, '<!!S!!>', ' ', 'g')
- call add(l:expanded_args, l:arg)
- endif
- endfor
-
- let l:each_word_shell_escaped=map(l:expanded_args, 'shellescape(v:val)')
- let l:joined=join(l:each_word_shell_escaped)
- return substitute(l:joined, '<!!S!!>', ' ', 'g')
-endfunction
-
-function! ferret#private#post(type) abort
- if has('autocmd')
- augroup FerretPostQF
- autocmd!
- augroup END
- endif
-
- let l:lastsearch = get(g:, 'ferret_lastsearch', '')
- let l:qflist = a:type == 'qf' ? getqflist() : getloclist(0)
- let l:tip = ' [see `:help ferret-quotes`]'
- if len(l:qflist) == 0
- let l:base = 'No results for search pattern `' . l:lastsearch . '`'
-
- " Search pattern has no spaces and is entirely enclosed in quotes;
- " eg 'foo' or "bar"
- if l:lastsearch =~ '\v^([' . "'" . '"])[^ \1]+\1$'
- call s:error(l:base . l:tip)
- else
- call s:error(l:base)
- endif
- else
- " Find any "invalid" entries in the list.
- let l:invalid = filter(copy(l:qflist), 'v:val.valid == 0')
- if len(l:invalid) == len(l:qflist)
- " Every item in the list was invalid.
- redraw!
- echohl ErrorMsg
- for l:item in l:invalid
- echomsg l:item.text
- endfor
- echohl NONE
-
- let l:base = 'Search for `' . l:lastsearch . '` failed'
-
- " When using vim-dispatch, the messages printed above get cleared, so the
- " only way to see them is with `:messages`.
- let l:suffix = a:type == 'qf' && s:dispatch() ?
- \ ' (run `:messages` to see details)' :
- \ ''
-
- " If search pattern looks like `'foo` or `"bar`, it means the user
- " probably tried to search for 'foo bar' or "bar baz" etc.
- if l:lastsearch =~ '\v^[' . "'" . '"].+[^' . "'" . '"]$'
- call s:error(l:base . l:tip . l:suffix)
- else
- call s:error(l:base . l:suffix)
- endif
- endif
- endif
-endfunction
-
-function! ferret#private#ack(command) abort
- let l:command=s:parse(a:command)
- call ferret#private#hlsearch()
-
- if empty(&grepprg)
- return
- endif
-
- " Prefer vim-dispatch unless otherwise instructed.
- if s:dispatch()
- if has('autocmd')
- augroup FerretPostQF
- autocmd!
- autocmd QuickfixCmdPost cgetfile call ferret#private#post('qf')
- augroup END
- endif
- let l:original_makeprg=&l:makeprg
- let l:original_errorformat=&l:errorformat
- try
- let &l:makeprg=&grepprg . ' ' . l:command
- let &l:errorformat=&grepformat
- Make
- catch
- if has('autocmd')
- augroup! FerretPostQF
- endif
- finally
- let &l:makeprg=l:original_makeprg
- let &l:errorformat=l:original_errorformat
- endtry
- else
- cexpr system(&grepprg . ' ' . l:command)
- cwindow
- call ferret#private#post('qf')
- endif
-endfunction
-
-function! ferret#private#lack(command) abort
- let l:command=s:parse(a:command)
- call ferret#private#hlsearch()
-
- if empty(&grepprg)
- return
- endif
-
- lexpr system(&grepprg . ' ' . l:command)
- lwindow
- call ferret#private#post('location')
-endfunction
-
-function! ferret#private#hlsearch() abort
- if has('extra_search')
- ""
- " @option g:FerretHlsearch boolean
- "
- " Controls whether Ferret should attempt to highlight the search pattern
- " when running |:Ack| or |:Lack|. If left unset, Ferret will respect the
- " current 'hlsearch' setting. To force highlighting on or off irrespective
- " of 'hlsearch', set |g:FerretHlsearch| to 1 (on) or 0 (off):
- "
- " ```
- " let g:FerretHlsearch=0
- " ```
- let l:hlsearch=get(g:, 'FerretHlsearch', &hlsearch)
- if l:hlsearch
- let @/=g:ferret_lastsearch
- call feedkeys(":let &hlsearch=1 | echo \<CR>", 'n')
- endif
- endif
-endfunction
-
-" Run the specified substitution command on all the files in the quickfix list
-" (mnemonic: "Ack substitute").
-"
-" Specifically, the sequence:
-"
-" :Ack foo
-" :Acks /foo/bar/
-"
-" is equivalent to:
-"
-" :Ack foo
-" :Qargs
-" :argdo %s/foo/bar/ge | update
-"
-" (Note: there's nothing specific to Ack in this function; it's just named this
-" way for mnemonics, as it will most often be preceded by an :Ack invocation.)
-function! ferret#private#acks(command) abort
- if match(a:command, '\v^/.+/.*/$') == -1 " crude sanity check
- echoerr 'Ferret: Expected a substitution expression (/foo/bar/); got: ' . a:command
- return
- endif
-
- let l:filenames=ferret#private#qargs()
- if l:filenames ==# ''
- echoerr 'Ferret: Quickfix filenames must be present, but there are none'
- return
- endif
-
- execute 'args' l:filenames
-
- if v:version > 703 || v:version == 703 && has('patch438')
- silent doautocmd <nomodeline> User FerretWillWrite
- else
- silent doautocmd User FerretWillWrite
- endif
- execute 'argdo' '%s' . a:command . 'ge | update'
- if v:version > 703 || v:version == 703 && has('patch438')
- silent doautocmd <nomodeline> User FerretDidWrite
- else
- silent doautocmd User FerretDidWrite
- endif
-endfunction
-
-" Populate the :args list with the filenames currently in the quickfix window.
-function! ferret#private#qargs() abort
- let l:buffer_numbers={}
- for l:item in getqflist()
- let l:buffer_numbers[l:item['bufnr']]=bufname(l:item['bufnr'])
- endfor
- return join(map(values(l:buffer_numbers), 'fnameescape(v:val)'))
-endfunction
-
-" Visual mode deletion and `dd` mapping (special case).
-function! ferret#private#qf_delete() range
- call s:delete(a:firstline, a:lastline)
-endfunction
-
-" Motion-based deletion from quickfix listing.
-function! ferret#private#qf_delete_motion(type, ...)
- " Save.
- let l:selection=&selection
- let &selection='inclusive'
-
- let l:firstline=line("'[")
- let l:lastline=line("']")
- call s:delete(l:firstline, l:lastline)
-
- " Restore.
- let &selection=l:selection
-endfunction
--- /dev/null
+../shared/integration-ferret-private.vim
\ No newline at end of file
+++ /dev/null
-""
-" @plugin Pinnacle Highlight group manipulation for Vim
-"
-" # Intro
-"
-" Pinnacle provides functions for manipulating |:highlight| groups.
-"
-"
-" # Installation
-"
-" To install Pinnacle, use your plug-in management system of choice.
-"
-" If you don't have a "plug-in management system of choice", I recommend
-" Pathogen (https://github.com/tpope/vim-pathogen) due to its simplicity and
-" robustness. Assuming that you have Pathogen installed and configured, and that
-" you want to install vim-docvim into `~/.vim/bundle`, you can do so with:
-"
-" ```
-" git clone https://github.com/wincent/pinnacle.git ~/.vim/bundle/pinnacle
-" ```
-"
-" Alternatively, if you use a Git submodule for each Vim plug-in, you could do
-" the following after `cd`-ing into the top-level of your Git superproject:
-"
-" ```
-" git submodule add https://github.com/wincent/pinnacle.git ~/vim/bundle/pinnacle
-" git submodule init
-" ```
-"
-" To generate help tags under Pathogen, you can do so from inside Vim with:
-"
-" ```
-" :call pathogen#helptags()
-" ```
-"
-"
-" # Website
-"
-" The official Pinnacle source code repo is at:
-"
-" http://git.wincent.com/pinnacle.git
-"
-" Mirrors exist at:
-"
-" - https://github.com/wincent/pinnacle
-" - https://gitlab.com/wincent/pinnacle
-" - https://bitbucket.org/ghurrell/pinnacle
-"
-" Official releases are listed at:
-"
-" http://www.vim.org/scripts/script.php?script_id=[TODO]
-"
-"
-" # License
-"
-" Copyright (c) 2016-present Greg Hurrell
-"
-" Permission is hereby granted, free of charge, to any person obtaining
-" a copy of this software and associated documentation files (the
-" "Software"), to deal in the Software without restriction, including
-" without limitation the rights to use, copy, modify, merge, publish,
-" distribute, sublicense, and/or sell copies of the Software, and to
-" permit persons to whom the Software is furnished to do so, subject to
-" the following conditions:
-"
-" The above copyright notice and this permission notice shall be
-" included in all copies or substantial portions of the Software.
-"
-" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-" EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-" NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-" LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-" OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-" WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-"
-"
-" # Development
-"
-" ## Contributing patches
-"
-" Patches can be sent via mail to greg@hurrell.net, or as GitHub pull requests
-" at: https://github.com/wincent/pinnacle/pulls
-"
-" ## Cutting a new release
-"
-" At the moment the release process is manual:
-"
-" - Perform final sanity checks and manual testing
-" - Update the |pinnacle-history| section of the documentation
-" - Verify clean work tree:
-"
-" ```
-" git status
-" ```
-"
-" - Tag the release:
-"
-" ```
-" git tag -s -m "$VERSION release" $VERSION
-" ```
-"
-" - Publish the code:
-"
-" ```
-" git push origin master --follow-tags
-" git push github master --follow-tags
-" ```
-"
-" - Produce the release archive:
-"
-" ```
-" git archive -o vim-docvim-$VERSION.zip HEAD -- .
-" ```
-"
-" - Upload to http://www.vim.org/scripts/script.php?script_id=[TODO]
-"
-"
-" # Authors
-"
-" Pinnacle is written and maintained by Greg Hurrell <greg@hurrell.net>.
-"
-"
-" # History
-"
-" ## 0.1 (30 March 2016)
-"
-" - Initial release.
--- /dev/null
+../shared/integration-pinnacle.vim
\ No newline at end of file
--- /dev/null
+../shared/integration-docvim.vim
\ No newline at end of file
+++ /dev/null
-" Copyright 2015-present Greg Hurrell. All rights reserved.
-" Licensed under the terms of the BSD 2-clause license.
-
-""
-" @option g:FerretQFOptions boolean 1
-"
-" Controls whether to set up setting overrides for |quickfix| windows. These are
-" various settings, such as |norelativenumber|, |nolist| and |nowrap|, that are
-" intended to make the |quickfix| window, which is typically very small relative
-" to other windows, more usable.
-"
-" A full list of overridden settings can be found in |ferret-overrides|.
-"
-" To prevent the custom settings from being applied, set |g:FerretQFOptions|
-" to 0:
-"
-" ```
-" let g:FerretQFOptions=0
-" ```
-let s:options=get(g:, 'FerretQFOptions', 1)
-if s:options
- setlocal nolist
- if exists('+relativenumber')
- setlocal norelativenumber
- endif
- setlocal nowrap
- setlocal number
-
- " Want to set scrolloff only for the qf window, but it is a global option.
- let s:original_scrolloff=&scrolloff
- set scrolloff=0
-
- if has('autocmd')
- augroup FerretQF
- autocmd!
- autocmd BufLeave <buffer> execute 'set scrolloff=' . s:original_scrolloff
- autocmd BufEnter <buffer> set scrolloff=0 | setlocal nocursorline
- augroup END
- endif
-endif
-
-""
-" @option g:FerretQFMap boolean 1
-"
-" Controls whether to set up mappings in the |quickfix| results window for
-" deleting results. The mappings include:
-"
-" - `d` (|visual-mode|): delete visual selection
-" - `dd` (|Normal-mode|): delete current line
-" - `d`{motion} (|Normal-mode|): delete range indicated by {motion}
-"
-" To prevent these mappings from being set up, set to 0:
-"
-" ```
-" let g:FerretQFMap=0
-" ```
-let s:map=get(g:, 'FerretQFMap', 1)
-if s:map
- " Make it easy to remove entries from the quickfix listing.
- " TODO: distinguish between quickfix and location list
- nnoremap <buffer> <silent> d :set operatorfunc=ferret#private#qf_delete_motion<CR>g@
- nnoremap <buffer> <silent> dd :call ferret#private#qf_delete()<CR>
- vnoremap <buffer> <silent> d :call ferret#private#qf_delete()<CR>
-endif
--- /dev/null
+../shared/integration-ferret-ftplugin-qf.vim
\ No newline at end of file
+++ /dev/null
-" Copyright 2015-present Greg Hurrell. All rights reserved.
-" Licensed under the terms of the BSD 2-clause license.
-
-""
-" @plugin ferret Ferret plug-in for Vim
-"
-" # Intro
-"
-" > "ferret (verb)<br />
-" > (ferret something out) search tenaciously for and find something: she had
-" > the ability to ferret out the facts."
-"
-" *ferret-features*
-" Ferret improves Vim's multi-file search in four ways:
-"
-" ## 1. Powerful multi-file search
-"
-" Ferret provides an |:Ack| command for searching across multiple files using
-" The Silver Searcher (https://github.com/ggreer/the_silver_searcher), Ack
-" (http://beyondgrep.com/), or Grep (http://www.gnu.org/software/grep/). Support
-" for passing options through to the underlying search command exists, along
-" with the ability to use full regular expression syntax without doing special
-" escaping.
-"
-" Shortcut mappings are provided to start an |:Ack| search (<leader>a) or to
-" search for the word currently under the cursor (<leader>s).
-"
-" Results are normally displayed in the |quickfix| window, but Ferret also
-" provides a |:Lack| command that behaves like |:Ack| but uses the
-" |location-list| instead, and a <leader>l mapping as a shortcut to |:Lack|.
-"
-" Finally, Ferret offers integration with dispatch.vim
-" (https://github.com/tpope/vim-dispatch), which enables asynchronous searching
-" despite the fact that Vim itself is single-threaded.
-"
-" ## 2. Streamlined multi-file replace
-"
-" The companion to |:Ack| is |:Acks| (mnemonic: "Ack substitute", accessible via
-" shortcut <leader>r), which allows you to run a multi-file replace across all
-" the files placed in the |quickfix| window by a previous invocation of |:Ack|.
-"
-" ## 3. Quickfix listing enhancements
-"
-" The |quickfix| listing itself is enhanced with settings to improve its
-" usability, and natural mappings that allow quick removal of items from the
-" list (for example, you can reduce clutter in the listing by removing lines
-" that you don't intend to make changes to).
-"
-" Additionally, Vim's |:cn|, |:cp|, |:cnf| and |:cpf| commands are tweaked to
-" make it easier to immediately identify matches by centering them within the
-" viewport.
-"
-" ## 4. Easy operations on files in the quickfix listing
-"
-" Finally, Ferret provides a |:Qargs| command that puts the files currently in
-" the |quickfix| listing into the |:args| list, where they can be operated on in
-" bulk via the |:argdo| command. This is what's used under the covers by |:Acks|
-" to do its work.
-"
-"
-" # Installation
-"
-" To install Ferret, use your plug-in management system of choice.
-"
-" If you don't have a "plug-in management system of choice", I recommend
-" Pathogen (https://github.com/tpope/vim-pathogen) due to its simplicity and
-" robustness. Assuming that you have Pathogen installed and configured, and that
-" you want to install Ferret into `~/.vim/bundle`, you can do so with:
-"
-" ```
-" git clone https://github.com/wincent/ferret.git ~/.vim/bundle/ferret
-" ```
-"
-" Alternatively, if you use a Git submodule for each Vim plug-in, you could do
-" the following after `cd`-ing into the top-level of your Git superproject:
-"
-" ```
-" git submodule add https://github.com/wincent/ferret.git ~/vim/bundle/ferret
-" git submodule init
-" ```
-"
-" To generate help tags under Pathogen, you can do so from inside Vim with:
-"
-" ```
-" :call pathogen#helptags()
-" ```
-"
-" @mappings
-"
-" ## Circumstances where mappings do not get set up
-"
-" Note that Ferret will not try to set up the <leader> mappings if any of the
-" following are true:
-"
-" - A mapping for already exists.
-" - An alternative mapping for the same functionality has already been set up
-" from a |.vimrc|.
-" - The mapping has been suppressed by setting |g:FerretMap| to 1 in your
-" |.vimrc|.
-"
-" ## Mappings specific to the quickfix window
-"
-" Additionally, Ferret will set up special mappings in |quickfix| listings,
-" unless prevented from doing so by |g:FerretQFMap|:
-"
-" - `d` (|visual-mode|): delete visual selection
-" - `dd` (|Normal-mode|): delete current line
-" - `d`{motion} (|Normal-mode|): delete range indicated by {motion}
-"
-"
-" @footer
-"
-" # Custom autocommands
-"
-" *FerretWillWrite* *FerretDidWrite*
-" For maximum compatibility with other plug-ins, Ferret runs the following
-" "User" autocommands before and after running the file writing operations
-" during |:Acks|:
-"
-" - FerretWillWrite
-" - FerretDidWrite
-"
-" For example, to call a pair of custom functions in response to these events,
-" you might do:
-"
-" ```
-" autocmd! User FerretWillWrite
-" autocmd User FerretWillWrite call CustomWillWrite()
-" autocmd! User FerretDidWrite
-" autocmd User FerretDidWrite call CustomDidWrite()
-" ```
-"
-"
-" # Overrides
-"
-" Ferret overrides the 'grepformat' and 'grepprg' settings, preferentially
-" setting `ag`, `ack` or `grep` as the 'grepprg' (in that order) and configuring
-" a suitable 'grepformat'.
-"
-" Additionally, Ferret includes an |ftplugin| for the |quickfix| listing that
-" adjusts a number of settings to improve the usability of search results.
-"
-" @indent
-" *ferret-nolist*
-" 'nolist'
-"
-" Turned off to reduce visual clutter in the search results, and because
-" 'list' is most useful in files that are being actively edited, which is not
-" the case for |quickfix| results.
-"
-" *ferret-norelativenumber*
-" 'norelativenumber'
-"
-" Turned off, because it is more useful to have a sense of absolute progress
-" through the results list than to have the ability to jump to nearby results
-" (especially seeing as the most common operations are moving to the next or
-" previous file, which are both handled nicely by |:cnf| and |:cpf|
-" respectively).
-"
-" *ferret-nowrap*
-" 'nowrap'
-"
-" Turned off to avoid ugly wrapping that makes the results list hard to read,
-" and because in search results, the most relevant information is the
-" filename, which is on the left and is usually visible even without wrapping.
-"
-" *ferret-number*
-" 'number'
-"
-" Turned on to give a sense of absolute progress through the results.
-"
-" *ferret-scrolloff*
-" 'scrolloff'
-"
-" Set to 0 because the |quickfix| listing is usually small by default, so
-" trying to keep the current line away from the edge of the viewpoint is
-" futile; by definition it is usually near the edge.
-"
-" *ferret-nocursorline*
-" 'nocursorline'
-"
-" Turned off to reduce visual clutter.
-"
-" @dedent
-"
-" To prevent any of these |quickfix|-specific overrides from being set up, you
-" can set |g:FerretQFOptions| to 0 in your |.vimrc|:
-"
-" ```
-" let g:FerretQFOptions=0
-" ```
-"
-"
-" # Troubleshooting
-"
-" *ferret-quotes*
-" ## Ferret fails to find patterns containing spaces
-"
-" As described in the documentation for |:Ack|, the search pattern is passed
-" through as-is to the underlying search command, and no escaping is required
-" other than preceding spaces by a single backslash.
-"
-" So, to find "foo bar", you would search like:
-"
-" ```
-" :Ack foo\ bar
-" ```
-"
-" Unescaped spaces in the search are treated as argument separators, so a
-" command like the following means pass the `-w` option through, search for
-" pattern "foo", and limit search to the "bar" directory:
-"
-" ```
-" :Ack -w foo bar
-" ```
-"
-" Note that including quotes will not do what you intend.
-"
-" ```
-" " Search for '"foo' in the 'bar"' directory:
-" :Ack "foo bar"
-"
-" " Search for "'foo' in the "bar'" directory:
-" :Ack 'foo bar'
-" ```
-"
-" This approach to escaping is taken in order to make it straightfoward to use
-" powerful Perl-compatible regular expression syntax in an unambiguous way
-" without having to worry about shell escaping rules:
-"
-" ```
-" :Ack \blog\((['"]).*?\1\) -i --ignore-dir=src/vendor src dist build
-" ```
-"
-"
-" # FAQ
-"
-" ## Why do Ferret commands start with "Ack", "Lack" and so on?
-"
-" Ferret was originally the thinnest of wrappers (7 lines of code in my
-" |.vimrc|) around `ack`. The earliest traces of it can be seen in the initial
-" commit to my dotfiles repo in May, 2009 (https://wt.pe/h).
-"
-" So, even though Ferret has a new name now and actually prefers `ag` over `ack`
-" when available, I prefer to keep the command names intact and benefit from
-" years of accumulated muscle-memory.
-"
-"
-"
-" # Related
-"
-" Just as Ferret aims to improve the multi-file search and replace experience,
-" Loupe does the same for within-file searching:
-"
-" https://github.com/wincent/loupe
-"
-"
-" # Website
-"
-" The official Ferret source code repo is at:
-"
-" http://git.wincent.com/ferret.git
-"
-" A mirror exists at:
-"
-" https://github.com/wincent/ferret
-"
-" Official releases are listed at:
-"
-" http://www.vim.org/scripts/script.php?script_id=5220
-"
-"
-" # License
-"
-" Copyright 2015-present Greg Hurrell. All rights reserved.
-"
-" Redistribution and use in source and binary forms, with or without
-" modification, are permitted provided that the following conditions are met:
-"
-" 1. Redistributions of source code must retain the above copyright notice,
-" this list of conditions and the following disclaimer.
-" 2. Redistributions in binary form must reproduce the above copyright notice,
-" this list of conditions and the following disclaimer in the documentation
-" and/or other materials provided with the distribution.
-"
-" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-" ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
-" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-" POSSIBILITY OF SUCH DAMAGE.
-"
-"
-" # Development
-"
-" ## Contributing patches
-"
-" Patches can be sent via mail to greg@hurrell.net, or as GitHub pull requests
-" at: https://github.com/wincent/ferret/pulls
-"
-" ## Cutting a new release
-"
-" At the moment the release process is manual:
-"
-" - Perform final sanity checks and manual testing
-" - Update the |ferret-history| section of the documentation
-" - Verify clean work tree:
-"
-" ```
-" git status
-" ```
-"
-" - Tag the release:
-"
-" ```
-" git tag -s -m "$VERSION release" $VERSION
-" ```
-"
-" - Publish the code:
-"
-" ```
-" git push origin master --follow-tags
-" git push github master --follow-tags
-" ```
-"
-" - Produce the release archive:
-"
-" ```
-" git archive -o ferret-$VERSION.zip HEAD -- .
-" ```
-"
-" - Upload to http://www.vim.org/scripts/script.php?script_id=5220
-"
-"
-" # Authors
-"
-" Ferret is written and maintained by Greg Hurrell <greg@hurrell.net>.
-"
-" The idea for vim-dispatch integration was taken from Miles Sterrett's ack.vim
-" plug-in (https://github.com/mileszs/ack.vim).
-"
-" Other contributors that have submitted patches include (in alphabetical
-" order):
-"
-" - Daniel Silva
-" - Joe Lencioni
-" - Nelo-Thara Wallus
-" - Vaibhav Sagar
-"
-"
-" # History
-"
-" 0.3.1 (not yet released)
-"
-" - Fix broken |:Qargs| command (patch from Daniel Silva).
-"
-" 0.3 (24 July 2015)
-"
-" - Added highlighting of search pattern and related |g:FerretHlsearch| option
-" (patch from Nelo-Thara Wallus).
-" - Add better error reporting for failed or incorrect searches.
-"
-" 0.2 (16 July 2015)
-"
-" - Added |FerretDidWrite| and |FerretWillWrite| autocommands (patch from Joe
-" Lencioni).
-" - Add |<Plug>(FerretAcks)| mapping (patch from Nelo-Thara Wallus).
-"
-" 0.1 (8 July 2015)
-"
-" - Initial release, extracted from my dotfiles
-" (https://github.com/wincent/wincent).
-
-""
-" @option g:FerretLoaded any
-"
-" To prevent Ferret from being loaded, set |g:FerretLoaded| to any value in your
-" |.vimrc|. For example:
-"
-" ```
-" let g:FerretLoaded=1
-" ```
-if exists('g:FerretLoaded') || &compatible || v:version < 700
- finish
-endif
-let g:FerretLoaded = 1
-
-" Temporarily set 'cpoptions' to Vim default as per `:h use-cpo-save`.
-let s:cpoptions = &cpoptions
-set cpoptions&vim
-
-if executable('ag') " The Silver Searcher: faster than ack.
- let s:ackprg = 'ag --column --nocolor --nogroup'
-elseif executable('ack') " Ack: better than grep.
- let s:ackprg = 'ack --column'
-elseif executable('grep') " Grep: it's just grep.
- let s:ackprg = &grepprg " default is: grep -n $* /dev/null
-endif
-
-if !empty(s:ackprg)
- let &grepprg=s:ackprg
- set grepformat=%f:%l:%c:%m
-endif
-
-if has('autocmd')
- augroup Ferret
- autocmd!
- autocmd QuickFixCmdPost [^l]* nested cwindow
- autocmd QuickFixCmdPost l* nested lwindow
- augroup END
-endif
-
-""
-" @command :Ack {pattern} {options}
-"
-" Searches for {pattern} in all the files under the current directory (see
-" |:pwd|), unless otherwise overridden via {options}, and displays the results
-" in the |quickfix| listing.
-"
-" `ag` (The Silver Searcher) will be used preferentially if present on the
-" system, because it is faster, falling back to `ack` and then `grep` as needed.
-"
-" If dispatch.vim is installed the search process will run asynchronously via
-" the |:Make| command, otherwise it will be run synchronously via |:cexpr|.
-" Asynchronous searches are preferred because they do not block, despite the
-" fact that Vim itself is single threaded. The |g:FerretDispatch| option can be
-" used to prevent the use of dispatch.vim.
-"
-" The {pattern} is passed through as-is to the underlying search program, and no
-" escaping is required other than preceding spaces by a single backslash. For
-" example, to search for "\bfoo[0-9]{2} bar\b" (ie. using `ag`'s Perl-style
-" regular expression syntax), you could do:
-"
-" ```
-" :Ack \bfoo[0-9]{2}\ bar\b
-" ```
-"
-" Likewise, {options} are passed through. In this example, we pass the `-w`
-" option (to search on word boundaries), and scope the search to the "foo" and
-" "bar" subdirectories: >
-"
-" ```
-" :Ack -w something foo bar
-" ```
-"
-" As a convenience <leader>a is set-up (|<Plug>(FerretAck)|) as a shortcut to
-" enter |Cmdline-mode| with `:Ack` inserted on the |Cmdline|. Likewise <leader>s
-" (|<Plug>(FerretAckWord)|) is a shortcut for running |:Ack| with the word
-" currently under the cursor.
-command! -nargs=+ -complete=file Ack call ferret#private#ack(<q-args>)
-
-""
-" @command :Lack {pattern} {options}
-"
-" Just like |:Ack|, but instead of using the |quickfix| listing, which is global
-" across an entire Vim instance, it uses the |location-list|, which is a
-" per-window construct.
-"
-" Note that |:Lack| always runs synchronously via |:cexpr|, because dispatch.vim
-" doesn't currently support the |location-list|.
-command! -nargs=+ -complete=file Lack call ferret#private#lack(<q-args>)
-
-""
-" @command :Acks /{pattern}/{replacement}/
-"
-" Takes all of the files currently in the |quickfix| listing and performs a
-" substitution of all instances of {pattern} (a standard Vim search |pattern|)
-" by {replacement}.
-"
-" A typical sequence consists of an |:Ack| invocation to populate the |quickfix|
-" listing and then |:Acks| (mnemonic: "Ack substitute") to perform replacements.
-" For example, to replace "foo" with "bar" across all files in the current
-" directory:
-"
-" ```
-" :Ack foo
-" :Acks /foo/bar/
-" ```
-command! -nargs=1 Acks call ferret#private#acks(<q-args>)
-
-""
-" @option g:FerretMap boolean 1
-"
-" Controls whether to set up the Ferret mappings, such as |<Plug>(FerretAck)|
-" (see |ferret-mappings| for a full list). To prevent any mapping from being
-" configured, set to 0:
-"
-" ```
-" let g:FerretMap=0
-" ```
-let s:map=get(g:, 'FerretMap', 1)
-if s:map
- if !hasmapto('<Plug>(FerretAck)') && maparg('<leader>a', 'n') ==# ''
- ""
- " @mapping <Plug>(FerretAck)
- "
- " Ferret maps <leader>a to |<Plug>(FerretAck)|, which triggers the |:Ack|
- " command. To use an alternative mapping instead, create a different one in
- " your |.vimrc| instead using |:nmap|:
- "
- " ```
- " " Instead of <leader>a, use <leader>x.
- " nmap <leader>x <Plug>(FerretAck)
- " ```
- nmap <unique> <leader>a <Plug>(FerretAck)
- endif
- nnoremap <Plug>(FerretAck) :Ack<space>
-
- if !hasmapto('<Plug>FerretLack') && maparg('<leader>l', 'n') ==# ''
- ""
- " @mapping <Plug>(FerretLack)
- "
- " Ferret maps <leader>l to |<Plug>(FerretLack)|, which triggers the |:Lack|
- " command. To use an alternative mapping instead, create a different one in
- " your |.vimrc| instead using |:nmap|:
- "
- " ```
- " " Instead of <leader>l, use <leader>y.
- " nmap <leader>y <Plug>(FerretLack)
- " ```
- nmap <unique> <leader>l <Plug>(FerretLack)
- endif
- nnoremap <Plug>(FerretLack) :Lack<space>
-
- if !hasmapto('<Plug>(FerretAckWord)') && maparg('<leader>s', 'n') ==# ''
- " Call :Ack with word currently under cursor (mnemonic: selection).
-
-
- ""
- " @mapping <Plug>(FerretAckWord)
- "
- " Ferret maps <leader>s (mnemonix: "selection) to |<Plug>(FerretAckWord)|,
- " which uses |:Ack| to search for the word currently under the cursor. To
- " use an alternative mapping instead, create a different one in your
- " |.vimrc| instead using |:nmap|:
- "
- " ```
- " " Instead of <leader>s, use <leader>z.
- " nmap <leader>z <Plug>(FerretAckWord)
- " ```
- nmap <unique> <leader>s <Plug>(FerretAckWord)
- endif
- nnoremap <Plug>(FerretAckWord) :Ack <C-r><C-w><CR>
-
- if !hasmapto('<Plug>(FerretAcks)') && maparg('<leader>r', 'n') ==# ''
- ""
- " @mapping *<Plug>(FerretAcks)*
- "
- " Ferret maps <leader>r (mnemonic: "replace") to |<Plug>(FerretAcks)|, which
- " triggers the |:Acks| command and fills the prompt with the last search
- " term from Ferret. to use an alternative mapping instead, create a
- " different one in your |.vimrc| instead using |:nmap|:
- "
- " ```
- " " Instead of <leader>r, use <leader>u.
- " nmap <leader>u <Plug>(FerretAcks)
- " ```
- nmap <unique> <leader>r <Plug>(FerretAcks)
- endif
- nnoremap <Plug>(FerretAcks)
- \ :Acks <c-r>=(exists('g:ferret_lastsearch') ? '/' . g:ferret_lastsearch . '//' : ' ')<CR><Left>
-endif
-
-""
-" @command :Qargs
-"
-" This is a utility function that is used by the |:Acks| command but is also
-" generally useful enough to warrant being exposed publicly.
-"
-" It takes the files currently in the |quickfix| listing and sets them as
-" |:args| so that they can be operated on en masse via the |:argdo| command.
-command! -bar Qargs execute 'args' ferret#private#qargs()
-
-""
-" @option g:FerretQFCommands boolean 1
-"
-" Controls whether to set up custom versions of the |quickfix| commands, |:cn|,
-" |:cnf|, |:cp| an |:cpf|. These overrides vertically center the match within
-" the viewport on each jump. To prevent the custom versions from being
-" configured, set to 0:
-"
-" ```
-" let g:FerretQFCommands=0
-" ```
-let s:commands=get(g:, 'FerretQFCommands', 1)
-if s:commands
- " Keep quickfix result centered, if possible, when jumping from result to result.
- cabbrev <silent> <expr> cn ((getcmdtype() == ':' && getcmdpos() == 3) ? 'cn <bar> normal zz' : 'cn')
- cabbrev <silent> <expr> cnf ((getcmdtype() == ':' && getcmdpos() == 4) ? 'cnf <bar> normal zz' : 'cnf')
- cabbrev <silent> <expr> cp ((getcmdtype() == ':' && getcmdpos() == 3) ? 'cp <bar> normal zz' : 'cp')
- cabbrev <silent> <expr> cpf ((getcmdtype() == ':' && getcmdpos() == 4) ? 'cpf <bar> normal zz' : 'cpf')
-endif
-
-" Restore 'cpoptions' to its former value.
-let &cpoptions = s:cpoptions
-unlet s:cpoptions
--- /dev/null
+../shared/integration-ferret-plugin.vim
\ No newline at end of file
+++ /dev/null
-" Copyright 2015-present Greg Hurrell. All rights reserved.
-" Licensed under the terms of the BSD 2-clause license.
-
-" Remove lines a:first through a:last from the quickfix listing.
-function! s:delete(first, last)
- let l:list=getqflist()
- let l:line=a:first
-
- while l:line >= a:first && l:line <= a:last
- " Non-dictionary items will be ignored. This effectively deletes the line.
- let l:list[l:line - 1]=0
- let l:line=l:line + 1
- endwhile
- call setqflist(l:list, 'r')
-
- " Show to next entry.
- execute 'cc ' . a:first
-
- " Move focus back to quickfix listing.
- execute "normal \<C-W>\<C-P>"
-endfunction
-
-" Returns 1 if we should/can use vim-dispatch.
-function! s:dispatch()
- ""
- " @option g:FerretDispatch boolean 1
- "
- " Controls whether to use vim-dispatch (and specifically, |:Make|) to run
- " |:Ack| searches asynchronously, when available. To prevent vim-dispatch from
- " being used, set to 0:
- "
- " ```
- " let g:FerretDispatch=0
- " ```
- let l:dispatch=get(g:, 'FerretDispatch', 1)
- return l:dispatch && exists(':Make') == 2
-endfunction
-
-" Use `input()` to show error output to user. Ideally, we would do this in a way
-" that didn't require user interaction, but this is the only reliable mechanism
-" that works for all cases. Alternatives considered:
-"
-" (1) Using `:echomsg`
-"
-" When not using vim-dispatch, the screen is getting cleared before the
-" user sees it, even with a pre-emptive `:redraw!` beforehand. Note that
-" we can get the message to linger on the screen by making it multi-line and
-" forcing Vim to show a prompt (see `:h hit-enter-prompt`), but this is not
-" reliable because the number of lines required to force the prompt will
-" vary by system, depending on the value of `'cmdheight'`.
-"
-" When using vim-dispatch, anything we output ends up getting swallowed
-" before the user sees it, because something it is doing is clearing the
-" screen. This is true no matter how many lines we output.
-"
-" (2) Writing back into the quickfix/location list
-"
-" This interacts poorly with vim-dispatch. If we write back an error message
-" and then call `:copen 1`, vim-dispatch ends up closing the listing before
-" the user sees it.
-"
-" (3) Using `:echoerr`
-"
-" This works, but presents to the user as an exception (see `:h :echoerr`).
-"
-function! s:error(message) abort
- call inputsave()
- echohl ErrorMsg
- call input(a:message . ': press ENTER to continue')
- echohl NONE
- call inputrestore()
- echo
-endfunction
-
-" Parses arguments, extracting a search pattern (which is stored in
-" g:ferret_lastsearch) and escaping space-delimited arguments for use by
-" `system()`. A string containing all the escaped arguments is returned.
-"
-" The basic strategy is to split on spaces, expand wildcards for non-option
-" arguments, shellescape each word, and join.
-"
-" To support an edge-case (the ability to search for strings with spaces in
-" them, however, we swap out escaped spaces first (subsituting the unlikely
-" "<!!S!!>") and then swap them back in at the end. This allows us to perform
-" searches like:
-"
-" :Ack -i \bFoo_?Bar\b
-" :Ack that's\ nice\ dear
-"
-" and so on...
-function! s:parse(arg) abort
- if exists('g:ferret_lastsearch')
- unlet g:ferret_lastsearch
- endif
-
- let l:escaped_spaces_replaced_with_markers=substitute(a:arg, '\\ ', '<!!S!!>', 'g')
- let l:split_on_spaces=split(l:escaped_spaces_replaced_with_markers)
- let l:expanded_args=[]
-
- for l:arg in l:split_on_spaces
- if l:arg =~# '^-'
- " Options get passed through as-is.
- call add(l:expanded_args, l:arg)
- elseif exists('g:ferret_lastsearch')
- let l:file_args=glob(l:arg, 1, 1) " Ignore 'wildignore', return a list.
- if len(l:file_args)
- call extend(l:expanded_args, l:file_args)
- else
- " Let through to `ag`/`ack`/`grep`, which will throw ENOENT.
- call add(l:expanded_args, l:arg)
- endif
- else
- " First non-option arg is considered to be search pattern.
- let g:ferret_lastsearch=substitute(l:arg, '<!!S!!>', ' ', 'g')
- call add(l:expanded_args, l:arg)
- endif
- endfor
-
- let l:each_word_shell_escaped=map(l:expanded_args, 'shellescape(v:val)')
- let l:joined=join(l:each_word_shell_escaped)
- return substitute(l:joined, '<!!S!!>', ' ', 'g')
-endfunction
-
-function! ferret#private#post(type) abort
- if has('autocmd')
- augroup FerretPostQF
- autocmd!
- augroup END
- endif
-
- let l:lastsearch = get(g:, 'ferret_lastsearch', '')
- let l:qflist = a:type == 'qf' ? getqflist() : getloclist(0)
- let l:tip = ' [see `:help ferret-quotes`]'
- if len(l:qflist) == 0
- let l:base = 'No results for search pattern `' . l:lastsearch . '`'
-
- " Search pattern has no spaces and is entirely enclosed in quotes;
- " eg 'foo' or "bar"
- if l:lastsearch =~ '\v^([' . "'" . '"])[^ \1]+\1$'
- call s:error(l:base . l:tip)
- else
- call s:error(l:base)
- endif
- else
- " Find any "invalid" entries in the list.
- let l:invalid = filter(copy(l:qflist), 'v:val.valid == 0')
- if len(l:invalid) == len(l:qflist)
- " Every item in the list was invalid.
- redraw!
- echohl ErrorMsg
- for l:item in l:invalid
- echomsg l:item.text
- endfor
- echohl NONE
-
- let l:base = 'Search for `' . l:lastsearch . '` failed'
-
- " When using vim-dispatch, the messages printed above get cleared, so the
- " only way to see them is with `:messages`.
- let l:suffix = a:type == 'qf' && s:dispatch() ?
- \ ' (run `:messages` to see details)' :
- \ ''
-
- " If search pattern looks like `'foo` or `"bar`, it means the user
- " probably tried to search for 'foo bar' or "bar baz" etc.
- if l:lastsearch =~ '\v^[' . "'" . '"].+[^' . "'" . '"]$'
- call s:error(l:base . l:tip . l:suffix)
- else
- call s:error(l:base . l:suffix)
- endif
- endif
- endif
-endfunction
-
-function! ferret#private#ack(command) abort
- let l:command=s:parse(a:command)
- call ferret#private#hlsearch()
-
- if empty(&grepprg)
- return
- endif
-
- " Prefer vim-dispatch unless otherwise instructed.
- if s:dispatch()
- if has('autocmd')
- augroup FerretPostQF
- autocmd!
- autocmd QuickfixCmdPost cgetfile call ferret#private#post('qf')
- augroup END
- endif
- let l:original_makeprg=&l:makeprg
- let l:original_errorformat=&l:errorformat
- try
- let &l:makeprg=&grepprg . ' ' . l:command
- let &l:errorformat=&grepformat
- Make
- catch
- if has('autocmd')
- augroup! FerretPostQF
- endif
- finally
- let &l:makeprg=l:original_makeprg
- let &l:errorformat=l:original_errorformat
- endtry
- else
- cexpr system(&grepprg . ' ' . l:command)
- cwindow
- call ferret#private#post('qf')
- endif
-endfunction
-
-function! ferret#private#lack(command) abort
- let l:command=s:parse(a:command)
- call ferret#private#hlsearch()
-
- if empty(&grepprg)
- return
- endif
-
- lexpr system(&grepprg . ' ' . l:command)
- lwindow
- call ferret#private#post('location')
-endfunction
-
-function! ferret#private#hlsearch() abort
- if has('extra_search')
- ""
- " @option g:FerretHlsearch boolean
- "
- " Controls whether Ferret should attempt to highlight the search pattern
- " when running |:Ack| or |:Lack|. If left unset, Ferret will respect the
- " current 'hlsearch' setting. To force highlighting on or off irrespective
- " of 'hlsearch', set |g:FerretHlsearch| to 1 (on) or 0 (off):
- "
- " ```
- " let g:FerretHlsearch=0
- " ```
- let l:hlsearch=get(g:, 'FerretHlsearch', &hlsearch)
- if l:hlsearch
- let @/=g:ferret_lastsearch
- call feedkeys(":let &hlsearch=1 | echo \<CR>", 'n')
- endif
- endif
-endfunction
-
-" Run the specified substitution command on all the files in the quickfix list
-" (mnemonic: "Ack substitute").
-"
-" Specifically, the sequence:
-"
-" :Ack foo
-" :Acks /foo/bar/
-"
-" is equivalent to:
-"
-" :Ack foo
-" :Qargs
-" :argdo %s/foo/bar/ge | update
-"
-" (Note: there's nothing specific to Ack in this function; it's just named this
-" way for mnemonics, as it will most often be preceded by an :Ack invocation.)
-function! ferret#private#acks(command) abort
- if match(a:command, '\v^/.+/.*/$') == -1 " crude sanity check
- echoerr 'Ferret: Expected a substitution expression (/foo/bar/); got: ' . a:command
- return
- endif
-
- let l:filenames=ferret#private#qargs()
- if l:filenames ==# ''
- echoerr 'Ferret: Quickfix filenames must be present, but there are none'
- return
- endif
-
- execute 'args' l:filenames
-
- if v:version > 703 || v:version == 703 && has('patch438')
- silent doautocmd <nomodeline> User FerretWillWrite
- else
- silent doautocmd User FerretWillWrite
- endif
- execute 'argdo' '%s' . a:command . 'ge | update'
- if v:version > 703 || v:version == 703 && has('patch438')
- silent doautocmd <nomodeline> User FerretDidWrite
- else
- silent doautocmd User FerretDidWrite
- endif
-endfunction
-
-" Populate the :args list with the filenames currently in the quickfix window.
-function! ferret#private#qargs() abort
- let l:buffer_numbers={}
- for l:item in getqflist()
- let l:buffer_numbers[l:item['bufnr']]=bufname(l:item['bufnr'])
- endfor
- return join(map(values(l:buffer_numbers), 'fnameescape(v:val)'))
-endfunction
-
-" Visual mode deletion and `dd` mapping (special case).
-function! ferret#private#qf_delete() range
- call s:delete(a:firstline, a:lastline)
-endfunction
-
-" Motion-based deletion from quickfix listing.
-function! ferret#private#qf_delete_motion(type, ...)
- " Save.
- let l:selection=&selection
- let &selection='inclusive'
-
- let l:firstline=line("'[")
- let l:lastline=line("']")
- call s:delete(l:firstline, l:lastline)
-
- " Restore.
- let &selection=l:selection
-endfunction
--- /dev/null
+../shared/integration-ferret-private.vim
\ No newline at end of file
--- /dev/null
+Unit
+ [ DocBlock
+ [ PluginAnnotation
+ "Pinnacle" "Highlight group manipulation for Vim"
+ , HeadingAnnotation "Intro"
+ , Paragraph
+ [ Plaintext "Pinnacle"
+ , Whitespace
+ , Plaintext "provides"
+ , Whitespace
+ , Plaintext "functions"
+ , Whitespace
+ , Plaintext "for"
+ , Whitespace
+ , Plaintext "manipulating"
+ , Whitespace
+ , Link ":highlight"
+ , Whitespace
+ , Plaintext "groups."
+ ]
+ , HeadingAnnotation "Installation"
+ , Paragraph
+ [ Plaintext "To"
+ , Whitespace
+ , Plaintext "install"
+ , Whitespace
+ , Plaintext "Pinnacle,"
+ , Whitespace
+ , Plaintext "use"
+ , Whitespace
+ , Plaintext "your"
+ , Whitespace
+ , Plaintext "plug-in"
+ , Whitespace
+ , Plaintext "management"
+ , Whitespace
+ , Plaintext "system"
+ , Whitespace
+ , Plaintext "of"
+ , Whitespace
+ , Plaintext "choice."
+ ]
+ , Paragraph
+ [ Plaintext "If"
+ , Whitespace
+ , Plaintext "you"
+ , Whitespace
+ , Plaintext "don't"
+ , Whitespace
+ , Plaintext "have"
+ , Whitespace
+ , Plaintext "a"
+ , Whitespace
+ , Plaintext "\"plug-in"
+ , Whitespace
+ , Plaintext "management"
+ , Whitespace
+ , Plaintext "system"
+ , Whitespace
+ , Plaintext "of"
+ , Whitespace
+ , Plaintext "choice\","
+ , Whitespace
+ , Plaintext "I"
+ , Whitespace
+ , Plaintext "recommend"
+ , Whitespace
+ , Plaintext "Pathogen"
+ , Whitespace
+ , Plaintext "(https://github.com/tpope/vim-pathogen)"
+ , Whitespace
+ , Plaintext "due"
+ , Whitespace
+ , Plaintext "to"
+ , Whitespace
+ , Plaintext "its"
+ , Whitespace
+ , Plaintext "simplicity"
+ , Whitespace
+ , Plaintext "and"
+ , Whitespace
+ , Plaintext "robustness."
+ , Whitespace
+ , Plaintext "Assuming"
+ , Whitespace
+ , Plaintext "that"
+ , Whitespace
+ , Plaintext "you"
+ , Whitespace
+ , Plaintext "have"
+ , Whitespace
+ , Plaintext "Pathogen"
+ , Whitespace
+ , Plaintext "installed"
+ , Whitespace
+ , Plaintext "and"
+ , Whitespace
+ , Plaintext "configured,"
+ , Whitespace
+ , Plaintext "and"
+ , Whitespace
+ , Plaintext "that"
+ , Whitespace
+ , Plaintext "you"
+ , Whitespace
+ , Plaintext "want"
+ , Whitespace
+ , Plaintext "to"
+ , Whitespace
+ , Plaintext "install"
+ , Whitespace
+ , Plaintext "vim-docvim"
+ , Whitespace
+ , Plaintext "into"
+ , Whitespace
+ , Code "~/.vim/bundle"
+ , Plaintext ","
+ , Whitespace
+ , Plaintext "you"
+ , Whitespace
+ , Plaintext "can"
+ , Whitespace
+ , Plaintext "do"
+ , Whitespace
+ , Plaintext "so"
+ , Whitespace
+ , Plaintext "with:"
+ ]
+ , Fenced
+ [ "git clone https://github.com/wincent/pinnacle.git ~/.vim/bundle/pinnacle"
+ ]
+ , Paragraph
+ [ Plaintext "Alternatively,"
+ , Whitespace
+ , Plaintext "if"
+ , Whitespace
+ , Plaintext "you"
+ , Whitespace
+ , Plaintext "use"
+ , Whitespace
+ , Plaintext "a"
+ , Whitespace
+ , Plaintext "Git"
+ , Whitespace
+ , Plaintext "submodule"
+ , Whitespace
+ , Plaintext "for"
+ , Whitespace
+ , Plaintext "each"
+ , Whitespace
+ , Plaintext "Vim"
+ , Whitespace
+ , Plaintext "plug-in,"
+ , Whitespace
+ , Plaintext "you"
+ , Whitespace
+ , Plaintext "could"
+ , Whitespace
+ , Plaintext "do"
+ , Whitespace
+ , Plaintext "the"
+ , Whitespace
+ , Plaintext "following"
+ , Whitespace
+ , Plaintext "after"
+ , Whitespace
+ , Code "cd"
+ , Plaintext "-ing"
+ , Whitespace
+ , Plaintext "into"
+ , Whitespace
+ , Plaintext "the"
+ , Whitespace
+ , Plaintext "top-level"
+ , Whitespace
+ , Plaintext "of"
+ , Whitespace
+ , Plaintext "your"
+ , Whitespace
+ , Plaintext "Git"
+ , Whitespace
+ , Plaintext "superproject:"
+ ]
+ , Fenced
+ [ "git submodule add https://github.com/wincent/pinnacle.git ~/vim/bundle/pinnacle"
+ , "git submodule init"
+ ]
+ , Paragraph
+ [ Plaintext "To"
+ , Whitespace
+ , Plaintext "generate"
+ , Whitespace
+ , Plaintext "help"
+ , Whitespace
+ , Plaintext "tags"
+ , Whitespace
+ , Plaintext "under"
+ , Whitespace
+ , Plaintext "Pathogen,"
+ , Whitespace
+ , Plaintext "you"
+ , Whitespace
+ , Plaintext "can"
+ , Whitespace
+ , Plaintext "do"
+ , Whitespace
+ , Plaintext "so"
+ , Whitespace
+ , Plaintext "from"
+ , Whitespace
+ , Plaintext "inside"
+ , Whitespace
+ , Plaintext "Vim"
+ , Whitespace
+ , Plaintext "with:"
+ ]
+ , Fenced [ ":call pathogen#helptags()" ]
+ , HeadingAnnotation "Website"
+ , Paragraph
+ [ Plaintext "The"
+ , Whitespace
+ , Plaintext "official"
+ , Whitespace
+ , Plaintext "Pinnacle"
+ , Whitespace
+ , Plaintext "source"
+ , Whitespace
+ , Plaintext "code"
+ , Whitespace
+ , Plaintext "repo"
+ , Whitespace
+ , Plaintext "is"
+ , Whitespace
+ , Plaintext "at:"
+ ]
+ , Paragraph [ Plaintext "http://git.wincent.com/pinnacle.git" ]
+ , Paragraph
+ [ Plaintext "Mirrors"
+ , Whitespace
+ , Plaintext "exist"
+ , Whitespace
+ , Plaintext "at:"
+ ]
+ , List
+ [ ListItem [ Plaintext "https://github.com/wincent/pinnacle" ]
+ , ListItem [ Plaintext "https://gitlab.com/wincent/pinnacle" ]
+ , ListItem [ Plaintext "https://bitbucket.org/ghurrell/pinnacle" ]
+ ]
+ , Paragraph
+ [ Plaintext "Official"
+ , Whitespace
+ , Plaintext "releases"
+ , Whitespace
+ , Plaintext "are"
+ , Whitespace
+ , Plaintext "listed"
+ , Whitespace
+ , Plaintext "at:"
+ ]
+ , Paragraph
+ [ Plaintext
+ "http://www.vim.org/scripts/script.php?script_id=[TODO]"
+ ]
+ , HeadingAnnotation "License"
+ , Paragraph
+ [ Plaintext "Copyright"
+ , Whitespace
+ , Plaintext "(c)"
+ , Whitespace
+ , Plaintext "2016-present"
+ , Whitespace
+ , Plaintext "Greg"
+ , Whitespace
+ , Plaintext "Hurrell"
+ ]
+ , Paragraph
+ [ Plaintext "Permission"
+ , Whitespace
+ , Plaintext "is"
+ , Whitespace
+ , Plaintext "hereby"
+ , Whitespace
+ , Plaintext "granted,"
+ , Whitespace
+ , Plaintext "free"
+ , Whitespace
+ , Plaintext "of"
+ , Whitespace
+ , Plaintext "charge,"
+ , Whitespace
+ , Plaintext "to"
+ , Whitespace
+ , Plaintext "any"
+ , Whitespace
+ , Plaintext "person"
+ , Whitespace
+ , Plaintext "obtaining"
+ , Whitespace
+ , Plaintext "a"
+ , Whitespace
+ , Plaintext "copy"
+ , Whitespace
+ , Plaintext "of"
+ , Whitespace
+ , Plaintext "this"
+ , Whitespace
+ , Plaintext "software"
+ , Whitespace
+ , Plaintext "and"
+ , Whitespace
+ , Plaintext "associated"
+ , Whitespace
+ , Plaintext "documentation"
+ , Whitespace
+ , Plaintext "files"
+ , Whitespace
+ , Plaintext "(the"
+ , Whitespace
+ , Plaintext "\"Software\"),"
+ , Whitespace
+ , Plaintext "to"
+ , Whitespace
+ , Plaintext "deal"
+ , Whitespace
+ , Plaintext "in"
+ , Whitespace
+ , Plaintext "the"
+ , Whitespace
+ , Plaintext "Software"
+ , Whitespace
+ , Plaintext "without"
+ , Whitespace
+ , Plaintext "restriction,"
+ , Whitespace
+ , Plaintext "including"
+ , Whitespace
+ , Plaintext "without"
+ , Whitespace
+ , Plaintext "limitation"
+ , Whitespace
+ , Plaintext "the"
+ , Whitespace
+ , Plaintext "rights"
+ , Whitespace
+ , Plaintext "to"
+ , Whitespace
+ , Plaintext "use,"
+ , Whitespace
+ , Plaintext "copy,"
+ , Whitespace
+ , Plaintext "modify,"
+ , Whitespace
+ , Plaintext "merge,"
+ , Whitespace
+ , Plaintext "publish,"
+ , Whitespace
+ , Plaintext "distribute,"
+ , Whitespace
+ , Plaintext "sublicense,"
+ , Whitespace
+ , Plaintext "and/or"
+ , Whitespace
+ , Plaintext "sell"
+ , Whitespace
+ , Plaintext "copies"
+ , Whitespace
+ , Plaintext "of"
+ , Whitespace
+ , Plaintext "the"
+ , Whitespace
+ , Plaintext "Software,"
+ , Whitespace
+ , Plaintext "and"
+ , Whitespace
+ , Plaintext "to"
+ , Whitespace
+ , Plaintext "permit"
+ , Whitespace
+ , Plaintext "persons"
+ , Whitespace
+ , Plaintext "to"
+ , Whitespace
+ , Plaintext "whom"
+ , Whitespace
+ , Plaintext "the"
+ , Whitespace
+ , Plaintext "Software"
+ , Whitespace
+ , Plaintext "is"
+ , Whitespace
+ , Plaintext "furnished"
+ , Whitespace
+ , Plaintext "to"
+ , Whitespace
+ , Plaintext "do"
+ , Whitespace
+ , Plaintext "so,"
+ , Whitespace
+ , Plaintext "subject"
+ , Whitespace
+ , Plaintext "to"
+ , Whitespace
+ , Plaintext "the"
+ , Whitespace
+ , Plaintext "following"
+ , Whitespace
+ , Plaintext "conditions:"
+ ]
+ , Paragraph
+ [ Plaintext "The"
+ , Whitespace
+ , Plaintext "above"
+ , Whitespace
+ , Plaintext "copyright"
+ , Whitespace
+ , Plaintext "notice"
+ , Whitespace
+ , Plaintext "and"
+ , Whitespace
+ , Plaintext "this"
+ , Whitespace
+ , Plaintext "permission"
+ , Whitespace
+ , Plaintext "notice"
+ , Whitespace
+ , Plaintext "shall"
+ , Whitespace
+ , Plaintext "be"
+ , Whitespace
+ , Plaintext "included"
+ , Whitespace
+ , Plaintext "in"
+ , Whitespace
+ , Plaintext "all"
+ , Whitespace
+ , Plaintext "copies"
+ , Whitespace
+ , Plaintext "or"
+ , Whitespace
+ , Plaintext "substantial"
+ , Whitespace
+ , Plaintext "portions"
+ , Whitespace
+ , Plaintext "of"
+ , Whitespace
+ , Plaintext "the"
+ , Whitespace
+ , Plaintext "Software."
+ ]
+ , Paragraph
+ [ Plaintext "THE"
+ , Whitespace
+ , Plaintext "SOFTWARE"
+ , Whitespace
+ , Plaintext "IS"
+ , Whitespace
+ , Plaintext "PROVIDED"
+ , Whitespace
+ , Plaintext "\"AS"
+ , Whitespace
+ , Plaintext "IS\","
+ , Whitespace
+ , Plaintext "WITHOUT"
+ , Whitespace
+ , Plaintext "WARRANTY"
+ , Whitespace
+ , Plaintext "OF"
+ , Whitespace
+ , Plaintext "ANY"
+ , Whitespace
+ , Plaintext "KIND,"
+ , Whitespace
+ , Plaintext "EXPRESS"
+ , Whitespace
+ , Plaintext "OR"
+ , Whitespace
+ , Plaintext "IMPLIED,"
+ , Whitespace
+ , Plaintext "INCLUDING"
+ , Whitespace
+ , Plaintext "BUT"
+ , Whitespace
+ , Plaintext "NOT"
+ , Whitespace
+ , Plaintext "LIMITED"
+ , Whitespace
+ , Plaintext "TO"
+ , Whitespace
+ , Plaintext "THE"
+ , Whitespace
+ , Plaintext "WARRANTIES"
+ , Whitespace
+ , Plaintext "OF"
+ , Whitespace
+ , Plaintext "MERCHANTABILITY,"
+ , Whitespace
+ , Plaintext "FITNESS"
+ , Whitespace
+ , Plaintext "FOR"
+ , Whitespace
+ , Plaintext "A"
+ , Whitespace
+ , Plaintext "PARTICULAR"
+ , Whitespace
+ , Plaintext "PURPOSE"
+ , Whitespace
+ , Plaintext "AND"
+ , Whitespace
+ , Plaintext "NONINFRINGEMENT."
+ , Whitespace
+ , Plaintext "IN"
+ , Whitespace
+ , Plaintext "NO"
+ , Whitespace
+ , Plaintext "EVENT"
+ , Whitespace
+ , Plaintext "SHALL"
+ , Whitespace
+ , Plaintext "THE"
+ , Whitespace
+ , Plaintext "AUTHORS"
+ , Whitespace
+ , Plaintext "OR"
+ , Whitespace
+ , Plaintext "COPYRIGHT"
+ , Whitespace
+ , Plaintext "HOLDERS"
+ , Whitespace
+ , Plaintext "BE"
+ , Whitespace
+ , Plaintext "LIABLE"
+ , Whitespace
+ , Plaintext "FOR"
+ , Whitespace
+ , Plaintext "ANY"
+ , Whitespace
+ , Plaintext "CLAIM,"
+ , Whitespace
+ , Plaintext "DAMAGES"
+ , Whitespace
+ , Plaintext "OR"
+ , Whitespace
+ , Plaintext "OTHER"
+ , Whitespace
+ , Plaintext "LIABILITY,"
+ , Whitespace
+ , Plaintext "WHETHER"
+ , Whitespace
+ , Plaintext "IN"
+ , Whitespace
+ , Plaintext "AN"
+ , Whitespace
+ , Plaintext "ACTION"
+ , Whitespace
+ , Plaintext "OF"
+ , Whitespace
+ , Plaintext "CONTRACT,"
+ , Whitespace
+ , Plaintext "TORT"
+ , Whitespace
+ , Plaintext "OR"
+ , Whitespace
+ , Plaintext "OTHERWISE,"
+ , Whitespace
+ , Plaintext "ARISING"
+ , Whitespace
+ , Plaintext "FROM,"
+ , Whitespace
+ , Plaintext "OUT"
+ , Whitespace
+ , Plaintext "OF"
+ , Whitespace
+ , Plaintext "OR"
+ , Whitespace
+ , Plaintext "IN"
+ , Whitespace
+ , Plaintext "CONNECTION"
+ , Whitespace
+ , Plaintext "WITH"
+ , Whitespace
+ , Plaintext "THE"
+ , Whitespace
+ , Plaintext "SOFTWARE"
+ , Whitespace
+ , Plaintext "OR"
+ , Whitespace
+ , Plaintext "THE"
+ , Whitespace
+ , Plaintext "USE"
+ , Whitespace
+ , Plaintext "OR"
+ , Whitespace
+ , Plaintext "OTHER"
+ , Whitespace
+ , Plaintext "DEALINGS"
+ , Whitespace
+ , Plaintext "IN"
+ , Whitespace
+ , Plaintext "THE"
+ , Whitespace
+ , Plaintext "SOFTWARE."
+ ]
+ , HeadingAnnotation "Development"
+ , SubheadingAnnotation "Contributing patches"
+ , Paragraph
+ [ Plaintext "Patches"
+ , Whitespace
+ , Plaintext "can"
+ , Whitespace
+ , Plaintext "be"
+ , Whitespace
+ , Plaintext "sent"
+ , Whitespace
+ , Plaintext "via"
+ , Whitespace
+ , Plaintext "mail"
+ , Whitespace
+ , Plaintext "to"
+ , Whitespace
+ , Plaintext "greg@hurrell.net,"
+ , Whitespace
+ , Plaintext "or"
+ , Whitespace
+ , Plaintext "as"
+ , Whitespace
+ , Plaintext "GitHub"
+ , Whitespace
+ , Plaintext "pull"
+ , Whitespace
+ , Plaintext "requests"
+ , Whitespace
+ , Plaintext "at:"
+ , Whitespace
+ , Plaintext "https://github.com/wincent/pinnacle/pulls"
+ ]
+ , SubheadingAnnotation "Cutting a new release"
+ , Paragraph
+ [ Plaintext "At"
+ , Whitespace
+ , Plaintext "the"
+ , Whitespace
+ , Plaintext "moment"
+ , Whitespace
+ , Plaintext "the"
+ , Whitespace
+ , Plaintext "release"
+ , Whitespace
+ , Plaintext "process"
+ , Whitespace
+ , Plaintext "is"
+ , Whitespace
+ , Plaintext "manual:"
+ ]
+ , List
+ [ ListItem
+ [ Plaintext "Perform"
+ , Whitespace
+ , Plaintext "final"
+ , Whitespace
+ , Plaintext "sanity"
+ , Whitespace
+ , Plaintext "checks"
+ , Whitespace
+ , Plaintext "and"
+ , Whitespace
+ , Plaintext "manual"
+ , Whitespace
+ , Plaintext "testing"
+ ]
+ , ListItem
+ [ Plaintext "Update"
+ , Whitespace
+ , Plaintext "the"
+ , Whitespace
+ , Link "pinnacle-history"
+ , Whitespace
+ , Plaintext "section"
+ , Whitespace
+ , Plaintext "of"
+ , Whitespace
+ , Plaintext "the"
+ , Whitespace
+ , Plaintext "documentation"
+ ]
+ , ListItem
+ [ Plaintext "Verify"
+ , Whitespace
+ , Plaintext "clean"
+ , Whitespace
+ , Plaintext "work"
+ , Whitespace
+ , Plaintext "tree:"
+ ]
+ ]
+ , Fenced [ "git status" ]
+ , List
+ [ ListItem
+ [ Plaintext "Tag"
+ , Whitespace
+ , Plaintext "the"
+ , Whitespace
+ , Plaintext "release:"
+ ]
+ ]
+ , Fenced [ "git tag -s -m \"$VERSION release\" $VERSION" ]
+ , List
+ [ ListItem
+ [ Plaintext "Publish"
+ , Whitespace
+ , Plaintext "the"
+ , Whitespace
+ , Plaintext "code:"
+ ]
+ ]
+ , Fenced
+ [ "git push origin master --follow-tags"
+ , "git push github master --follow-tags"
+ ]
+ , List
+ [ ListItem
+ [ Plaintext "Produce"
+ , Whitespace
+ , Plaintext "the"
+ , Whitespace
+ , Plaintext "release"
+ , Whitespace
+ , Plaintext "archive:"
+ ]
+ ]
+ , Fenced [ "git archive -o vim-docvim-$VERSION.zip HEAD -- ." ]
+ , List
+ [ ListItem
+ [ Plaintext "Upload"
+ , Whitespace
+ , Plaintext "to"
+ , Whitespace
+ , Plaintext
+ "http://www.vim.org/scripts/script.php?script_id=[TODO]"
+ ]
+ ]
+ , HeadingAnnotation "Authors"
+ , Paragraph
+ [ Plaintext "Pinnacle"
+ , Whitespace
+ , Plaintext "is"
+ , Whitespace
+ , Plaintext "written"
+ , Whitespace
+ , Plaintext "and"
+ , Whitespace
+ , Plaintext "maintained"
+ , Whitespace
+ , Plaintext "by"
+ , Whitespace
+ , Plaintext "Greg"
+ , Whitespace
+ , Plaintext "Hurrell"
+ , Whitespace
+ , Plaintext "<greg@hurrell.net>."
+ ]
+ , HeadingAnnotation "History"
+ , SubheadingAnnotation "0.1 (30 March 2016)"
+ , List
+ [ ListItem
+ [ Plaintext "Initial" , Whitespace , Plaintext "release." ]
+ ]
+ ]
+ ]
--- /dev/null
+../shared/integration-pinnacle.vim
\ No newline at end of file
--- /dev/null
+" Copyright 2015-present Greg Hurrell. All rights reserved.
+" Licensed under the terms of the BSD 2-clause license.
+
+""
+" @option g:FerretQFOptions boolean 1
+"
+" Controls whether to set up setting overrides for |quickfix| windows. These are
+" various settings, such as |norelativenumber|, |nolist| and |nowrap|, that are
+" intended to make the |quickfix| window, which is typically very small relative
+" to other windows, more usable.
+"
+" A full list of overridden settings can be found in |ferret-overrides|.
+"
+" To prevent the custom settings from being applied, set |g:FerretQFOptions|
+" to 0:
+"
+" ```
+" let g:FerretQFOptions=0
+" ```
+let s:options=get(g:, 'FerretQFOptions', 1)
+if s:options
+ setlocal nolist
+ if exists('+relativenumber')
+ setlocal norelativenumber
+ endif
+ setlocal nowrap
+ setlocal number
+
+ " Want to set scrolloff only for the qf window, but it is a global option.
+ let s:original_scrolloff=&scrolloff
+ set scrolloff=0
+
+ if has('autocmd')
+ augroup FerretQF
+ autocmd!
+ autocmd BufLeave <buffer> execute 'set scrolloff=' . s:original_scrolloff
+ autocmd BufEnter <buffer> set scrolloff=0 | setlocal nocursorline
+ augroup END
+ endif
+endif
+
+""
+" @option g:FerretQFMap boolean 1
+"
+" Controls whether to set up mappings in the |quickfix| results window for
+" deleting results. The mappings include:
+"
+" - `d` (|visual-mode|): delete visual selection
+" - `dd` (|Normal-mode|): delete current line
+" - `d`{motion} (|Normal-mode|): delete range indicated by {motion}
+"
+" To prevent these mappings from being set up, set to 0:
+"
+" ```
+" let g:FerretQFMap=0
+" ```
+let s:map=get(g:, 'FerretQFMap', 1)
+if s:map
+ " Make it easy to remove entries from the quickfix listing.
+ " TODO: distinguish between quickfix and location list
+ nnoremap <buffer> <silent> d :set operatorfunc=ferret#private#qf_delete_motion<CR>g@
+ nnoremap <buffer> <silent> dd :call ferret#private#qf_delete()<CR>
+ vnoremap <buffer> <silent> d :call ferret#private#qf_delete()<CR>
+endif
--- /dev/null
+" Copyright 2015-present Greg Hurrell. All rights reserved.
+" Licensed under the terms of the BSD 2-clause license.
+
+""
+" @plugin ferret Ferret plug-in for Vim
+"
+" # Intro
+"
+" > "ferret (verb)<br />
+" > (ferret something out) search tenaciously for and find something: she had
+" > the ability to ferret out the facts."
+"
+" *ferret-features*
+" Ferret improves Vim's multi-file search in four ways:
+"
+" ## 1. Powerful multi-file search
+"
+" Ferret provides an |:Ack| command for searching across multiple files using
+" The Silver Searcher (https://github.com/ggreer/the_silver_searcher), Ack
+" (http://beyondgrep.com/), or Grep (http://www.gnu.org/software/grep/). Support
+" for passing options through to the underlying search command exists, along
+" with the ability to use full regular expression syntax without doing special
+" escaping.
+"
+" Shortcut mappings are provided to start an |:Ack| search (<leader>a) or to
+" search for the word currently under the cursor (<leader>s).
+"
+" Results are normally displayed in the |quickfix| window, but Ferret also
+" provides a |:Lack| command that behaves like |:Ack| but uses the
+" |location-list| instead, and a <leader>l mapping as a shortcut to |:Lack|.
+"
+" Finally, Ferret offers integration with dispatch.vim
+" (https://github.com/tpope/vim-dispatch), which enables asynchronous searching
+" despite the fact that Vim itself is single-threaded.
+"
+" ## 2. Streamlined multi-file replace
+"
+" The companion to |:Ack| is |:Acks| (mnemonic: "Ack substitute", accessible via
+" shortcut <leader>r), which allows you to run a multi-file replace across all
+" the files placed in the |quickfix| window by a previous invocation of |:Ack|.
+"
+" ## 3. Quickfix listing enhancements
+"
+" The |quickfix| listing itself is enhanced with settings to improve its
+" usability, and natural mappings that allow quick removal of items from the
+" list (for example, you can reduce clutter in the listing by removing lines
+" that you don't intend to make changes to).
+"
+" Additionally, Vim's |:cn|, |:cp|, |:cnf| and |:cpf| commands are tweaked to
+" make it easier to immediately identify matches by centering them within the
+" viewport.
+"
+" ## 4. Easy operations on files in the quickfix listing
+"
+" Finally, Ferret provides a |:Qargs| command that puts the files currently in
+" the |quickfix| listing into the |:args| list, where they can be operated on in
+" bulk via the |:argdo| command. This is what's used under the covers by |:Acks|
+" to do its work.
+"
+"
+" # Installation
+"
+" To install Ferret, use your plug-in management system of choice.
+"
+" If you don't have a "plug-in management system of choice", I recommend
+" Pathogen (https://github.com/tpope/vim-pathogen) due to its simplicity and
+" robustness. Assuming that you have Pathogen installed and configured, and that
+" you want to install Ferret into `~/.vim/bundle`, you can do so with:
+"
+" ```
+" git clone https://github.com/wincent/ferret.git ~/.vim/bundle/ferret
+" ```
+"
+" Alternatively, if you use a Git submodule for each Vim plug-in, you could do
+" the following after `cd`-ing into the top-level of your Git superproject:
+"
+" ```
+" git submodule add https://github.com/wincent/ferret.git ~/vim/bundle/ferret
+" git submodule init
+" ```
+"
+" To generate help tags under Pathogen, you can do so from inside Vim with:
+"
+" ```
+" :call pathogen#helptags()
+" ```
+"
+" @mappings
+"
+" ## Circumstances where mappings do not get set up
+"
+" Note that Ferret will not try to set up the <leader> mappings if any of the
+" following are true:
+"
+" - A mapping for already exists.
+" - An alternative mapping for the same functionality has already been set up
+" from a |.vimrc|.
+" - The mapping has been suppressed by setting |g:FerretMap| to 1 in your
+" |.vimrc|.
+"
+" ## Mappings specific to the quickfix window
+"
+" Additionally, Ferret will set up special mappings in |quickfix| listings,
+" unless prevented from doing so by |g:FerretQFMap|:
+"
+" - `d` (|visual-mode|): delete visual selection
+" - `dd` (|Normal-mode|): delete current line
+" - `d`{motion} (|Normal-mode|): delete range indicated by {motion}
+"
+"
+" @footer
+"
+" # Custom autocommands
+"
+" *FerretWillWrite* *FerretDidWrite*
+" For maximum compatibility with other plug-ins, Ferret runs the following
+" "User" autocommands before and after running the file writing operations
+" during |:Acks|:
+"
+" - FerretWillWrite
+" - FerretDidWrite
+"
+" For example, to call a pair of custom functions in response to these events,
+" you might do:
+"
+" ```
+" autocmd! User FerretWillWrite
+" autocmd User FerretWillWrite call CustomWillWrite()
+" autocmd! User FerretDidWrite
+" autocmd User FerretDidWrite call CustomDidWrite()
+" ```
+"
+"
+" # Overrides
+"
+" Ferret overrides the 'grepformat' and 'grepprg' settings, preferentially
+" setting `ag`, `ack` or `grep` as the 'grepprg' (in that order) and configuring
+" a suitable 'grepformat'.
+"
+" Additionally, Ferret includes an |ftplugin| for the |quickfix| listing that
+" adjusts a number of settings to improve the usability of search results.
+"
+" @indent
+" *ferret-nolist*
+" 'nolist'
+"
+" Turned off to reduce visual clutter in the search results, and because
+" 'list' is most useful in files that are being actively edited, which is not
+" the case for |quickfix| results.
+"
+" *ferret-norelativenumber*
+" 'norelativenumber'
+"
+" Turned off, because it is more useful to have a sense of absolute progress
+" through the results list than to have the ability to jump to nearby results
+" (especially seeing as the most common operations are moving to the next or
+" previous file, which are both handled nicely by |:cnf| and |:cpf|
+" respectively).
+"
+" *ferret-nowrap*
+" 'nowrap'
+"
+" Turned off to avoid ugly wrapping that makes the results list hard to read,
+" and because in search results, the most relevant information is the
+" filename, which is on the left and is usually visible even without wrapping.
+"
+" *ferret-number*
+" 'number'
+"
+" Turned on to give a sense of absolute progress through the results.
+"
+" *ferret-scrolloff*
+" 'scrolloff'
+"
+" Set to 0 because the |quickfix| listing is usually small by default, so
+" trying to keep the current line away from the edge of the viewpoint is
+" futile; by definition it is usually near the edge.
+"
+" *ferret-nocursorline*
+" 'nocursorline'
+"
+" Turned off to reduce visual clutter.
+"
+" @dedent
+"
+" To prevent any of these |quickfix|-specific overrides from being set up, you
+" can set |g:FerretQFOptions| to 0 in your |.vimrc|:
+"
+" ```
+" let g:FerretQFOptions=0
+" ```
+"
+"
+" # Troubleshooting
+"
+" *ferret-quotes*
+" ## Ferret fails to find patterns containing spaces
+"
+" As described in the documentation for |:Ack|, the search pattern is passed
+" through as-is to the underlying search command, and no escaping is required
+" other than preceding spaces by a single backslash.
+"
+" So, to find "foo bar", you would search like:
+"
+" ```
+" :Ack foo\ bar
+" ```
+"
+" Unescaped spaces in the search are treated as argument separators, so a
+" command like the following means pass the `-w` option through, search for
+" pattern "foo", and limit search to the "bar" directory:
+"
+" ```
+" :Ack -w foo bar
+" ```
+"
+" Note that including quotes will not do what you intend.
+"
+" ```
+" " Search for '"foo' in the 'bar"' directory:
+" :Ack "foo bar"
+"
+" " Search for "'foo' in the "bar'" directory:
+" :Ack 'foo bar'
+" ```
+"
+" This approach to escaping is taken in order to make it straightfoward to use
+" powerful Perl-compatible regular expression syntax in an unambiguous way
+" without having to worry about shell escaping rules:
+"
+" ```
+" :Ack \blog\((['"]).*?\1\) -i --ignore-dir=src/vendor src dist build
+" ```
+"
+"
+" # FAQ
+"
+" ## Why do Ferret commands start with "Ack", "Lack" and so on?
+"
+" Ferret was originally the thinnest of wrappers (7 lines of code in my
+" |.vimrc|) around `ack`. The earliest traces of it can be seen in the initial
+" commit to my dotfiles repo in May, 2009 (https://wt.pe/h).
+"
+" So, even though Ferret has a new name now and actually prefers `ag` over `ack`
+" when available, I prefer to keep the command names intact and benefit from
+" years of accumulated muscle-memory.
+"
+"
+"
+" # Related
+"
+" Just as Ferret aims to improve the multi-file search and replace experience,
+" Loupe does the same for within-file searching:
+"
+" https://github.com/wincent/loupe
+"
+"
+" # Website
+"
+" The official Ferret source code repo is at:
+"
+" http://git.wincent.com/ferret.git
+"
+" A mirror exists at:
+"
+" https://github.com/wincent/ferret
+"
+" Official releases are listed at:
+"
+" http://www.vim.org/scripts/script.php?script_id=5220
+"
+"
+" # License
+"
+" Copyright 2015-present Greg Hurrell. All rights reserved.
+"
+" Redistribution and use in source and binary forms, with or without
+" modification, are permitted provided that the following conditions are met:
+"
+" 1. Redistributions of source code must retain the above copyright notice,
+" this list of conditions and the following disclaimer.
+" 2. Redistributions in binary form must reproduce the above copyright notice,
+" this list of conditions and the following disclaimer in the documentation
+" and/or other materials provided with the distribution.
+"
+" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+" ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+" POSSIBILITY OF SUCH DAMAGE.
+"
+"
+" # Development
+"
+" ## Contributing patches
+"
+" Patches can be sent via mail to greg@hurrell.net, or as GitHub pull requests
+" at: https://github.com/wincent/ferret/pulls
+"
+" ## Cutting a new release
+"
+" At the moment the release process is manual:
+"
+" - Perform final sanity checks and manual testing
+" - Update the |ferret-history| section of the documentation
+" - Verify clean work tree:
+"
+" ```
+" git status
+" ```
+"
+" - Tag the release:
+"
+" ```
+" git tag -s -m "$VERSION release" $VERSION
+" ```
+"
+" - Publish the code:
+"
+" ```
+" git push origin master --follow-tags
+" git push github master --follow-tags
+" ```
+"
+" - Produce the release archive:
+"
+" ```
+" git archive -o ferret-$VERSION.zip HEAD -- .
+" ```
+"
+" - Upload to http://www.vim.org/scripts/script.php?script_id=5220
+"
+"
+" # Authors
+"
+" Ferret is written and maintained by Greg Hurrell <greg@hurrell.net>.
+"
+" The idea for vim-dispatch integration was taken from Miles Sterrett's ack.vim
+" plug-in (https://github.com/mileszs/ack.vim).
+"
+" Other contributors that have submitted patches include (in alphabetical
+" order):
+"
+" - Daniel Silva
+" - Joe Lencioni
+" - Nelo-Thara Wallus
+" - Vaibhav Sagar
+"
+"
+" # History
+"
+" 0.3.1 (not yet released)
+"
+" - Fix broken |:Qargs| command (patch from Daniel Silva).
+"
+" 0.3 (24 July 2015)
+"
+" - Added highlighting of search pattern and related |g:FerretHlsearch| option
+" (patch from Nelo-Thara Wallus).
+" - Add better error reporting for failed or incorrect searches.
+"
+" 0.2 (16 July 2015)
+"
+" - Added |FerretDidWrite| and |FerretWillWrite| autocommands (patch from Joe
+" Lencioni).
+" - Add |<Plug>(FerretAcks)| mapping (patch from Nelo-Thara Wallus).
+"
+" 0.1 (8 July 2015)
+"
+" - Initial release, extracted from my dotfiles
+" (https://github.com/wincent/wincent).
+
+""
+" @option g:FerretLoaded any
+"
+" To prevent Ferret from being loaded, set |g:FerretLoaded| to any value in your
+" |.vimrc|. For example:
+"
+" ```
+" let g:FerretLoaded=1
+" ```
+if exists('g:FerretLoaded') || &compatible || v:version < 700
+ finish
+endif
+let g:FerretLoaded = 1
+
+" Temporarily set 'cpoptions' to Vim default as per `:h use-cpo-save`.
+let s:cpoptions = &cpoptions
+set cpoptions&vim
+
+if executable('ag') " The Silver Searcher: faster than ack.
+ let s:ackprg = 'ag --column --nocolor --nogroup'
+elseif executable('ack') " Ack: better than grep.
+ let s:ackprg = 'ack --column'
+elseif executable('grep') " Grep: it's just grep.
+ let s:ackprg = &grepprg " default is: grep -n $* /dev/null
+endif
+
+if !empty(s:ackprg)
+ let &grepprg=s:ackprg
+ set grepformat=%f:%l:%c:%m
+endif
+
+if has('autocmd')
+ augroup Ferret
+ autocmd!
+ autocmd QuickFixCmdPost [^l]* nested cwindow
+ autocmd QuickFixCmdPost l* nested lwindow
+ augroup END
+endif
+
+""
+" @command :Ack {pattern} {options}
+"
+" Searches for {pattern} in all the files under the current directory (see
+" |:pwd|), unless otherwise overridden via {options}, and displays the results
+" in the |quickfix| listing.
+"
+" `ag` (The Silver Searcher) will be used preferentially if present on the
+" system, because it is faster, falling back to `ack` and then `grep` as needed.
+"
+" If dispatch.vim is installed the search process will run asynchronously via
+" the |:Make| command, otherwise it will be run synchronously via |:cexpr|.
+" Asynchronous searches are preferred because they do not block, despite the
+" fact that Vim itself is single threaded. The |g:FerretDispatch| option can be
+" used to prevent the use of dispatch.vim.
+"
+" The {pattern} is passed through as-is to the underlying search program, and no
+" escaping is required other than preceding spaces by a single backslash. For
+" example, to search for "\bfoo[0-9]{2} bar\b" (ie. using `ag`'s Perl-style
+" regular expression syntax), you could do:
+"
+" ```
+" :Ack \bfoo[0-9]{2}\ bar\b
+" ```
+"
+" Likewise, {options} are passed through. In this example, we pass the `-w`
+" option (to search on word boundaries), and scope the search to the "foo" and
+" "bar" subdirectories: >
+"
+" ```
+" :Ack -w something foo bar
+" ```
+"
+" As a convenience <leader>a is set-up (|<Plug>(FerretAck)|) as a shortcut to
+" enter |Cmdline-mode| with `:Ack` inserted on the |Cmdline|. Likewise <leader>s
+" (|<Plug>(FerretAckWord)|) is a shortcut for running |:Ack| with the word
+" currently under the cursor.
+command! -nargs=+ -complete=file Ack call ferret#private#ack(<q-args>)
+
+""
+" @command :Lack {pattern} {options}
+"
+" Just like |:Ack|, but instead of using the |quickfix| listing, which is global
+" across an entire Vim instance, it uses the |location-list|, which is a
+" per-window construct.
+"
+" Note that |:Lack| always runs synchronously via |:cexpr|, because dispatch.vim
+" doesn't currently support the |location-list|.
+command! -nargs=+ -complete=file Lack call ferret#private#lack(<q-args>)
+
+""
+" @command :Acks /{pattern}/{replacement}/
+"
+" Takes all of the files currently in the |quickfix| listing and performs a
+" substitution of all instances of {pattern} (a standard Vim search |pattern|)
+" by {replacement}.
+"
+" A typical sequence consists of an |:Ack| invocation to populate the |quickfix|
+" listing and then |:Acks| (mnemonic: "Ack substitute") to perform replacements.
+" For example, to replace "foo" with "bar" across all files in the current
+" directory:
+"
+" ```
+" :Ack foo
+" :Acks /foo/bar/
+" ```
+command! -nargs=1 Acks call ferret#private#acks(<q-args>)
+
+""
+" @option g:FerretMap boolean 1
+"
+" Controls whether to set up the Ferret mappings, such as |<Plug>(FerretAck)|
+" (see |ferret-mappings| for a full list). To prevent any mapping from being
+" configured, set to 0:
+"
+" ```
+" let g:FerretMap=0
+" ```
+let s:map=get(g:, 'FerretMap', 1)
+if s:map
+ if !hasmapto('<Plug>(FerretAck)') && maparg('<leader>a', 'n') ==# ''
+ ""
+ " @mapping <Plug>(FerretAck)
+ "
+ " Ferret maps <leader>a to |<Plug>(FerretAck)|, which triggers the |:Ack|
+ " command. To use an alternative mapping instead, create a different one in
+ " your |.vimrc| instead using |:nmap|:
+ "
+ " ```
+ " " Instead of <leader>a, use <leader>x.
+ " nmap <leader>x <Plug>(FerretAck)
+ " ```
+ nmap <unique> <leader>a <Plug>(FerretAck)
+ endif
+ nnoremap <Plug>(FerretAck) :Ack<space>
+
+ if !hasmapto('<Plug>FerretLack') && maparg('<leader>l', 'n') ==# ''
+ ""
+ " @mapping <Plug>(FerretLack)
+ "
+ " Ferret maps <leader>l to |<Plug>(FerretLack)|, which triggers the |:Lack|
+ " command. To use an alternative mapping instead, create a different one in
+ " your |.vimrc| instead using |:nmap|:
+ "
+ " ```
+ " " Instead of <leader>l, use <leader>y.
+ " nmap <leader>y <Plug>(FerretLack)
+ " ```
+ nmap <unique> <leader>l <Plug>(FerretLack)
+ endif
+ nnoremap <Plug>(FerretLack) :Lack<space>
+
+ if !hasmapto('<Plug>(FerretAckWord)') && maparg('<leader>s', 'n') ==# ''
+ " Call :Ack with word currently under cursor (mnemonic: selection).
+
+
+ ""
+ " @mapping <Plug>(FerretAckWord)
+ "
+ " Ferret maps <leader>s (mnemonix: "selection) to |<Plug>(FerretAckWord)|,
+ " which uses |:Ack| to search for the word currently under the cursor. To
+ " use an alternative mapping instead, create a different one in your
+ " |.vimrc| instead using |:nmap|:
+ "
+ " ```
+ " " Instead of <leader>s, use <leader>z.
+ " nmap <leader>z <Plug>(FerretAckWord)
+ " ```
+ nmap <unique> <leader>s <Plug>(FerretAckWord)
+ endif
+ nnoremap <Plug>(FerretAckWord) :Ack <C-r><C-w><CR>
+
+ if !hasmapto('<Plug>(FerretAcks)') && maparg('<leader>r', 'n') ==# ''
+ ""
+ " @mapping *<Plug>(FerretAcks)*
+ "
+ " Ferret maps <leader>r (mnemonic: "replace") to |<Plug>(FerretAcks)|, which
+ " triggers the |:Acks| command and fills the prompt with the last search
+ " term from Ferret. to use an alternative mapping instead, create a
+ " different one in your |.vimrc| instead using |:nmap|:
+ "
+ " ```
+ " " Instead of <leader>r, use <leader>u.
+ " nmap <leader>u <Plug>(FerretAcks)
+ " ```
+ nmap <unique> <leader>r <Plug>(FerretAcks)
+ endif
+ nnoremap <Plug>(FerretAcks)
+ \ :Acks <c-r>=(exists('g:ferret_lastsearch') ? '/' . g:ferret_lastsearch . '//' : ' ')<CR><Left>
+endif
+
+""
+" @command :Qargs
+"
+" This is a utility function that is used by the |:Acks| command but is also
+" generally useful enough to warrant being exposed publicly.
+"
+" It takes the files currently in the |quickfix| listing and sets them as
+" |:args| so that they can be operated on en masse via the |:argdo| command.
+command! -bar Qargs execute 'args' ferret#private#qargs()
+
+""
+" @option g:FerretQFCommands boolean 1
+"
+" Controls whether to set up custom versions of the |quickfix| commands, |:cn|,
+" |:cnf|, |:cp| an |:cpf|. These overrides vertically center the match within
+" the viewport on each jump. To prevent the custom versions from being
+" configured, set to 0:
+"
+" ```
+" let g:FerretQFCommands=0
+" ```
+let s:commands=get(g:, 'FerretQFCommands', 1)
+if s:commands
+ " Keep quickfix result centered, if possible, when jumping from result to result.
+ cabbrev <silent> <expr> cn ((getcmdtype() == ':' && getcmdpos() == 3) ? 'cn <bar> normal zz' : 'cn')
+ cabbrev <silent> <expr> cnf ((getcmdtype() == ':' && getcmdpos() == 4) ? 'cnf <bar> normal zz' : 'cnf')
+ cabbrev <silent> <expr> cp ((getcmdtype() == ':' && getcmdpos() == 3) ? 'cp <bar> normal zz' : 'cp')
+ cabbrev <silent> <expr> cpf ((getcmdtype() == ':' && getcmdpos() == 4) ? 'cpf <bar> normal zz' : 'cpf')
+endif
+
+" Restore 'cpoptions' to its former value.
+let &cpoptions = s:cpoptions
+unlet s:cpoptions
--- /dev/null
+" Copyright 2015-present Greg Hurrell. All rights reserved.
+" Licensed under the terms of the BSD 2-clause license.
+
+" Remove lines a:first through a:last from the quickfix listing.
+function! s:delete(first, last)
+ let l:list=getqflist()
+ let l:line=a:first
+
+ while l:line >= a:first && l:line <= a:last
+ " Non-dictionary items will be ignored. This effectively deletes the line.
+ let l:list[l:line - 1]=0
+ let l:line=l:line + 1
+ endwhile
+ call setqflist(l:list, 'r')
+
+ " Show to next entry.
+ execute 'cc ' . a:first
+
+ " Move focus back to quickfix listing.
+ execute "normal \<C-W>\<C-P>"
+endfunction
+
+" Returns 1 if we should/can use vim-dispatch.
+function! s:dispatch()
+ ""
+ " @option g:FerretDispatch boolean 1
+ "
+ " Controls whether to use vim-dispatch (and specifically, |:Make|) to run
+ " |:Ack| searches asynchronously, when available. To prevent vim-dispatch from
+ " being used, set to 0:
+ "
+ " ```
+ " let g:FerretDispatch=0
+ " ```
+ let l:dispatch=get(g:, 'FerretDispatch', 1)
+ return l:dispatch && exists(':Make') == 2
+endfunction
+
+" Use `input()` to show error output to user. Ideally, we would do this in a way
+" that didn't require user interaction, but this is the only reliable mechanism
+" that works for all cases. Alternatives considered:
+"
+" (1) Using `:echomsg`
+"
+" When not using vim-dispatch, the screen is getting cleared before the
+" user sees it, even with a pre-emptive `:redraw!` beforehand. Note that
+" we can get the message to linger on the screen by making it multi-line and
+" forcing Vim to show a prompt (see `:h hit-enter-prompt`), but this is not
+" reliable because the number of lines required to force the prompt will
+" vary by system, depending on the value of `'cmdheight'`.
+"
+" When using vim-dispatch, anything we output ends up getting swallowed
+" before the user sees it, because something it is doing is clearing the
+" screen. This is true no matter how many lines we output.
+"
+" (2) Writing back into the quickfix/location list
+"
+" This interacts poorly with vim-dispatch. If we write back an error message
+" and then call `:copen 1`, vim-dispatch ends up closing the listing before
+" the user sees it.
+"
+" (3) Using `:echoerr`
+"
+" This works, but presents to the user as an exception (see `:h :echoerr`).
+"
+function! s:error(message) abort
+ call inputsave()
+ echohl ErrorMsg
+ call input(a:message . ': press ENTER to continue')
+ echohl NONE
+ call inputrestore()
+ echo
+endfunction
+
+" Parses arguments, extracting a search pattern (which is stored in
+" g:ferret_lastsearch) and escaping space-delimited arguments for use by
+" `system()`. A string containing all the escaped arguments is returned.
+"
+" The basic strategy is to split on spaces, expand wildcards for non-option
+" arguments, shellescape each word, and join.
+"
+" To support an edge-case (the ability to search for strings with spaces in
+" them, however, we swap out escaped spaces first (subsituting the unlikely
+" "<!!S!!>") and then swap them back in at the end. This allows us to perform
+" searches like:
+"
+" :Ack -i \bFoo_?Bar\b
+" :Ack that's\ nice\ dear
+"
+" and so on...
+function! s:parse(arg) abort
+ if exists('g:ferret_lastsearch')
+ unlet g:ferret_lastsearch
+ endif
+
+ let l:escaped_spaces_replaced_with_markers=substitute(a:arg, '\\ ', '<!!S!!>', 'g')
+ let l:split_on_spaces=split(l:escaped_spaces_replaced_with_markers)
+ let l:expanded_args=[]
+
+ for l:arg in l:split_on_spaces
+ if l:arg =~# '^-'
+ " Options get passed through as-is.
+ call add(l:expanded_args, l:arg)
+ elseif exists('g:ferret_lastsearch')
+ let l:file_args=glob(l:arg, 1, 1) " Ignore 'wildignore', return a list.
+ if len(l:file_args)
+ call extend(l:expanded_args, l:file_args)
+ else
+ " Let through to `ag`/`ack`/`grep`, which will throw ENOENT.
+ call add(l:expanded_args, l:arg)
+ endif
+ else
+ " First non-option arg is considered to be search pattern.
+ let g:ferret_lastsearch=substitute(l:arg, '<!!S!!>', ' ', 'g')
+ call add(l:expanded_args, l:arg)
+ endif
+ endfor
+
+ let l:each_word_shell_escaped=map(l:expanded_args, 'shellescape(v:val)')
+ let l:joined=join(l:each_word_shell_escaped)
+ return substitute(l:joined, '<!!S!!>', ' ', 'g')
+endfunction
+
+function! ferret#private#post(type) abort
+ if has('autocmd')
+ augroup FerretPostQF
+ autocmd!
+ augroup END
+ endif
+
+ let l:lastsearch = get(g:, 'ferret_lastsearch', '')
+ let l:qflist = a:type == 'qf' ? getqflist() : getloclist(0)
+ let l:tip = ' [see `:help ferret-quotes`]'
+ if len(l:qflist) == 0
+ let l:base = 'No results for search pattern `' . l:lastsearch . '`'
+
+ " Search pattern has no spaces and is entirely enclosed in quotes;
+ " eg 'foo' or "bar"
+ if l:lastsearch =~ '\v^([' . "'" . '"])[^ \1]+\1$'
+ call s:error(l:base . l:tip)
+ else
+ call s:error(l:base)
+ endif
+ else
+ " Find any "invalid" entries in the list.
+ let l:invalid = filter(copy(l:qflist), 'v:val.valid == 0')
+ if len(l:invalid) == len(l:qflist)
+ " Every item in the list was invalid.
+ redraw!
+ echohl ErrorMsg
+ for l:item in l:invalid
+ echomsg l:item.text
+ endfor
+ echohl NONE
+
+ let l:base = 'Search for `' . l:lastsearch . '` failed'
+
+ " When using vim-dispatch, the messages printed above get cleared, so the
+ " only way to see them is with `:messages`.
+ let l:suffix = a:type == 'qf' && s:dispatch() ?
+ \ ' (run `:messages` to see details)' :
+ \ ''
+
+ " If search pattern looks like `'foo` or `"bar`, it means the user
+ " probably tried to search for 'foo bar' or "bar baz" etc.
+ if l:lastsearch =~ '\v^[' . "'" . '"].+[^' . "'" . '"]$'
+ call s:error(l:base . l:tip . l:suffix)
+ else
+ call s:error(l:base . l:suffix)
+ endif
+ endif
+ endif
+endfunction
+
+function! ferret#private#ack(command) abort
+ let l:command=s:parse(a:command)
+ call ferret#private#hlsearch()
+
+ if empty(&grepprg)
+ return
+ endif
+
+ " Prefer vim-dispatch unless otherwise instructed.
+ if s:dispatch()
+ if has('autocmd')
+ augroup FerretPostQF
+ autocmd!
+ autocmd QuickfixCmdPost cgetfile call ferret#private#post('qf')
+ augroup END
+ endif
+ let l:original_makeprg=&l:makeprg
+ let l:original_errorformat=&l:errorformat
+ try
+ let &l:makeprg=&grepprg . ' ' . l:command
+ let &l:errorformat=&grepformat
+ Make
+ catch
+ if has('autocmd')
+ augroup! FerretPostQF
+ endif
+ finally
+ let &l:makeprg=l:original_makeprg
+ let &l:errorformat=l:original_errorformat
+ endtry
+ else
+ cexpr system(&grepprg . ' ' . l:command)
+ cwindow
+ call ferret#private#post('qf')
+ endif
+endfunction
+
+function! ferret#private#lack(command) abort
+ let l:command=s:parse(a:command)
+ call ferret#private#hlsearch()
+
+ if empty(&grepprg)
+ return
+ endif
+
+ lexpr system(&grepprg . ' ' . l:command)
+ lwindow
+ call ferret#private#post('location')
+endfunction
+
+function! ferret#private#hlsearch() abort
+ if has('extra_search')
+ ""
+ " @option g:FerretHlsearch boolean
+ "
+ " Controls whether Ferret should attempt to highlight the search pattern
+ " when running |:Ack| or |:Lack|. If left unset, Ferret will respect the
+ " current 'hlsearch' setting. To force highlighting on or off irrespective
+ " of 'hlsearch', set |g:FerretHlsearch| to 1 (on) or 0 (off):
+ "
+ " ```
+ " let g:FerretHlsearch=0
+ " ```
+ let l:hlsearch=get(g:, 'FerretHlsearch', &hlsearch)
+ if l:hlsearch
+ let @/=g:ferret_lastsearch
+ call feedkeys(":let &hlsearch=1 | echo \<CR>", 'n')
+ endif
+ endif
+endfunction
+
+" Run the specified substitution command on all the files in the quickfix list
+" (mnemonic: "Ack substitute").
+"
+" Specifically, the sequence:
+"
+" :Ack foo
+" :Acks /foo/bar/
+"
+" is equivalent to:
+"
+" :Ack foo
+" :Qargs
+" :argdo %s/foo/bar/ge | update
+"
+" (Note: there's nothing specific to Ack in this function; it's just named this
+" way for mnemonics, as it will most often be preceded by an :Ack invocation.)
+function! ferret#private#acks(command) abort
+ if match(a:command, '\v^/.+/.*/$') == -1 " crude sanity check
+ echoerr 'Ferret: Expected a substitution expression (/foo/bar/); got: ' . a:command
+ return
+ endif
+
+ let l:filenames=ferret#private#qargs()
+ if l:filenames ==# ''
+ echoerr 'Ferret: Quickfix filenames must be present, but there are none'
+ return
+ endif
+
+ execute 'args' l:filenames
+
+ if v:version > 703 || v:version == 703 && has('patch438')
+ silent doautocmd <nomodeline> User FerretWillWrite
+ else
+ silent doautocmd User FerretWillWrite
+ endif
+ execute 'argdo' '%s' . a:command . 'ge | update'
+ if v:version > 703 || v:version == 703 && has('patch438')
+ silent doautocmd <nomodeline> User FerretDidWrite
+ else
+ silent doautocmd User FerretDidWrite
+ endif
+endfunction
+
+" Populate the :args list with the filenames currently in the quickfix window.
+function! ferret#private#qargs() abort
+ let l:buffer_numbers={}
+ for l:item in getqflist()
+ let l:buffer_numbers[l:item['bufnr']]=bufname(l:item['bufnr'])
+ endfor
+ return join(map(values(l:buffer_numbers), 'fnameescape(v:val)'))
+endfunction
+
+" Visual mode deletion and `dd` mapping (special case).
+function! ferret#private#qf_delete() range
+ call s:delete(a:firstline, a:lastline)
+endfunction
+
+" Motion-based deletion from quickfix listing.
+function! ferret#private#qf_delete_motion(type, ...)
+ " Save.
+ let l:selection=&selection
+ let &selection='inclusive'
+
+ let l:firstline=line("'[")
+ let l:lastline=line("']")
+ call s:delete(l:firstline, l:lastline)
+
+ " Restore.
+ let &selection=l:selection
+endfunction
--- /dev/null
+""
+" @plugin Pinnacle Highlight group manipulation for Vim
+"
+" # Intro
+"
+" Pinnacle provides functions for manipulating |:highlight| groups.
+"
+"
+" # Installation
+"
+" To install Pinnacle, use your plug-in management system of choice.
+"
+" If you don't have a "plug-in management system of choice", I recommend
+" Pathogen (https://github.com/tpope/vim-pathogen) due to its simplicity and
+" robustness. Assuming that you have Pathogen installed and configured, and that
+" you want to install vim-docvim into `~/.vim/bundle`, you can do so with:
+"
+" ```
+" git clone https://github.com/wincent/pinnacle.git ~/.vim/bundle/pinnacle
+" ```
+"
+" Alternatively, if you use a Git submodule for each Vim plug-in, you could do
+" the following after `cd`-ing into the top-level of your Git superproject:
+"
+" ```
+" git submodule add https://github.com/wincent/pinnacle.git ~/vim/bundle/pinnacle
+" git submodule init
+" ```
+"
+" To generate help tags under Pathogen, you can do so from inside Vim with:
+"
+" ```
+" :call pathogen#helptags()
+" ```
+"
+"
+" # Website
+"
+" The official Pinnacle source code repo is at:
+"
+" http://git.wincent.com/pinnacle.git
+"
+" Mirrors exist at:
+"
+" - https://github.com/wincent/pinnacle
+" - https://gitlab.com/wincent/pinnacle
+" - https://bitbucket.org/ghurrell/pinnacle
+"
+" Official releases are listed at:
+"
+" http://www.vim.org/scripts/script.php?script_id=[TODO]
+"
+"
+" # License
+"
+" Copyright (c) 2016-present Greg Hurrell
+"
+" Permission is hereby granted, free of charge, to any person obtaining
+" a copy of this software and associated documentation files (the
+" "Software"), to deal in the Software without restriction, including
+" without limitation the rights to use, copy, modify, merge, publish,
+" distribute, sublicense, and/or sell copies of the Software, and to
+" permit persons to whom the Software is furnished to do so, subject to
+" the following conditions:
+"
+" The above copyright notice and this permission notice shall be
+" included in all copies or substantial portions of the Software.
+"
+" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+" EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+" NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+" LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+" OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+" WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+"
+"
+" # Development
+"
+" ## Contributing patches
+"
+" Patches can be sent via mail to greg@hurrell.net, or as GitHub pull requests
+" at: https://github.com/wincent/pinnacle/pulls
+"
+" ## Cutting a new release
+"
+" At the moment the release process is manual:
+"
+" - Perform final sanity checks and manual testing
+" - Update the |pinnacle-history| section of the documentation
+" - Verify clean work tree:
+"
+" ```
+" git status
+" ```
+"
+" - Tag the release:
+"
+" ```
+" git tag -s -m "$VERSION release" $VERSION
+" ```
+"
+" - Publish the code:
+"
+" ```
+" git push origin master --follow-tags
+" git push github master --follow-tags
+" ```
+"
+" - Produce the release archive:
+"
+" ```
+" git archive -o vim-docvim-$VERSION.zip HEAD -- .
+" ```
+"
+" - Upload to http://www.vim.org/scripts/script.php?script_id=[TODO]
+"
+"
+" # Authors
+"
+" Pinnacle is written and maintained by Greg Hurrell <greg@hurrell.net>.
+"
+"
+" # History
+"
+" ## 0.1 (30 March 2016)
+"
+" - Initial release.
-../markdown/integration-ferret-ftplugin-qf.vim
\ No newline at end of file
+../shared/integration-ferret-ftplugin-qf.vim
\ No newline at end of file
-../markdown/integration-ferret-plugin.vim
\ No newline at end of file
+../shared/integration-ferret-plugin.vim
\ No newline at end of file
-../markdown/integration-ferret-private.vim
\ No newline at end of file
+../shared/integration-ferret-private.vim
\ No newline at end of file
-../markdown/integration-pinnacle.vim
\ No newline at end of file
+../shared/integration-pinnacle.vim
\ No newline at end of file