dreftymac
dreftymac

Reputation: 32370

How to detect existence of Visual selection in VimL script

Background

Question

Does VimL have a means of polling the current Visual selection?

Goal

Failed attempts

Upvotes: 1

Views: 336

Answers (2)

Ingo Karkat
Ingo Karkat

Reputation: 172600

As your question is about polling, the strict answer is mode(). But polling only happens during status line evaluation, or in triggered :autocmd event handlers.

If the other function that you're vaguely referring to is invoked by a custom mapping or command, mode() doesn't help you, as visual mode has already been left by the time your function is invoked. The right way™ to handle visual selections for this is as follows:

  • Custom commands should work on a supplied range, and that range can be generated from a visual selection; Vim will automatically prepend the :'<,'> range for you. In rare cases, you may want to create a special command to work on the visual selection, e.g. :Frobnize vs. :FrobnizeVisual, and then just use :normal! gv to get and work on the selection.
  • Separate custom mappings can be defined for normal and visual mode, and pass information as a flag to the invoked function:
:nnoremap <Leader>x :<C-u>call Frobnize(0)<CR>
:xnoremap <Leader>x :<C-u>call Frobnize(1)<CR>
function! Frobnize( isVisualMode )
    ...

TL/DR: There's a reason you didn't find such convenient function; rethink your approach.

Upvotes: 2

FDinoff
FDinoff

Reputation: 31429

I believe the mode() function is what you are looking for. (From :h mode())

                                                        mode()
mode([expr])    Return a string that indicates the current mode.
                If [expr] is supplied and it evaluates to a non-zero Number or
                a non-empty String (non-zero-arg), then the full mode is
                returned, otherwise only the first letter is returned.  Note
                that " " and "0" are also non-empty strings.

                        n       Normal
                        no      Operator-pending
                        v       Visual by character
                        V       Visual by line
                        CTRL-V  Visual blockwise
                        s       Select by character
                        S       Select by line
                        CTRL-S  Select blockwise
                        i       Insert
                        R       Replace R
                        Rv      Virtual Replace gR
                        c       Command-line
                        cv      Vim Ex mode gQ
                        ce      Normal Ex mode Q
                        r       Hit-enter prompt
                        rm      The -- more -- prompt
                        r?      A :confirm query of some sort
                        !       Shell or external command is executing
                This is useful in the 'statusline' option or when used
                with remote_expr() In most other places it always returns
                "c" or "n".
                Also see visualmode().

If will return v, V or CTRL-V if you are in a visual mode.

However this function almost always returns c or n since a visual selection ends immediately when an ex command is run. You can determine where the visual selection was by using the marks '< and '>. You can also determine if you were in a visual function by using xnoremap commands that pass a flag to the function to say you were in visual mode.


If you put your function in a mapping mode() seems to work properly.

Upvotes: 4

Related Questions