So zeigen Sie Suchergebnisse für alle offenen Puffer an


17

Eine Sache, die ich oft tue (aber auf die Befehlszeile angewiesen bin), ist das Suchen / Greifen in mehreren Dateien.

Gibt es eine Möglichkeit, Suchergebnisse für alle offenen Puffer anzuzeigen?

Idealerweise hätte ich gerne einen neuen geteilten Puffer, der die Position des Ergebnisses und das Snippet enthält, ähnlich wie dies der grepFall ist. Zum Beispiel ( /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();

Als Bonus möchte ich in der Lage sein, nach dem Begriff unter dem Cursor zu suchen, ähnlich wie dies der gdFall ist.


Antworten:


15

Mit können Sie :vimgrep /pattern/ {files}die Quickfix-Liste mit übereinstimmenden Mustern füllen. Das Problem ist, dass die :vimgrepOption files Puffer nicht direkt zulässt. Sie können verwenden:

%   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}

Eine andere Möglichkeit besteht darin, ein Skript zu schreiben, aus dem eine Dateiliste generiert wird :buffers. Für diesen SO-Beitrag mit einer kurzen Woche erhalten wir:

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

Sie können jetzt :GrepBufs <expression>die Standardausgabe aufrufen und abrufen , :vimgrepaber stattdessen die Puffer verwenden.

Aktualisieren Wenn Sie GrepBuffersmit dem Wert unter dem Cursor aufrufen möchten, fügen Sie dieses neue Mapping hinzu.

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

Wenn Sie sich im normalen Modus befinden, geben <leader>zSie :vimgrepdas Cursorwort über den geöffneten Puffern ein.


2
In einzelnen Zeile Form: command! -bang -nargs=+ Bufgrep execute 'vimgrep<bang><args> ' . join(map(filter(range(1, bufnr('$')), 'buflisted(v:val)'), '"#".v:val'), ' '). Verwendung::Bufgrep/foo/
Peter Rincker

8

Das Suchen in nur geöffneten Puffern ist nett, aber es kann vorkommen, dass Sie über ein gesamtes Projekt hinweg suchen möchten. Es kann schneller und einfacher sein als Sie denken!

Projektübergreifende Suche

  • grepist das Unix-Standardsuchwerkzeug. Erwähnenswert wegen seiner Allgegenwart. Bereits per :grepBefehl in Vim integriert . zb :grep -r 'foo'. Sehen :h :grep.
  • Ack ist schneller als reguläres grep, da es VCS-Verzeichnisse und Binärdateien überspringt und nach bestimmten Dateitypen wie sucht --perl. Informationen zur Vim-Integration finden Sie unter Ack.vim
  • Ag the Silver Surfer ist ein Code-Suchwerkzeug, das ack ähnelt, aber schneller ist. Vim-Plugin: Ag.vim
  • git grepdurchsucht ein Repository sehr schnell. Fugitive.vim bietet :Ggrep.
  • Ripgrep ist noch schneller als Ag und git grep. Kann auch mit verwendet werden :grep.

Ich empfehle sowohl Ripgrep, Ag, und git grepwie sie alle super schnell sind. Ich habe über 4700+ in weniger als einer Sekunde gesucht. Es ist ziemlich schwer, Ripgrep zu schlagen.

Um eine dieser Alternativen ohne Plugin zu testen oder Sie möchten einfach kein Plugin, können Sie Ihre 'grepprg'Option entsprechend einstellen . zB set grepprg=ag\ --vimgrepoder set grepprg=rg\ --vimgrep. Siehe :h 'grepprg'und :h 'grepformat'für weitere Informationen. Jetzt können Sie über suchen :grep. zb :grep 'foo'.

Als letztes Fallback können Sie verwenden, :vimgrepwie es auf allen Systemen verfügbar ist, auf denen Vim verfügbar ist. Sehen Sie :h :vimgfür weitere Hilfe.

QuickFix-Liste

Da die meisten dieser Optionen die Quickfix-Liste verwenden, sollten Sie einige benutzerfreundlichere Zuordnungen verwenden, um die Quickfix-Liste zu durchlaufen. Ich benutze Tim Popes unbeeinträchtigt Plugin , das verwendet ]qund [qfür :cnextund :cprevjeweils. Einige Leute mögen die quickfix zu öffnen , nachdem eine Suche durchgeführt wird , dann kann das folgende in hinzufügen ~/.vimrcDatei: autocmd QuickFixCmdPost *grep* cwindow. Sie können die QuickFix-Liste auch manuell über öffnen :copen.

Willst du noch schneller "suchen"?

Sie müssen ein Tool verwenden, das vorgefertigte Indizes wie ctags , cscope oder GNU global verwendet .

  • Vim hat in CTAG Unterstützung via gebaut :tag, <c-]>und viele andere Befehle und Optionen. Sehen :h tags. Vielleicht möchten Sie auch Effortless Ctags mit Git lesen oder sich das Gutentags- Plugin ansehen
  • Cscope-Unterstützung ist ebenfalls integriert und kann per :cscopeBefehl verwendet werden . Sehen:h cscope

Mehr Hilfe

Ich würde mit dieser netten Vimcast- Episode beginnen: Durchsuche mehrere Dateien mit:vimgrep .

Weitere Hilfe zu Vim finden Sie in der Dokumentation:

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

6

Das GrepCommands-Plugin definiert Varianten des eingebauten :vimgrepBefehls, die auf alle Argumente, aufgelisteten Puffer, Fenster auf der aktuellen Registerkarte oder auf allen Registerkarten für die Suche abzielen. Grundsätzlich eine robuste Plugin-Implementierung von @ jecxjos Antwort.


1

Befehle :bufdound:vimgrepadd

Diese Antwort basiert auf /programming//a/11976158/1057593 .

Ich wollte jedoch ein paar Bits hinzufügen. Wieder ist der grundlegende Befehl

:bufdo vimgrepadd pattern %

Wenn Ihre Quickfix-Liste nicht leer ist, möchten Sie sie wahrscheinlich zuerst löschen (siehe /programming//q/27385970/1057593 ). Dies kann mit erfolgen

:cexpr []

vim-unimpaired stellt die Mappings zur Verfügung ]qund [qfährt durch die Matches.

cmdline-history

Es ist ein guter Workflow, das Suchmuster separat mit einzugeben /pattern. Auf diese Weise können Sie einen allgemeinen Befehl aus Ihrem Befehlszeilenverlauf unter Verwendung des aktuellen Suchmusters verwenden. Das würde so aussehen

/pattern
:bufdo vimgrepadd // %

Eine typische neue pufferweite Suche wäre

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

Ich habe meinem vimrc die folgenden Zuordnungen hinzugefügt, um <C-N>und <C-P>anstelle der Pfeiltasten zu verwenden

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

Um die Befehlshistorie Verwendung zu suchen q:, dann /bufdo<CR>und rufen Sie einen Befehl mit <CR>. Weitere Informationen finden Sie unter https://vim.fandom.com/wiki/Using_command-line_history sowie auf den Hilfeseiten :h historyund :h cmdline-window.

Sie können den wiederverwendbaren Befehl :copenfolgendermaßen hinzufügen, um die Quickfix-Liste sofort anzuzeigen:

:execute "bufdo vimgrepadd // %" | copen

Der Vorschlag von stackoverflow hat :bufdo vimgrepadd // % | copenin meinem Fall mehrere unbeabsichtigte Fenster geöffnet.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.