Como mostrar resultados de pesquisa para todos os buffers abertos


17

Uma coisa que costumo fazer (mas confio na linha de comando) é pesquisar / fazer grepping em vários arquivos.

Existe uma maneira de exibir resultados de pesquisa para todos os buffers abertos?

Idealmente, eu gostaria de ter um novo buffer dividido contendo a localização e o fragmento do resultado, da mesma forma que o grepfaz. Por exemplo ( /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 bônus, eu gostaria de poder pesquisar o termo sob o cursor, como gdfaz.


Respostas:


15

Você pode usar :vimgrep /pattern/ {files}para preencher a lista de correções rápidas com padrões correspondentes. O problema é que a :vimgrepopção de arquivos não permite diretamente buffers. Você pode 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}

Outra opção é escrever um script que gere uma lista de arquivos :buffers. Por este post do SO, com uma pequena revisão, obtemos:

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

Agora você pode ligar :GrepBufs <expression>e obter a :vimgrepsaída padrão, mas usando os buffers.

Atualizar Se você gostaria de chamar GrepBuffersusando o valor abaixo do cursor, adicione este novo mapeamento.

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

Quando você está no tipo de modo normal <leader>ze você vai :vimgrepa palavra cursor sobre seus buffers abertos.


2
Na forma de linha único: 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

Pesquisando apenas buffers abertos é bom, mas pode chegar um momento em que você deseja pesquisar em um projeto inteiro. Pode ser mais rápido e fácil do que você pensa!

Pesquisando em um Projeto

  • grepé a ferramenta de pesquisa padrão do Unix. Vale mencionar devido à sua onipresença. Já integrado ao Vim via :grepcomando. por exemplo :grep -r 'foo'. Veja :h :grep.
  • Ack é mais rápido que o grep normal, porque ignora diretórios VCS, arquivos binários e pode procurar tipos específicos de arquivos como --perl. Para integração ao Vim, consulte Ack.vim
  • Ag the Silver Surfer é uma ferramenta de busca de código semelhante ao ack, mas mais rápida. Plug-in Vim: Ag.vim
  • git greppesquisa um repositório muito rapidamente. O Fugitive.vim fornece :Ggrep.
  • Ripgrep é ainda mais rápido que Ag e git grep. Pode ser usado :greptambém.

Eu recomendo o ripgrep, o Ag e git grepcomo são todos super rápidos. Pesquisei mais de 4700+ em menos de um segundo. É muito difícil vencer o ripgrep.

Para testar uma dessas alternativas sem um plug-in ou você simplesmente não deseja um plug-in, defina sua 'grepprg'opção de acordo. por exemplo set grepprg=ag\ --vimgrepou set grepprg=rg\ --vimgrep. Veja :h 'grepprg'e :h 'grepformat'para mais informações. Agora você pode pesquisar por :grep. por exemplo :grep 'foo'.

Como substituto final, você pode usar :vimgrep, pois está disponível em todos os sistemas que o Vim está disponível. Veja :h :vimgpara mais ajuda.

Lista do QuickFix

Como a maioria dessas opções usa a lista de correções rápidas, sugiro que você use alguns mapeamentos mais amigáveis ​​para atravessar a lista de correções rápidas. Eu uso o plugin intacto de Tim Pope, que usa ]qe [qpara :cnexte :cprevrespectivamente. Algumas pessoas gostam da quickfix para abrir depois de uma pesquisa é realizada em seguida, adicione o seguinte ao seu ~/.vimrcarquivo: autocmd QuickFixCmdPost *grep* cwindow. Você também pode abrir manualmente a lista do QuickFix via :copen.

Deseja "pesquisas" ainda mais rápidas?

Você precisará usar alguma ferramenta que use índices pré- criados como ctags , cscope ou GNU global .

  • Vim tem suporte embutido ctag via :tag, <c-]>e muitos outros comandos e opções. Veja :h tags. Também pode querer ler Ctags sem esforço com Git ou procurar no plugin Gutentags
  • O suporte ao Cscope também é incorporado e pode ser usado via :cscopecomando. Vejo:h cscope

Mais ajuda

Eu começaria com este belo episódio do Vimcast : pesquise vários arquivos com:vimgrep .

Para obter mais ajuda do Vim, consulte a documentação:

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

6

Meu plug-in GrepCommands define variantes do :vimgrepcomando interno que têm como alvo todos os argumentos, buffers listados, janelas na página de guias atual ou todas as páginas de guias para sua pesquisa. Basicamente, uma implementação robusta de plug-in da resposta do @ jecxjo.


1

Comandos :bufdoe:vimgrepadd

Esta resposta é baseada em /programming//a/11976158/1057593 .

No entanto, eu queria adicionar alguns bits. Novamente, o comando básico é

:bufdo vimgrepadd pattern %

Se sua lista de correções rápidas não estiver vazia, você provavelmente deseja desmarcá-la primeiro (consulte /programming//q/27385970/1057593 ). Isso pode ser feito com

:cexpr []

O vim-unimpaired fornece os mapeamentos ]qe [qpercorre as correspondências.

cmdline-history

É um bom fluxo de trabalho para inserir o padrão de pesquisa separadamente /pattern. Isso permite que você use um comando genérico do histórico da linha de comando usando o padrão de pesquisa atual. Isso pareceria

/pattern
:bufdo vimgrepadd // %

Uma nova pesquisa típica de amplo buffer seria

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

Adicionei os seguintes mapeamentos ao meu vimrc para usar <C-N>e em <C-P>vez das teclas de seta

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

Para pesquisar o histórico de comandos q:, use e , em seguida, /bufdo<CR>chame um comando com <CR>. Para mais detalhes, consulte https://vim.fandom.com/wiki/Using_command-line_history e as páginas de ajuda :h historye :h cmdline-window.

Você pode adicionar ao comando reutilizável :copenpara ver imediatamente a lista de correções rápidas da seguinte maneira:

:execute "bufdo vimgrepadd // %" | copen

A proposta do stackoverflow :bufdo vimgrepadd // % | copenabriu várias janelas não intencionais no meu caso.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.