Jak wyszukać bieżące słowo we wszystkich otwartych kartach w Vimie?

16

Zacząłem uczyć się wyszukiwania słów Vima za pomocą *i #gdy kursor znajduje się nad bieżącym słowem. Ale to wyszukiwanie jest ograniczone do bieżącego bufora plików.

Czy istnieje polecenie lub skrót do rozszerzenia tego wyszukiwania na:

  1. wszystkie otwarte zakładki?
  2. wszystkie otwarte bufory?
Stephane Rolland
źródło
1
To wyjaśnienie tabulatorów i buforów może być dla ciebie interesujące i pomocne.
Wildcard
bufory stackoverflow.com/questions/11975174/...
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Odpowiedzi:

4

Nie mam dokładnego rozwiązania twojego problemu, mam nadzieję, że pojawi się lepsza odpowiedź niż moja. Ale w ten sposób rozwiązałem problem znalezienia słowa we wszystkich buforach.

" 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

Pierwszy wiersz tworzy polecenie Searchz wzorcem wyszukiwania jako argumentem, który zapisuje wyniki na liście szybkich poprawek. Dwie pozostałe linie mapują (przynajmniej dla mnie) niepotrzebne klawisze strzałek na coś użytecznego; są mapowane, aby przejść do następnego / poprzedniego wyszukiwania lub do następnego / poprzedniego błędu kompilacji itp., po prostu przechodzą przez listę szybkich poprawek. Możesz użyć tego w następujący sposób:

:Search foobar
<right>
<right>
…
Marco
źródło
Uwielbiam to polecenie, ale dodałem kilka rzeczy, aby lepiej unikał wyszukiwanych haseł i wymusił przerysowanie. (użycie cichego z podziałem może spowodować błąd w vim ui). Komenda! -nargs = 1 Wyszukaj połączenie setqflist ([]) | cichy wykonaj polecenie „bufdo grepadd! '<args>'%” | przerysować!
Igorio
możesz także po prostu wpisać :cnlub :cpprzejść do następnego dokumentu.
phyatt
7

W rzeczywistości jest to zachowanie domyślne, chociaż może być trudne do zauważenia: spróbuj *następnie przejść do innej karty i użyć nans Nw trybie poleceń, aby przeskakiwać do przodu i do tyłu między wynikami wyszukiwania.

Może to mieć większy sens, jeśli najpierw podświetlisz wszystkie trafienia:

:set hlsearch
Złotowłosa
źródło
1
+1 tylko z hlsearchtego powodu , że nie wiedziałem, a którego szukałbym jednego dnia :-). Jednak domyślnie próbowałem * #, n i N, i nie przeskakuje do innych buforów plików ...
Stephane Rolland
Nie ni Nnie przeskakuj buforów (owijają się), ale szukany termin jest wyszukiwany na wszystkich kartach; hit *z podświetlenie następnie cyklu thru swoimi kartami - wszystkie będą podświetlone tym samym okresie, dzięki czemu można używać ni Nlokalnie tam bez nowego wyszukiwania.
goldilocks
2
Chodzi o to, żeby NIE przeglądać kart, aby znaleźć wszystkie dopasowania.
Magnus
1
@Magnus Chociaż może to być preferowane, w rzeczywistości nie jest to wyraźnie określone w pytaniu, które pyta, jak „rozszerzyć to wyszukiwanie na ... wszystkie bufory” -> jest ono rozszerzone na wszystkie bufory. Celem mojej odpowiedzi było wyjaśnienie tego, ponieważ może tak nie być, zwłaszcza jeśli nie hlsearchustawiłeś.
goldilocks
4
 :bufdo vimgrepadd yoursearchterm % | copen
Magnus
źródło
1

Ponieważ często to robię, opracowałem (możliwy do ulepszenia) skrypt.

Ty lub ktoś inny może ci się przydać.


Krótkie wyjaśnienie:

Zasadniczo przeszukuje listę buforów i pokazuje wynik w oknie szybkiego dostępu.

Dodano dwa podstawowe polecenia.

  1. Search <pattern> : Przeszukaj wszystkie bufory dla <pattern>.
  2. Search1 <pattern>: Przeszukaj wszystkie bufory <pattern>, ale pokaż tylko pierwszy wynik dla każdego bufora. Zwykle przydatne do wyświetlania wszystkich buforów, w których fooużywana jest funkcja, zmienna (lub cokolwiek innego).

Użyj bang ( :Search! foo), aby dołączyć do wyników.

Dodatkowo GSearchi GSearch1dodaje gdzie różnica polega na tym, że z Searchregex ogranicznika skrypt dodawać, np:

foo -> /foo/

Gdzie zgodnie z GSearchoczekiwaniami, należy go załączyć.

jFlaga jest zawsze dodawana do zapobiegania skok.


Kod:

Istnieje kilka hacków, aby zapobiec wyświetlaniu błędów, a jednocześnie utrzymywać krótki kod. try / catchbyło trochę kłopotliwe 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
źródło