vim 可以在不将换行 (^@) 字符视为 "Enter" 按键的情况下回显寄存器的内容吗?
Can vim echo the contents of a register without treating linefeed(^@) characters as "Enter" key press?
我有一些文本行要输入到寄存器中,然后将寄存器的内容回显到生成 vim 进程的终端,以便文本在终端中可见window 在 vim 退出后。
我可以用一行文本让它正常工作,但是一旦添加 newline/linebreak,所有尝试都失败了。
使用示例文件包含:
1个
2 ab
3 abc
4 abce
5 个 abcef
6 abcefg
首先我将文件内容放入寄存器("m) via ":%y m"
然后我尝试 ":exe '!echo '@m"
这会将第一行文本回显到终端
一个
但是 vim 将字母 "a" 后的第一行 feed/break 视为按回车键,因此它会抛出以下错误消息
E492: 不是编辑器命令:abce^@abcef^@abcefg^@^@
我 运行 在“:debug”模式下执行以下命令,希望用换行符 (\n)
替换 ^@ 字符
:回声替代(strtrans(@m),"^@",'\n',"g")
:echo substitute(strtrans(@m),'^@','\n',"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) 的一般思路也是正确的。您希望 shell 接收 foo\nbar
。
:echo substitute(@m, '\n', '\n', 'g')
a
ab
abc
abce
abcef
abcefg
输出显然仍然包含实际的换行符,所以我们必须转义这些。
:echo substitute(@m, '\n', '\n', 'g')
a\nab\nabc\nabce\nabcef\nabcefg\n
这看起来不错!那么,让我们尝试一下您想到的整个命令:
:execute '!echo' substitute(@m, '\n', '\n', 'g')
anabnabcnabcenabcefnabcefgn
Press ENTER or type command to continue
嗯?嗯,:execute
评估字符串,因此 消耗 "one level of strings"。因此,我们必须再次转义我们的换行符,而我们必须 double 每个 "level of strings".
的转义量
所以,我们不仅需要a\nab\nabc
,我们还需要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()
我有一些文本行要输入到寄存器中,然后将寄存器的内容回显到生成 vim 进程的终端,以便文本在终端中可见window 在 vim 退出后。
我可以用一行文本让它正常工作,但是一旦添加 newline/linebreak,所有尝试都失败了。
使用示例文件包含:
1个
2 ab
3 abc
4 abce
5 个 abcef
6 abcefg
首先我将文件内容放入寄存器("m) via ":%y m" 然后我尝试 ":exe '!echo '@m"
这会将第一行文本回显到终端
一个
但是 vim 将字母 "a" 后的第一行 feed/break 视为按回车键,因此它会抛出以下错误消息
E492: 不是编辑器命令:abce^@abcef^@abcefg^@^@
我 运行 在“:debug”模式下执行以下命令,希望用换行符 (\n)
替换 ^@ 字符:回声替代(strtrans(@m),"^@",'\n',"g")
:echo substitute(strtrans(@m),'^@','\n',"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) 的一般思路也是正确的。您希望 shell 接收 foo\nbar
。
:echo substitute(@m, '\n', '\n', 'g')
a
ab
abc
abce
abcef
abcefg
输出显然仍然包含实际的换行符,所以我们必须转义这些。
:echo substitute(@m, '\n', '\n', 'g')
a\nab\nabc\nabce\nabcef\nabcefg\n
这看起来不错!那么,让我们尝试一下您想到的整个命令:
:execute '!echo' substitute(@m, '\n', '\n', 'g')
anabnabcnabcenabcefnabcefgn
Press ENTER or type command to continue
嗯?嗯,:execute
评估字符串,因此 消耗 "one level of strings"。因此,我们必须再次转义我们的换行符,而我们必须 double 每个 "level of strings".
所以,我们不仅需要a\nab\nabc
,我们还需要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()