6

So I do a visual selection and hit a vnoremap which calls a function and executes mode(), but everything it ever does it output n, indicating I'm in normal mode, even though that is certainly not true.

vnoremap <silent> qb :<c-u>call <sid>func()<cr>

function! func()
  echo mode()
endfunction
4
  • 2
    Why would you expect to execute an omap-ing from visual mode? You should be executing an xmap (preferably) or vmap form visual mode. Commented Jul 14, 2016 at 23:29
  • Actually it is a vmap (and an omap)
    – hgiesel
    Commented Jul 14, 2016 at 23:31
  • 1
    If you are executing a vmap/xmap then you know the mode is visual mode already. It is a common vim script idiom to pass some argument to a function call to let the function know it came from visual mode (You can see an example :h g@). If you really need the mode from the mapping then you need to convert your mapping to a map expression (See :h :map-<expr>). Commented Jul 15, 2016 at 0:25
  • 1
    mode() is more or less usefull for statusline functions, else you usually won't see other modes than normal or ex-mode Commented Jul 15, 2016 at 7:41

2 Answers 2

8

In visual mode, press :, then press enter or escape. The selection is gone and you're in normal mode. This is what's happening with your maps and why mode() returns n.

To deal with this, you need tell your function that it should be in visual mode. You already know that it will be since you're using vmap.

vnoremap <silent> qb :<c-u>call <sid>func(1)<cr>

function! func(visual)
  if a:visual
    normal! gv
  endif
  echo mode()
endfunction

echo mode() will then give you the correct mode.

3

Vim has left Visual mode by the time Func is called. The following will get mode() to echo'V':

function! Func()
    normal! V
    echoerr mode()
endfunction

call Func()

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.