Wie suche ich das aktuelle Wort in allen geöffneten Registerkarten in Vim?

16

Ich habe angefangen, die Vim-Wortsuche mit *und zu lernen, #während sich der Cursor über dem aktuellen Wort befindet. Diese Suche ist jedoch auf den aktuellen Dateipuffer beschränkt.

Gibt es einen Befehl oder eine Verknüpfung, um diese Suche zu erweitern:

  1. alle geöffneten tabs?
  2. alle geöffneten Puffer?
Stephane Rolland
quelle
1
Diese Erklärung zu Registerkarten und Puffern ist möglicherweise interessant und hilfreich.
Wildcard
Puffer stackoverflow.com/questions/11975174/...
Ciro Santilli新疆改造中心法轮功六四事件

Antworten:

4

Ich habe keine genaue Lösung für Ihr Problem, hoffentlich eine bessere Antwort als meine. Aber so ging ich das Problem an, in allen Puffern ein Wort zu finden.

" 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

Die erste Zeile erstellt einen Befehl Searchmit dem Suchmuster als Argument, der die Ergebnisse in eine Quickfix-Liste schreibt. Die beiden anderen Zeilen ordnen die (zumindest für mich) nutzlosen Pfeiltasten etwas Nützliches zu; Sie werden zugeordnet, um zur nächsten / vorherigen Suche oder zum nächsten / vorherigen Kompilierungsfehler zu springen. Sie durchlaufen einfach die Quickfix-Liste. Sie können dies wie folgt verwenden:

:Search foobar
<right>
<right>
…
Marco
quelle
Ich liebe diesen Befehl, habe aber ein paar Dinge hinzugefügt, damit er den Suchbegriffen besser entgeht und ein Neuzeichnen erzwingt. (Die Verwendung von silent mit Splits kann dazu führen, dass vim ui fehlerhaft wird.) Befehl! -nargs = 1 Suchanruf setqflist ([]) | Stille Ausführung von "bufdo grepadd! '<args>'%" | neu zeichnen!
Igorio
Sie können auch einfach :cnoder :cpeingeben, um zum nächsten Dokument zu wechseln.
Phyatt
7

Eigentlich ist es das Standardverhalten, auch wenn es schwer zu bemerken ist: *Wechseln Sie in einen anderen Tab und verwenden Sie nans Nim Befehlsmodus, um zwischen den Suchtreffern vorwärts und rückwärts zu springen.

Dies kann sinnvoller sein, wenn Sie zuerst die Hervorhebung für alle Treffer aktivieren:

:set hlsearch
Goldlöckchen
quelle
1
+1 nur deswegen hlsearchwusste ich nicht, und welche ich für den einen oder anderen tag suchen müsste :-). Standardmäßig habe ich jedoch * #, n und N ausprobiert und es wird nicht zu anderen Dateipuffern gesprungen ...
Stephane Rolland
Nein, nund Nspringen Sie nicht in Puffer (sie werden umbrochen), sondern der Begriff, auf den sie abzielen, wird in allen Registerkarten gesucht. Hit *mit der Markierung zurück dann Zyklus durch Ihre Tabs - sie werden alle mit dem gleichen Begriff hervorgehoben werden, so dass Sie verwenden können nund Ndort lokal ohne erneute Suche.
Goldlöckchen
2
Der springende Punkt ist, dass Sie NICHT durch Ihre Registerkarten blättern müssen, um alle Übereinstimmungen zu finden.
Magnus
1
@Magnus Auch wenn dies vorzuziehen ist, wird dies in der Frage, in der gefragt wird, wie diese Suche auf alle Puffer ausgeweitet werden soll, nicht explizit angegeben . Der Sinn meiner Antwort war es, dies klar zu machen, da dies möglicherweise nicht der Fall ist, insbesondere wenn Sie es nicht festgelegt haben hlsearch.
Goldlöckchen
4
 :bufdo vimgrepadd yoursearchterm % | copen
Magnus
quelle
1

Da ich dies oft gemacht habe, habe ich ein (verbesserungsfähiges) Skript zusammengestellt.

Sie oder jemand anderes könnten es nützlich finden.


Kurze Erklärung:

Grundsätzlich durchsucht es die Pufferliste und zeigt das Ergebnis im Quickfix-Fenster an.

Zwei grundlegende Befehle wurden hinzugefügt.

  1. Search <pattern> : In allen Puffern nach suchen <pattern>.
  2. Search1 <pattern>: Durchsucht alle Puffer nach <pattern>, zeigt aber nur das erste Ergebnis für jeden Puffer an. Dies ist in der Regel nützlich, um alle Puffer aufzulisten, in denen Funktion, Variable foo(oder was auch immer) verwendet wird.

Verwenden Sie bang ( :Search! foo), um an die Ergebnisse anzuhängen.

Zusätzlich GSearchund GSearch1wird hinzugefügt, wenn der Unterschied darin besteht, dass mit Searchdem Skript Regex-Trennzeichen hinzugefügt werden , zB:

foo -> /foo/

Wo, wie zu GSearcherwarten, wird es eingeschlossen.

Das jFlag wird immer hinzugefügt, um ein Springen zu verhindern.


Code:

Es gibt einige Hacks, um die Auflistung von Fehlern zu verhindern und gleichzeitig den Code kurz zu halten. try / catchwar etwas umständlich auf 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
quelle