Come cercare la parola corrente in tutte le schede aperte in Vim?


16

Ho iniziato a imparare la ricerca di parole di Vim usando *e #mentre il cursore si trova sulla parola corrente. Ma questa ricerca è limitata al buffer di file corrente.

Esiste un comando o un collegamento per estendere questa ricerca a:

  1. tutte le schede aperte?
  2. tutti i buffer aperti?

1
Questa spiegazione delle schede rispetto ai buffer potrebbe essere interessante e utile.
Wildcard

Risposte:


4

Non ho una soluzione esatta per il tuo problema, spero una risposta migliore della mia verrà fuori. Ma è così che ho affrontato il problema di trovare una parola in tutti i 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

La prima riga crea un comando Searchcon il modello di ricerca come argomento, che scrive i risultati in un elenco di correzioni rapide. Le altre due linee mappano gli inutili tasti freccia (almeno per me) a qualcosa di utile; sono mappati per saltare alla ricerca successiva / precedente o all'errore di compilazione successivo / precedente, ecc., semplicemente passano attraverso l'elenco di correzioni rapide. Puoi usarlo come segue:

:Search foobar
<right>
<right>
…

Adoro questo comando, ma ho aggiunto alcune cose in modo da sfuggire meglio ai termini di ricerca e forzare un ridisegno. (l'uso di silent con split può causare la fuoriuscita di vim ui). comando! -nargs = 1 Cerca call setqflist ([]) | silent esegue "bufdo grepadd! '<args>'%" | ridisegnare!
Igorio,

puoi anche semplicemente digitare :cno :cpper passare al documento successivo.
Phyatt,

7

In realtà è il comportamento predefinito anche se può essere difficile da notare: prova *quindi a passare a un'altra scheda e usa nans Nin modalità comando per saltare avanti e indietro tra i risultati della ricerca.

Questo potrebbe avere più senso se per prima cosa attivi l'evidenziazione per tutti i colpi:

:set hlsearch

1
+1 solo per hlsearchquello che non sapevo e che avrei cercato un giorno o l'altro :-). Tuttavia, per impostazione predefinita ho provato * #, n e N e non passa ad altri buffer di file ...
Stephane Rolland

No, ne Nnon saltare i buffer (vanno a capo), ma il termine scelto come target viene cercato in tutte le schede; premi *con l'evidenziazione attiva quindi scorri le tue schede: saranno tutte evidenziate con lo stesso termine, in modo da poterle utilizzare localmente ne Nlì senza una nuova ricerca.
Riccioli d'oro

1
Il punto è NON dover scorrere le schede per trovare tutte le corrispondenze.
Magnus,

1
@Magnus Sebbene sia preferibile, in realtà non è esplicitamente indicato nella domanda, che chiede come "estendere questa ricerca a ... tutti i buffer" -> è estesa a tutti i buffer. Il punto della mia risposta è stato quello di chiarirlo, dal momento che potrebbe non esserlo, soprattutto se non lo hai hlsearchimpostato.
Riccioli d'oro,


1

Dato che mi sono ritrovato a fare spesso questo, ho creato una sceneggiatura (migliorabile).

Tu o qualcun altro potresti trovarlo utile.


Breve spiegazione:

Fondamentalmente cerca l'elenco dei buffer e mostra i risultati nella finestra di quickfix.

Sono stati aggiunti due comandi di base.

  1. Search <pattern> : Cerca tutti i buffer per <pattern>.
  2. Search1 <pattern>: Cerca tutti i buffer <pattern>, ma mostra solo il primo risultato per ciascun buffer. In genere utile per elencare tutti i buffer in cui fooviene utilizzata la funzione, la variabile (o qualunque cosa).

Usa bang ( :Search! foo) per aggiungere ai risultati.

Inoltre GSearche GSearch1viene aggiunto dove la differenza è che con Searchlo script aggiungi delimitatore regex, ad esempio:

foo -> /foo/

Dove GSearchaspettarsi che sia racchiuso.

Il jflag viene sempre aggiunto per impedire il salto.


Codice:

Ci sono alcuni hack per impedire la lista degli errori mantenendo allo stesso tempo il codice breve. try / catchera un po 'ingombrante 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)
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.