Cara menampilkan hasil pencarian untuk semua buffer terbuka

17

Satu hal yang sering saya lakukan (tetapi bergantung pada baris perintah untuk melakukannya) adalah mencari / menangkap beberapa file.

Apakah ada cara untuk menampilkan hasil pencarian untuk semua buffer terbuka?

Idealnya, saya ingin memiliki buffer split baru yang berisi lokasi hasil dan cuplikan seperti grephalnya. Misalnya ( /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();

Sebagai bonus, saya ingin dapat mencari istilah di bawah kursor, seperti gdhalnya.

Roflo
sumber
2
stackoverflow.com/questions/11975174/…
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Jawaban:

15

Anda dapat menggunakan :vimgrep /pattern/ {files}untuk mengisi daftar perbaikan cepat dengan pola yang cocok. Masalahnya adalah bahwa :vimgrepopsi file tidak memungkinkan buffer secara langsung. Kamu bisa memakai:

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

Pilihan lain adalah menulis skrip yang menghasilkan daftar file dari :buffers. Per posting SO ini dengan sedikit tweek kita dapatkan:

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

Anda sekarang dapat memanggil :GrepBufs <expression>dan mendapatkan :vimgrepoutput standar tetapi menggunakan buffer sebagai gantinya.

Perbarui Jika Anda ingin menelepon GrepBuffersmenggunakan nilai di bawah kursor, tambahkan pemetaan baru ini.

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

Ketika Anda berada dalam tipe mode normal <leader>zdan Anda akan :vimgrepkata kursor di atas buffer terbuka.

jecxjo
sumber
2
Dalam bentuk garis tunggal: command! -bang -nargs=+ Bufgrep execute 'vimgrep<bang><args> ' . join(map(filter(range(1, bufnr('$')), 'buflisted(v:val)'), '"#".v:val'), ' '). Penggunaan::Bufgrep/foo/
Peter Rincker
8

Pencarian di buffer yang dibuka itu bagus, tetapi mungkin ada saatnya Anda ingin mencari di seluruh proyek. Ini bisa lebih cepat dan lebih mudah dari yang Anda pikirkan!

Mencari di seluruh proyek

  • grepadalah alat pencarian standar Unix. Layak disebutkan karena keberadaannya di mana-mana. Sudah terintegrasi ke Vim via :grepperintah. mis :grep -r 'foo'. Lihat :h :grep.
  • Ack lebih cepat daripada grep biasa karena melompati direktori VCS, file biner, dan dapat mencari tipe file seperti spesifik --perl. Untuk integrasi Vim, lihat Ack.vim
  • Ag the Silver Surfer adalah alat pencarian kode yang mirip dengan ack, tetapi lebih cepat. Plugin Vim: Ag.vim
  • git grepmencari repositori dengan sangat cepat. Fugitive.vim menyediakan :Ggrep.
  • Ripgrep bahkan lebih cepat daripada Ag dan git grep. Dapat digunakan dengan :grepjuga.

Saya merekomendasikan ripgrep, Ag, dan git grepkarena keduanya super cepat. Saya telah mencari lebih dari 4700+ dalam waktu kurang dari 1 detik. Cukup sulit untuk mengalahkan ripgrep.

Untuk menguji salah satu dari alternatif ini tanpa plugin atau Anda hanya tidak ingin plugin, Anda dapat mengatur 'grepprg'opsi Anda sesuai. misalnya set grepprg=ag\ --vimgrepatau set grepprg=rg\ --vimgrep. Lihat :h 'grepprg'dan :h 'grepformat'untuk informasi lebih lanjut. Sekarang Anda dapat mencari via :grep. mis :grep 'foo'.

Sebagai fallback akhir, Anda dapat menggunakannya :vimgrepkarena tersedia di semua sistem yang Vim tersedia. Lihat :h :vimguntuk bantuan lebih lanjut.

Daftar QuickFix

Karena sebagian besar opsi ini menggunakan daftar perbaikan cepat, saya sarankan Anda menggunakan beberapa pemetaan yang lebih ramah untuk melintangkan daftar perbaikan cepat. Saya menggunakan plugin Tim Pope yang tidak rusak yang menggunakan ]qdan [quntuk masing :cnext- :cprevmasing. Beberapa orang seperti quickfix untuk membuka setelah pencarian dilakukan kemudian tambahkan berikut ini untuk Anda ~/.vimrcberkas: autocmd QuickFixCmdPost *grep* cwindow. Anda juga dapat secara manual membuka daftar QuickFix via :copen.

Ingin "pencarian" lebih cepat?

Anda akan perlu menggunakan beberapa alat yang menggunakan indeks prebuilt seperti ctags , cscope , atau GNU global .

  • Vim telah dibangun untuk mendukung ctag melalui :tag, <c-]>dan banyak perintah dan opsi. Lihat :h tags. Juga mungkin ingin membaca Ctag yang mudah dengan Git atau melihat ke dalam plugin Gutentags
  • Dukungan Cscope juga terintegrasi dan dapat digunakan melalui :cscopeperintah. Lihat:h cscope

Lebih banyak bantuan

Saya akan mulai dengan episode Vimcast yang bagus ini : Cari beberapa file dengan:vimgrep .

Untuk bantuan Vim lebih lanjut, lihat dokumentasi:

:h grep
:h :vimgrep
:h :grep
:h 'grepprg'
:h 'grepformat'
:h quickfix
:h :cnext
:h tags
:h cscope
Peter Rincker
sumber
6

Plugin GrepCommands saya mendefinisikan varian perintah built-in :vimgrepyang menargetkan semua argumen, buffer yang terdaftar, jendela di halaman tab saat ini atau semua halaman tab untuk pencariannya. Pada dasarnya, implementasi plugin yang kuat dari jawaban @ jecxjo.

Ingo Karkat
sumber
1

Perintah :bufdodan:vimgrepadd

Jawaban ini didasarkan pada /programming//a/11976158/1057593 .

Namun, saya ingin menambahkan beberapa bit. Sekali lagi perintah dasarnya adalah

:bufdo vimgrepadd pattern %

Jika daftar perbaikan cepat Anda tidak kosong, Anda mungkin ingin menghapusnya terlebih dahulu (lihat /programming//q/27385970/1057593 ). Ini bisa dilakukan dengan

:cexpr []

vim-unimpaired menyediakan pemetaan ]qdan [quntuk menelusuri pertandingan.

cmdline-history

Ini adalah alur kerja yang baik untuk memasukkan pola pencarian secara terpisah /pattern. Ini memungkinkan Anda untuk menggunakan perintah generik dari riwayat baris perintah Anda menggunakan pola pencarian saat ini. Ini akan terlihat seperti

/pattern
:bufdo vimgrepadd // %

Sebuah pencarian lebar buffer yang khas akan

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

Saya telah menambahkan pemetaan berikut ke vimrc saya untuk digunakan <C-N>dan <C-P>bukan tombol panah

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

Untuk mencari riwayat perintah gunakan q:, lalu /bufdo<CR>dan panggil perintah dengan <CR>. Untuk detail lebih lanjut, lihat https://vim.fandom.com/wiki/Using_command-line_history dan halaman bantuan :h historydan :h cmdline-window.

Anda dapat menambahkan ke perintah yang dapat digunakan kembali :copenuntuk segera melihat daftar perbaikan cepat dengan cara berikut:

:execute "bufdo vimgrepadd // %" | copen

Proposal dari stackoverflow :bufdo vimgrepadd // % | copenmembuka beberapa jendela yang tidak diinginkan dalam kasus saya.

Hotschke
sumber