3

So you search /needle, and end up trapped in a haystack of result lines. Is there a quick way to skip to the first non-matching line (and then the next batch of results)?

E.g. I'm viewing the results of updatedb -v, which shows paths considered by the locate engine, and I'm trying to figure out why a particular *.svg file isn't beeing considered. Searching for /svg leads me first somewhere deep inside /home/user/, where there are a whole lot of .*svg lines. How can I easily skip over all contiguous matches and go to the first non-matching line (and then probably repeat and so on)? Perhaps define a key mapping that reverses the search?

1 Answer 1

4

I was trying to come up with something fairly short and found this novel approach (novel to me anyways...I'd never tried it before).

There is an inverse counterpart to :g (global command): :v. This will run specified commands on all lines that don't match the given pattern. Because it's really easy to invoke when a pattern is already in use (i.e. :v// {cmds}, I was wondering if there's a way to break out of it easily at the first line it operates on (i.e. the first line below the cursor without the offending pattern). I found that :visual does the trick. (See update, though.)

One added requirement, though, is that you need to give a range or the process will begin at the start of the file which we definitely don't want. So what you want is a range starting with the current line (.) and going as far as the end of the buffer ($)...

:.,$v// vis

and that's it. You'll be on the next line that doesn't have the pattern. It's easy to map it, too...

:nnoremap <leader>x :.,$v// vis<cr>

The nice thing with this approach is that you don't need to use a different search and thus you won't have to deal with getting your original search back as the active one. If there is a downside to it it may be a little slow depending on various factors (i.e. YMMV).

Update: A twist. :visual is actually behaving as :e and the above will not work cleanly if the file has unsaved changes. Do :w before running the above and it will work as described.

11
  • 1
    I get E37: No write since last change. I'm betting you have :set hidden and that's why you don't see the E37 message (just editing the same file again, means switching to the buffer you're already in.)
    – filbranden
    Dec 23, 2020 at 15:55
  • 2
    I thought you mean Ex command line mode. You're talking about the actual but obscure Ex. The behavior I'm seeing is not matching up fully with some things. That includes what's described at the very end of :h :v. For now you'll just have to avoid running the command with an unsaved file. Do a :w beforehand.
    – B Layer
    Dec 23, 2020 at 18:26
  • 1
    I only read :h :visual before writing the above. I discovered the other part afterwards. I fully comprehend everything that's documented...it's not behaving that way for me. Clearly I have something in my configuration that's interfering. Doubt I'll dig further since it's not going to change anything in the answer now that I noted the need for :w.
    – B Layer
    Dec 23, 2020 at 18:47
  • 1
    Time for a break. And anyways, I can't earn any more rep today because some wonderful, anonymous person upvoted a bunch of my answers. Thought it was a general gift from SE for all at first but I checked a few profiles and they didn't have it. My guardian angel, I guess. :)
    – B Layer
    Dec 23, 2020 at 19:11
  • 1
    @BLayer, I came up with almost the same answer a while ago, except I didn't think about a no-op, but some kind of :throw or :abort. vi.stackexchange.com/questions/26339/command-to-abort-sequence/…
    – usretc
    Jan 3, 2021 at 7:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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