Come mostrare i risultati della ricerca per tutti i buffer aperti


17

Una cosa che faccio spesso (ma faccio affidamento sulla riga di comando per fare) è la ricerca / grepping in più file.

C'è un modo per visualizzare i risultati della ricerca per tutti i buffer aperti?

Idealmente, mi piacerebbe avere un nuovo buffer diviso contenente la posizione dei risultati e lo snippet, proprio come grepfa. Ad esempio ( /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();

Come bonus, vorrei essere in grado di cercare il termine sotto il cursore, proprio come gdfa.


Risposte:


15

È possibile utilizzare :vimgrep /pattern/ {files}per popolare l'elenco di correzioni rapide con modelli corrispondenti. Il problema è che l' :vimgrepopzione file non consente direttamente i buffer. Puoi usare:

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

Un'altra opzione è quella di scrivere uno script che genera un elenco di file da :buffers. Per questo post SO con un leggero tweek otteniamo:

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

Ora puoi chiamare :GrepBufs <expression>e ottenere l' :vimgrepoutput standard ma usando invece i buffer.

Aggiorna Se desideri chiamare GrepBuffersutilizzando il valore sotto il cursore aggiungi questa nuova mappatura.

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

Quando si è in normale tipo di modalità <leader>ze avrete :vimgrepla parola cursore sopra i vostri buffer aperti.


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

8

La ricerca nei soli buffer aperti è buona, ma potrebbe arrivare un momento in cui si desidera cercare in un intero progetto. Può essere più veloce e più facile di quanto pensi!

Ricerca in un progetto

  • grepè lo strumento di ricerca standard Unix. Vale la pena menzionarlo per la sua ubiquità. Già integrato in Vim tramite :grepcomando. es :grep -r 'foo'. Vedere :h :grep.
  • Ack è più veloce del normale grep perché salta directory VCS, file binari e può cercare tipi specifici di tipi di file come --perl. Per l'integrazione di Vim, consultare Ack.vim
  • Ag the Silver Surfer è uno strumento di ricerca del codice simile a ack, ma più veloce. Plug-in Vim: Ag.vim
  • git grepcerca un repository molto rapidamente. Fugitive.vim fornisce :Ggrep.
  • Ripgrep è persino più veloce di Ag e git grep. Può essere usato anche con :grep.

Consiglio sia Ripgrep, Ag, sia git grepdato che sono tutti super veloci. Ho cercato oltre 4700+ in meno di 1 secondo. È abbastanza difficile battere Ripgrep.

Per provare una di queste alternative senza un plug-in o semplicemente non vuoi un plug-in, puoi impostare l' 'grepprg'opzione di conseguenza. es . set grepprg=ag\ --vimgrepo set grepprg=rg\ --vimgrep. Vedi :h 'grepprg'e :h 'grepformat'per maggiori informazioni. Ora puoi cercare tramite :grep. es :grep 'foo'.

Come fallback finale puoi usare :vimgrepin quanto è disponibile su tutti i sistemi che Vim è disponibile. Vedere :h :vimgper ulteriore aiuto.

Elenco QuickFix

Poiché la maggior parte di queste opzioni utilizza l'elenco degli aggiornamenti rapidi, suggerisco di utilizzare alcuni mapping più intuitivi per attraversare l'elenco degli aggiornamenti rapidi. Uso il plugin non compromesso di Tim Pope che usa ]qe [qper :cnexte :cprevrispettivamente. Alcune persone, come il quickfix per aprire dopo una ricerca viene effettuata quindi aggiungere la seguente al vostro ~/.vimrcfile di: autocmd QuickFixCmdPost *grep* cwindow. È inoltre possibile aprire manualmente l'elenco QuickFix tramite :copen.

Vuoi "ricerche" ancora più veloci?

Dovrai utilizzare uno strumento che utilizza indici precompilati come ctags , cscope o GNU global .

  • Vim ha un supporto incorporato CTAG via :tag, <c-]>e molti altri comandi e opzioni. Vedere :h tags. Inoltre, potresti voler leggere Ctags senza sforzo con Git o guardare nel plugin Gutentags
  • Anche il supporto per Cscope è integrato e può essere utilizzato tramite :cscopecomando. Vedere:h cscope

Più aiuto

Vorrei iniziare con questo bel episodio di Vimcast : cercare più file con:vimgrep .

Per ulteriori informazioni su Vim, consultare la documentazione:

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

6

Il mio plug-in GrepCommands definisce le varianti del :vimgrepcomando integrato che hanno come target tutti gli argomenti, i buffer elencati, le finestre nella scheda corrente o tutte le schede per la sua ricerca. Fondamentalmente, una solida implementazione plug-in della risposta di @ jecxjo.


1

Comandi :bufdoe:vimgrepadd

Questa risposta si basa su /programming//a/11976158/1057593 .

Tuttavia, volevo aggiungere alcuni bit. Ancora una volta il comando di base è

:bufdo vimgrepadd pattern %

Se l'elenco delle correzioni rapide non è vuoto, probabilmente vorrai prima cancellarlo (vedi /programming//q/27385970/1057593 ). Questo può essere fatto con

:cexpr []

vim-impaired fornisce i mapping ]qe [qper scorrere le partite.

cmdline-history

È un buon flusso di lavoro inserire il modello di ricerca separatamente con /pattern. Ciò consente di utilizzare un comando generico dalla cronologia della riga di comando utilizzando il modello di ricerca corrente. Questo sarebbe simile

/pattern
:bufdo vimgrepadd // %

Una tipica nuova ricerca a livello di buffer sarebbe

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

Ho aggiunto le seguenti mappature al mio vimrc da usare <C-N>e al <C-P>posto dei tasti freccia

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

Per cercare nella cronologia dei comandi utilizzare q:, quindi /bufdo<CR>e invocare un comando con <CR>. Per maggiori dettagli, consultare https://vim.fandom.com/wiki/Using_command-line_history e le pagine della guida :h historye :h cmdline-window.

È possibile aggiungere al comando riutilizzabile :copenper visualizzare immediatamente l'elenco delle correzioni rapide nel modo seguente:

:execute "bufdo vimgrepadd // %" | copen

La proposta di StackOverflow ha :bufdo vimgrepadd // % | copenaperto diverse finestre non intenzionali nel mio caso.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.