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.