FANDOM


(add see also section)
(Insert TipProposed template + minor manual clean)
Line 1: Line 1:
  +
{{TipProposed
  +
|id=0
  +
|previous=0
  +
|next=0
  +
|created=April 22, 2008
  +
|complexity=basic
  +
|author=Niels AdB
  +
|version=7.0
  +
|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>.
 
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>.
   
 
<pre>
 
<pre>
function! Gather( line_pattern )
+
function! Gather( line_pattern )
if empty(a:line_pattern)
+
if empty(a:line_pattern)
return
+
return
endif
+
endif
   
" fill gather list, return if there are no results
+
" fill gather list, return if there are no results
let gather_list = []
+
let gather_list = []
let l:orig = getpos(".")
+
let l:orig = getpos(".")
let l:orig_ft = &ft
+
let l:orig_ft = &ft
execute "g/" . a:line_pattern . "/call insert(gather_list, getline(\".\"))"
+
execute "g/" . a:line_pattern . "/call insert(gather_list, getline(\".\"))"
call setpos(".", l:orig)
+
call setpos(".", l:orig)
if empty(gather_list)
+
if empty(gather_list)
return
+
return
endif
+
endif
   
" create new scratch buffer
+
" create new scratch buffer
new
+
new
setlocal buftype=nofile
+
setlocal buftype=nofile
setlocal bufhidden=hide
+
setlocal bufhidden=hide
setlocal noswapfile
+
setlocal noswapfile
execute "setlocal filetype=".l:orig_ft
+
execute "setlocal filetype=".l:orig_ft
   
" copy all results in the new scratch buffer
+
" copy all results in the new scratch buffer
for line in gather_list
+
for line in gather_list
call append(0, line)
+
call append(0, line)
endfor
+
endfor
normal ddgg
+
normal ddgg
unlet gather_list
+
unlet gather_list
endfunction
+
endfunction
 
</pre>
 
</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 easy. You might want to change that line to the key you're mapping this function onto.
+
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.
   
function! CloseScratch()
+
<pre>
if &buftype == "nofile" && &bufhidden == "hide" && !&swapfile
+
function! CloseScratch()
" this is a scratch buffer
+
if &buftype == "nofile" && &bufhidden == "hide" && !&swapfile
bdelete
+
" this is a scratch buffer
else
+
bdelete
" this is not a scratch buffer
+
else
normal! "<Esc>"
+
" this is not a scratch buffer
endif
+
normal! "<Esc>"
endfunction
+
endif
  +
endfunction
  +
</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.
 
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.
   
nmap ,f :call Gather( input("Filter on term: ") )<CR>
+
<pre>
nmap ,F :call Gather( @/ )<CR>
+
nmap ,f :call Gather( input("Filter on term: ") )<CR>
nmap <Esc> :call CloseScratch()<CR>
+
nmap ,F :call Gather( @/ )<CR>
  +
nmap <Esc> :call CloseScratch()<CR>
  +
</pre>
   
 
In this case, <tt>,f</tt> asks the user for input, <tt>,F</tt> re-uses the search register.
 
In this case, <tt>,f</tt> asks the user for input, <tt>,F</tt> re-uses the search register.
   
Niels AdB
+
==See also==
 
==See Also==
 
 
*[[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]] for some simple techniques to display lines of interest
  +
  +
==Comments==

Revision as of 23:44, April 22, 2008

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

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 @/). 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 :v/EXP/d, which deletes all lines that don't match EXP.

function! Gather( line_pattern )
  if empty(a:line_pattern)
    return
  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

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.

function! CloseScratch()
  if &buftype == "nofile" && &bufhidden == "hide" && !&swapfile
    " this is a scratch buffer
    bdelete
  else
    " this is not a scratch buffer
    normal! "<Esc>"
  endif
endfunction

And finally some key mappings to make it all available. I'm using , as a mapleader and find using "generic" binding such as execute "nmap" g:mapleader."f :call Whatever()<CR>" not very readable in my vimrc. Adjust as needed.

nmap ,f :call Gather( input("Filter on term: ") )<CR>
nmap ,F :call Gather( @/ )<CR>
nmap <Esc> :call CloseScratch()<CR>

In this case, ,f asks the user for input, ,F re-uses the search register.

See also

Comments

Community content is available under CC-BY-SA unless otherwise noted.