Assume I am inside a function and currently in visual mode (mode() returns v or V or "\<c-v>", such as when you run vmap-expr)

How can I quit the visual mode? Should I call feedkeys("\<esc>", 'ni')?

How to run a mapping in the visual mode, like 4> to indent the lines 4 times. It seems normal 4> does not work.

  • > already works in visual mode, what you need the mapping for? Nov 23, 2018 at 11:53
  • I need to do a lot of other things after indentation. The question is actually general: how to type some keystroke or execute a visual mapping <Plug>xxx in function in visual mode.
    – doraemon
    Nov 23, 2018 at 11:57
  • so have you tried using xmap? Nov 23, 2018 at 12:27
  • I have some vmaps that calls functions. I use something like vmap ,x :<C-U>call MyFunc()<CR>. Inside the function I could do normal gv4>. See help gv. How do you call your function?
    – Ralf
    Nov 25, 2018 at 11:30
  • @Ralf : makes you in normal mode. I use vmap <express> Func() so that I am still in visual mode(). Or it is because I did “normal gv “.
    – doraemon
    Nov 25, 2018 at 11:37

1 Answer 1


Instead of another comment:

As far as I understand you want to work with vmap <expr> Like mapping ," to a function:

vmap <expr> ," MyFunction()

In this case the the function has to return the keystrokes that should be executed by Vim. Lets assume you want to surround visually selected text with something (function hardly tested):

function! ExecSurround(pre, post)
    let mode = mode()
    if(mode == "V")
        " line: Put it above and below the selected lines
        return "V`>o" . a:post . "\e`<O" . a:pre . "\e"
    elseif(mode == "\<C-V>")
        " block: Put it before and after selection on every line
        return "A" . a:post . "\egvI" . a:pre . "\e"
        " char: put it before first and after last char
        return "v`>a" . a:post . "\e`<i" . a:pre . "\e"

vmap <expr> ," ExecSurround('"', '"')

As far as I understand :help :map-expression, the things you can do in the function are limited. You have to return the keystrokes, that change your text.

As said in my comment, I would choose another way:

function! Surround(pre, post)
    let mode = visualmode()
    if(mode == "V")
        call execute("normal `>o" . a:post . "\e`<O" . a:pre . "\e")
    elseif(mode == "\<C-V>")
        call execute("normal gvA" . a:post . "\egvI" . a:pre . "\e")
        call execute("normal `>a" . a:post . "\e`<i" . a:pre . "\e")

vmap ," :<C-U>call Surround('"', '"')<CR>

That way you are not limited by the restrictions from "map-expression" and could easily add additional functionality.

Whatever you want to do might be more complex than this, but perhaps it helps to go on.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.