buscar - vim search and replace
¿Cómo busco los búferes abiertos en Vim? (5)
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:
- No puedo 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 quickfix.
Aquí hay un buen ejemplo de búsqueda de archivos múltiples en Sublime Text 2:
¿Algunas ideas?
Al igual que la respuesta de Waz, he escrito comandos personalizados para eso, publicados en mi complemento GrepCommands . Permite buscar en búferes ( :BufGrep
), ventanas visibles ( :WinGrep
), pestañas y argumentos.
(Pero como todas las demás respuestas, aún no maneja los búferes sin nombre).
Hice esta función hace mucho tiempo, y supongo que probablemente no sea la más limpia de las soluciones, pero me ha resultado útil:
" 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'')
O
:bufdo vimgrepadd threading % | copen
Es posible que la ventana de solución rápida no se vea bien, pero es mucho más funcional que el "panel de resultados" de ST2, aunque solo sea porque puedes mantenerla abierta y visible mientras saltas a ubicaciones e interactúas con ella si no está allí.
Una versión mejorada (en esteroides) de la respuesta de Waz, con una mejor búsqueda de búferes y manejo especial de casos, se puede encontrar a continuación (Los moderadores no me dejaron actualizar la respuesta de Waz: D). Una versión más descarnada 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 tengo ganas de averiguar cómo hacer un plugin i '' Actualizaré esta respuesta. Quería agilizar el intercambio por el momento)
" 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