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 ...

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.


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).


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 .


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

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

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ść.


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]+$/'))
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.