2

I have a vimscript function that needs to call Python code, depending on what mode I'm in. Some posts here recommend to use :mode() such as Within a function, Is there a way to determine if vim is in insert mode? and How to get the current mode in vim?

The problem that I'm having is that mode() doesn't work as expected for me.

For example, if you do this ...

function Test()
echo mode()
endfunction

vnoremap <leader>v :call Test()<CR>

and then go into visual mode or visual block mode or visual line mode (v, <ctrl-v>, V) and run <leader>v, this function prints "n" for all three.

What I wanted to do was to, in python, call

vim.command('let l:mode = mode()')
mode = vim.eval('l:mode')

and then use the mode variable for my script but because it always seems to return "n", this hasn't worked.

Any advice is appreciated

1 Answer 1

4

As the doc :h mode() says:

    [mode()] is useful in the 'statusline' option or when used
    with |remote_expr()| In most other places it always returns
    "c" or "n".

Depending on what your code should do, you could use an <expr> mapping like this:

function! Test()
    echo mode()
endfunction

xnoremap <expr> <leader>v Test() " echos 'v'
nnoremap <expr> <leader>v Test() " echo 'n'

I think the problem comes from the fact that when your mapping uses : to switch to command line it exits visual mode and returns a different mode from what you are looking for.

Maybe you would be interested instead in :h visualmode() which allows you to get the last visual mode used in the current buffer.


Otherwise I think your best bet is to create two mappings in normal mode and in visual mode and to give them the mode as parameter like this:

function! Test(mode)
    echo a:mode
endfunction

xnoremap <leader>v :call Test('v')<CR>
nnoremap <leader>v :call Test('n')<CR>

This way you don't need to rely on mode() to know in which mode you are.

3
  • 1
    Passing the mode explicitly makes sense. I will do that. Thanks! Apr 3, 2019 at 15:40
  • "...and to give them the mode as parameter like this" how does this answer the question about getting the mode you are in if you have to pass it beforehand as parameter? You're basically stating that you can output the mode you are in by passing the mode you are in :)
    – gented
    Jan 31, 2021 at 0:57
  • @gented OP's goal was to have a python function which would work differently based on the user's current mode. But when you call a function you do it from the command mode so getting the current mode is useless in the function. My solution suggests to pass the mode the user was in before calling the python function. It answers the question by allowing OP to create mappings which will call the function from any mode and keep track of this mode. Now if that you have a different issue and my answer doesn't solve your problem don't hesitate to open your question so that we can have a look :)
    – statox
    Feb 1, 2021 at 13:47

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.