如果我有以下文字:
foo
bar
我从视觉上选择它并复制它。
现在,该文本存储在未命名的寄存器中"
,这是其内容(的输出:reg "
):
"" foo^Jbar^J
根据此图表,似乎^J
是换行符的插入符号。
如果要a
通过键入:let @a = @"
以下内容在寄存器中复制未命名的寄存器:这是其内容(的输出:reg a
):
"a foo^Jbar^J
它没有改变。
如果现在我输入:let @/ = @"
,将其复制到搜索寄存器中,则其内容为的输出:reg /
:
"/ foo^@bar^@
根据上一张图表,它似乎^@
是Null字符的插入符号。
为什么换行符会自动在搜索寄存器(而不是a
寄存器)内转换为Null字符?
如果我在命令行上(或之后的搜索中/
)插入未命名的寄存器,则通过输入:<C-R>"
,将插入以下内容:
:foo^Mbar^M
同样,根据最后一张图表,这^M
似乎是回车符的插入符号。
为什么在命令行上将换行符自动转换为回车符?
编辑:
通常,您可以通过键入以下内容来插入文字控制字符:
<C-V><C-{character in caret notation}>
例如,您可以<C-R>
通过键入插入文字<C-V><C-R>
。
您可以为看似任何控制字符执行此操作。
但是,我注意到我无法在缓冲区内或命令行上插入文字LF,因为如果键入:<C-V><C-J>
它会插入^@
,空字符而不是^J
。
是否出于相同的原因将LF在搜索寄存器中转换为NUL?
编辑2:
在中:h key-notation
,我们可以阅读以下内容:
<Nul> zero CTRL-@ 0 (stored as 10) <Nul>
<NL> linefeed CTRL-J 10 (used for <Nul>)
在stored as 10
第一行和部分used for <Nul>
第二行可能表明有一些不大不小的LF和NUL之间的重叠,并且它们可以被解释为同样的事情。但是它们不可能是同一回事,因为在执行上一条命令之后:let @/ = @"
,如果我n
以普通模式键入以到达下一行出现的2行foo
和bar
,而不是得到正匹配,则出现以下错误消息:
E486: Pattern not found: foo^@bar^@
此外,此链接似乎可以解释为NUL表示字符串的结尾,而LF表示文本文件中行的结尾。
而且,如stored as 10
帮助人员所言,NUL 与LF的代码相同,那么Vim如何使两者之间有区别?
编辑3:
10
如帮助所说,也许LF和NUL用相同的十进制代码编码。由于上下文,Vim使这两者之间有所不同。如果它遇到一个十进制代码10
在缓冲区或任何寄存器(搜索和命令寄存器除外)中的字符,则将其解释为LF。
但是在搜索寄存器(:reg /
)中它解释为NUL,因为在搜索的上下文中,Vim只搜索一个字符串的end of line in a file
含义不合理的字符串,因为字符串不是文件(这很奇怪,因为您可以仍然\n
在搜索模式中使用原子,但这也许只是正则表达式引擎的功能?)。因此它自动解释10
为NUL,因为它是最接近的概念(end of string
≈ end of line
)。
同样,在命令行/命令寄存器(:reg :
)上,它将代码解释10
为CR,因为end of line in a file
此处的概念没有意义。最接近的概念end of command
因此被Vim解释10
为CR,因为点击Enter
是结束/执行命令的方式,CR与点击相同Enter
,因为当您使用插入文字时<C-V><Enter>
,^M
会显示CR 。
可能是其字符10
随上下文而变化的字符的解释:
- 缓冲区中的行尾(
^J
) - 搜索(
^@
)中字符串的结尾 - 命令行上的命令结尾(
^M
)
someFunction(arg1, "")
,arg 2是""
“引号之间的项目,实际上什么都不是-“空”。可能会出现NULL,因为它由分隔字符串的基础C实现“添加”了。我不知道您将如何检查这一点-但它可能是造成这种情况的原因
\r
和\n
区别:substitute
。
NULL
字符的出现是由处理字符串的基础C函数引起的。这章C如何处理字符串的解释,你链接到解释说,内部ç界定串用NULL
。NULL
s在文本中很少出现,因此使其成为很好的字符。这样的结果是,如果C程序(vim)试图将“空”字符串传递到内部C函数中