VIM/Python: visualmode/mode detection
Question: 
    function! Delete() range
    python3 << EOF
    import vim
    
    vim.command('let x = visualmode()')
    mode = vim.eval('x')
    
    EOF
    endfunction
    

I'm not able to detect 'mode' properly in vim (xterm). It can't switch between
'visual' 'normal' - i get 'n' or '^V' always, regardless of what mode i'm
actually in. I invoke the function like so:

    
    
     :map <kDel> :call Delete()<CR>
    :imap <kDel> <Esc>l:call Delete()<CR>
    :vmap <kDel> <Esc>:call Delete()<CR>
    

How exactly are these functions used?


Answer: This simplified version of your function (please use testable examples):

    
    
    function! Delete() range
        python << EOF
        import vim
    
        print vim.eval('visualmode()')
    
        EOF
    endfunction
    

does exactly what it is supposed to do:

  * if the last visual mode was plain _visual_ mode, it echoes `v`,
  * if the last visual mode was _visual-line_ mode, it echoes `V`,
  * if the last visual mode was plain _visual-block_ mode, it echoes `^V`.

Of course, you would do the following in your real function:

    
    
    mode = vim.eval('visualmode()')
    

What, _exactly_ , do you expect and what, _exactly_ , are you trying to
achieve?

\--- edit ---

From `:help visualmode()`, emphasis mine:

> The result is a String, which describes **_the last_** Visual mode used in
> the current buffer.

So it is obvious that `visualmode()` can't be used to know the _current_ mode.
The right function is `mode()`.

From `:help mode()`, emphasis mine:

> This is useful in the 'statusline' option or when used with remote_expr()
> **_In most other places it always returns "c" or "n"._**

So using straight `mode()` in most contexts will be useless, as demonstrated
by the mappings below that all put you in normal mode before calling `mode()`
so you always get `n`.

    
    
    function! Delete() range
        python << EOF
        import vim
    
        print vim.eval('mode()')
    
        EOF
    endfunction
    
    nmap <key> :call Delete()<CR>         --> n
    imap <key> <Esc>:call Delete()<CR>    --> n
    xmap <key> <Esc>:call Delete()<CR>    --> n
    

For `mode()` to return the value you want, you need to be in an _expression_
context which allows you to _evaluate_ stuff without leaving the current mode:

    
    
    nmap <expr> <key> Delete()            --> n
    imap <expr> <key> Delete()            --> i
    xmap <expr> <key> Delete()            --> v, V or ^V
    

