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>/