在自定义命令/功能中检查当前缓冲区是否有某些文本被“选中”(v / V / C-v)

时间:2013-10-16 12:16:49

标签: vim

我有一个自定义命令,在命令中将调用一个函数。

我想确保只有在当前缓冲区处于VISUAL模式(v, V or C-V)时才执行该命令。或者说,只有当前选择当前缓冲区中的某些文本时才会执行该功能。

  • visualmode()我无法使用,因为它提供了最后可视模式类型。
  • 我尝试将echo mode()放在函数中,它总是n
  • 并且我不确定,如果我选择了某些内容,并按:它已进入command模式,如何检查缓冲区是否有选择现在强>?

解决方案可能很简单,但我被困在这里......有人能给我一些光明吗?谢谢。

2 个答案:

答案 0 :(得分:1)

如果您需要这种功能,则必须使用映射(或者对于普通模式和可视模式使用两种不同的映射)。

正如您所说,只要按:,视觉模式就会停留在命令行模式下。但是,当自动插入:'<,'>范围时,您可以将该范围传递给您的函数并对其进行操作。这样就可以通过显式范围从正常模式中使用,但这只是合理的,并且与内置命令一致。

答案 1 :(得分:1)

我一直在努力找出同样的问题,我想出了这个问题。

使用此autocmd:

autocmd CursorMoved * let s:Mode = mode()

如下所示的命令也使用范围选项-range=0来改变<count>参数(当没有传递范围时为0,其他方式与调用命令的行相同):

command! -range=0 CmdName call FuncName(<count>, <line1>, <line2>)

然后使用这样的逻辑,您可以检查视觉选择,传递的正常范围,以及根本没有传递范围:

function! FuncName(count, firstLine, lastLine)
    if a:count == 0 "no range given 
            "do stuff for no given range
    else
        if s:Mode  =~ '\vV|v|'  "range was given
            "do stuff for visual selection
        else 
            "do stuff for normal range
            " w/ a:firstLine & a:lastLine 
        endif
    endif
endfunction

注意:

  • 已知问题 - 我发现这种情况不起作用的唯一情况是视觉选择只有一个字符(光标没有移动),但对于大多数情况来说这个应该不是问题。

  • 命令注释 - 您必须传递和作为参数而不是使用之前的调用,因此不会传递无效范围。