为什么`set shm + = s`和`cno <silent> <cr> <cr>`当模式在当前缓冲区中没有匹配时,使Vim显示搜索命令?

时间:2017-07-05 09:54:53

标签: vim

如果我使用最少的初始化启动Vim:

vim -Nu NONE /path/to/a/file

然后执行以下两个命令:

set shm+=s
cno <silent> <cr> <cr>

最后搜索当前缓冲区中没有匹配的模式:

/pattern_with_no_match

Vim显示错误:

E486: Pattern not found: pattern_with_no_match

......这是预期的。但是Vim还会显示一行显示文字搜索命令。因此,Vim总共会显示2行+一个提示:

/pattern_with_no_match
E486: Pattern not found: pattern_with_no_match
Press ENTER or type command to continue

而不是只有一行没有提示:

E486: Pattern not found: pattern_with_no_match

如果我从s选项中删除'shortmess'标记:

set shm-=s

或者如果我删除映射中的<silent>参数:

cno <cr> <cr>

Vim再次只显示1行:

E486: Pattern not found: pattern_with_no_match

s标志添加到'shortmess'会抑制以下消息:

search hit BOTTOM, continuing at TOP

传递给<silent>命令的:cnoremap参数应该阻止映射在命令行上回显。

这些设置都不应该让Vim更加冗长。 那么,为什么设置set shm+=s和映射cno <silent> <cr> <cr>的组合使Vim显示搜索命令,当模式在当前缓冲区中没有匹配时?

这可能是一个众所周知的问题,因为我刚刚在插件中发现comment似乎有关:

" NOTE: This cannot use <silent> - it would break cmdline refresh in some
" cases (e.g. multiline commands, <C-R>= usage).

但我无法在帮助中找到相关部分来描述它。

:h map-<silent>中的这一行:

Using "<silent>" for an abbreviation is possible, but will cause redrawing of the command line to fail.

但它是关于缩写而不是映射。也许这两者是相关联的。

1 个答案:

答案 0 :(得分:1)

Vim有一些内置逻辑来确定用户消息是否已被显示并且可以被丢弃。仅当一次有更多消息时,才会出现命中输入提示。通过在命令行中静默<CR>,可以破坏这种逻辑; <silent>表示没有输出(通过映射),但命令行仍然打开并包含键入的搜索。通常情况下,搜索换行消息会清除命令行,但是使用'shm'设置时,您也会禁用它。因此,通过两者的结合,您会看到这种效果。

我故意在我的解释中模糊,因为大多数这是实施的副作用,而不是正式指定。 cno <silent> <cr> <cr>没有意义。如果您有一个导致问题的真实用例,请发布有关该问题的详细信息。一般来说,挂钩改变模式的键(如<CR><Esc>)是一个坏主意,应该避免使用。