25

In a long file, I would like to search for a pattern that will match roughly 200 lines or so. The matched lines are in random places in the file.
When a line matches, only the line itself is relevant, no context above or below.

Normally, I would search with / and jump through the matches with n.
But that means there are only one or two relevant lines on the screen at a time.

Is there a way to hide all lines that did not match, while going through the list of result lines?


A brute force approach would be to delete all non-matching lines, and undo that deletion later. But that's ugly in various ways, even if it would not end up in persistent undo...

27
:vimgrep pattern %
:cwin

vimgrep will search for your pattern in the current file (%), or whatever files you specify.

cwin will then open a buffer in your window that will only show the desired lines. You can use pretty much any navigating/search command within the cwin buffer. Press return to jump to the line under your cursor in the source file.

  • 1
    :vimgrep can be abbreviated to :vim – D. Ben Knoble Jun 11 '18 at 14:51
  • how do i get back to the buffer again? – pasha Dec 2 '18 at 12:19
  • also how do i close the buffer? thanks in advance – pasha Dec 2 '18 at 12:23
  • From the quickfix (cwindow) buffer you can hit return on any line to jump to that location in the original buffer. You can can close the cwindow buffer from anywhere with :ccl[ose] or however you normally close a buffer (e.g., switch to it and :bd). You can reopen the quickfix buffer by running :cw[indow] again, and it will use your last vimgrep results. – Zach Ingbretsen Mar 23 at 12:59
10

You can use the foldmethod and foldexpr options to fold away irrelevant lines.

After searching, the last search is stored in the @/ register. So, you can readily fold away everything that doesn't match like this (for one-line matches only):

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

More advanced methods, like adding multiple levels of folding for context lines you can show or hide, or matching multiple lines, can be found on the Vim Tips Wiki.

  • Seems like there is a set foldlevel=0 needed? But maybe that's default. – Volker Siegel Feb 28 '15 at 3:16
  • 1
    Yeah the default is zero, but if it doesn't work without, adding it can't hurt. :-) – Ben Feb 28 '15 at 3:18
  • But now... how to switch it back again, with no traces? – Volker Siegel Feb 28 '15 at 3:23
  • in normal mode, you can use 'zi' to toggle folding off and on. – John O'M. Feb 28 '15 at 4:04
  • Most of the time when I do this I first :tab sp to get a new throwaway view on the file. Then going back is as simple as :close or any other way to kill the tab. – Ben Feb 28 '15 at 17:49
7

You can list all matching lines with

:g/{pattern}

(The :print command can be omitted; it is the default for :g.)

  • 1
    This is the "original grep" (g/REgexp/p) ... Problem is that you can't easily jump to one of the matches, though... – Martin Tournoij Feb 28 '15 at 19:44
  • @Carpetsmoker: You're right; for that, I have a plugin, see my other answer. – Ingo Karkat Feb 28 '15 at 20:00
  • That could be useful for many cases. Can the output be redirected to a new buffer? That would allow to still have syntax highlighting on the lines. (Hmm... that raises another question, wait a second...) – Volker Siegel Feb 28 '15 at 20:18
4

If order doesn't matter then just move the lines.

:g/pat/m0

For more help see:

:h :g
:h :m
  • 1
    And :g/pat/m$ (move the matched lines to the end) is also OK, – Lerner Zhang Sep 28 '16 at 9:05
1

If you want to list all matching lines (as in my other answer), and then jump to one particular match, my FindOccurrence plugin provides a [/ mapping for that (and [n for the last search pattern, instead of querying for one). [/pattern lists like :g/pattern, but then asks for the number of the match to jump to.

1
:g!/pattern/d

or simpler (thanks for the comments by 'B Layer'):

:v/patter/d

[d]elete all lines not(!) matching patterns

  • Yeah, but it's more conventional to use the equivalent :v rather than :g!. (I don't remember the last time I saw the latter used, TBH!) – B Layer Jun 12 '18 at 4:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.