(add see also section) |
(→See also: link to target of merged link) |
||
(6 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
+ | {{TipNew |
||
− | This is a little function you can use to quickly filter a whole buffer for a term, with a convenient shortcut for the term you just searched for (available in register <tt>@/</tt>). It's similar to the search function in e.g. mutt or mocp, only the output is written to a scratch buffer rather than modifying the current buffer. If you want the former behaviour, use an Ex command like <tt>:v/EXP/d</tt>, which deletes all lines that don't match <tt>EXP</tt>. |
||
+ | |id=1557 |
||
+ | |previous=1556 |
||
+ | |next=1558 |
||
+ | |created=2008 |
||
+ | |complexity=basic |
||
⚫ | |||
+ | |version=7.0 |
||
+ | |subpage=/200804 |
||
+ | |category1= |
||
+ | |category2= |
||
+ | }} |
||
+ | You may want to list all lines in the current buffer that match a pattern, for example, list all lines containing "Warning". The following script copies all matching lines to a scratch (temporary) buffer. You can then examine the list, or save it to a file. |
||
+ | |||
+ | Create a file called (for example) filter.vim containing: |
||
<pre> |
<pre> |
||
⚫ | |||
− | + | function! Gather(pattern) |
|
− | + | if !empty(a:pattern) |
|
⚫ | |||
⚫ | |||
⚫ | |||
+ | " append search hits to results list |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
+ | 1d " delete initial blank line |
||
endif |
endif |
||
⚫ | |||
⚫ | |||
+ | " Delete the current buffer if it is a scratch buffer (any changes are lost). |
||
− | " fill gather list, return if there are no results |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
+ | return 1 |
||
⚫ | |||
⚫ | |||
⚫ | |||
+ | return 0 |
||
− | return |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
− | new |
||
⚫ | |||
⚫ | |||
− | setlocal bufhidden=hide |
||
− | setlocal noswapfile |
||
⚫ | |||
− | |||
⚫ | |||
− | for line in gather_list |
||
⚫ | |||
− | endfor |
||
− | normal ddgg |
||
− | unlet gather_list |
||
⚫ | |||
</pre> |
</pre> |
||
+ | In Vim, the command <code>:source filter.vim</code> will execute the script. |
||
− | This function can be used to quickly close a scratch buffer. I mapped it to <Esc> in normal mode, so that's the keystroke this function defaults to if the current buffer is not a scratch buffer. We don't want to close "real" buffers that easy. You might want to change that line to the key you're mapping this function onto. |
||
+ | Assuming the default leader key (backslash), you can now: |
||
⚫ | |||
+ | *Type <code>\f</code> and enter a pattern when prompted. |
||
⚫ | |||
+ | *Type <code>\F</code> to filter on the last search pattern. |
||
⚫ | |||
+ | *Press Escape to close the scratch buffer listing the search hits. |
||
⚫ | |||
− | else |
||
− | " this is not a scratch buffer |
||
− | normal! "<Esc>" |
||
⚫ | |||
⚫ | |||
+ | For example, you could put the cursor on a word and press <code>*</code> to search for the next occurrence of that word. If you now type <code>\F</code> a new window will open with a list of all lines that contain the word you searched for. Press Escape to close the window. |
||
− | And finally some key mappings to make it all available. I'm using <tt>,</tt> as a mapleader and find using "generic" binding such as <tt>execute "nmap" g:mapleader."f :call Whatever()<CR>"</tt> not very readable in my vimrc. Adjust as needed. |
||
+ | ==Alternative procedures== |
||
⚫ | |||
+ | A simple procedure to list all lines matching a pattern is: |
||
⚫ | |||
+ | <pre> |
||
⚫ | |||
+ | " Print all lines that contain "pattern". |
||
+ | :g/pattern/p |
||
+ | " Following is equivalent. |
||
+ | :g/pattern |
||
+ | </pre> |
||
+ | The following will delete all lines that do not contain a pattern, leaving only the search hits. You could then press <code>u</code> to undo the changes. |
||
− | In this case, <tt>,f</tt> asks the user for input, <tt>,F</tt> re-uses the search register. |
||
+ | <pre> |
||
+ | :v/pattern/d |
||
+ | </pre> |
||
⚫ | |||
⚫ | |||
− | |||
⚫ | |||
*[[Folding with Regular Expression]] to fold away lines without a search pattern rather than modifying it or using a scratch buffer |
*[[Folding with Regular Expression]] to fold away lines without a search pattern rather than modifying it or using a scratch buffer |
||
+ | *[[Search_for_lines_not_containing_pattern_and_other_helpful_searches#Using_the_:v_command]] for some simple techniques to display lines of interest |
||
+ | *[[VimTip478|Copy the search results into clipboard]] to copy matching patterns (not lines) |
||
+ | *[[VimTip1063|Redirect g search output]] uses <code>:redir</code> with <code>g//p</code> for a limited one-line version of this tip |
||
+ | *[[VimTip1141|List lines with current search pattern highlighted]] defines command <code>PP</code> to highlight matches displayed with <code>:g//PP</code> |
||
+ | |||
+ | ==Comments== |
Latest revision as of 15:25, 1 July 2013
created 2008 · complexity basic · author Niels AdB · version 7.0
You may want to list all lines in the current buffer that match a pattern, for example, list all lines containing "Warning". The following script copies all matching lines to a scratch (temporary) buffer. You can then examine the list, or save it to a file.
Create a file called (for example) filter.vim containing:
" Gather search hits, and display in a new scratch buffer. function! Gather(pattern) if !empty(a:pattern) let save_cursor = getpos(".") let orig_ft = &ft " append search hits to results list let results = [] execute "g/" . a:pattern . "/call add(results, getline('.'))" call setpos('.', save_cursor) if !empty(results) " put list in new scratch buffer new setlocal buftype=nofile bufhidden=hide noswapfile execute "setlocal filetype=".orig_ft call append(1, results) 1d " delete initial blank line endif endif endfunction " Delete the current buffer if it is a scratch buffer (any changes are lost). function! CloseScratch() if &buftype == "nofile" && &bufhidden == "hide" && !&swapfile " this is a scratch buffer bdelete return 1 endif return 0 endfunction nnoremap <silent> <Leader>f :call Gather(input("Search for: "))<CR> nnoremap <silent> <Leader>F :call Gather(@/)<CR> nnoremap <silent> <Esc> :call CloseScratch()<CR>
In Vim, the command :source filter.vim
will execute the script.
Assuming the default leader key (backslash), you can now:
- Type
\f
and enter a pattern when prompted. - Type
\F
to filter on the last search pattern. - Press Escape to close the scratch buffer listing the search hits.
For example, you could put the cursor on a word and press *
to search for the next occurrence of that word. If you now type \F
a new window will open with a list of all lines that contain the word you searched for. Press Escape to close the window.
Alternative procedures[]
A simple procedure to list all lines matching a pattern is:
" Print all lines that contain "pattern". :g/pattern/p " Following is equivalent. :g/pattern
The following will delete all lines that do not contain a pattern, leaving only the search hits. You could then press u
to undo the changes.
:v/pattern/d
See also[]
- Folding with Regular Expression to fold away lines without a search pattern rather than modifying it or using a scratch buffer
- Search_for_lines_not_containing_pattern_and_other_helpful_searches#Using_the_:v_command for some simple techniques to display lines of interest
- Copy the search results into clipboard to copy matching patterns (not lines)
- Redirect g search output uses
:redir
withg//p
for a limited one-line version of this tip - List lines with current search pattern highlighted defines command
PP
to highlight matches displayed with:g//PP