Cómo mostrar resultados de búsqueda para todos los buffers abiertos


17

Una cosa que hago a menudo (pero confío en la línea de comando para hacer) es buscar / grepping en múltiples archivos.

¿Hay alguna forma de mostrar los resultados de búsqueda para todos los búferes abiertos?

Idealmente, me gustaría tener un nuevo búfer dividido que contenga la ubicación del resultado y el fragmento como lo grephace. Por ejemplo ( /statistics):

models/statistics.php: /*! \file   statistics.php
controllers/stats.php: $this->load->model('statistics');
controllers/stats.php: // Query statistics...
controllers/stats.php: $num_exams = $this->statistics->countExams();

Como beneficio adicional, me gustaría poder buscar el término debajo del cursor, más o menos como lo gdhace.


Respuestas:


15

Puede usar :vimgrep /pattern/ {files}para completar la lista de soluciones rápidas con patrones coincidentes. El problema es que la :vimgrepopción de archivos no permite directamente buffers. Puedes usar:

%   Is replaced with the current file name.       *:_%* *c_%*
#   Is replaced with the alternate file name.     *:_#* *c_#*
#n  (where n is a number) is replaced with        *:_#0* *:_#n*
    the file name of buffer n.  "#0" is the same as "#".     *c_#n*
##  Is replaced with all names in the argument list   *:_##* *c_##*
    concatenated, separated by spaces.  Each space in a name
    is preceded with a backslash.
#<n (where n is a number > 0) is replaced with old    *:_#<* *c_#<*
    file name n.  See |:oldfiles| or |v:oldfiles| to get the
    number.                         *E809*
    {only when compiled with the |+eval| and |+viminfo| features}

Otra opción es escribir un script que genere una lista de archivos :buffers. Por esta publicación SO con un ligero tweek obtenemos:

function! BuffersList()
  let all = range(0, bufnr('$'))
  let res = []
  for b in all
    if buflisted(b)
      call add(res, bufname(b))
    endif
  endfor
  return res
endfunction

function! GrepBuffers (expression)
  exec 'vimgrep/'.a:expression.'/ '.join(BuffersList())
endfunction

command! -nargs=+ GrepBufs call GrepBuffers(<q-args>)

Ahora puede llamar :GrepBufs <expression>y obtener la :vimgrepsalida estándar pero utilizando los buffers en su lugar.

Actualización Si usted quiere llamar GrepBuffersusando el valor bajo el cursor agregar esta nueva asignación.

nnoremap <leader>z :call GrepBuffers("<C-R><C-W>")<CR>

Cuando esté en el tipo de modo normal <leader>zy usted :vimgrepla palabra cursor sobre sus buffers abiertos.


2
En la forma de una sola línea: command! -bang -nargs=+ Bufgrep execute 'vimgrep<bang><args> ' . join(map(filter(range(1, bufnr('$')), 'buflisted(v:val)'), '"#".v:val'), ' '). Uso::Bufgrep/foo/
Peter Rincker

8

Buscar solo en buffers abiertos es bueno, pero puede llegar un momento en el que desee buscar en todo un proyecto. ¡Puede ser más rápido y más fácil de lo que piensas!

Buscando en un proyecto

  • grepes la herramienta de búsqueda estándar de Unix. Vale la pena mencionar debido a su ubicuidad. Ya integrado en Vim a través del :grepcomando. por ej :grep -r 'foo'. Ver :h :grep.
  • Ack es más rápido que el grep normal porque omite directorios VCS, archivos binarios y puede buscar tipos específicos de tipos de archivos como --perl. Para la integración de Vim, consulte Ack.vim
  • Ag the Silver Surfer es una herramienta de búsqueda de código similar a ack, pero más rápida. Complemento Vim: Ag.vim
  • git grepbusca en un repositorio muy rápidamente. Fugitive.vim proporciona :Ggrep.
  • Ripgrep es incluso más rápido que Ag y git grep. Se puede usar con :greptambién.

Recomiendo tanto ripgrep, Ag, git grepcomo todos son súper rápidos. He buscado más de 4700+ en menos de 1 segundo. Es bastante difícil vencer a ripgrep.

Para probar una de estas alternativas sin un complemento o simplemente no desea un complemento, puede configurar su 'grepprg'opción en consecuencia. por ejemplo set grepprg=ag\ --vimgrepo set grepprg=rg\ --vimgrep. Ver :h 'grepprg'y :h 'grepformat'para más información. Ahora puedes buscar a través de :grep. por ej :grep 'foo'.

Como alternativa final, puede usarla :vimgrepya que está disponible en todos los sistemas que Vim está disponible. Ver :h :vimgpara más ayuda.

Lista QuickFix

Como la mayoría de estas opciones usan la lista de soluciones rápidas, le sugiero que use algunas asignaciones más amigables para atravesar la lista de soluciones rápidas. Uso el complemento intacto de Tim Pope que usa ]qy [qpara :cnexty :cprevrespectivamente. Algunas personas, como el quickfix a abrir después de una búsqueda se realiza a continuación, añadir lo siguiente a su ~/.vimrcarchivo: autocmd QuickFixCmdPost *grep* cwindow. También puede abrir manualmente la lista QuickFix mediante :copen.

¿Quieres "búsquedas" aún más rápidas?

Necesitará usar alguna herramienta que use índices preconstruidos como ctags , cscope o GNU global .

  • Vim ha construido en apoyo a través de CTAG :tag, <c-]>y muchos otros comandos y opciones. Ver :h tags. También es posible que desee leer Ctags sin esfuerzo con Git o buscar en el complemento Gutentags
  • El soporte de Cscope también está integrado y se puede usar mediante un :cscopecomando. Ver:h cscope

Más ayuda

Comenzaría con este bonito episodio de Vimcast : busca en varios archivos:vimgrep .

Para obtener más ayuda de Vim, consulte la documentación:

:h grep
:h :vimgrep
:h :grep
:h 'grepprg'
:h 'grepformat'
:h quickfix
:h :cnext
:h tags
:h cscope

6

El complemento My GrepCommands define variantes del :vimgrepcomando incorporado que se dirigen a todos los argumentos, buffers listados, ventanas en la página de pestañas actual o todas las páginas de pestañas para su búsqueda. Básicamente, una implementación robusta del complemento de la respuesta de @ jecxjo.


1

Comandos :bufdoy:vimgrepadd

Esta respuesta se basa en /programming//a/11976158/1057593 .

Sin embargo, quería agregar algunos bits. De nuevo, el comando básico es

:bufdo vimgrepadd pattern %

Si su lista de soluciones rápidas no está vacía, probablemente quiera borrarla primero (consulte /programming//q/27385970/1057593 ). Esto se puede hacer con

:cexpr []

vim-unimpaired proporciona las asignaciones ]qy [qpara recorrer las coincidencias.

cmdline-history

Es un buen flujo de trabajo ingresar el patrón de búsqueda por separado /pattern. Esto le permite utilizar un comando genérico de su historial de línea de comandos utilizando el patrón de búsqueda actual. Esto se vería como

/pattern
:bufdo vimgrepadd // %

Una nueva búsqueda típica de todo el búfer sería

/pattern2
:bufdo<up><up>...

He agregado las siguientes asignaciones a mi vimrc para usar <C-N>y en <C-P>lugar de las teclas de flecha

cmap <C-P> <Up>
cmap <C-N> <Down>

Para buscar en el historial de comandos q:, utilice /bufdo<CR>e invoque un comando con <CR>. Para obtener más detalles, consulte https://vim.fandom.com/wiki/Using_command-line_history y las páginas de ayuda :h historyy :h cmdline-window.

Puede agregar al comando reutilizable :copenpara ver inmediatamente la lista de soluciones rápidas de la siguiente manera:

:execute "bufdo vimgrepadd // %" | copen

La propuesta de stackoverflow :bufdo vimgrepadd // % | copenabrió varias ventanas no deseadas en mi caso.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.