Mostra solo le linee corrispondenti?


31

In un lungo file, vorrei cercare un modello che corrisponda a circa 200 righe circa. Le linee corrispondenti si trovano in punti casuali nel file.
Quando una linea corrisponde, è rilevante solo la linea stessa, nessun contesto sopra o sotto.

Normalmente, vorrei cercare con /e saltare attraverso le partite con n.
Ciò significa che sullo schermo sono presenti solo una o due righe pertinenti alla volta.

C'è un modo per nascondere tutte le linee che non corrispondono, mentre si passa attraverso l'elenco delle linee dei risultati?


Un approccio a forza bruta sarebbe quello di eliminare tutte le linee non corrispondenti e annullare tale eliminazione in seguito. Ma è brutto in vari modi, anche se non finirebbe in un annullamento persistente ...

Risposte:


34
:vimgrep pattern %
:cwin

vimgrepcercherà il tuo modello nel file corrente ( %), o qualunque file tu specifichi.

cwinaprirà quindi un buffer nella finestra che mostrerà solo le linee desiderate. Puoi usare praticamente qualsiasi comando di navigazione / ricerca all'interno del cwinbuffer. Premi Invio per passare alla riga sotto il cursore nel file di origine.


1
:vimgreppuò essere abbreviato in:vim
D. Ben Knoble l'

come posso tornare di nuovo al buffer?
pasha,

anche come chiudo il buffer? grazie in anticipo
pasha

Dal buffer quickfix (cwindow) puoi premere return su qualsiasi linea per saltare a quella posizione nel buffer originale. Puoi chiudere il buffer di cwindow da qualsiasi luogo con :ccl[ose]o comunque normalmente chiudi un buffer (ad esempio, passa a esso e :bd). È possibile riaprire il buffer quickfix eseguendolo di :cw[indow]nuovo e utilizzerà gli ultimi risultati di vimgrep.
Zach Ingbretsen,

15

Puoi elencare tutte le righe corrispondenti con

:g/{pattern}

(Il :printcomando può essere omesso; è il valore predefinito per :g.)


1
Questo è il "grep originale" ( g/REgexp/p) ... Il problema è che non puoi saltare facilmente a una delle partite, però ...
Martin Tournoij,

@Carpetsmoker: hai ragione; per questo, ho un plugin, vedi la mia altra risposta.
Ingo Karkat,

Ciò potrebbe essere utile in molti casi. L'output può essere reindirizzato a un nuovo buffer? Ciò consentirebbe di avere ancora l'evidenziazione della sintassi sulle linee. (Hmm ... che solleva un'altra domanda, aspetta un secondo ...)
Volker Siegel,

@IngoKarkat qual è il significato di g. Presumo che sia un modello globale. Di solito faccio una ricerca VI con una barra /patterne questo troverebbe tutte le occorrenze. Si può navigare verso di loro premendo la letteran
Alexander Cska

@AlexanderCska: No, non è un modificatore per la ricerca, ma un comando separato :g[lobal]che accetta uno schema come argomento. Troverai tutti i dettagli su :help :global.
Ingo Karkat,

12

È possibile utilizzare le opzioni foldmethode foldexprper piegare le linee irrilevanti.

Dopo la ricerca, l'ultima ricerca viene memorizzata nel @/registro. Quindi, puoi facilmente piegare tutto ciò che non corrisponde in questo modo (solo per le partite a una riga):

:setlocal foldexpr=getline(v:lnum)=~@/?0:1 foldmethod=expr

Metodi più avanzati, come l'aggiunta di più livelli di piegatura per le linee di contesto che è possibile mostrare o nascondere, o la corrispondenza di più linee, sono disponibili nel Wiki di Vim Tips .


Sembra che ci sia set foldlevel=0bisogno? Ma forse è predefinito.
Volker Siegel,

1
Sì, il valore predefinito è zero, ma se non funziona senza, aggiungerlo non può far male. :-)
Ben

Ma ora ... come ripristinarlo di nuovo, senza tracce?
Volker Siegel,

in modalità normale, è possibile utilizzare 'zi' per attivare e disattivare la piegatura.
John O'M.

La maggior parte delle volte quando lo faccio, :tab spper prima cosa ottengo una nuova vista usa e getta sul file. Quindi tornare indietro è semplice come :closeo in qualsiasi altro modo per uccidere la scheda.
Ben

6

Se l'ordine non ha importanza, basta spostare le linee.

:g/pat/m0

Per ulteriori informazioni, consultare:

:h :g
:h :m

1
E :g/pat/m$(sposta le linee abbinate alla fine) va anche bene,
Lerner Zhang,

6

[d] elimina tutte le linee che non corrispondono (!) ai modelli:

:g!/pattern/d

o anche più semplice (grazie per i commenti di 'B Layer'):

:v/pattern/d

Sì, ma è più convenzionale usare l'equivalente :vpiuttosto che :g!. (Non ricordo l'ultima volta che ho visto quest'ultimo usato, TBH!)
B Layer

2

Se vuoi elencare tutte le linee corrispondenti (come nella mia altra risposta), e poi saltare a una corrispondenza particolare, il mio plug-in FindOccurrence fornisce una [/mappatura per quello (e [nper l'ultimo modello di ricerca, invece di eseguire una query per uno). [/patternelenca come :g/pattern, ma poi chiede il numero della partita a cui saltare.


0

Un altro modo è usare :h :ilist, lo uso per avere una panoramica della pagina man. il risultato è simile al seguente:

~/find.~
  1:    3 NAME
  2:    6 SYNOPSIS
  3:    9 DESCRIPTION
  4:   18 OPTIONS
  5:   93 EXPRESSION
  6:  779 EXAMPLES
  7:  877 HISTORY
  8:  931 BUGS

Ecco una piccola funzione che ti consente di scegliere di andare alla riga dei risultati per indice:

function! s:select_ilist(ilist_result)
  if empty(a:ilist_result) || a:ilist_result =~# '^\_s*Error'
    return
  endif

  let select = input(a:ilist_result . "\ngoto : ")
  if empty(select) | return | endif

  " ilist result starts with '\nfilename\n', filename can be empty
  let lines = split(a:ilist_result[stridx(a:ilist_result, "\n", 1) : ], "\n")
  if select <= 0 || select > len(lines) | return | endif

  exec matchstr(lines[select-1], '^\v\s*\d+\:\s+\zs\d+')
endfunction

Può essere usato in questo modo:

command! -buffer Section call s:select_ilist(execute('silent! ilist /\v\C^[A-Z][^a-z]+$/'))
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.