1

I'm trying to do the following mapping in my vimrc:

nnoremap <silent> / :call <SID>FooFunction()<CR><BAR>norm! /

But when I press /, instead of running the function and then starting the search prompt, I get this text inserted to my buffer:

rm! /

I also tried to put the normal command to as the last line of FooFunction:

function! s:FooFunction() abort
    ...
    ...
    norm! /
endfunction

but then I don't get any prompt after pressing /.

How can I achieve this?

2 Answers 2

3

It seems you've already found a working solution, but I wanted to address the issues with your attempted approaches.

But when I press /, instead of running the function and then starting the search prompt, I get this text inserted to my buffer:

rm! /

You're getting this result because you're using <BAR> in your mapping after you already left command-line mode:

:call <SID>FooFunction()<CR><BAR>norm! /

You're using a <CR>, which means you're back in normal mode, so <BAR>norm! / (or, equivalent, |norm! /) is evaluated as a series of normal mode commands.

Command | moves to a column based on count, without a count, it moves to first column. n repeats the last search. o inserts a new line below the current line and starts insert mode. As you're now in insert mode, the rest of the mapping, rm! /, gets inserted as text.

Removing the <CR> would fix that part of the issue, however that'd be equivalent to your second approach, which doesn't work either, let's take a look:

I also tried to put the normal command to as the last line of FooFunction:

function! s:FooFunction() abort
    ...
    ...
    norm! /
endfunction

but then I don't get any prompt after pressing /.

That's because the norm! command expects to execute a complete command, it doesn't allow for a prompt to be pending at the end of its execution.

From :help :normal:

{commands} should be a complete command. If {commands} does not finish a command, the last one will be aborted as if <Esc> or <C-C> was typed.

So :norm! / doesn't work, the search gets cancelled as the command completes.

An alternative you can use in a function is to call feedkeys(), which doesn't exhibit this behavior. For example, this would have worked:

function! s:FooFunction() abort
    ...
    ...
    call feedkeys('/')
endfunction

But, as you've noticed, an even easier approach is to simply use / directly in your mapping:

nnoremap / :call <SID>FooFunction()<CR>/
1

Figured out the the <silent> was hiding the search prompt, and also the mapping can be done just like this:

nnoremap / :call <SID>FooFunction()<CR>/
1
  • You could have used autocmds
    – eyal karni
    Feb 3, 2020 at 1:56

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.