Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Version 1.00: Initial upload

  • Loading branch information...
commit abb87abd43e49d8f5e3f13840f34cf670f28cd61 0 parents
Ingo Karkat authored committed
69 README
@@ -0,0 +1,69 @@
+This is a mirror of http://www.vim.org/scripts/script.php?script_id=4191
+
+DESCRIPTION
+This plugin defines a command and mappings to quickly list all occurrences of
+the current search pattern, passed pattern, current word or selection in the
+quickfix list. This is useful to get a somewhat persistent list of matches
+that act like bookmarks, so you can recall them later (when your search
+pattern has changed).
+
+HOW IT WORKS
+The plugin uses :vimgrep over the current buffer.
+
+SOURCE
+Inspired by vimtip #483: Using GREP for a "list occurrences" and quickfix help
+command.
+ http://vim.wikia.com/wiki/Search_using_quickfix_to_list_occurrences
+ command GREP :execute 'grep '.expand('<cword>') expand('%') | :copen | cc
+
+SEE ALSO
+- The GrepCommands plugin (vimscript #4173) provides additional grep commands
+ covering arguments, buffers, windows and tab pages.
+- The FindOccurrence plugin (vimscript #0000) can also show all occurrences of
+ the <cword>, current search results, etc., but instead of the quickfix list,
+ the result is either jumped to or listed.
+- The SearchPosition plugin (vimscript #2634) shows the relation of the cursor
+ position to the other matches of the search pattern, and provides similar
+ mappings. Like the quickfix list, it can provide an orientation of where and
+ how many matches there are.
+
+RELATED WORKS
+- outline (vimscript #1947) creates a custom view of the file based on regex,
+ in a scratch buffer
+- ttoc (vimscript #2014) is based on outline and creates a regexp-based table
+ of contents of the current buffer
+
+USAGE
+:GrepHere [{pattern}]
+:GrepHere /{pattern}/[g][j]
+:GrepHereAdd [{pattern}]
+:GrepHereAdd /{pattern}/[g][j]
+ Grep the passed pattern (or current search pattern if
+ omitted) in the current file (or the current entry of
+ the quickfix list).
+
+<A-N> Grep the current search pattern in the current file
+ and show matching lines in the quickfix window (but
+ don't go there).
+ This is similar to [N defined by
+ FindOccurrence.vim, but uses the quickfix list
+ instead of just printing all matching lines.
+
+<A-M> Grep the current whole word under the cursor in the
+ current file and show matching lines in the quickfix
+ window (but don't go there).
+ This is similar to [I defined by
+ FindOccurrence.vim, but uses the quickfix list
+ instead of just printing all matching lines.
+g<A-M> Grep the current word under the cursor in the current
+ file and show matching lines in the quickfix window
+ (but don't go there).
+ Only whole keywords are searched for, like with the
+ star command.
+{Visual}<A-M> Grep the selected text in the current file and show
+ matching lines in the quickfix window (but don't go
+ there).
+
+ Imagine 'M' stood for "more occurrences".
+ These mappings reuse the last used <cword> when issued
+ on a blank line.
61 autoload/GrepHere.vim
@@ -0,0 +1,61 @@
+" GrepHere.vim: List occurrences in the current buffer in the quickfix window.
+"
+" DEPENDENCIES:
+" - GrepCommands.vim autoload script
+" - ingosearch.vim autoload script
+" - ingowindow.vim autoload script
+"
+" Copyright: (C) 2003-2012 Ingo Karkat
+" The VIM LICENSE applies to this script; see ':help copyright'.
+
+" Maintainer: Ingo Karkat <ingo@karkat.de>
+"
+" REVISION DATE REMARKS
+" 1.00.002 24-Aug-2012 Add mappings for the [whole] <cword> via
+" GrepHere#SetCword(), analog to the
+" SearchPosition plugin's implementation.
+" Factor out the mapping logic to GrepHere#List().
+" Extract g:GrepHere_MappingGrepFlags.
+" 001 21-Mar-2012 file creation from plugin script
+
+function! GrepHere#Grep( count, grepCommand, pattern, ... )
+ let l:currentFile = expand('%')
+
+ if empty(l:currentFile) && ingowindow#IsQuickfixList()
+ " Use the file from the current line in the quickfix window.
+ let l:currentFile = ingowindow#ParseFileFromQuickfixList()
+ if empty(l:currentFile) && ingowindow#GotoPreviousWindow()
+ " If the cursor is on no file name line in the quickfix window, use
+ " the previous window instead.
+ let l:currentFile = expand('%:p')
+ noautocmd wincmd p
+ endif
+ endif
+
+ if empty(l:currentFile)
+ echohl ErrorMsg
+ echomsg 'E32: No file name'
+ echohl None
+ return 0
+ endif
+
+ return call('GrepCommands#Grep', [a:count, a:grepCommand, [l:currentFile], a:pattern] + a:000)
+endfunction
+
+let s:pattern = ''
+function! GrepHere#SetCword( isWholeWord )
+ let l:cword = expand('<cword>')
+ if ! empty(l:cword)
+ let s:pattern = ingosearch#LiteralTextToSearchPattern(l:cword, a:isWholeWord, '')
+ endif
+ return s:pattern
+endfunction
+
+function! GrepHere#List( pattern )
+ if GrepHere#Grep(0, 'vimgrep', a:pattern, g:GrepHere_MappingGrepFlags)
+ copen
+ call ingowindow#GotoPreviousWindow()
+ endif
+endfunction
+
+" vim: set ts=8 sts=4 sw=4 noexpandtab ff=unix fdm=syntax :
335 autoload/ingointegration.vim
@@ -0,0 +1,335 @@
+" ingointegration.vim: Custom functions for Vim integration.
+"
+" DEPENDENCIES:
+"
+" Copyright: (C) 2010-2012 Ingo Karkat
+" The VIM LICENSE applies to this script; see ':help copyright'.
+"
+" Maintainer: Ingo Karkat <ingo@karkat.de>
+"
+" REVISION DATE REMARKS
+" 010 20-Jun-2012 BUG: ingointegration#GetRange() can throw E486;
+" add try...finally and document this.
+" 009 14-Jun-2012 Add ingointegration#GetRange().
+" 008 16-May-2012 Add ingointegration#GetCurrentRegexpSelection()
+" and ingointegration#SelectCurrentRegexp().
+" 007 06-Mar-2012 Add ingointegration#IsFiletype() from
+" insertsignature.vim.
+" 006 12-Dec-2011 Assume mutating a:rangeCommand in
+" ingointegration#OperatorMappingForRangeCommand()
+" and handle 'readonly' and 'nomodifiable' buffers
+" without function errors. Implementation copied
+" from autoload/ReplaceWithRegister.vim.
+" 005 22-Sep-2011 Include ingointegration#IsOnSyntaxItem() from
+" SearchInSyntax.vim to allow reuse.
+" 004 12-Sep-2011 Add ingointegration#GetVisualSelection().
+" 003 06-Jul-2010 Added ingointegration#DoWhenBufLoaded().
+" 002 24-Mar-2010 Added ingointegration#BufferRangeToLineRangeCommand().
+" 001 19-Mar-2010 file creation
+
+function! s:OpfuncExpression( opfunc )
+ let &opfunc = a:opfunc
+
+ let l:keys = 'g@'
+
+ if ! &l:modifiable || &l:readonly
+ " Probe for "Cannot make changes" error and readonly warning via a no-op
+ " dummy modification.
+ " In the case of a nomodifiable buffer, Vim will abort the normal mode
+ " command chain, discard the g@, and thus not invoke the operatorfunc.
+ let l:keys = ":call setline(1, getline(1))\<CR>" . l:keys
+ endif
+
+ return l:keys
+endfunction
+function! ingointegration#OperatorMappingForRangeCommand( mapArgs, mapKeys, rangeCommand )
+"******************************************************************************
+"* PURPOSE:
+" Define a custom operator mapping "\xx{motion}" (where \xx is a:mapKeys) that
+" allow a [count] before and after the operator and support repetition via
+" |.|.
+"
+"* ASSUMPTIONS / PRECONDITIONS:
+" Checks for a 'nomodifiable' or 'readonly' buffer and forces the proper Vim
+" error / warning, so it assumes that a:rangeCommand mutates the buffer.
+"
+"* EFFECTS / POSTCONDITIONS:
+" Defines a normal mode mapping for a:mapKeys.
+"* INPUTS:
+" a:mapArgs Arguments to the :map command, like '<buffer>' for a
+" buffer-local mapping.
+" a:mapKeys Mapping key [sequence].
+" a:rangeCommand Custom Ex command which takes a [range].
+"
+"* RETURN VALUES:
+" None.
+"******************************************************************************
+ let l:rangeCommandOperator = a:rangeCommand . 'Operator'
+ execute printf("
+ \ function! s:%s( type )\n
+ \ execute \"'[,']%s\"\n
+ \ endfunction\n",
+ \ l:rangeCommandOperator,
+ \ a:rangeCommand
+ \)
+
+ execute 'nnoremap <expr>' a:mapArgs a:mapKeys '<SID>OpfuncExpression(''<SID>' . l:rangeCommandOperator . ''')'
+endfunction
+
+
+function! ingointegration#BufferRangeToLineRangeCommand( cmd ) range
+"******************************************************************************
+"* MOTIVATION:
+" You want to invoke a command :Foo in a line-wise mapping <Leader>foo; the
+" command has a default range=%. The simplest solution is
+" nnoremap <Leader>foo :<C-u>.Foo<CR>
+" but that doesn't support a [count]. You cannot use
+" nnoremap <Leader>foo :Foo<CR>
+" neither, because then the mapping will work on the entire buffer if no
+" [count] is given. This utility function wraps the Foo command, passes the
+" given range, and falls back to the current line when no [count] is given:
+" nnoremap <Leader>foo :call ingointegration#BufferRangeToLineRangeCommand('Foo')<CR>
+"
+"* PURPOSE:
+" Always pass the line-wise range to a:cmd.
+"
+"* ASSUMPTIONS / PRECONDITIONS:
+" None.
+"* EFFECTS / POSTCONDITIONS:
+" None.
+"* INPUTS:
+" a:cmd Ex command which has a default range=%.
+"* RETURN VALUES:
+" None.
+"******************************************************************************
+ try
+ execute a:firstline . ',' . a:lastline . a:cmd
+ catch /^Vim\%((\a\+)\)\=:E/
+ echohl ErrorMsg
+ " v:exception contains what is normally in v:errmsg, but with extra
+ " exception source info prepended, which we cut away.
+ let v:errmsg = substitute(v:exception, '^Vim\%((\a\+)\)\=:', '', '')
+ echomsg v:errmsg
+ echohl None
+ endtry
+endfunction
+
+
+let s:autocmdCnt = 0
+function! ingointegration#DoWhenBufLoaded( command, ... )
+"******************************************************************************
+"* MOTIVATION:
+" You want execute a command from a ftplugin (e.g. "normal! gg0") that only is
+" effective when the buffer is already fully loaded, modelines have been
+" processed, other autocmds have run, etc.
+"
+"* PURPOSE:
+" Schedule the passed a:command to execute once after the current buffer has
+" been fully loaded.
+"
+"* ASSUMPTIONS / PRECONDITIONS:
+" None.
+"* EFFECTS / POSTCONDITIONS:
+" None.
+"* INPUTS:
+" a:command Ex command to be executed.
+" a:when Optional configuration of when a:command is executed.
+" By default, it is only executed on the BufWinEnter event, i.e.
+" only when the buffer actually is being loaded. If you want to
+" always execute it (and can live with it being potentially
+" executed twice), so that it is also executed when just the
+" filetype changed of an existing buffer, pass "always" in here.
+"* RETURN VALUES:
+" None.
+"******************************************************************************
+ if a:0 && a:1 ==# 'always'
+ execute a:command
+ endif
+
+ let s:autocmdCnt += 1
+ let l:groupName = 'ingointegration' . s:autocmdCnt
+ execute 'augroup' l:groupName
+ autocmd!
+ execute 'autocmd BufWinEnter <buffer> execute' string(a:command) '| autocmd!' l:groupName '* <buffer>'
+ " Remove the run-once autocmd in case the this command was NOT set up
+ " during the loading of the buffer (but e.g. by a :setfiletype in an
+ " existing buffer), so that it doesn't linger and surprise the user
+ " later on.
+ execute 'autocmd BufWinLeave,CursorHold,CursorHoldI,WinLeave <buffer> autocmd!' l:groupName '* <buffer>'
+ augroup END
+endfunction
+
+
+
+function! ingointegration#GetVisualSelection()
+"******************************************************************************
+"* PURPOSE:
+" Retrieve the contents of the current visual selection without clobbering any
+" register.
+"* ASSUMPTIONS / PRECONDITIONS:
+" Visual selection is / has been made.
+"* EFFECTS / POSTCONDITIONS:
+" None.
+"* INPUTS:
+" None.
+"* RETURN VALUES:
+" Text of visual selection.
+"******************************************************************************
+ let l:save_clipboard = &clipboard
+ set clipboard= " Avoid clobbering the selection and clipboard registers.
+ let l:save_reg = getreg('"')
+ let l:save_regmode = getregtype('"')
+ execute 'silent normal! gvy'
+ let l:selection = @"
+ call setreg('"', l:save_reg, l:save_regmode)
+ let &clipboard = l:save_clipboard
+ return l:selection
+endfunction
+function! ingointegration#GetRange( range )
+"******************************************************************************
+"* PURPOSE:
+" Retrieve the contents of the passed range without clobbering any register.
+"* ASSUMPTIONS / PRECONDITIONS:
+" None.
+"* EFFECTS / POSTCONDITIONS:
+" None.
+"* INPUTS:
+" a:range A valid |:range|; when empty, the current line is used.
+"* RETURN VALUES:
+" Text of the range on lines. Each line ends with a newline character.
+" Throws Vim error "E486: Pattern not found" when the range does not match.
+"******************************************************************************
+ let l:save_clipboard = &clipboard
+ set clipboard= " Avoid clobbering the selection and clipboard registers.
+ let l:save_reg = getreg('"')
+ let l:save_regmode = getregtype('"')
+ try
+ silent execute a:range . 'yank'
+ let l:contents = @"
+ finally
+ call setreg('"', l:save_reg, l:save_regmode)
+ let &clipboard = l:save_clipboard
+ endtry
+
+ return l:contents
+endfunction
+
+
+if exists('*synstack')
+function! ingointegration#IsOnSyntaxItem( pos, syntaxItemPattern )
+ " Taking the example of comments:
+ " Other syntax groups (e.g. Todo) may be embedded in comments. We must thus
+ " check whole stack of syntax items at the cursor position for comments.
+ " Comments are detected via the translated, effective syntax name. (E.g. in
+ " Vimscript, 'vimLineComment' is linked to 'Comment'.)
+ for l:id in synstack(a:pos[1], a:pos[2])
+ let l:actualSyntaxItemName = synIDattr(l:id, 'name')
+ let l:effectiveSyntaxItemName = synIDattr(synIDtrans(l:id), 'name')
+"****D echomsg '****' l:actualSyntaxItemName . '->' . l:effectiveSyntaxItemName
+ if l:actualSyntaxItemName =~# a:syntaxItemPattern || l:effectiveSyntaxItemName =~# a:syntaxItemPattern
+ return 1
+ endif
+ endfor
+ return 0
+endfunction
+else
+function! ingointegration#IsOnSyntaxItem( pos, syntaxItemPattern )
+ " Taking the example of comments:
+ " Other syntax groups (e.g. Todo) may be embedded in comments. As the
+ " synstack() function is not available, we can only try to get the actual
+ " syntax ID and the one of the syntax item that determines the effective
+ " color.
+ " Comments are detected via the translated, effective syntax name. (E.g. in
+ " Vimscript, 'vimLineComment' is linked to 'Comment'.)
+ for l:id in [synID(a:pos[1], a:pos[2], 0), synID(a:pos[1], a:pos[2], 1)]
+ let l:actualSyntaxItemName = synIDattr(l:id, 'name')
+ let l:effectiveSyntaxItemName = synIDattr(synIDtrans(l:id), 'name')
+"****D echomsg '****' l:actualSyntaxItemName . '->' . l:effectiveSyntaxItemName
+ if l:actualSyntaxItemName =~# a:syntaxItemPattern || l:effectiveSyntaxItemName =~# a:syntaxItemPattern
+ return 1
+ endif
+ endfor
+ return 0
+endfunction
+endif
+
+function! ingointegration#GetCurrentRegexpSelection( pattern, ... )
+"******************************************************************************
+"* PURPOSE:
+" Similar to <cword>, get the selection under / after the cursor that matches
+" a:pattern.
+"* ASSUMPTIONS / PRECONDITIONS:
+" None.
+"* EFFECTS / POSTCONDITIONS:
+" None.
+"* INPUTS:
+" a:pattern Regular expression to match at the cursor position.
+" a:stopline Optional line number where the search will stop. To get a
+" behavior like <cword>, pass in line('.').
+" a:timeout Optional timeout when the search will stop.
+"* RETURN VALUES:
+" [startLnum, startCol, endLnum, endCol] or [0, 0, 0, 0]
+"******************************************************************************
+ let l:save_view = winsaveview()
+ let l:endPos = call('searchpos', [a:pattern, 'ceW'] + a:000)
+ if l:endPos == [0, 0]
+ return [0, 0, 0, 0]
+ endif
+
+ let l:startPos = call('searchpos', [a:pattern, 'bcnW'] + a:000)
+ if l:startPos == [0, 0]
+ let l:selection = [0, 0, 0, 0]
+ else
+ let l:selection = l:startPos + l:endPos
+ endif
+ call winrestview(l:save_view)
+
+ return l:selection
+endfunction
+
+function! ingointegration#SelectCurrentRegexp( selectMode, pattern, ... )
+"******************************************************************************
+"* PURPOSE:
+" Similar to <cword>, create a visual selection of the text region under /
+" after the cursor that matches a:pattern.
+"* ASSUMPTIONS / PRECONDITIONS:
+" None.
+"* EFFECTS / POSTCONDITIONS:
+" Creates a visual selection if a:pattern matches.
+"* INPUTS:
+" a:selectMode Visual selection mode, one of "v", "V", or "\<C-v>".
+" a:pattern Regular expression to match at the cursor position.
+" a:stopline Optional line number where the search will stop. To get a
+" behavior like <cword>, pass in line('.').
+" a:timeout Optional timeout when the search will stop.
+"* RETURN VALUES:
+" 1 if a selection was made, 0 if there was no match.
+"******************************************************************************
+ let [l:startLnum, l:startCol, l:endLnum, l:endCol] = call('ingointegration#GetCurrentRegexpSelection', [a:pattern] + a:000)
+ if [l:startLnum, l:startCol, l:endLnum, l:endCol] == [0, 0, 0, 0]
+ return 0
+ endif
+ call cursor(l:startLnum, l:startCol)
+ execute 'normal! zv' . a:selectMode
+ call cursor(l:endLnum, l:endCol)
+ if &selection ==# 'exclusive'
+ normal! l
+ endif
+ execute "normal! \<Esc>"
+
+ return 1
+endfunction
+
+function! ingointegration#IsFiletype( filetypes )
+ let l:filetypes = (type(a:filetypes) == type([]) ? a:filetypes : [a:filetypes])
+
+ for l:ft in split(&filetype, '\.')
+ if (index(l:filetypes, l:ft) != -1)
+ return 1
+ endif
+ endfor
+
+ return 0
+endfunction
+
+" vim: set ts=8 sts=4 sw=4 noexpandtab ff=unix fdm=syntax :
253 autoload/ingosearch.vim
@@ -0,0 +1,253 @@
+" ingosearch.vim: Custom search functions.
+"
+" DEPENDENCIES:
+" - ingocollections.vim autoload script for ingosearch#NormalizeMagicness().
+"
+" Copyright: (C) 2010-2011 by Ingo Karkat
+" The VIM LICENSE applies to this script; see ':help copyright'.
+"
+" Maintainer: Ingo Karkat <ingo@karkat.de>
+"
+" REVISION DATE REMARKS
+" 007 03-Sep-2011 Extend ingosearch#GetLastForwardSearchPattern()
+" to take optional count into search history.
+" 006 02-Sep-2011 Add ingosearch#GetLastForwardSearchPattern().
+" 005 10-Jun-2011 Add ingosearch#NormalizeMagicness().
+" 004 17-May-2011 Make ingosearch#EscapeText() public.
+" Extract ingosearch#GetSpecialSearchCharacters()
+" from s:specialSearchCharacters and expose it.
+" 003 12-Feb-2010 Added ingosearch#WildcardExprToSearchPattern()
+" from the :Help command in ingocommands.vim.
+" 002 05-Jan-2010 BUG: Wrong escaping with 'nomagic' setting.
+" Corrected s:specialSearchCharacters for that
+" case.
+" Renamed ingosearch#GetSearchPattern() to
+" ingosearch#LiteralTextToSearchPattern().
+" 001 05-Jan-2010 file creation with content from
+" SearchHighlighting.vim.
+
+function! ingosearch#GetSpecialSearchCharacters()
+ " The set of characters that must be escaped depends on the 'magic' setting.
+ return ['^$', '^$.*[~'][&magic]
+endfunction
+function! ingosearch#EscapeText( text, additionalEscapeCharacters )
+"*******************************************************************************
+"* PURPOSE:
+" Escape the literal a:text for use in search command.
+" The ignorant approach is to use atom \V, which sets the following pattern to
+" "very nomagic", i.e. only the backslash has special meaning. For \V, \ still
+" must be escaped. But that's not how the built-in star command works.
+" Instead, all special search characters must be escaped.
+"
+" This works well even with <Tab> (no need to change ^I into \t), but not with
+" a line break, which must be changed from ^M to \n.
+"
+" We also may need to escape additional characters like '/' or '?', because
+" that's done in a search via '*', '/' or '?', too. As the character depends
+" on the search direction ('/' vs. '?'), this is passed in as
+" a:additionalEscapeCharacters.
+"
+"* ASSUMPTIONS / PRECONDITIONS:
+" None.
+"* EFFECTS / POSTCONDITIONS:
+" None.
+"* INPUTS:
+" a:text Literal text.
+" a:additionalEscapeCharacters For use in the / command, add '/', for the
+" backward search command ?, add '?'. For
+" assignment to @/, always add '/', regardless
+" of the search direction; this is how Vim
+" escapes it, too. For use in search(), pass
+" nothing.
+"* RETURN VALUES:
+" Regular expression for matching a:text.
+"*******************************************************************************
+ return substitute( escape(a:text, '\' . ingosearch#GetSpecialSearchCharacters() . a:additionalEscapeCharacters), "\n", '\\n', 'ge' )
+endfunction
+
+function! s:MakeWholeWordSearch( text, isWholeWordSearch, pattern )
+ " The star command only creates a \<whole word\> search pattern if the
+ " <cword> actually only consists of keyword characters.
+ if a:isWholeWordSearch && a:text =~# '^\k\+$'
+ return '\<' . a:pattern . '\>'
+ else
+ return a:pattern
+ endif
+endfunction
+
+function! ingosearch#LiteralTextToSearchPattern( text, isWholeWordSearch, additionalEscapeCharacters )
+"*******************************************************************************
+"* PURPOSE:
+" Convert literal a:text into a regular expression, similar to what the
+" built-in * command does.
+"* ASSUMPTIONS / PRECONDITIONS:
+" None.
+"* EFFECTS / POSTCONDITIONS:
+" None.
+"* INPUTS:
+" a:text Literal text.
+" a:isWholeWordSearch Flag whether only whole words (* command) or any
+" contained text (g* command) should match.
+" a:additionalEscapeCharacters For use in the / command, add '/', for the
+" backward search command ?, add '?'. For
+" assignment to @/, always add '/', regardless
+" of the search direction; this is how Vim
+" escapes it, too. For use in search(), pass
+" nothing.
+"* RETURN VALUES:
+" Regular expression for matching a:text.
+"*******************************************************************************
+ " return '\V' . (a:isWholeWordSearch ? '\<' : '') . substitute( escape(a:text, a:additionalEscapeCharacters . '\'), "\n", '\\n', 'ge' ) . (a:isWholeWordSearch ? '\>' : '')
+ return s:MakeWholeWordSearch( a:text, a:isWholeWordSearch, ingosearch#EscapeText( a:text, a:additionalEscapeCharacters) )
+endfunction
+
+function! ingosearch#WildcardExprToSearchPattern( wildcardExpr, additionalEscapeCharacters )
+"*******************************************************************************
+"* PURPOSE:
+" Convert a shell-like a:wildcardExpr which may contain wildcards ? and * into
+" a regular expression.
+"* ASSUMPTIONS / PRECONDITIONS:
+" None.
+"* EFFECTS / POSTCONDITIONS:
+" None.
+"* INPUTS:
+" a:wildcardExpr Text containing file wildcards.
+" a:additionalEscapeCharacters For use in the / command, add '/', for the
+" backward search command ?, add '?'. For
+" assignment to @/, always add '/', regardless
+" of the search direction; this is how Vim
+" escapes it, too. For use in search(), pass
+" nothing.
+"* RETURN VALUES:
+" Regular expression for matching a:wildcardExpr.
+"*******************************************************************************
+ " From the ? and * and [xyz] wildcards; we emulate the first two here:
+ return '\V' . substitute( substitute( escape(a:wildcardExpr, '\' . a:additionalEscapeCharacters), '?', '\\.', 'g' ), '*', '\\.\\*', 'g' )
+endfunction
+
+function! ingosearch#GetNormalizeMagicnessAtom( pattern )
+"******************************************************************************
+"* PURPOSE:
+" Return normalizing \m (or \M) if a:pattern contains atom(s) that change the
+" default magicness. This makes it possible to append another pattern without
+" having a:pattern affect it.
+"
+"* ASSUMPTIONS / PRECONDITIONS:
+" None.
+"* EFFECTS / POSTCONDITIONS:
+" None.
+"* INPUTS:
+" a:pattern Regular expression to observe.
+"* RETURN VALUES:
+" Normalizing atom or empty string.
+"******************************************************************************
+ let l:normalizingAtom = (&magic ? 'm' : 'M')
+ let l:magicChangeAtoms = substitute('vmMV', l:normalizingAtom, '', '')
+
+ return (a:pattern =~# '\%(\%(^\|[^\\]\)\%(\\\\\)*\\\)\@<!\\[' . l:magicChangeAtoms . ']' ? '\' . l:normalizingAtom : '')
+endfunction
+
+let s:magicAtomsExpr = '\%(\%(^\|[^\\]\)\%(\\\\\)*\\\)\@<!\\[vmMV]'
+function! ingosearch#HasMagicAtoms( pattern )
+ return a:pattern =~# s:magicAtomsExpr
+endfunction
+let s:specialSearchCharacterExpressions = {
+\ 'v': '\W',
+\ 'm': '[\\^$.*[~]',
+\ 'M': '[\\^$]',
+\ 'V': '\\',
+\}
+function! s:ConvertMagicness( pattern, sourceSpecialCharacterExpr, targetSpecialCharacterExpr )
+ let l:isEscaped = 0
+ let l:chars = split(a:pattern, '\zs')
+ for l:index in range(len(l:chars))
+ let l:char = l:chars[l:index]
+
+ if (l:char =~# a:sourceSpecialCharacterExpr) + (l:char =~# a:targetSpecialCharacterExpr) == 1
+ " The current character belongs to different classes in source and target.
+ if l:isEscaped
+ let l:chars[l:index - 1] = ''
+ else
+ let l:chars[l:index] = '\' . l:char
+ endif
+ endif
+
+ if l:char ==# '\'
+ let l:isEscaped = ! l:isEscaped
+ else
+ let l:isEscaped = 0
+ endif
+ endfor
+
+ return join(l:chars, '')
+endfunction
+function! ingosearch#NormalizeMagicness( pattern )
+"******************************************************************************
+"* PURPOSE:
+" Remove any \v, /m, \M, \V atoms from a:pattern that change the magicness,
+" and re-write the pattern (by selective escaping and unescaping) into an
+" equivalent pattern that is based on the current 'magic' setting.
+"
+"* ASSUMPTIONS / PRECONDITIONS:
+" None.
+"* EFFECTS / POSTCONDITIONS:
+" None.
+"* INPUTS:
+" a:pattern Regular expression that may contain atoms that affect the
+" magicness.
+"* RETURN VALUES:
+" Equivalent pattern that has any atoms affecting the magicness removed and is
+" based on the current 'magic' setting.
+"******************************************************************************
+ let l:currentMagicMode = (&magic ? 'm' : 'M')
+ let l:defaultMagicMode = l:currentMagicMode
+ let l:patternFragments = ingocollections#SplitKeepSeparators(a:pattern, s:magicAtomsExpr, 1)
+ " Because we asked to keep any empty fragments, we can easily test whether
+ " there's any work to do.
+ if len(l:patternFragments) == 1
+ return a:pattern
+ endif
+"****D echomsg string(l:patternFragments)
+ for l:fragmentIndex in range(len(l:patternFragments))
+ let l:fragment = l:patternFragments[l:fragmentIndex]
+ if l:fragment =~# s:magicAtomsExpr
+ let l:currentMagicMode = l:fragment[1]
+ let l:patternFragments[l:fragmentIndex] = ''
+ continue
+ endif
+
+ if l:currentMagicMode ==# l:defaultMagicMode
+ " No need for conversion.
+ continue
+ endif
+
+ let l:patternFragments[l:fragmentIndex] = s:ConvertMagicness(
+ \ l:fragment,
+ \ s:specialSearchCharacterExpressions[l:currentMagicMode],
+ \ s:specialSearchCharacterExpressions[l:defaultMagicMode]
+ \)
+ endfor
+"****D echomsg string(l:patternFragments)
+ return join(l:patternFragments, '')
+endfunction
+
+function! ingosearch#GetLastForwardSearchPattern( ... )
+"******************************************************************************
+"* PURPOSE:
+" Get @/, or the a:count'th last search pattern, but also handle the case
+" where the pattern was set from a backward search, and doesn't have "/"
+" characters properly escaped.
+"* ASSUMPTIONS / PRECONDITIONS:
+" None.
+"* EFFECTS / POSTCONDITIONS:
+" None.
+"* INPUTS:
+" None.
+"* RETURN VALUES:
+" Last search pattern ready to use in a :s/{pat}/ command, with forward
+" slashes properly escaped.
+"******************************************************************************
+ return substitute((a:0 ? histget('search', -1 * a:1) : @/), '\%(\%(^\|[^\\]\)\%(\\\\\)*\\\)\@<!/', '\\/', 'g')
+endfunction
+
+" vim: set ts=8 sts=4 sw=4 noexpandtab ff=unix fdm=syntax :
413 autoload/ingowindow.vim
@@ -0,0 +1,413 @@
+" ingowindow.vim: Custom window functions.
+"
+" Maintainer: Ingo Karkat <ingo@karkat.de>
+" REVISION DATE REMARKS
+" 018 12-Jul-2012 Add optional a:folddirection to
+" ingowindow#RelativeWindowLine().
+" 017 11-Jul-2012 Add ingowindow#RelativeWindowLine().
+" 016 30-May-2012 ENH: Allow custom preview window placement for
+" ingowindow#OpenPreview() via
+" g:previewwindowsplitmode.
+" 015 08-Feb-2012 Add ingowindow#DisplayedLines().
+" 014 11-Jan-2012 Corrected naming of
+" ingowindow#IsQuickfixWindowVisible() to
+" ingowindow#IsPreviewWindowVisible(); what was I
+" thinking?
+" Overloaded ingowindow#IsQuickfixList() to also
+" determine the type.
+" 013 04-Sep-2011 Extract ingowindow#GetNumberWidth() for use in
+" ingodiff#DiffPrint().
+" 012 30-Apr-2011 Add ingowindow#IsQuickfixWindowVisible().
+" 011 29-Apr-2011 Move ingowindow#SplitToPreview() and
+" ingowindow#GotoPreview() from
+" plugin/ingowindowmappings.vim.
+" 010 15-Apr-2011 Renamed ingowindow#IsQuickfixWindow() to
+" ingowindow#IsQuickfixList(), because it also
+" detects location lists.
+" 009 10-Dec-2010 Simplified ingowindow#IsQuickfixList().
+" 008 08-Dec-2010 Moved s:GotoPreviousWindow() from
+" ingowindowmappings.vim here for reuse.
+" Added ingowindow#IsQuickfixList() and
+" ingowindow#ParseFileFromQuickfixList().
+" 007 10-Sep-2010 ingowindow#NetWindowWidth() now considers
+" 'relativenumber' setting introduced in Vim 7.3.
+" 006 02-Dec-2009 Added ingowindow#WindowDecorationColumns() and
+" ingowindow#NetWindowWidth(), taken from
+" LimitWindowWidth.vim.
+" ENH: Implemented support for adjusted
+" numberwidth and sign column to
+" ingowindow#WindowDecorationColumns().
+" 005 27-Jun-2009 Added augroup.
+" 004 04-Aug-2008 ingowindow#FoldedLines() also returns number of
+" folds in range.
+" 003 03-Aug-2008 Added ingowindow#FoldedLines() and
+" ingowindow#NetVisibleLines().
+" 002 31-Jul-2008 Added ingowindow#UndefineMappingForCmdwin().
+" 001 31-Jul-2008 Moved common window movement mappings from
+" ingowindowmappings.vim
+" file creation
+
+" Special windows are preview, quickfix (and location lists, which is also of
+" type 'quickfix').
+function! ingowindow#IsSpecialWindow(...)
+ let l:winnr = (a:0 > 0 ? a:1 : winnr())
+ return getwinvar(l:winnr, '&previewwindow') || getwinvar(l:winnr, '&buftype') ==# 'quickfix'
+endfunction
+function! ingowindow#SaveSpecialWindowSize()
+ let s:specialWindowSizes = {}
+ for w in range(1, winnr('$'))
+ if ingowindow#IsSpecialWindow(w)
+ let s:specialWindowSizes[w] = [winwidth(w), winheight(w)]
+ endif
+ endfor
+endfunction
+function! ingowindow#RestoreSpecialWindowSize()
+ for w in keys(s:specialWindowSizes)
+ execute 'vert' w.'resize' s:specialWindowSizes[w][0]
+ execute w.'resize' s:specialWindowSizes[w][1]
+ endfor
+endfunction
+
+function! ingowindow#GotoPreviousWindow()
+"*******************************************************************************
+"* PURPOSE:
+" Goto the previous window (CTRL-W_p). If there is no previous window, but
+" only one other window, go there.
+"
+"* ASSUMPTIONS / PRECONDITIONS:
+" None.
+"* EFFECTS / POSTCONDITIONS:
+" Changes the current window, or:
+" Prints error message.
+"* INPUTS:
+" None.
+"* RETURN VALUES:
+" 1 on success, 0 if there is no previous window.
+"*******************************************************************************
+ let l:problem = ''
+ let l:window = 'p'
+
+ if winnr('$') == 1
+ let l:problem = 'Only one window'
+ elseif winnr('#') == 0 || winnr('#') == winnr()
+ if winnr('$') == 2
+ " There is only one more window, we take that one.
+ let l:window = 'w'
+ else
+ let l:problem = 'No previous window'
+ endif
+ endif
+ if ! empty(l:problem)
+ echohl WarningMsg
+ let v:warningmsg = l:problem
+ echomsg v:warningmsg
+ echohl None
+ return 0
+ endif
+
+ execute 'noautocmd' 'wincmd' l:window
+ return 1
+endfunction
+
+
+function! ingowindow#OpenPreview( ... )
+ " Note: We do not use :pedit to open the current file in the preview window,
+ " because that command reloads the current buffer, which would fail (nobang)
+ " / forcibly write (bang) it, and reset the current folds.
+ "execute 'pedit! +' . escape( 'call setpos(".", ' . string(getpos('.')) . ')', ' ') . ' %'
+ try
+ " If the preview window is open, just go there.
+ wincmd P
+ catch /^Vim\%((\a\+)\)\=:E441/
+ " Else, temporarily open a dummy file. (There's no :popen command.)
+ execute 'silent' (a:0 ? a:1 : '') (exists('g:previewwindowsplitmode') ? g:previewwindowsplitmode : '') 'pedit +setlocal\ buftype=nofile\ bufhidden=wipe\ nobuflisted\ noswapfile [No\ Name]'
+ wincmd P
+ endtry
+endfunction
+function! ingowindow#SplitToPreview( ... )
+ if &l:previewwindow
+ wincmd p
+ if &l:previewwindow | return 0 | endif
+ endif
+
+ let l:cursor = getpos('.')
+ let l:bufnum = bufnr('')
+
+ call ingowindow#OpenPreview()
+
+ " Load the current buffer in the preview window, if it's not already there.
+ if bufnr('') != l:bufnum
+ silent execute l:bufnum . 'buffer'
+ endif
+
+ " Clone current cursor position to preview window (which now shows the same
+ " file) or passed position.
+ call setpos('.', (a:0 ? a:1 : l:cursor))
+ return 1
+endfunction
+function! ingowindow#GotoPreview()
+ if &l:previewwindow | return | endif
+ try
+ wincmd P
+ catch /^Vim\%((\a\+)\)\=:E441/
+ call ingowindow#SplitToPreview()
+ endtry
+endfunction
+
+
+function! ingowindow#IsPreviewWindowVisible()
+ for l:winnr in range(1, winnr('$'))
+ if getwinvar(l:winnr, '&previewwindow')
+ " There's still a preview window.
+ return l:winnr
+ endif
+ endfor
+
+ return 0
+endfunction
+
+function! ingowindow#IsQuickfixList( ... )
+"******************************************************************************
+"* PURPOSE:
+" Check whether the current window is the quickfix window or a location list.
+"* ASSUMPTIONS / PRECONDITIONS:
+" None.
+"* EFFECTS / POSTCONDITIONS:
+" None.
+"* INPUTS:
+" determineType Flag whether it should also be attempted to determine the
+" type (global quickfix / local location list).
+"* RETURN VALUES:
+" Boolean when no a:determineType is given. Else:
+" 1 if the current window is the quickfix window.
+" 2 if the current window is a location list window.
+" 0 for any other window.
+"******************************************************************************
+ if &buftype !=# 'quickfix'
+ return 0
+ elseif a:0
+ " Try to determine the type; this heuristic only fails when the location
+ " list exists but is empty.
+ return (empty(getloclist(0)) ? 1 : 2)
+ else
+ return 1
+ endif
+endfunction
+function! ingowindow#ParseFileFromQuickfixList()
+ return (ingowindow#IsQuickfixList() ? matchstr(getline('.'), '^.\{-}\ze|') : '')
+endfunction
+
+
+" The command-line window is implemented as a window, so normal mode mappings
+" apply here as well. However, certain actions cannot be performed in this
+" special window. The 'CmdwinEnter' event can be used to redefine problematic
+" normal mode mappings.
+let s:CmdwinMappings = {}
+function! ingowindow#UndefineMappingForCmdwin( mappings, ... )
+"*******************************************************************************
+"* PURPOSE:
+" Register mappings that should be undefined in the command-line window.
+" Previously registered mappings equal to a:mappings will be overwritten.
+"* ASSUMPTIONS / PRECONDITIONS:
+" none
+"* EFFECTS / POSTCONDITIONS:
+" :nnoremap <buffer> the a:mapping
+"* INPUTS:
+" a:mapping Mapping (or list of mappings) to be undefined.
+" a:alternative Optional mapping to be used instead. If omitted, the
+" a:mapping is undefined (i.e. mapped to itself). If empty,
+" a:mapping is mapped to <Nop>.
+"* RETURN VALUES:
+" 1 if accepted; 0 if autocmds not available
+"*******************************************************************************
+ let l:alternative = (a:0 > 0 ? (empty(a:1) ? '<Nop>' : a:1) : '')
+
+ if type(a:mappings) == type([])
+ let l:mappings = a:mappings
+ elseif type(a:mappings) == type('')
+ let l:mappings = [ a:mappings ]
+ else
+ throw 'passed invalid type ' . type(a:mappings)
+ endif
+ for l:mapping in l:mappings
+ let s:CmdwinMappings[ l:mapping ] = l:alternative
+ endfor
+ return has('autocmd')
+endfunction
+function! s:UndefineMappings()
+ for l:mapping in keys(s:CmdwinMappings)
+ let l:alternative = s:CmdwinMappings[ l:mapping ]
+ execute 'nnoremap <buffer> ' . l:mapping . ' ' . (empty(l:alternative) ? l:mapping : l:alternative)
+ endfor
+endfunction
+if has('autocmd')
+ augroup ingowindow
+ autocmd!
+ autocmd CmdwinEnter * call <SID>UndefineMappings()
+ augroup END
+endif
+
+
+
+function! s:FoldBorder( lnum, direction )
+ let l:foldBorder = (a:direction < 0 ? foldclosed(a:lnum) : foldclosedend(a:lnum))
+ return (l:foldBorder == -1 ? a:lnum : l:foldBorder)
+endfunction
+function! ingowindow#RelativeWindowLine( lnum, count, direction, ... )
+"******************************************************************************
+"* PURPOSE:
+" Determine the line number a:count visible (i.e. not folded) lines away from
+" a:lnum, including all lines in closed folds.
+"* ASSUMPTIONS / PRECONDITIONS:
+" None.
+"* EFFECTS / POSTCONDITIONS:
+" None.
+"* INPUTS:
+" a:lnum Line number to base the calculation on.
+" a:count Number of visible lines away from a:lnum.
+" a:direction -1 for upward, 1 for downward relative movement of a:count lines
+" a:folddirection for a fold at the target, return the fold start lnum when
+" -1, or the fold end lnum when 1. Defaults to a:direction,
+" which amounts to the maximum covered lines, i.e. for upward
+" movement, the fold start, for downward movement, the fold
+" end
+"* RETURN VALUES:
+" line number, or -1 if the relative line is out of the range of the lines in
+" the buffer.
+"******************************************************************************
+ let l:lnum = a:lnum
+ let l:count = a:count
+
+ while l:count > 0
+ let l:lnum = s:FoldBorder(l:lnum, a:direction) + a:direction
+ if a:direction < 0 && l:lnum < 1 || a:direction > 0 && l:lnum > line('$')
+ return -1
+ endif
+
+ let l:count -= 1
+ endwhile
+
+ return s:FoldBorder(l:lnum, (a:0 ? a:1 : a:direction))
+endfunction
+
+
+" Determine the number of lines in the passed range that lie hidden in a closed
+" fold; that is, everything but the first line of a closed fold.
+" Returns [ number of folds in range, number of folded away (i.e. invisible)
+" lines ]. Sum both values to get the total number of lines in a fold in the
+" passed range.
+function! ingowindow#FoldedLines( startLine, endLine )
+ let l:foldCnt = 0
+ let l:foldedAwayLines = 0
+ let l:line = a:startLine
+
+ while l:line < a:endLine
+ if foldclosed(l:line) == l:line
+ let l:foldCnt += 1
+ let l:foldend = foldclosedend(l:line)
+ let l:foldedAwayLines += (l:foldend > a:endLine ? a:endLine : l:foldend) - l:line
+ let l:line = l:foldend
+ endif
+ let l:line += 1
+ endwhile
+
+ return [ l:foldCnt, l:foldedAwayLines ]
+endfunction
+
+" Determine the number of lines in the passed range that aren't folded away;
+" folded ranges count only as one line. Visible doesn't mean "currently
+" displayed in the window"; for that, you could create the difference of the
+" start and end winline(), or use ingowindow#DisplayedLines().
+function! ingowindow#NetVisibleLines( startLine, endLine )
+ return a:endLine - a:startLine + 1 - ingowindow#FoldedLines(a:startLine, a:endLine)[1]
+endfunction
+
+" Determine the range of lines that are currently displayed in the window.
+function! ingowindow#DisplayedLines()
+ let l:startLine = winsaveview().topline
+ let l:endLine = l:startLine
+ let l:screenLineCnt = 0
+ while l:screenLineCnt < winheight(0)
+ let l:lastFoldedLine = foldclosedend(l:endLine)
+ if l:lastFoldedLine == -1
+ let l:endLine += 1
+ else
+ let l:endLine = l:lastFoldedLine + 1
+ endif
+
+ let l:screenLineCnt += 1
+ endwhile
+
+ return [l:startLine, l:endLine - 1]
+endfunction
+
+
+
+function! ingowindow#GetNumberWidth( isGetAbsoluteNumberWidth )
+"******************************************************************************
+"* PURPOSE:
+" Get the width of the number column for the current window.
+"* ASSUMPTIONS / PRECONDITIONS:
+" None.
+"* EFFECTS / POSTCONDITIONS:
+" None.
+"* INPUTS:
+" a:isGetAbsoluteNumberWidth If true, assumes absolute number are requested.
+" Otherwise, determines whether 'number' or
+" 'relativenumber' are actually set and calculates
+" based on the actual window settings.
+"* RETURN VALUES:
+" Width for displaying numbers. To use the result for printf()-style
+" formatting of numbers, subtract 1:
+" printf('%' . (ingowindow#GetNumberWidth(1) - 1) . 'd', l:lnum)
+"******************************************************************************
+ let l:maxNumber = 0
+ " Note: 'numberwidth' is only the minimal width, can be more if...
+ if &l:number || a:isGetAbsoluteNumberWidth
+ " ...the buffer has many lines.
+ let l:maxNumber = line('$')
+ elseif exists('+relativenumber') && &l:relativenumber
+ " ...the window width has more digits.
+ let l:maxNumber = winheight(0)
+ endif
+ if l:maxNumber > 0
+ let l:actualNumberWidth = strlen(string(l:maxNumber)) + 1
+ return (l:actualNumberWidth > &l:numberwidth ? l:actualNumberWidth : &l:numberwidth)
+ else
+ return 0
+ endif
+endfunction
+
+" Determine the number of virtual columns of the current window that are not
+" used for displaying buffer contents, but contain window decoration like line
+" numbers, fold column and signs.
+function! ingowindow#WindowDecorationColumns()
+ let l:decorationColumns = 0
+ let l:decorationColumns += ingowindow#GetNumberWidth(0)
+
+ if has('folding')
+ let l:decorationColumns += &l:foldcolumn
+ endif
+
+ if has('signs')
+ redir => l:signsOutput
+ silent execute 'sign place buffer=' . bufnr('')
+ redir END
+
+ " The ':sign place' output contains two header lines.
+ " The sign column is fixed at two columns.
+ if len(split(l:signsOutput, "\n")) > 2
+ let l:decorationColumns += 2
+ endif
+ endif
+
+ return l:decorationColumns
+endfunction
+
+" Determine the number of virtual columns of the current window that are
+" available for displaying buffer contents.
+function! ingowindow#NetWindowWidth()
+ return winwidth(0) - ingowindow#WindowDecorationColumns()
+endfunction
+
+" vim: set ts=8 sts=4 sw=4 noexpandtab ff=unix fdm=syntax :
155 doc/GrepHere.txt
@@ -0,0 +1,155 @@
+*GrepHere.txt* List occurrences in the current buffer in the quickfix window.
+
+ GREP HERE by Ingo Karkat
+ *GrepHere.vim*
+description |GrepHere-description|
+usage |GrepHere-usage|
+installation |GrepHere-installation|
+configuration |GrepHere-configuration|
+limitations |GrepHere-limitations|
+known problems |GrepHere-known-problems|
+todo |GrepHere-todo|
+history |GrepHere-history|
+
+==============================================================================
+DESCRIPTION *GrepHere-description*
+
+This plugin defines a command and mappings to quickly list all occurrences of
+the current search pattern, passed pattern, current word or selection in the
+|quickfix| list. This is useful to get a somewhat persistent list of matches
+that act like bookmarks, so you can recall them later (when your search
+pattern has changed).
+
+HOW IT WORKS *
+
+The plugin uses |:vimgrep| over the current buffer.
+
+SOURCE *
+
+Inspired by vimtip #483: Using GREP for a "list occurrences" and quickfix help
+command.
+ http://vim.wikia.com/wiki/Search_using_quickfix_to_list_occurrences >
+ command GREP :execute 'grep '.expand('<cword>') expand('%') | :copen | cc
+<
+SEE ALSO *
+
+- The GrepCommands plugin (vimscript #4173) provides additional grep commands
+ covering arguments, buffers, windows and tab pages.
+- The FindOccurrence plugin (vimscript #0000) can also show all occurrences of
+ the <cword>, current search results, etc., but instead of the quickfix list,
+ the result is either jumped to or listed.
+- The SearchPosition plugin (vimscript #2634) shows the relation of the cursor
+ position to the other matches of the search pattern, and provides similar
+ mappings. Like the quickfix list, it can provide an orientation of where and
+ how many matches there are.
+
+RELATED WORKS *
+
+- outline (vimscript #1947) creates a custom view of the file based on regex,
+ in a scratch buffer
+- ttoc (vimscript #2014) is based on outline and creates a regexp-based table
+ of contents of the current buffer
+
+==============================================================================
+USAGE *GrepHere-usage*
+ *:GrepHere* *:GrepHereAdd*
+:GrepHere [{pattern}]
+:GrepHere /{pattern}/[g][j]
+:GrepHereAdd [{pattern}]
+:GrepHereAdd /{pattern}/[g][j]
+ Grep the passed pattern (or current search pattern if
+ omitted) in the current file (or the current entry of
+ the quickfix list).
+
+ *ALT-SHIFT-N*
+<A-N> Grep the current search pattern in the current file
+ and show matching lines in the quickfix window (but
+ don't go there).
+ This is similar to |[N| defined by
+ |FindOccurrence.vim|, but uses the quickfix list
+ instead of just printing all matching lines.
+
+ *ALT-SHIFT-M* *v_ALT-SHIFT-M*
+<A-M> Grep the current whole word under the cursor in the
+ current file and show matching lines in the quickfix
+ window (but don't go there).
+ This is similar to |[I| defined by
+ |FindOccurrence.vim|, but uses the quickfix list
+ instead of just printing all matching lines.
+g<A-M> Grep the current word under the cursor in the current
+ file and show matching lines in the quickfix window
+ (but don't go there).
+ Only whole keywords are searched for, like with the
+ |star| command.
+{Visual}<A-M> Grep the selected text in the current file and show
+ matching lines in the quickfix window (but don't go
+ there).
+
+ Imagine 'M' stood for "more occurrences".
+ These mappings reuse the last used <cword> when issued
+ on a blank line.
+
+==============================================================================
+INSTALLATION *GrepHere-installation*
+
+This script is packaged as a |vimball|. If you have the "gunzip" decompressor
+in your PATH, simply edit the *.vmb.gz package in Vim; otherwise, decompress
+the archive first, e.g. using WinZip. Inside Vim, install by sourcing the
+vimball or via the |:UseVimball| command. >
+ vim GrepHere*.vmb.gz
+ :so %
+To uninstall, use the |:RmVimball| command.
+
+DEPENDENCIES *GrepHere-dependencies*
+
+- Requires Vim 7.0 or higher.
+- Requires the |GrepCommands.vim| plugin (vimscript #4173).
+
+==============================================================================
+CONFIGURATION *GrepHere-configuration*
+
+For a permanent configuration, put the following commands into your |vimrc|:
+
+ *g:GrepHere_MappingGrepFlags*
+By default, the mappings list all occurrences in a line and do not jump to the
+first match; you can adapt the behavior by removing some of the |:vimgrep|
+flags: >
+ let g:GrepHere_MappingGrepFlags = 'gj'
+<
+
+If you want to use different mappings, map your keys to the
+<Plug>(GrepHere...) mapping targets _before_ sourcing the script (e.g. in your
+|vimrc|): >
+ nmap <Leader>N <Plug>(GrepHereCurrent)
+ nmap <Leader>M <Plug>(GrepHereWholeCword)
+ nmap <Leader>gM <Plug>(GrepHereCword)
+ vmap <Leader>M <Plug>(GrepHereCword)
+<
+==============================================================================
+LIMITATIONS *GrepHere-limitations*
+
+- Unnamed buffers cannot be searched via |:vimgrep|, resulting in "E32: no
+ file name".
+
+KNOWN PROBLEMS *GrepHere-known-problems*
+
+TODO *GrepHere-todo*
+
+IDEAS *GrepHere-ideas*
+
+==============================================================================
+HISTORY *GrepHere-history*
+
+1.00 24-Aug-2012
+First published version.
+
+0.01 11-Jun-2003
+Started development.
+
+==============================================================================
+Copyright: (C) 2003-2012 Ingo Karkat
+The VIM LICENSE applies to this script; see |copyright|.
+
+Maintainer: Ingo Karkat <ingo@karkat.de>
+==============================================================================
+ vim:tw=78:ts=8:ft=help:norl:
87 plugin/GrepHere.vim
@@ -0,0 +1,87 @@
+" GrepHere.vim: List occurrences in the current buffer in the quickfix window.
+"
+" DEPENDENCIES:
+" - GrepHere.vim autoload script
+" - ingointegration.vim autoload script
+"
+" Copyright: (C) 2003-2012 Ingo Karkat
+" The VIM LICENSE applies to this script; see ':help copyright'.
+
+" Maintainer: Ingo Karkat <ingo@karkat.de>
+"
+" REVISION DATE REMARKS
+" 1.00.011 24-Aug-2012 Add mappings for the [whole] <cword> and visual
+" selection, and align the mapping keys with the
+" SearchPosition plugin.
+" Factor out the mapping logic to GrepHere#List().
+" Extract g:GrepHere_MappingGrepFlags.
+" 010 21-Mar-2012 Rename to GrepHere.vim, define <Plug>-mapping,
+" factor out function to autoload script and
+" separate documentation.
+" 009 19-Mar-2012 Extract vimgrep wrapping to new GrepCommands
+" plugin for reuse.
+" 008 15-Apr-2011 Renamed ingowindow#IsQuickfixWindow() to
+" ingowindow#IsQuickfixList(), because it also
+" detects location lists.
+" 007 08-Dec-2010 Moved 'grepprg' setting to .vimrc.
+" Complete reimplementation of :GrepHere,
+" combining it with :GrepSearch. Script is Vim 7
+" and later now.
+" Added :GrepAddHere command.
+" Changed behavior of <A-?> so that only the
+" quickfix window is opened, but the cursor stays
+" in the original window.
+" 006 28-Jun-2008 Added Windows detection via has('win64').
+" 005 13-Jun-2008 Added -bar to all commands that do not take any
+" arguments, so that these can be chained together.
+" 0.04 26-Jul-2006 BF: Passing <q-args> escaped backslashes,
+" disallowing things like :GrepSearch \sfoo\s\+
+" Added g:ingogrep_no_vimgrep customization.
+" 0.03 11-May-2006 VIM7: Now using :vimgrep instead of external
+" grep.
+" BF: Wrong filename enclosing single quotes
+" caused shell error 1 on :GrepSearch.
+" 0.02 13-Aug-2004 Make grep work for single files (grep -H)
+" 0.01 11-Jun-2003 file creation
+
+" Avoid installing twice or when in unsupported Vim version.
+if exists('g:loaded_GrepHere') || v:version < 700
+ finish
+endif
+let g:loaded_GrepHere = 1
+
+"- configuration ---------------------------------------------------------------
+
+if ! exists('g:GrepHere_MappingGrepFlags')
+ let g:GrepHere_MappingGrepFlags = 'gj'
+endif
+
+
+"- commands --------------------------------------------------------------------
+
+command! -count -nargs=? GrepHere call GrepHere#Grep(<count>, 'vimgrep', <q-args>)
+command! -count -nargs=? GrepHereAdd call GrepHere#Grep(<count>, 'vimgrepadd', <q-args>)
+
+
+"- mappings --------------------------------------------------------------------
+
+nnoremap <silent> <Plug>(GrepHereCurrent) :<C-u>call GrepHere#List('')<CR>
+nnoremap <silent> <Plug>(GrepHereWholeCword) :<C-u>call GrepHere#List(GrepHere#SetCword(1))<CR>
+nnoremap <silent> <Plug>(GrepHereCword) :<C-u>call GrepHere#List(GrepHere#SetCword(0))<CR>
+vnoremap <silent> <Plug>(GrepHereCword) :<C-u>call GrepHere#List(substitute(ingointegration#GetVisualSelection(), "\n", '\\n', 'g'))<CR>
+if ! hasmapto('<Plug>(GrepHereCurrent)', 'n')
+ nmap <A-N> <Plug>(GrepHereCurrent)
+endif
+if ! hasmapto('<Plug>(GrepHereWholeCword)', 'n')
+ nmap <A-M> <Plug>(GrepHereWholeCword)
+endif
+if ! hasmapto('<Plug>(GrepHereCword)', 'n')
+ nmap g<A-M> <Plug>(GrepHereCword)
+endif
+if ! hasmapto('<Plug>(GrepHereCword)', 'v')
+ vmap <A-M> <Plug>(GrepHereCword)
+endif
+
+
+
+" vim: set ts=8 sts=4 sw=4 noexpandtab ff=unix fdm=syntax :
Please sign in to comment.
Something went wrong with that request. Please try again.