5

I was looking at the documentation for search() (:help search()). I noticed that there is a "z" flag:

'z'    start searching at the cursor column instead of zero

When the 'z' flag is not given, searching always starts in column zero and then matches before the cursor are skipped.

What does this mean exactly? I tried :call search('\S') and :call search('\S', 'z'), and both of them behave the same when in a file full of text.

What is the "z" flag used for? Could you provide a simple example demonstrating the use of the "z" flag?

3 Answers 3

8

Here's an example that doesn't depend on 'W'. Enter ALFALFA, position the cursor on the first L and compare:

:call search('ALFA')

This moves the cursor left to the first A in the line. Surprising! Why didn't it move forward?

:call search('ALFA', 'z')

This moves the cursor right to the second A in the line. This seems more like what you'd expect.

The difference is that the default behaviour, as documented in the snippet you quote, starts the search from column zero but discards results left of the cursor. As you can see, in some circumstances, this doesn't give the exact same results as starting searching from the cursor, because it will never find overlapping results. Without 'z', the first ALFA is matched, but discarded because it is left of the cursor, then searching resumes after it, but finds no match in the remaining LFA. Afterwards searching wraps around and finally finds the first ALFA again. I'm guessing the 'z' option was added because it is genuinely useful and I would say more intuitive in this circumstance, but changing the default behaviour would have broken existings scripts.

2
  • Welcome to Vi and Vim!
    – D. Ben Knoble
    Commented Mar 5, 2021 at 13:57
  • 1
    This is a terrific answer. +1!
    – Rich
    Commented Mar 5, 2021 at 20:10
4

An example that illustrates the use of this flag is below.

Add the text 'abc123' to a buffer. Place the cursor on 'b' and execute the following command:

call search('abc\zs123', 'W')

The cursor will be positioned on '123' even though the cursor is after the start of the match. Now move the cursor back to 'b' and execute the following command:

call search('abc\zs123', 'Wz')

Now the search will fail and the cursor will not be moved because the pattern doesn't match after the cursor with the 'z' flag.

3

The "z" flag is really used to what it describes in the documentation, it'll make the search start from wherever your cursor is placed at the moment.

As for the behaviour you have experienced, what you might have missed on the docs is:

'w' Wrap around the end of the file

'W' don't Wrap around the end of the file

If neither 'w' or 'W' is given, the 'wrapscan' option applies.

And what wrapscan option does:

Searches wrap around the end of file.

As a quick example:

This is a text to be searched

If you try, lets say :call search('text') or :call search('text', 'z') while the cursor is anywhere you won't notice the difference because by default wrapscan will be applied, hence reaching EOF and continuing the search up until its starting point.

While if you try, given the same piece of text:

  • position your cursor after the word "text":

:call cursor(1, 15)

  • and then search disabling wrapscan:

:call search('text', 'zW')

You should note the different behaviour.

8
  • I don't see any difference. Steps to reproduce: vim --clean, insert This is a text to be searched, :call cursor(1, 15). At this point, I don't see any difference between :call search('text', 'zW') and :call search('text', 'W') (the cursor does not move). Note that the question is about the 'z' flag, not about the 'W' flag.
    – Flux
    Commented Mar 4, 2021 at 14:36
  • "[The 'z' flag will] make the search start from wherever your cursor is placed at the moment" Isn't that the default behavior without the 'z' flag?
    – Flux
    Commented Mar 4, 2021 at 14:39
  • Per your first comment, the steps you provided differ from the example I offered, you should :call search('text', 'zW') and :call search('text', 'z') to note the differences, not :call search('text', 'W') alone. And to your second comment, no, it isn't the default behaviour: "When the 'z' flag is not given, searching always starts in column zero..."
    – dillenburg
    Commented Mar 4, 2021 at 14:46
  • The expected behaviour when positioning your cursor after the word "text" and searching supplying the "W" flag is to not having the cursor moved, because your search criteria won't find any matches. You'd be searching from a starting point (after the end of word "text") until the EOF, not finding any matches for "text". Although the question is about the "z" flag, it's behaviour is directly affected by other available flags to your search().
    – dillenburg
    Commented Mar 4, 2021 at 14:49
  • 2
    Here's the thing: after :call cursor(1, 15), there is no difference between :call search('text') and :call search('text', 'z'). Furthermore, there is no difference between:call cursor(1, 15) followed by :call search('text', 'W'), and :call cursor(1, 15) followed by :call search('text', 'Wz'). So what's the point of the 'z' flag?
    – Flux
    Commented Mar 4, 2021 at 14:53

Your Answer

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

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