On Sep 10, 10:15 pm, "Ed S. Peschko" <[EMAIL PROTECTED]> wrote:
> 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..

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()




--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_dev" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---

Raspunde prin e-mail lui