2012-08-15 12 views
32

Me gustaría buscar texto en todos los archivos actualmente abiertos en vim y mostrar todos los resultados en un solo lugar. Hay dos problemas, supongo:¿Cómo busco los búferes abiertos en Vim?

  • no puedo dejar pasar la lista de archivos abiertos a :grep/:vim, especialmente los nombres de los archivos que no están en el disco; El resultado de :grep -C 1 text no se ve bien en la ventana de revisión.

Aquí es un buen ejemplo de búsqueda de archivos en múltiples Sublime Text 2: enter image description here

¿Alguna idea?

+0

realmente me gustaría poner de relieve los patrones de búsqueda como la de :-) gvim – cnicutar

+2

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

Respuesta

30

O

:bufdo vimgrepadd threading % | copen 

La ventana quickfix puede no verse bien para usted, pero es un infierno de mucho más funcional que "panel de resultados" de ST2 aunque sólo sea porque puede mantenerla abierta y visible, mientras que saltar a lugares e interactuar con él si no está allí.

+0

Muy buena solución. No sabía sobre el comando vimgrepadd. Sin embargo, el comando no funciona para mí como está, tenía que hacer: : patrón vimgrepadd bufdo% seguido de : copen o: cw, o mejor aún: botright cw –

+0

Tienes razón sobre el '%', Lo olvidé por completo No es necesario emitir ': copen' * después *, ponerlo después de un tubo y el quickfix se abre automáticamente. Respuesta editada. – romainl

+1

Gracias, es más o menos lo que quería.': bufdo grepadd -C 1 threading%' produce más o menos lo que quería. con algunos ajustes de cómo vim interpreta los resultados, puede ser probablemente lindo y agradable. Por cierto, puede dividir fácilmente la ventana en ST2 y mostrar los resultados junto con otros archivos, si lo desea. Por lo tanto, – squirrel

5

ack y Ack.vim resuelven este problema maravillosamente. También puede usar :help :vimgrep. Por ejemplo:

:bufdo AckAdd -n threading 

creará una ventana de revisión agradable que le permite saltar a la posición del cursor.

+2

¿Cómo se consigue que funcione sin que se abran todos los buffers que encuentra el resultado en una división? – ThePosey

2

hice esta función hace mucho tiempo, y supongo que probablemente no es el más limpio de soluciones, pero ha sido útil para mí:

" 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

Al igual que la respuesta de Waz, he escrito comandos personalizados para eso, publicados en mi GrepCommands plugin. Permite buscar en búferes (:BufGrep), ventanas visibles (:WinGrep), pestañas y argumentos.

(Pero como todas las otras respuestas, que no se ocupa de los tampones no identificadas todavía.)

+0

Creo que el motivo vimgrep no buscará búferes sin nombre es porque no tiene forma de presentar la coincidencia en la ventana de QuickFix sin un nombre. p.ej. los partidos se ven así: "HillarysEmails.txt | 4 col 6 | Soy Rusia". Si lo hace: archive HillarysEmails, entonces puede grep el buffer no guardado. – FocusedWolf

0

Una mejora (en los esteroides) versión de la respuesta de Waz, con una mejor búsqueda de amortiguación y manejo de casos especiales, se pueden encontrar a continuación (Los moderadores no me dejaron actualizar la respuesta de Waz nunca más: D). Una versión más cargada con enlaces para las teclas de flecha para navegar en la lista de QuickFix y F3 para cerrar la ventana de QuickFix se puede encontrar aquí: https://pastebin.com/5AfbY8sm (Cuando me apetezca averiguar cómo hacer un complemento, actualizaré esta respuesta. quería agilizar el intercambio de todo por ahora)

" 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 
Cuestiones relacionadas