11

What is the best way to check in a vimscript which visual mode is currently active (visual or visual block)?

I've read about mode() but I can't make it work.
echo mode() doesn't work for me
if mode() == "v" doesn't work for me as well.

Reman
  • 7,931
  • 11
  • 55
  • 97

3 Answers3

10

Look at the help for mode(). The relevant part:

          v       Visual by character
          V       Visual by line
          CTRL-V  Visual blockwise

You need to be checking mode() == "\<C-V>" (literal ^V character), not mode() == "v", to check for blockwise visual mode.

Chris Morgan
  • 86,207
  • 24
  • 208
  • 215
  • Yes I know but can't make it work. It doesn't recognize a visual block. What would be the echo command line code? – Reman Apr 09 '12 at 15:26
  • What do you mean by not being able to make it work? How are you trying to trigger it? – Chris Morgan Apr 09 '12 at 21:57
  • '@Chris, like this: `if mode() == "CTRL-V" | echo "block" | else | "echo no block" | endif` - It doesn't not work as well in the command line. – Reman Apr 10 '12 at 06:03
  • You won't get it to work that way as entering a command like that of necessity changes the mode, but you can view it in other ways; e.g. `au CursorMoved * echo mode()` will show you the mode when you move the cursor. (Note also that I've fixed the code; it is the CTRL-V character which you need, not the string CTRL-V. You can achieve the literal character with `"\"`.) – Chris Morgan Apr 10 '12 at 13:10
  • thanks for your info. I learned something new. The problem is that I need to know in a vimscript which mode is active. Cannot use CursorMoved for this. – Reman Apr 10 '12 at 14:52
  • this is what I need in my vimscript: `if mode() == "\CTRL-V" | do this " | else | do that | endif` – Reman Apr 10 '12 at 17:08
  • 4
    *But how are you triggering it?* – Chris Morgan Apr 11 '12 at 00:40
  • 1
    Sorry for my late answer. I trigger it in a vimscript. :call MyScript --> `function! s:MyScript | if mode == "\" | do this | else | do that | endfunction` – Reman May 02 '12 at 08:15
  • Had to be in double quotes for me, single quotes like this '\' will NOT work. – run_the_race Apr 28 '20 at 15:45
1

@Remonn already said it in the comments, but it was not very clear to me. This is how I managed to see results:

function! F()
    normal! gv
    throw mode()
endfunction
vnoremap <F9> <ESC>:call F()<CR>

Go into different visual modes and then hit F9 to see.

I need a throw because the -- VISUAL -- line covers any echo message. Can anyone echo in VISUAL mode?

In general, I think the best thing to do when you would need mode() is to make two different mappings, and then either two different functions that do completely different things:

function! Fnorm()
endfunction

function! Fvis()
endfunction

nnoremap <F9> :call Fnorm()<CR>
nnoremap <F9> <ESC>:call Fvis()<CR>gv

or one single function and give different parameters to it depending on the mapping:

function! F(param)
endfunction

nnoremap <F9> :call F(1)<CR>
nnoremap <F9> <ESC>:call F(2)<CR>gv

Another related trick is what to do if you want to do something while you are in visual mode, like move the cursor. The best I can do is:

function! Fvis()
    normal! gv
    cursor(1, 1)
endfunction

nnoremap <F9> <ESC>:call Fvis()<CR>gv
Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
  • Remember that to do mapping in visual mode, you use `v[no]remap` instead of `n[no]remap`, and you don't want the `` in there if the selection is important. So your mappings would look more like `nnoremap :call Fnormal()` and `vnoremap :call Fvisual()`. For my needs, and how I ended up here but realized this point after getting here, I define my function as `function! F() range` and then do `nnoremap :F()` and `vnoremap :'<,'>F()`. – dash-tom-bang Jun 06 '16 at 02:36
0

Old question. Came here via DDG search.
The function mode does not work inside a vimscript.
There is a new function visualmode that's meant to be used in vimscript functions. It returns the last used visual mode. So to check for block visual mode...

if visualmode() == "\<C-V>"
   " we are in visual block mode
endif
pellucide
  • 3,407
  • 2
  • 22
  • 25