Bagaimana cara mencari kata saat ini di semua tab yang terbuka di Vim?

16

Saya sudah mulai belajar pencarian kata Vim menggunakan *dan #sementara kursor di atas kata saat ini. Tetapi pencarian ini terbatas pada buffer file saat ini.

Apakah ada perintah atau pintasan untuk memperluas pencarian ini ke:

  1. semua tab yang dibuka?
  2. semua buffer terbuka?
Stephane Rolland
sumber
1
Anda mungkin menemukan penjelasan tentang tab vs buffer ini menarik dan bermanfaat.
Wildcard
buffer stackoverflow.com/questions/11975174/…
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Jawaban:

4

Saya tidak punya solusi tepat untuk masalah Anda, semoga jawaban yang lebih baik dari saya akan muncul. Tetapi inilah bagaimana saya mengatasi masalah menemukan kata di semua buffer.

" enables to search in all open buffers with :Search <pattern>
command! -nargs=1 Search call setqflist([]) | silent bufdo grepadd! <args> %

nnoremap <left>  :cprev<cr>zvzz
nnoremap <right> :cnext<cr>zvzz

Baris pertama membuat perintah Searchdengan pola pencarian sebagai argumen, yang menuliskan hasilnya dalam daftar perbaikan cepat. Dua baris lainnya memetakan tombol panah (setidaknya untuk saya) yang tidak berguna ke sesuatu yang berguna; mereka dipetakan untuk melompat ke Pencarian berikutnya / sebelumnya atau ke kesalahan kompilasi berikutnya / sebelumnya, dll., mereka hanya melangkah melalui daftar perbaikan cepat. Anda dapat menggunakan ini sebagai berikut:

:Search foobar
<right>
<right>
…
Marco
sumber
Saya suka perintah ini, tetapi menambahkan beberapa hal sehingga akan luput dari istilah pencarian yang lebih baik, dan memaksa redraw. (Menggunakan diam dengan split dapat menyebabkan vim ui bug keluar). perintah! -nargs = 1 Cari panggilan setqflist ([]) | diam jalankan "bufdo grepadd! '<args>'%" | redraw!
Igorio
Anda juga bisa mengetik :cnatau :cpberalih ke dokumen berikutnya.
phyatt
7

Sebenarnya ini adalah perilaku default meskipun mungkin sulit untuk diperhatikan: coba *ubah ke tab lain dan gunakan nans Ndalam mode perintah untuk melompat maju dan mundur di antara pencarian pencarian.

Ini mungkin lebih masuk akal jika pertama kali Anda mengaktifkan sorotan untuk semua klik:

:set hlsearch
goldilocks
sumber
1
Memberi +1 hanya karena hlsearchitu saya tidak tahu, dan yang akan saya cari satu hari atau yang lain :-). Namun, secara default saya telah mencoba * #, n dan N, dan itu tidak melompat ke buffer file lainnya ...
Stephane Rolland
Tidak, ndan Njangan lompati buffer (mereka membungkus), tetapi istilah yang mereka targetkan dicari di semua tab; tekan *dengan sorotan pada kemudian siklus melalui tab Anda - mereka semua akan disorot dengan istilah yang sama, sehingga Anda dapat menggunakan ndan Nsecara lokal di sana tanpa pencarian baru.
goldilocks
2
Intinya adalah TIDAK harus menelusuri tab Anda untuk menemukan semua kecocokan.
Magnus
1
@ Magnus Sementara itu mungkin lebih disukai, itu sebenarnya tidak secara eksplisit dinyatakan dalam pertanyaan, yang menanyakan bagaimana "memperluas pencarian ini ke ... semua buffer" -> itu diperluas di semua buffer. Inti dari jawaban saya adalah untuk memperjelas ini, karena mungkin tidak, terutama jika Anda belum hlsearchmenetapkan.
goldilocks
4
 :bufdo vimgrepadd yoursearchterm % | copen
Magnus
sumber
1

Karena saya sering melakukan ini, saya membuat skrip (yang tidak bisa diperbaiki).

Anda atau orang lain mungkin menganggapnya berguna.


Penjelasan singkat:

Pada dasarnya mencari daftar buffer dan menunjukkan hasil di jendela perbaikan cepat.

Dua perintah dasar ditambahkan.

  1. Search <pattern> : Cari semua buffer untuk <pattern>.
  2. Search1 <pattern>: Cari semua buffer <pattern>, tetapi hanya tampilkan hasil pertama untuk setiap buffer. Biasanya berguna untuk membuat daftar semua buffer di mana fungsi, variabel foodigunakan, (atau apa pun).

Gunakan bang ( :Search! foo) untuk menambahkan hasil.

Selain itu GSearchdan GSearch1ditambahkan di mana perbedaannya adalah dengan Searchskrip tambahkan regex delimiter, misalnya:

foo -> /foo/

Dimana seperti yang GSearchdiharapkan untuk dilampirkan.

The jflag selalu ditambahkan untuk mencegah melompat.


Kode:

Ada beberapa peretasan untuk mencegah daftar kesalahan sementara pada saat yang sama menjaga kode pendek. try / catchsedikit rumit bufdo.

let s:not_idents = split("/!#$%&\"`´¨'¯()*+,-.:;<=>?¿@[\]^{|}µ¶·¸~±×÷®©«»¬­ª°º¹²³¼½¾", '\zs')
" Create a delimited pattern. "
fun! s:Parse_pat(pat)
    for c in s:not_idents
        if stridx(a:pat, c) == -1
            return c . a:pat . c
        endif
    endfor
    echohl Error
    echom "Could not delimit pattern '". a:pat ."'"
    echohl None
    return ''
endfun

fun! s:AllBufSearch(pat, bang, uno, isg)
    if a:isg
        let pat = a:pat
    else
        let pat = s:Parse_pat(a:pat)
    endif
    if pat == ''
        return
    endif
    cclose
    let [_buf, _view] = [bufnr("%"), winsaveview()]
    let _foldenable = &foldenable
    set nofoldenable

    " Copy of current qflist. "
    let qfc = getqflist()
    " Hack to prevent error if no matches. "
    call setqflist([{}])
    silent execute "bufdo vimgrepadd! " . pat . "j %"
    " Restore "
    exec "buffer " . _buf
    let &foldenable = _foldenable
    call winrestview(_view)
    " Fix "
    let qf = getqflist()
    call remove(qf, 0)
    " Only one listing per buffer. "
    if a:uno
        let bn = {}
        let i  = 0
        for m in qf
            if has_key(bn, m["bufnr"])
                call remove(qf, i)
            else
                let bn[m["bufnr"]] = 1
                call remove(qf[i], "valid")
                let i += 1
            endif
        endfor
    endif
    if a:bang == "!"
        let qf = qfc + qf
    endif
    " If any matches, copen. "
    if len(qf)
        call setqflist(qf)
        copen
    endif
endfun

command! -nargs=1 -bang Search   call s:AllBufSearch(<q-args>, "<bang>", 0, 0)
command! -nargs=1 -bang Search1  call s:AllBufSearch(<q-args>, "<bang>", 1, 0)
command! -nargs=1 -bang GSearch  call s:AllBufSearch(<q-args>, "<bang>", 0, 1)
command! -nargs=1 -bang GSearch1 call s:AllBufSearch(<q-args>, "<bang>", 1, 1)
Runium
sumber