Nur passende Zeilen anzeigen?

31

In einer langen Datei möchte ich nach einem Muster suchen, das ungefähr 200 Zeilen entspricht. Die übereinstimmenden Zeilen befinden sich an zufälligen Stellen in der Datei.
Wenn eine Zeile übereinstimmt, ist nur die Zeile selbst relevant, kein Kontext darüber oder darunter.

Normalerweise würde ich mit suchen /und durch die Übereinstimmungen mit springen n.
Dies bedeutet jedoch, dass nur ein oder zwei relevante Zeilen gleichzeitig auf dem Bildschirm angezeigt werden.

Gibt es eine Möglichkeit, alle nicht übereinstimmenden Zeilen auszublenden, während Sie die Liste der Ergebniszeilen durchgehen?


Ein Brute-Force-Ansatz wäre, alle nicht übereinstimmenden Zeilen zu löschen und diese Löschung später rückgängig zu machen. Aber das ist in vielerlei Hinsicht hässlich, auch wenn es nicht zum dauerhaften Rückgängigmachen führen würde ...

Volker Siegel
quelle

Antworten:

34
:vimgrep pattern %
:cwin

vimgrepsucht nach Ihrem Muster in der aktuellen Datei ( %) oder in den von Ihnen angegebenen Dateien.

cwinöffnet dann einen Puffer in Ihrem Fenster, der nur die gewünschten Zeilen anzeigt. Sie können so ziemlich jeden Navigations- / Suchbefehl innerhalb des cwinPuffers verwenden. Drücken Sie die Eingabetaste, um zur Zeile unter Ihrem Cursor in der Quelldatei zu springen.

Zach Ingbretsen
quelle
1
:vimgrepkann abgekürzt werden mit:vim
D. Ben Knoble
Wie komme ich wieder in den Puffer?
Pasha
auch wie schließe ich den Puffer?
Vielen
Aus dem Quickfix-Puffer (Cwindow-Puffer) können Sie in jeder Zeile die Eingabetaste drücken, um zu dieser Stelle im ursprünglichen Puffer zu springen. Sie können den Fensterpuffer von überall mit schließen :ccl[ose]oder aber Sie schließen normalerweise einen Puffer (z. B. wechseln Sie zu ihm und :bd). Sie können den Quickfix-Puffer :cw[indow]erneut öffnen, indem Sie ihn erneut ausführen. Dabei werden die letzten vimgrep-Ergebnisse verwendet.
Zach Ingbretsen
15

Sie können alle übereinstimmenden Zeilen mit auflisten

:g/{pattern}

(Der :printBefehl kann weggelassen werden. Dies ist die Standardeinstellung für :g.)

Ingo Karkat
quelle
1
Dies ist das "Original Grep" ( g/REgexp/p) ... Das Problem ist, dass Sie nicht einfach zu einem der Spiele springen können ...
Martin Tournoij
@Carpetsmoker: Du hast recht; dafür habe ich ein plugin, siehe meine andere antwort.
Ingo Karkat
Das könnte in vielen Fällen nützlich sein. Kann die Ausgabe in einen neuen Puffer umgeleitet werden? Das würde es erlauben, Syntax-Hervorhebungen in den Zeilen zu haben. (Hmm ... das wirft eine andere Frage auf, warte eine Sekunde ...)
Volker Siegel
@IngoKarkat was ist die Bedeutung der g. Ich gehe davon aus, dass es sich um ein globales Muster handelt. Normalerweise mache ich VI-Suche mit einem Schrägstrich /patternund dies würde alle Vorkommen finden. Man kann durch Drücken des Buchstabens zu ihnen navigierenn
Alexander Cska
@AlexanderCska: Nein, es ist kein Modifikator für die Suche, sondern ein separater Befehl :g[lobal], der ein Muster als Argument verwendet. Alle Details finden Sie unter :help :global.
Ingo Karkat
12

Mit den Optionen foldmethodund foldexprkönnen irrelevante Linien weggefaltet werden.

Nach dem Suchen wird die letzte Suche im @/Register gespeichert . So können Sie leicht alles wegklappen, was nicht so passt (nur für Einzeilen-Matches):

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

Weiterführende Methoden, wie das Hinzufügen mehrerer Falzstufen für Kontextlinien, die Sie ein- oder ausblenden können, oder das Übereinstimmen mehrerer Linien, finden Sie im Vim Tips Wiki .

Ben
quelle
Scheint als wäre da eine set foldlevel=0nötig? Aber vielleicht ist das Standard.
Volker Siegel
1
Ja, die Standardeinstellung ist Null, aber wenn es nicht ohne funktioniert, kann das Hinzufügen nicht schaden. :-)
Ben
Aber jetzt ... wie schalte ich es wieder zurück, ohne Spuren zu hinterlassen?
Volker Siegel
Im normalen Modus können Sie mit 'zi' das Ein- und Ausklappen umschalten.
John O'M.
Die meiste Zeit, wenn ich das tue :tab sp, erhalte ich zuerst eine neue Wegwerfansicht für die Datei. Dann ist das Zurückgehen so einfach wie :closejede andere Möglichkeit, den Tab zu töten.
Ben
6

Wenn die Reihenfolge keine Rolle spielt, verschieben Sie einfach die Zeilen.

:g/pat/m0

Weitere Hilfe finden Sie unter:

:h :g
:h :m
Peter Rincker
quelle
1
Und :g/pat/m$(verschieben Sie die übereinstimmenden Zeilen bis zum Ende) ist auch OK,
Lerner Zhang
6

[d] lösche alle nicht (!) passenden Zeilen:

:g!/pattern/d

oder noch einfacher (danke für die Kommentare von 'B Layer'):

:v/pattern/d
Kevin Liu
quelle
Ja, aber es ist konventioneller, das Äquivalent zu verwenden :vals :g!. (Ich erinnere mich nicht, wann ich das letzte Mal gesehen habe, TBH!)
B Layer
2

Wenn Sie alle übereinstimmenden Zeilen auflisten möchten (wie in meiner anderen Antwort) und dann zu einer bestimmten Übereinstimmung springen möchten, bietet mein FindOccurrence-Plugin eine [/Zuordnung für diese (und [nfür das letzte Suchmuster, anstatt nach einer abzufragen ). [/patternListen wie :g/pattern, fragt dann aber nach der Nummer des Treffers, zu dem gesprungen werden soll.

Ingo Karkat
quelle
0

Eine andere Möglichkeit ist, es zu benutzen :h :ilist, um einen Überblick über die Manpage zu bekommen. Das Ergebnis sieht so aus:

~/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

Hier ist eine kleine Funktion, mit der Sie nach Index in die Ergebniszeile wechseln können:

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

Es kann so verwendet werden:

command! -buffer Section call s:select_ilist(execute('silent! ilist /\v\C^[A-Z][^a-z]+$/'))
dedowsdi
quelle