I wrote a vimscript function that prevents the cursor from changing its location on the screen when I press n:

function! my_n()
    let l:start=line("w0")
    let end = line("w$")
    let cursor = line(".")
    let from_top = cursor-l:start
    normal! n
    let new_start = line("w0")
    let new_end = line("w$")
    let new_cursor = line(".")
    let new_from_top = new_cursor-new_start
    if new_from_top>from_top
        for i in range(new_from_top-from_top)
            execute "normal! \<C-e>"
        for i in range(from_top-new_from_top)
            execute "normal! \<C-y>"
nnoremap n :call <SID>my_n()<CR>

Everything works fine, except for the messages:

I'd want the same as a normal n, namely:

  • When there is a match, get .. match x out of y
  • When there is no match, get E486 Pattern not found: ...

Instead, what I get is:

  • If I press n directly after the / command and when there is a match, I get :call <SNR>1_my_n() in the command line, but once I move away from matches and then press n again, I don't get anything at all anymore.

  • When there is no match, the command line grows in size and displays

    Error detected while processing function 1_contextn: line 6: E486: Pattern not found: asdfsdf Press ENTER or type command to continue

I tried a few things:

(A) Use silent normal! n

Nothing changes

(B) Use silent! normal! n

When there is no match, I don't get an error message anymore and instead get :call <SNR>1_my_n()

(C) Use map <silent> n and go back to normal! n

  • When there is a match, I get the proper message .. match x out of y, but once I leave the matches and then press n I don't get anything at all
  • Same behavior as in the original when there are no matches

(D) Use map <silent> n and silent normal! n

Exactly as (C)

(E) Use map <silent> n and silent! normal! n

  • When there is a match, same as in (C)
  • When there is no match, no message or error at all

Note: This question is basically the same as How to show "/foobar match 1 of " or "E486: Pattern not found: foobar" in commandline when calling `normal! n` in function but cleaned up, with the complete code, and with all my attempts. In comparison to that question, I am omitting here another complexity, namely that my full mapping is nnoremap n :call <SID>my_n()<CR><SID>my_other_function()<CR> and if the solution to my problem involves changing this mapping, it'd be also good to know how to control the output of the two function calls separately

  • confused, because printing "match x out of y" is not normal vim behavior – Mass Jan 25 at 15:27
  • @Mass, I'm sorry, I guess that's a plug-in that I installed, I'll figure that out later and update the question – Bananach Jan 25 at 19:35

Your Answer

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

Browse other questions tagged or ask your own question.