如何检测 VimL 脚本中是否存在视觉选择
How to detect existence of Visual selection in VimL script
背景
- vim 7.4
- VimL 脚本问题
问题
VimL 是否有轮询当前视觉选择的方法?
目标
Trevor 希望在 VimL 脚本中创建一个只做一件事的函数。
- return
TRUE
如果在当前活动的缓冲区中当前有包含一个或多个字符的视觉选择。
- return
FALSE
如果当前活动缓冲区中当前没有包含一个或多个字符的视觉选择。
该函数将是其他需要展示不同行为的函数的附加组件,具体取决于当前是否存在非空视觉选择(逐行或逐字符) ) 在当前活动缓冲区中。
尝试失败
- 出于某种原因,这并没有出现在文档中,似乎没有现成的解决方案显而易见,而且这似乎是一个非常基本的事情。
我相信 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().
如果您处于可视模式,则 return v
、V
或 CTRL-V
。
但是这个函数几乎总是 returns c
或 n
因为当 ex 命令是 运行 时视觉选择会立即结束。您可以使用标记 '<
和 '>
来确定视觉选择的位置。您还可以通过使用 xnoremap
命令来确定您是否处于视觉功能中,这些命令将标志传递给函数以表明您处于视觉模式中。
如果您将函数放在映射中 mode()
似乎可以正常工作。
由于您的问题是关于 轮询,因此严格的答案是 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:你没找到这么方便的功能是有原因的;重新考虑你的方法。
背景
- vim 7.4
- VimL 脚本问题
问题
VimL 是否有轮询当前视觉选择的方法?
目标
Trevor 希望在 VimL 脚本中创建一个只做一件事的函数。
- return
TRUE
如果在当前活动的缓冲区中当前有包含一个或多个字符的视觉选择。 - return
FALSE
如果当前活动缓冲区中当前没有包含一个或多个字符的视觉选择。
- return
该函数将是其他需要展示不同行为的函数的附加组件,具体取决于当前是否存在非空视觉选择(逐行或逐字符) ) 在当前活动缓冲区中。
尝试失败
- 出于某种原因,这并没有出现在文档中,似乎没有现成的解决方案显而易见,而且这似乎是一个非常基本的事情。
我相信 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().
如果您处于可视模式,则 return v
、V
或 CTRL-V
。
但是这个函数几乎总是 returns c
或 n
因为当 ex 命令是 运行 时视觉选择会立即结束。您可以使用标记 '<
和 '>
来确定视觉选择的位置。您还可以通过使用 xnoremap
命令来确定您是否处于视觉功能中,这些命令将标志传递给函数以表明您处于视觉模式中。
如果您将函数放在映射中 mode()
似乎可以正常工作。
由于您的问题是关于 轮询,因此严格的答案是 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:你没找到这么方便的功能是有原因的;重新考虑你的方法。