vim 是否可以在不将换行 (^@) 字符视为"Enter"按键的情况下回显寄存器的内容?



我有一些文本行,我正在尝试进入寄存器,然后将寄存器的内容回显到生成 vim 进程的终端,以便在 vim 退出后文本将在终端窗口中可见。

我可以在一行文本上正常工作,但是一旦添加了换行符/换行符,所有执行此操作的尝试都会失败。

使用包含以下内容的示例文件:

1 A
2 ab
3 abc
4 abce
5 abcef
6 abcefg

首先,我通过":%y m"将文件内容放入寄存器("m")中 然后我尝试":exe '!echo '@m">

这会将第一行文本回显到终端

一个

但是 vim 将字母"a"后面的第一个换行符/换行符视为按 Enter 键,因此它会抛出以下错误消息

E492:不是编辑器命令:abce^@abcef^@abcefg^@^@

我在":d ebug"模式下运行以下命令,希望用换行符替换^@字符()

:echo substitute(strtrans(@m),"^@",'',"g")
:echo substitute(strtrans(@m),'^@','',"g")

我尝试过双引号和单引号,并且尝试从字面上键入插入符号和与号,以及使用特殊字符 CTRL-V+CTRL-J 不幸的是,在调试模式下,我可以看到输出始终如下:

a^@ab^@abc^@abce^@abcef^@abcefg^@^@

printf 也会发生同样的情况。 我已经对换行符、空字符的歧义以及 vim 如何在寄存器中处理这些进行了一些复习,但不清楚我想要实现的目标是否合理。

:h nl-used-for-nul解释说,换行符'n'由 Vim 显示为^@。所以,是的,正如你已经说过的,你将实际的换行符发送到 shell。

接下来,将一个字符'n'(ASCII 0x0a)替换为两个字符"n"(0x5c 0x6e)的一般想法也是正确的。您希望外壳程序接收foonbar

:echo substitute(@m, 'n', 'n', 'g')
a
ab
abc
abce
abcef
abcefg

输出显然仍然包含实际的换行符,因此我们必须转义这些字符。

:echo substitute(@m, 'n', '\n', 'g')
anabnabcnabcenabcefnabcefgn

这看起来不错!因此,让我们尝试一下您想到的整个命令:

:execute '!echo' substitute(@m, 'n', '\n', 'g')
anabnabcnabcenabcefnabcefgn
Press ENTER or type command to continue

嗯?好吧,:execute计算字符串,因此消耗"一级字符串"。因此,我们必须再次转义换行符,而我们必须将每个"字符串级别"的转义数量加倍

所以,我们不仅需要anabnabc,还需要a\nab\nabc

:echo substitute(@m, 'n', '\\n', 'g')
a\nab\nabc\nabce\nabcef\nabcefg\n
:execute '!echo' substitute(@m, 'n', '\\n', 'g')
a
ab
abc
abce
abcef
abcefg

Press ENTER or type command to continue

🎉

附加说明:

  • 当使用双引号处理转义字符时,与单引号字符串相反,我们将不得不再次将转义的数量加倍:substitute(@m, 'n', "\\\\n", 'g').
  • 如果要去除尾随换行符,请使用trim(@)

我想你正在寻找shellescape()

:execute "!echo " . shellescape(@@, 1)

使用非零参数作为第二个参数,<NL>字符也会被转义。

有关更多帮助,请参阅:

:h shellescape()

相关内容

最新更新