2012-08-15 88 views
32

我想搜索當前在vim中打開的所有文件中的文本,並在一個地方顯示所有結果。有兩個問題,我想:如何在Vim中搜索打開的緩衝區?

  • 我可以打開的文件列表中沒有傳遞給:grep/:vim,特別是那些沒有在磁盤上的文件的名稱;
  • :grep -C 1 text的結果在quickfix窗口中看起來不太好。

這裏是崇高的文本2多個文件搜索的一個很好的例子:enter image description here

任何想法?

+0

我真的想強調的搜索模式一樣,在gvim的:-) – cnicutar 2012-08-15 19:08:37

+2

http://vi.stackexchange.com/questions/2904/how-to-show- search-results-for-all-open-buffers – 2016-05-17 07:05:14

回答

30

或者

:bufdo vimgrepadd threading % | copen 

quickfix窗口可就不好看了你,但它是一個很多比ST2的「結果面板」功能更強大的地獄,如果僅僅是因爲你可以把它打開,可見的,而跳轉到位置並且如果它不在那裏與它進行交互。

+0

非常好的解決方案。我不知道vimgrepadd命令。然而,這個命令對我來說不起作用,必須這樣做: :bufdo vimgrepadd pattern% 其次是 :copen或者:cw,或者甚至更好:botright cw – 2012-08-15 20:40:21

+0

您對'%'是正確的,我完全忘了它。不需要在後面發佈':copen' *,把它放在一個管道後面並且自動打開quickfix。回答編輯。 – romainl 2012-08-15 21:27:30

+1

謝謝,這或多或少是我想要的。':bufdo grepadd -C 1 threading%'產生或多或少的我想要的。並對vim如何解釋結果進行了一些調整,可能會使它變得美觀可愛。順便說一下,如果需要,您可以在ST2中輕鬆拆分窗口並將結果與​​其他文件一起顯示。 So-- – squirrel 2012-08-15 23:18:54

5

ackAck.vim美麗地處理這個問題。您也可以使用:help :vimgrep。例如:

:bufdo AckAdd -n threading 

將創建一個很好的quickfix窗口,讓您跳轉到光標位置。

+2

如何在不打開緩衝區的情況下打開所有緩衝區並找到結果? – ThePosey 2016-09-14 17:56:42

2

我很久以前做這個功能,我猜它可能不是最乾淨的解決方案,但它一直有用對我來說:

" Looks for a pattern in the open buffers. 
" If list == 'c' then put results in the quickfix list. 
" If list == 'l' then put results in the location list. 
function! GrepBuffers(pattern, list) 
    let str = '' 

    if (a:list == 'l') 
     let str = 'l' 
    endif 

    let str = str . 'vimgrep /' . a:pattern . '/' 

    for i in range(1, bufnr('$')) 
     let str = str . ' ' . fnameescape(bufname(i)) 
    endfor 

    execute str 
    execute a:list . 'w' 
endfunction 

" :GrepBuffers('pattern') puts results into the quickfix list 
command! -nargs=1 GrepBuffers call GrepBuffers(<args>, 'c') 

" :GrepBuffersL('pattern') puts results into the location list 
command! -nargs=1 GrepBuffersL call GrepBuffers(<args>, 'l') 
2

像WAZ的答案,我已經寫自定義命令,發佈在我的GrepCommands plugin。它允許搜索緩衝區(:BufGrep),可見窗口(:WinGrep),選項卡和參數。

(但是,像所有其他的答案,它不處理無名緩衝區呢。)

+0

我認爲使用vimgrep的原因將不會搜索未命名緩衝區是因爲它沒有辦法在沒有名字的QuickFix窗口中顯示匹配。例如匹配看起來像這樣「HillarysEmails.txt | 4 col 6 |我是俄羅斯。」如果你這樣做:文件HillarysEmails然後你可以grep未保存的緩衝區。 – FocusedWolf 2017-08-09 00:28:24

0

的改善(類固醇)WAZ的回答,具有較好的緩衝搜索和特殊情況處理的版本,可以在下面找到(主持人不會讓我更新Waz的答案:D)。 更加充實的版本綁定箭頭鍵來瀏覽QuickFix列表和F3來關閉QuickFix窗口可以在這裏找到:https://pastebin.com/5AfbY8sm (當我想搞清楚如何製作一個插件我會更新這個答案。要加快分享了它)

" Looks for a pattern in the buffers. 
" Usage :GrepBuffers [pattern] [matchCase] [matchWholeWord] [prefix] 
" If pattern is not specified then usage instructions will get printed. 
" If matchCase = '1' then exclude matches that do not have the same case. If matchCase = '0' then ignore case. 
" If prefix == 'c' then put results in the QuickFix list. If prefix == 'l' then put results in the location list for the current window. 
function! s:GrepBuffers(...) 
    if a:0 > 4 
     throw "Too many arguments" 
    endif 

    if a:0 >= 1 
     let l:pattern = a:1 
    else 
     echo 'Usage :GrepBuffers [pattern] [matchCase] [matchWholeWord] [prefix]' 
     return 
    endif 

    let l:matchCase = 0 
    if a:0 >= 2 
     if a:2 !~ '^\d\+$' || a:2 > 1 || a:2 < 0 
      throw "ArgumentException: matchCase value '" . a:2 . "' is not in the bounds [0,1]." 
     endif 
     let l:matchCase = a:2 
    endif 

    let l:matchWholeWord = 0 
    if a:0 >= 3 
     if a:3 !~ '^\d\+$' || a:3 > 1 || a:3 < 0 
      throw "ArgumentException: matchWholeWord value '" . a:3 . "' is not in the bounds [0,1]." 
     endif 
     let l:matchWholeWord = a:3 
    endif 

    let l:prefix = 'c' 
    if a:0 >= 4 
     if a:4 != 'c' && a:4 != 'l' 
      throw "ArgumentException: prefix value '" . a:4 . "' is not 'c' or 'l'." 
     endif 
     let l:prefix = a:4 
    endif 

    let ignorecase = &ignorecase 
    let &ignorecase = l:matchCase == 0 
    try 
     if l:prefix == 'c' 
      let l:vimgrep = 'vimgrep' 
     elseif l:prefix == 'l' 
      let l:vimgrep = 'lvimgrep' 
     endif 

     if l:matchWholeWord 
      let l:pattern = '\<' . l:pattern . '\>' 
     endif 

     let str = 'silent ' . l:vimgrep . ' /' . l:pattern . '/' 

     for buf in getbufinfo() 
      if buflisted(buf.bufnr) " Skips unlisted buffers because they are not used for normal editing 
       if !bufexists(buf.bufnr) 
        throw 'Buffer does not exist: "' . buf.bufnr . '"' 
       elseif empty(bufname(buf.bufnr)) && getbufvar(buf.bufnr, '&buftype') != 'quickfix' 
        if len(getbufline(buf.bufnr, '2')) != 0 || strlen(getbufline(buf.bufnr, '1')[0]) != 0 
         echohl warningmsg | echomsg 'Skipping unnamed buffer: [' . buf.bufnr . ']' | echohl normal 
        endif 
       else 
        let str = str . ' ' . fnameescape(bufname(buf.bufnr)) 
       endif 
      endif 
     endfor 

     try 
      execute str 
     catch /^Vim\%((\a\+)\)\=:E\%(683\|480\):/ "E683: File name missing or invalid pattern --- E480: No match: 
      " How do you want to handle this exception? 
      echoerr v:exception 
      return 
     endtry 

     execute l:prefix . 'window' 
    "catch /.*/ 
    finally 
     let &ignorecase = ignorecase 
    endtry 
endfunction 
相關問題