Is there a way of searching through multiple buffers? ie: I'd like a derivative of '/' to 
be able to span files, ie: if it doesn't find it in one file, it goes to the next
in the bufferlist, and so on..
Having the ability to autosave if it exits the buffer would be cool too..
Ed
(ps - where this is coming from: I'm doing auto edits on thousands of files through 
macros: finding a pattern plus using a complicated set of edit commands to do the
modifications.
It'd be really nice if I could macro this up so that I could say: 'qa', record the
correct keystrokes, and then say '100@a' to get done really quick.. it snags though,
when you go to the next file and a pattern isn't found..
)
I'm not aware of any functionality quite like that, though there is the :bufdo 
command.
I suspect it would be easiest to use the functionality of :vimgrep to do the 
searching, provided your files are all in the same directory or something 
similarly convenient. Your recording would just use :cn rather than just n to jump 
to the line containing the next match.
Ben.
Send instant messages to your online friends http://au.messenger.yahoo.com
If files are sharing common element in name you can use:
:vimgrep /re/ {namewithwildcards}
For buffers you can also use
:bufdo vimgrep /re/ %
But it has few downsides: matches for all files will be saved into
separated quickfix lists, Vim will remember only last ten lists.
But you could probably write some simple script to save all data in
external error list and later load it.
:help quickfix
:help location-list
m.
I made a script that searches through all of my open buffers using
bufdo and shows them in a location list like window. It might help get
you started since I don't think it does quite what you want.
It doesn't use vimgrep because a lot of times I edit multiple unnamed
buffers that I need to search through. The results window keeps a
history of searches and matches, which I find useful.
HTH, _matt
"
========================================================================
" Search Stack - a quick solution to searching all open buffers (even
unnamed)
" To search - :SS /search pattern/
" This will open a window with the search stack results (most recent
search on
" top)
" To follow a match, hit enter.
" To return to the search results use <Leader>sh
"
========================================================================
if exists("loaded_sestack")
    finish
endif
let loaded_sestack = 1
let s:results = []
let s:last_line = -1
nmap <silent> <unique> <Leader>sh :SH<CR>
function! <SID>Search(pat)
    if len(s:results) > 10
        remove(s:results, 0)
    endif
    call add(s:results, [])
    let l:result = s:DoSearch(a:pat, 's:AppendResults')
    if l:result == -1
        return
    endif
    if len(s:results[-1]) == 0
        echo "No matches!"
        return
    endif
    call s:ShowResults()
    normal 5G
    call s:ShowMatch()
endfunction
command! -nargs=1 SS call <SID>Search(<q-args>)
function! <SID>DoSearch(pat, func)
    let v:errmsg = ""
    let l:startbuf = bufnr("%")
    let l:startwin = winnr()
    if a:pat !~ "^/.*/$"
        echo "Search must start and end with \"/\""
        return -1
    endif
    let l:pat = a:pat[1:-2]
    let l:cmd = "bufdo g/" . l:pat . "/call " . a:func . "()"
    silent! exe l:cmd
    exe l:startwin . "wincmd w"
    exe "buffer! " . l:startbuf
    if v:errmsg != ""
        echo v:errmsg
    endif
endfunction
function! <SID>AppendResults()
    if bufname('%') != '[SS]'
        let l:curtext = getline('.')
        let l:curline = line('.')
        let l:curbuf = bufnr('%')
        let l:bufname = bufname('%')
        if l:bufname == ''
            let l:bufname = '[Buffer #' . l:curbuf . ']'
        endif
        call add(s:results[-1], [@/, [l:curbuf, l:bufname, l:curline,
l:curtext]])
    endif
endfunction
function! <SID>FindWindow()
    for i in range(winnr('$'))
        let l:bn = winbufnr(i + 1)
        if l:bn != -1
            if bufname(l:bn) == '[SS]'
                return i
            endif
        endif
    endfor
    return -1
endfunction
function! <SID>ShowResults()
    let l:winnr = s:FindWindow()
    if l:winnr == -1
        exe "silent! botright sp [SS]"
        resize 6
    else
        " TODO: How do I goto a window, instead of assuming it's still
        " the bottom right window?
        wincmd b
        exe "silent! e! [SS]"
    endif
    setlocal bufhidden=delete
    setlocal buftype=nofile
    setlocal modifiable
    setlocal noswapfile
    setlocal nowrap
    nnoremap <buffer> <silent> <cr> :call <SID>SelectMatch()<cr>
    autocmd! CursorMoved <buffer> silent call <SID>ShowMatch()
    nnoremap <buffer> <silent> <LeftMouse> <LeftMouse>:call
<SID>SelectMatch()<cr>
    let l:revlist = reverse(copy(s:results))
    for r in l:revlist
        let l:ph = 0
        for m in r
            if !l:ph
                put = ''
                put = '================================='
                put = 'Search string: ' . m[0]
                let l:ph = 1
            endif
            let i = m[1]
            put = i[0] . ' ' . i[1] . ' ' . i[2] . ' : ' . i[3]
        endfor
    endfor
setlocal nomodifiable
    " Goto the saved line
    if s:last_line != -1
        exe 'normal ' . s:last_line . 'G'
    endif
endfunction
command! -nargs=0 SH call <SID>ShowResults()
function! <SID>SelectMatch()
    let l:line = getline('.')
    let l:ml = matchlist(getline('.'), '\v^\s*(\d+).{-}(\d+) :')
    let s:last_line = line('.')
    exe "normal \<c-w>p"
    exe 'b ' . l:ml[1]
    exe 'normal ' . l:ml[2] . 'G'
endfunction
function! <SID>ShowMatch()
    let l:ss = ''
    let l:line = line('.')
    while getline(l:line) !~ '\v^\=+$'
        let l:ml = matchlist(getline(l:line), '\vSearch string: (.*)
$')
        if len(l:ml)
            let l:ss = l:ml[1]
            break
        endif
        let l:line = l:line - 1
        if l:line == 0
            break
        endif
    endwhile
    if l:ss != ''
        exe '2match Search /' . l:ss . '/'
        exe "let @/ = \'" . escape(l:ss, "'") . "'"
        autocmd! BufLeave <buffer> call <SID>SeStackLeave()
    endif
endfunction
function! <SID>SeStackLeave()
    silent 2match none
    let s:last_line = line('.')
endfunction
function! <SID>SelectPrev()
    if s:FindWindow() == -1
        call s:ShowResults()
    endif
    " TODO: Goto the window (again blindly)
    wincmd b
    if s:last_line == -1
        normal G
    endif
    let l:res = search('\v^\s*\d+', 'bW')
    if l:res == 0
        echo 'No previous matches'
        return
    endif
    call s:SelectMatch()
endfunction
command! -nargs=0 SP call <SID>SelectPrev()
nmap <silent> <unique> <Leader>sp :SP<CR>
function! <SID>SelectNext()
    if s:FindWindow() == -1
        call s:ShowResults()
    endif
    " TODO: Goto the window (again blindly)
    wincmd b
    if s:last_line == -1
        normal gg
    endif
    let l:res = search('\v^\s*\d+', 'W')
    if l:res == 0
        echo 'No more matches'
        wincmd p
        return
    endif
    call s:ShowMatch()
    call s:SelectMatch()
endfunction
command! -nargs=0 SN call <SID>SelectNext()
nmap <silent> <unique> <Leader>sn :SN<CR>
function! <SID>ClearSearchStack()
    let s:results = []
endfunction
command! -nargs=0 SC call <SID>ClearSearchStack()
Well, I was going to suggest
:let qlist=[]
:bufdo silent vimgrep /pattern/ % | call add(qlist,getqflist())
:call setqflist(qlist)
:cope
Unfortunately, the formats for what getqflist() delivers and setqflist() 
takes are different, and beating them into compatiblity is more than I 
want to attempt at the moment.
Regards,
Chip Campbell
This does work. You have to use extend() instead of add() in
the above commands. When you call add(), the current quickfix
list is added as a single item to qlist.
- Yegappan
You should be able to join them together by doing
:bufdo vimgrepadd /re/ %
shouldn't you?
Need to clear the list beforehand, I suppose. I can't spot a simple command for 
that, but I think
:cexpr ""
will do it if nothing else!
Thanks, Yegappan!
Guess I didn't look much further as to why the above didn't work when I 
read, under the help for setqflist(), that:
"Note that the list is not exactly the same as what |getqflist()| returns."
So, here's a vim snippet implementing the above:
" qfbp.vim
"   Author: Charles E. Campbell, Jr.
"   Date:   Sep 12, 2007
"   Version: 1
" ---------------------------------------------------------------------
"  Load Once: {{{1
if &cp || exists("g:loaded_qfpat")
 finish
endif
let g:loaded_qfpat= "v1"
let s:keepcpo      = &cpo
set cpo&vim
" ---------------------------------------------------------------------
"  Public Interface: {{{1
com! -nargs=1 QFBP  call s:QuickFixBufPat(<q-args>)
" ---------------------------------------------------------------------
" s:QuickFixBufPat: {{{2
fun! s:QuickFixBufPat(pat)
"  call Dfunc("s:QuickFixBufPat(pat<".a:pat.">)")
  let qlist=[]
  exe "bufdo silent vimgrep /".a:pat."/ % | call extend(qlist,getqflist())"
  call setqflist(qlist)
  cope
"  call Dret("s:QuickFixBufPat")
endfun
" ---------------------------------------------------------------------
"  Restore: {{{1
let &cpo= s:keepcpo
unlet s:keepcpo
" vim: ts=4 fdm=marker
Regards,
Chip Campbell