Pokaż tylko pasujące linie?

31

W długim pliku chciałbym wyszukać wzór, który będzie pasował z grubsza około 200 linii. Dopasowane linie znajdują się w losowych miejscach w pliku.
Kiedy linia pasuje, tylko sama linia jest istotna, bez kontekstu powyżej lub poniżej.

Zwykle przeszukiwałbym /i przeskakiwał mecze n.
Ale to oznacza, że ​​na ekranie jest tylko jedna lub dwie odpowiednie linie na raz.

Czy istnieje sposób na ukrycie wszystkich niepasujących wierszy podczas przeglądania listy wierszy wyników?


Podejście brutalnej siły polegałoby na usunięciu wszystkich niepasujących wierszy i cofnięciu tego usunięcia później. Ale to brzydkie na różne sposoby, nawet jeśli nie skończyłoby się to ciągłym cofaniem ...

Volker Siegel
źródło

Odpowiedzi:

34
:vimgrep pattern %
:cwin

vimgrepwyszuka Twój wzorzec w bieżącym pliku ( %) lub dowolnych plikach, które określisz.

cwinnastępnie otworzy bufor w twoim oknie, który pokaże tylko pożądane linie. Możesz użyć praktycznie dowolnego polecenia nawigacyjnego / wyszukiwania w cwinbuforze. Naciśnij klawisz Return, aby przejść do linii pod kursorem w pliku źródłowym.

Zach Ingbretsen
źródło
1
:vimgrepmożna skrócić do:vim
D. Ben Knoble
jak mogę wrócić do bufora?
pasha
także jak mogę zamknąć bufor? z góry dziękuję
pasha
Z bufora szybkiej aktualizacji (cwindow) możesz nacisnąć return w dowolnej linii, aby przejść do tej lokalizacji w oryginalnym buforze. Możesz zamknąć bufor cwindow z dowolnego miejsca za pomocą :ccl[ose]lub jak zwykle zamykasz bufor (np. Przełączasz się na niego i :bd). Możesz ponownie otworzyć bufor Quickfix, uruchamiając go :cw[indow]ponownie, a on użyje twoich ostatnich wyników vimgrep.
Zach Ingbretsen
15

Możesz wyświetlić listę wszystkich pasujących linii za pomocą

:g/{pattern}

( :printPolecenie można pominąć; jest to ustawienie domyślne :g).

Ingo Karkat
źródło
1
To jest „oryginalny grep” ( g/REgexp/p) ... Problem polega na tym, że nie możesz łatwo wskoczyć na jeden z meczów ...
Martin Tournoij
@Carpetsmoker: Masz rację; do tego mam wtyczkę, zobacz moją drugą odpowiedź.
Ingo Karkat
Może to być przydatne w wielu przypadkach. Czy dane wyjściowe można przekierować do nowego bufora? Pozwoliłoby to nadal mieć podświetlanie składni w wierszach. (Hmm ... to rodzi kolejne pytanie, poczekaj chwilę ...)
Volker Siegel
@IngoKarkat jakie jest znaczenie g. Zakładam, że jest to wzór globalny. Zazwyczaj szukam VI z ukośnikiem, /patterna to by znaleźć wszystkie wystąpienia. Można do nich nawigować, naciskając literęn
Alexander Cska
@AlexanderCska: Nie, nie jest to modyfikator wyszukiwania, ale osobne polecenie, :g[lobal]które przyjmuje wzorzec jako argument. Wszystkie szczegóły znajdziesz na :help :global.
Ingo Karkat
12

Możesz użyć opcji foldmethodi, foldexpraby złożyć nieistotne linie.

Ostatnie wyszukiwanie jest zapisywane w @/rejestrze. Możesz więc łatwo złożyć wszystko, co się nie zgadza w ten sposób (tylko dla dopasowań jednowierszowych):

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

Bardziej zaawansowane metody, takie jak dodawanie wielu poziomów składania dla linii kontekstu, które można pokazać lub ukryć, lub dopasowywanie wielu linii, można znaleźć na Wiki Vim Tips .

Ben
źródło
Wydaje się, że jest set foldlevel=0potrzebny? Ale może to jest domyślne.
Volker Siegel
1
Tak, domyślną wartością jest zero, ale jeśli nie działa bez, dodanie nie może zaszkodzić. :-)
Ben
Ale teraz ... jak przywrócić go ponownie bez żadnych śladów?
Volker Siegel
w trybie normalnym możesz użyć „zi”, aby przełączyć składanie i włączanie.
John O'M.
Przez większość czasu, kiedy to robię, najpierw :tab spuzyskuję nowy rzut pliku na plik. Następnie powrót jest tak prosty, jak :closei jakikolwiek inny sposób, aby zabić kartę.
Ben
6

Jeśli kolejność nie ma znaczenia, po prostu przesuń linie.

:g/pat/m0

Aby uzyskać więcej pomocy, zobacz:

:h :g
:h :m
Peter Rincker
źródło
1
I :g/pat/m$(przesuń dopasowane linie na koniec) jest również OK,
Lerner Zhang
6

[d] usuń wszystkie linie, które nie pasują (!) do wzorów:

:g!/pattern/d

lub nawet prościej (dzięki za komentarze „B Layer”):

:v/pattern/d
Kevin Liu
źródło
Tak, ale bardziej konwencjonalne jest używanie ekwiwalentu :vniż :g!. (Nie pamiętam, kiedy ostatni raz widziałem ten ostatni używany, TBH!)
B Layer
2

Jeśli chcesz wyświetlić listę wszystkich pasujących wierszy (jak w mojej drugiej odpowiedzi), a następnie przejść do jednego konkretnego dopasowania, moja wtyczka FindOccurrence zapewnia [/odwzorowanie tego (i [nostatniego wzorca wyszukiwania zamiast zapytania o jeden). [/patternlisty takie jak :g/pattern, ale następnie pytają o numer meczu, do którego należy przejść.

Ingo Karkat
źródło
0

Innym sposobem jest użycie :h :ilist, używam go, aby uzyskać przegląd strony podręcznika man. jego wynik wygląda następująco:

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

Oto mała funkcja, która pozwala wybrać przejście do linii wyników według indeksu:

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

Można go użyć w następujący sposób:

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