I wrote a vimscript function that prevents the cursor from changing its location on the screen when I press n
:
function! s: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>"
endfor
else
for i in range(from_top-new_from_top)
execute "normal! \<C-y>"
endfor
endif
endfunction
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 pressn
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 pressn
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