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
-~----------~----~----~----~------~----~------~--~---