7

I'm looking for a way to execute some code within a function conditionally depending on the presence of some text within the edited file. I found a way to do it which works but doesn't feel very "clean".

Here's what I have:

function! foo()
    (...)
    let v:errmsg = 'ok'
    execute "silent! normal! :/" . l:pattern . "\r"
    if v:errmsg == 'ok'
        (... do stuff ...)
    else
        (... do other stuff ...)
    endif
 endfunction

The question is: can the same result be achieved somewhow without the clunky use of v:errmsg ?

What I have in mind is something of the form

function! foo()
   (...)
   if GrepInCurrentBuffer(l:pattern)
      (... do stuff ...)
   (...etc...)
  • 5
    Use search() - See:h search() – VanLaser Nov 7 '15 at 21:36
  • 1
    @VanLaser : this worked flawlessly and is exactly what I was looking for. Thanks a lot! – Dalker Nov 7 '15 at 21:43
  • 2
    You're welcome! In general, start from this to discover what's available: :h function-list – VanLaser Nov 7 '15 at 22:09
5

The function you are looking for is search(). This function will search starting at the cursor position, and when a match is found its line number will be returned. If no match is found, 0 is returned. The 'ignorecase', 'smartcase', and 'magic' options are used on the search pattern. Note that if you want to choose where the search starts at, you can use the cursor() or the setpos() function to set the cursor position, and the getcurpos() function to save the cursor location.

Here is an example of it in action:

function! SearchInRange(pattern, start_line, end_line)
    " Save cursor position.
    let save_cursor = getcurpos()

    " Set cursor position to beginning of file.
    call cursor(a:start_line, 0)

    " Search for the string 'hello' with a flag c.  The c flag means that a
    " match at the cursor position will be accepted.
    let search_result = search(pattern, "c", a:end_line)

    " Set the cursor back at the saved position.  The setpos function was
    " used here because the return value of getcurpos can be used directly
    " with it, unlike the cursor function.
    call setpos('.', save_cursor)

    " If the search function didn't find the pattern, it will have
    " returned 0, thus it wasn't found.  Any other number means that an instance
    " has been found.
    return search_result ? 1 : 0
endfunction

For more on the things mentioned in this answer, see the following help topics:

  • :help search()
  • :help 'ignorecase'
  • :help 'smartcase'
  • :help 'magic'
  • :help cursor()
  • :help setpos()
  • :help getcurpos()
  • 1
    How about just :echo search('pattern', 'nw') ? 1 : 0 instead ? :) – VanLaser Nov 8 '15 at 20:57
  • Because if an occurrence of hello is before the cursor, then it won't be detected. – EvergreenTree Nov 8 '15 at 20:59
  • The 'w' flag will wrap the search around the end of the file though. So any occurrence will be detected. – VanLaser Nov 8 '15 at 21:00
  • 1
    That is a very nice solution! I was trying to demonstrate the setting of the cursor position for searching within ranges, but I guess I didn't choose the best example. I have updated the example. – EvergreenTree Nov 8 '15 at 21:21
  • 1
    does it support regex search ? – Sergio Abreu Feb 3 '17 at 10:33
2

For reference to anyone looking at this question in the future, here's a working solution following the same pattern as the pseudo-code in the question. It is completely based on VanLaser's comments to both the original question and EvergreenTree's answer.

function! foo()
    (... do stuff that defines l:pattern ...)
    if search(l:pattern,'nw')
        (... do stuff ...)
    else
        (... do other stuff ...)
    endif
endfunction

In the particular case of the actual function that originated this question, the solution did not really require the 'nw' flags. These flags should however make the solution safer in general, based on their description in vim's help:

'n'     do Not move the cursor
'w'     wrap around the end of the file

(from :help search in Vim 7.4)

  • For simply checking if something exists in the buffer, this is the best way of doing it. – EvergreenTree Nov 8 '15 at 22:03

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.