如何在VimL脚本中检测Visual选择的存在

时间:2015-04-08 16:51:18

标签: vim scripting

背景

  • vim 7.4
  • VimL脚本问题

问题

VimL是否有轮询当前视觉选择的方法?

目标

  • Trevor希望在VimL脚本中创建一个只执行一项操作的函数。

    • 如果当前有一个视觉选择包含当前活动缓冲区中的一个或多个字符,则返回TRUE
    • 如果当前没有包含当前活动缓冲区中的一个或多个字符的可视选择,则返回FALSE
  • 该函数将成为需要展示不同行为的其他函数的插件,具体取决于当前是否存在当前非空的Visual选择(按行或按字符划分) - 有效缓冲区。

尝试失败

  • 由于某种原因,这不是在文档中得到的,现有的解决方案似乎不是很明显,而且它似乎是一个非常基本的东西。

2 个答案:

答案 0 :(得分:3)

我相信mode()功能正是您所寻找的。 (来自: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().

如果您处于可视模式,将返回vVCTRL-V

然而,此函数几乎总是返回cn,因为当运行ex命令时,视觉选择会立即结束。您可以使用标记'<'>来确定视觉选择的位置。您还可以使用xnoremap命令确定您是否处于可视化功能中,该命令将标志传递给该函数以表明您处于可视模式。


如果您将函数放在映射中mode()似乎正常工作。

答案 1 :(得分:2)

正如您的问题是关于民意调查,严格的答案是mode()轮询仅在状态行评估期间或触发的:autocmd事件处理程序中发生。

如果您通过自定义映射或命令调用了您隐约引用的其他功能mode()对您没有帮助,因为视觉模式已经在调用函数时离开了。正确处理视觉选择的方法如下:

  • 自定义命令应该适用于提供的范围,并且可以从视觉选择生成该范围; Vim会自动为您添加:'<,'>范围。在极少数情况下,您可能需要创建一个特殊命令来处理视觉选择,例如: :Frobnize:FrobnizeVisual的对比,然后只需使用:normal! gv来进行选择。
  • 可以为普通模式和可视模式定义单独的自定义映射,并将信息作为标志传递给调用的函数:
:nnoremap <Leader>x :<C-u>call Frobnize(0)<CR>
:xnoremap <Leader>x :<C-u>call Frobnize(1)<CR>
function! Frobnize( isVisualMode )
    ...

TL / DR:你没有找到这样方便的功能的原因;重新思考你的方法。