如果我有以下文字:
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。NULLs在文本中很少出现,因此使其成为很好的字符。这样的结果是,如果C程序(vim)试图将“空”字符串传递到内部C函数中