Line 9: |
Line 9: |
|
|subpage=/200804 |
|
|subpage=/200804 |
|
}} |
|
}} |
− |
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>.
|
+ |
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( line_pattern )
|
+ |
" Gather search hits, and display in a new scratch buffer. |
− |
if empty(a:line_pattern) |
+ |
function! Gather(pattern) |
− |
return |
+ |
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 |
|
endif |
− |
|
|
− |
" fill gather list, return if there are no results |
|
− |
let gather_list = [] |
|
− |
let l:orig = getpos(".") |
|
− |
let l:orig_ft = &ft |
|
− |
execute "g/" . a:line_pattern . "/call insert(gather_list, getline(\".\"))" |
|
− |
call setpos(".", l:orig) |
|
− |
if empty(gather_list) |
|
− |
return |
|
− |
endif |
|
− |
|
|
− |
" create new scratch buffer |
|
− |
new |
|
− |
setlocal buftype=nofile |
|
− |
setlocal bufhidden=hide |
|
− |
setlocal noswapfile |
|
− |
execute "setlocal filetype=".l:orig_ft |
|
− |
|
|
− |
" copy all results in the new scratch buffer |
|
− |
for line in gather_list |
|
− |
call append(0, line) |
|
− |
endfor |
|
− |
normal ddgg |
|
− |
unlet gather_list |
|
|
endfunction |
|
endfunction |
− |
</pre> |
|
|
|
|
|
− |
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 easily. You might want to change that line to the key you're mapping this function onto.
|
+ |
" Delete the current buffer if it is a scratch buffer (any changes are lost). |
− |
|
|
− |
<pre> |
|
|
function! CloseScratch() |
|
function! CloseScratch() |
|
if &buftype == "nofile" && &bufhidden == "hide" && !&swapfile |
|
if &buftype == "nofile" && &bufhidden == "hide" && !&swapfile |
|
" this is a scratch buffer |
|
" this is a scratch buffer |
|
bdelete |
|
bdelete |
− |
else |
+ |
return 1 |
− |
" this is not a scratch buffer |
|
− |
normal! "<Esc>" |
|
|
endif |
|
endif |
|
+ |
return 0 |
|
endfunction |
|
endfunction |
|
+ |
|
|
+ |
nnoremap <silent> <Leader>f :call Gather(input("Search for: "))<CR> |
|
+ |
nnoremap <silent> <Leader>F :call Gather(@/)<CR> |
|
+ |
nnoremap <silent> <Esc> :call CloseScratch()<CR> |
|
</pre> |
|
</pre> |
|
|
|
|
− |
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.
|
+ |
In Vim, the command <tt>:source filter.vim</tt> will execute the script. |
|
|
|
|
|
+ |
Assuming the default leader key (backslash), you can now: |
|
+ |
*Type <tt>\f</tt> and enter a pattern when prompted. |
|
+ |
*Type <tt>\F</tt> 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 <tt>*</tt> to search for the next occurrence of that word. If you now type <tt>\F</tt> 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: |
|
<pre> |
|
<pre> |
− |
nmap ,f :call Gather( input("Filter on term: ") )<CR>
|
+ |
" Print all lines that contain "pattern". |
− |
nmap ,F :call Gather( @/ )<CR>
|
+ |
:g/pattern/p |
− |
nmap <Esc> :call CloseScratch()<CR>
|
+ |
" Following is equivalent. |
|
+ |
:g/pattern |
|
</pre> |
|
</pre> |
|
|
|
|
− |
In this case, <tt>,f</tt> asks the user for input, <tt>,F</tt> re-uses the search register.
|
+ |
The following will delete all lines that do not contain a pattern, leaving only the search hits. You could then press <tt>u</tt> to undo the changes. |
|
+ |
<pre> |
|
+ |
:v/pattern/d |
|
+ |
</pre> |
|
|
|
|
|
==See also== |
|
==See also== |
Proposed tip Please edit this page to improve it, or add your comments below (do not use the discussion page).
Please use
new tips to discuss whether this page should be a permanent tip, or whether it should be merged to an existing tip.
created April 22, 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