更改

Nvim :help 页面,生成 使用 tree-sitter-vimdoc 解析器。


本文件描述了删除或更改文本的命令。在此上下文中,更改文本意味着使用一个命令删除文本并用其他文本替换它。您可以撤消所有这些命令。您可以使用“.”命令重复非 Ex 命令。
有关插入文本,请参见 insert.txt

1. 删除文本 E470

["x]<Del> 或 <Del> x dl ["x]x 删除光标下和光标后的 [count] 个字符 [到寄存器 x](不是 按行)。与“dl”相同。<Del> 键不接受 [count]。相反,它删除计数的最后一个字符。请参见 'whichwrap' 以了解如何删除换行符(连接行)。
X dh ["x]X 删除光标前的 [count] 个字符 [到寄存器 x](不是 按行)。与“dh”相同。另请参见 'whichwrap'
d
["x]d{motion} 删除 {motion} 移动的文本 [到寄存器 x]。请参见下文了解例外情况。
dd
["x]dd 删除 [count] 行 [到寄存器 x] 按行
D
["x]D 删除光标下的字符,直到行尾以及 [count]-1 行 [到寄存器 x];与“d$”同义。(不是 按行
{Visual}["x]x 或 v_x v_d v_<Del> {Visual}["x]d 或 {Visual}["x]<Del> 删除突出显示的文本 [到寄存器 x](有关 {Visual},请参见 可视模式)。
{Visual}["x]CTRL-H 或 v_CTRL-H v_<BS> {Visual}["x]<BS> 处于选择模式时:删除突出显示的文本 [到寄存器 x]。
{Visual}["x]X 或 v_X v_D v_b_D {Visual}["x]D 删除突出显示的行 [到寄存器 x](有关 {Visual},请参见 可视模式)。在可视块模式下,“D”会删除突出显示的文本以及所有文本,直到行尾。
:d :de :del :delete :dl :dp :[range]d[elete] [x] 删除 [range] 行(默认值:当前行)[到寄存器 x]。请注意这些奇怪的缩写::dl 删除并列出 :dell 同上 :delel 同上 :deletl 同上 :deletel 同上 :dp 删除并打印 :dep 同上 :delp 同上 :delep 同上 :deletp 同上 :deletep 同上
:[range]d[elete] [x] {count} 删除 {count} 行,从 [range] 开始(默认值:当前行 命令行范围)[到寄存器 x]。
这些命令删除文本。您可以使用“.”命令重复它们(除了“:d”),并撤消它们。使用可视模式删除文本块。请参见 寄存器 以了解有关寄存器的解释。
d{motion} 命令的一个例外情况:如果 motion 不是按行,motion 的起始和结束不在同一行,并且起始之前只有空格,并且结束之后没有非空格,则删除将变为按行。这意味着删除还会删除您可能期望保留的空格行。使用 o_v 运算符强制 motion 为按字符。
尝试删除文本的空区域(例如,在第一列中“d0”)是错误的,当 'cpoptions' 包含“E”标志时。
J
J 连接 [count] 行,至少两行。删除缩进并插入最多两个空格(参见下文)。在缓冲区的最后一行失败。如果 [count] 太大,它将减少到可用行的数量。
v_J
{Visual}J 连接突出显示的行,至少两行。删除缩进并插入最多两个空格(参见下文)。
gJ
gJ 连接 [count] 行,至少两行。不要插入或删除任何空格。
v_gJ
{Visual}gJ 连接突出显示的行,至少两行。不要插入或删除任何空格。
:j :join :[range]j[oin][!] [flags] 连接 [range] 行。与“J”相同,只是使用 [!] 连接不会插入或删除任何空格。如果 [range] 的起始值和结束值相等,则此命令不会执行任何操作。默认行为是将当前行与下一行连接起来。请参见 ex-标志 以了解 [flags]。
:[range]j[oin][!] {count} [flags] 连接 {count} 行,从 [range] 开始(默认值:当前行 命令行范围)。与“J”相同,只是使用 [!] 连接不会插入或删除任何空格。请参见 ex-标志 以了解 [flags]。
这些命令删除行之间的 <EOL>。这将把多行连接成一行。您可以重复这些命令(除了“:j”)并撤消它们。
这些命令(除了“gJ”)在 <EOL> 位置插入一个空格,除非存在尾部空格或下一行以“)”开头。这些命令(除了“gJ”)会删除下一行的所有前导空格。如果 'joinspaces' 选项处于打开状态,则这些命令会在“.”、“!”或“?”之后插入两个空格。在 'formatoptions' 中,“B”和“M”标志会更改在多字节字符之前和之后插入空格的行为 fo-table
“[”标记设置在连接的第一行的末尾,“]”设置在结果行的末尾。

2. 删除和插入 删除插入 替换

R
R 进入替换模式:您键入的每个字符都会替换一个现有字符,从光标下的字符开始。重复输入的文本 [count]-1 次。请参见 替换模式 以了解详细信息。
gR
gR 进入虚拟替换模式:您键入的每个字符都会替换屏幕空间中的现有字符。因此,<Tab> 可能会一次替换多个字符。重复输入的文本 [count]-1 次。请参见 虚拟替换模式 以了解详细信息。
c
["x]c{motion} 删除 {motion} 文本 [到寄存器 x] 并开始插入。当 'cpoptions' 包含“E”标志,并且没有文本要删除时(例如,当光标恰好在“x”之后时使用“cTx”),会发生错误,并且插入模式不会启动(这是与 Vi 兼容的)。当 'cpoptions' 不包含“E”标志时,“c”命令始终启动插入模式,即使没有文本要删除。
cc
["x]cc 删除 [count] 行 [到寄存器 x] 并开始插入 按行。如果 'autoindent' 处于打开状态,则保留第一行的缩进。
C
["x]C 从光标位置删除到行尾以及 [count]-1 行 [到寄存器 x],并开始插入。与 c$ 同义(不是 按行)。
s
["x]s 删除 [count] 个字符 [到寄存器 x] 并开始插入(s 代表替换)。与“cl”同义(不是 按行)。
S
["x]S 删除 [count] 行 [到寄存器 x] 并开始插入。与“cc”同义 按行
{Visual}["x]c 或 v_c v_s {Visual}["x]s 删除突出显示的文本 [到寄存器 x] 并开始插入(有关 {Visual},请参见 可视模式)。
v_r
{Visual}r{char} 将所有选定的字符替换为 {char}CTRL-C 将按字面意思插入。
v_C
{Visual}["x]C 删除突出显示的行 [到寄存器 x] 并开始插入。在可视块模式下,它的工作方式不同 v_b_Cv_S
{Visual}["x]S 删除突出显示的行 [到寄存器 x] 并开始插入(有关 {Visual},请参见 可视模式)。 v_R
{Visual}["x]R 目前与 {Visual}["x]S 相同。在下一个版本中,它可能会有所不同。
说明
您可以使用 <Esc> 退出插入模式和替换模式。
请参见“插入模式和替换模式”部分 mode-ins-repl,以了解这些模式中的其他特殊字符。
[count] 的效果在 Vim 退出插入模式或替换模式后才会生效。
'cpoptions' 选项包含“$”且更改在同一行内时,Vim 会继续显示要删除的文本,并在最后一个删除的字符处放置“$”。
请参见 寄存器 以了解有关寄存器的解释。
替换模式与插入模式相同,只是您输入的每个字符都会删除一个字符。如果您到达行尾,Vim 会追加任何其他字符(就像插入模式一样)。在替换模式下,退格键会恢复原始文本(如果有)。(请参见“插入模式和替换模式”部分 mode-ins-repl)。
cw cW 特殊情况:当光标位于一个单词中时,“cw”和“cW”不包括单词后的空格,它们只更改到单词的末尾。这是因为 Vim 将“cw”解释为更改单词,而单词不包括后面的空格。
如果您希望“cw”包括单词后的空格,请使用此映射
:map cw dwi
或者使用“caw”(请参见 aw)。
:c :ch :change :{range}c[hange][!] 用不同的文本替换文本行。键入一个只包含“.”的行来停止替换。没有 {range},此命令只更改当前行。添加 [!] 会切换 'autoindent',以便在执行此命令的时间内生效。

3. 简单更改 简单更改 更改

r
r{char} 将光标下的字符替换为 {char}。如果 {char}<CR><NL>,则换行符将替换该字符。要替换为真正的 <CR>,请使用 CTRL-V <CR>CTRL-V <NL><Nul> 替换。
如果 {char}CTRL-ECTRL-Y,则使用来自下一行或上一行的字符,就像 i_CTRL-Ei_CTRL-Y 一样。这在计数中也适用,因此 10r<C-E> 从下一行复制 10 个字符。
如果提供 [count],Vim 将用 [count] 个 {char} 替换 [count] 个字符。但是,当 {char}<CR><NL> 时,Vim 只插入一个 <CR>:“5r<CR>” 将五个字符替换为一个换行符。当 {char}<CR><NL> 时,Vim 会执行自动缩进。这就像删除要替换的字符,然后执行“i<CR><Esc>”一样。 {char} 可以作为双字输入 digraph-arg:lmap 映射应用于 {char}。 插入模式中的 CTRL-^ 命令可用于打开/关闭此功能 i_CTRL-^。 有关在 'encoding' 为 Unicode 时使用合成字符的信息,请参见 utf-8-char-arg
gr
gr{char} 将光标下的虚拟字符替换为 {char}。 这将在屏幕空间而不是文件空间中进行替换。 有关更多详细信息,请参见 gRVirtual-Replace-mode。 与 r 一样,可以提供计数。 {char} 可以像 r 那样输入,但插入模式中具有特殊含义的字符(例如大多数 CTRL-k 键)不能使用。
gr-default
Nvim 使用 "gr" 作为前缀创建默认映射,这可能会抑制 gr 的行为。 使用以下命令恢复内置行为
nnoremap <nowait> gr gr
digraph-arg
rt 这样的普通模式命令的参数是一个字符。 当 'cpo' 不包含 'D' 标志时,此字符也可以像 双字 那样输入。 首先键入 CTRL-K,然后键入两个双字字符。
case
以下命令会更改字母的大小写。 将使用当前活动 区域设置。 参见 :language。 LC_CTYPE 值在此很重要。
~
~ 'notildeop' 选项:切换光标下字符的大小写并将光标移到右侧。 如果提供 [count],则执行该次数的字符。
~{motion} 'tildeop' 选项:切换 {motion} 文本的大小写。
g~
g~{motion} 切换 {motion} 文本的大小写。
g~g~ g~g~ g~~ g~~ 切换当前行的大小写。
v_~
{Visual}~ 切换突出显示文本的大小写(有关 {Visual},请参见 Visual-mode)。
v_U
{Visual}U 将突出显示文本设为大写(有关 {Visual},请参见 Visual-mode)。
gU uppercase gU{motion} 将 {motion} 文本设为大写。 例如
:map! <C-F> <Esc>gUiw`]a
这在插入模式下有效:按 CTRL-F 将光标前的单词设为大写。 方便以小写字母键入单词,然后将它们设为大写。
gUgU gUgU gUU gUU 将当前行设为大写。
v_u
{Visual}u 将突出显示文本设为小写(有关 {Visual},请参见 Visual-mode)。
gu lowercase gu{motion} 将 {motion} 文本设为小写。
gugu gugu guu guu 将当前行设为小写。
g? rot13 g?{motion} 对 {motion} 文本进行 Rot13 编码。
v_g?
{Visual}g? 对突出显示的文本进行 Rot13 编码(有关 {Visual},请参见 Visual-mode)。
g?g? g?g? g?? g?? 对当前行进行 Rot13 编码。
要将一行转换为标题大小写,请将每个单词的首字母设为大写
:s/\v<(.)(\w*)/\u\1\L\2/g
加减
CTRL-A
CTRL-A 将 [count] 添加到光标处或之后数字或字母字符。
v_CTRL-A
{Visual}CTRL-A 将 [count] 添加到突出显示文本中的数字或字母字符。
v_g_CTRL-A
{Visual}g CTRL-A 将 [count] 添加到突出显示文本中的数字或字母字符。 如果突出显示多行,则每行都会增加一个额外的 [count](因此实际上创建了一个 [count] 增量序列)。 例如,如果你有以下数字列表
1.
1.
1.
1.
移动到第二个“1.”,然后以 Visual 模式选择三行,按 g CTRL-A,结果为
1.
2.
3.
4.
CTRL-X
CTRL-X 从光标处或之后的数字或字母字符中减去 [count]。
v_CTRL-X
{Visual}CTRL-X 从突出显示文本中的数字或字母字符中减去 [count]。
v_g_CTRL-X
{Visual}g CTRL-X 从突出显示文本中的数字或字母字符中减去 [count]。 如果突出显示多行,则每个值都会减少一个额外的 [count](因此实际上创建了一个 [count] 减量序列)。
CTRL-ACTRL-X 命令适用于(带符号的)十进制数、无符号二进制/八进制/十六进制数和字母字符。
这取决于 'nrformats' 选项
'nrformats' 包含 "bin" 时,Vim 会认为以 '0b' 或 '0B' 开头的数字是二进制数。
'nrformats' 包含 "octal" 时,Vim 会认为以 '0' 开头的数字是八进制数,除非数字包含 '8' 或 '9'。 其他数字是十进制数,前面可能带负号。 如果光标位于数字上,则命令将应用于该数字;否则 Vim 会使用光标右侧的数字。
'nrformats' 包含 "hex" 时,Vim 会认为以 '0x' 或 '0X' 开头的数字是十六进制数。 数字中最后一个字母的大小写决定了结果十六进制数的大小写。 如果当前数字中没有字母,Vim 会使用先前检测到的大小写。
'nrformats' 包含 "alpha" 时,Vim 会更改光标下方或之后的字母字符。 这对于使用字母索引制作列表非常有用。
对于十进制数,前导负号会被认为是用于增量或减量,对于二进制、八进制和十六进制值,它不会被认为是用于增量或减量。 若要忽略符号,请以 Visual 模式选择数字,然后再使用 CTRL-ACTRL-X
对于带有前导零的数字(包括所有八进制和十六进制数),Vim 尽可能地保留数字中的字符数。 对 "0077" 执行 CTRL-A,结果为 "0100",对 "0x100" 执行 CTRL-X,结果为 "0x0ff"。 只有一个例外:当发现以零开头的数字不是八进制数(它包含 '8' 或 '9'),但 'nrformats' 包含 "octal" 时,会删除前导零,以防止结果被识别为八进制数。
请注意,当 'nrformats' 包含 "octal" 时,带有前导零的十进制数会导致错误,因为它们可能会被误认为是八进制数。
同样请注意,当 'nrformats' 包含 "bin" 和 "hex" 时,带有前导 '0x' 或 '0X' 的二进制数可能会被解释为十六进制数而不是二进制数,因为 '0b' 是有效的十六进制数字。 对 "0x0b11" 执行 CTRL-A,结果为 "0x0b12",而不是 "0x0b100"。 当 'nrformats' 包含 "bin" 而不包含 "hex" 时,对 "0b11"(在 "0x0b11" 中)执行 CTRL-A,结果为 "0x0b100"。
当光标下的数字过大而无法容纳在 64 位中时,它将被舍入到最接近的可表示数字,并跳过加减运算。 例如,对 18446744073709551616 执行 CTRL-X,结果为 18446744073709551615。 更大的数字(例如 18446744073709551618)也是如此。
CTRL-A 命令在宏中非常有用。 例如:使用以下步骤创建编号列表。
1. 创建第一个列表条目,确保它以数字开头。 2. qa - 开始录制到寄存器 'a' 中 3. Y - 复制条目 4. p - 在第一个条目的下方粘贴复制的条目 5. CTRL-A - 增加数字 6. q - 停止录制 7. <count>@a - 重复复制、粘贴和增加 <count>

将行向左或向右移动 shift-left-right

<
<{motion} 将 {motion} 行向左移动一个 'shiftwidth'
如果 'shiftwidth' 选项设置为零,则缩进量将根据行中第一个非空字符计算。 <<
<< 将 [count] 行向左移动一个 'shiftwidth'
v_<
{Visual}[count]< 将突出显示的行向左移动 [count] 个 'shiftwidth'(有关 {Visual},请参见 Visual-mode)。
>
>{motion}{motion} 行向右移动一个 'shiftwidth'
如果 'shiftwidth' 选项设置为零,则缩进量将根据行中第一个非空字符计算。 >>
>> 将 [count] 行向右移动一个 'shiftwidth'
v_>
{Visual}[count]> 将突出显示的行向右移动 [count] 个 'shiftwidth'(有关 {Visual},请参见 Visual-mode)。
:<
:[range]< 将 [range] 行向左移动一个 'shiftwidth'。 重复 '<' 以移动多个 'shiftwidth'
:[range]< {count}{count} 行向左移动一个 'shiftwidth',从 [range] 开始(默认情况下为当前行 cmdline-ranges)。 重复 '<' 以移动多个 'shiftwidth'
:[range]le[ft] [indent] 将 [range] 中的行的对齐方式设置为左对齐。 将行的缩进设置为 [indent](默认为 0)。
:>
:[range]> [flags] 将 [range] 行向右移动一个 'shiftwidth'。 重复 '>' 以移动多个 'shiftwidth'。 有关 [flags],请参见 ex-flags
:[range]> {count} [flags] 将 {count} 行向右移动一个 'shiftwidth',从 [range] 开始(默认情况下为当前行 cmdline-ranges)。 重复 '>' 以移动多个 'shiftwidth'。 有关 [flags],请参见 ex-flags
“>” 和 “<” 命令对于更改程序中的缩进非常方便。 使用 'shiftwidth' 选项设置这些命令插入或删除的空格大小。 通常,'shiftwidth' 选项为 8,但你可以将其设置为 3(例如),以创建较小的缩进。 向左移动在没有缩进时停止。 向右移动不会影响空行。
如果 'shiftround' 选项已启用,则缩进将舍入为 'shiftwidth' 的倍数。
如果 'smartindent' 选项已启用,或者 'cindent' 已启用并且 'cinkeys' 包含值为零的 '#',则向右移动不会影响以 '#' 开头的行(这些行应该是应该保留在第 1 列的 C 预处理器行)。 这可以通过 'cino' 选项更改,请参见 cino-#
'expandtab' 选项已关闭(这是默认设置)时,Vim 会尽可能地使用 <Tab> 来创建缩进。 你可以使用 “>><<” 将由空格组成的缩进替换为由 <Tab>(以及一些必要空格)组成的相同缩进。 如果 'expandtab' 选项已启用,则 Vim 仅使用空格。 然后,你可以使用 “>><<” 将缩进中的 <Tab> 替换为空格(或使用 :retab!)。
若要将一行移动多个 'shiftwidth',请使用 Visual 模式或 : 命令。 例如
Vjj4>                move three lines 4 indents to the right
:<<<                move current line 3 indents to the left
:>> 5                move 5 lines 2 indents to the right
:5>>                move line 5 2 indents to the right

4. 复杂的更改 complex-change

4.1 过滤器命令 filter
过滤器是一个程序,它接受标准输入的文本,以某种方式更改它,并将其发送到标准输出。您可以使用以下命令将一些文本发送到过滤器,以便用过滤器的输出替换它。过滤器的示例包括 "sort",它按字母顺序对行进行排序,以及 "indent",它格式化 C 程序文件(您需要一个像过滤器一样工作的 indent 版本;并非所有版本都这样做)。'shell' 选项指定 Vim 用于执行过滤器命令的 shell。您可以用 "." 重复过滤器命令。Vim 不会识别 :! 命令后的注释(以 '"' 开头)。
!
!{motion}{filter} 将 {motion} 文本行通过外部程序 {filter} 进行过滤。
!!
!!{filter} 将 [count] 行通过外部程序 {filter} 进行过滤。
v_!
{Visual}!{filter} 将突出显示的行通过外部程序 {filter} 进行过滤(有关 {Visual},请参见 Visual-mode)。
:{range}![!]{filter} [!][arg] :range!
{range} 行通过外部程序 {filter} 进行过滤。Vim 将可选的感叹号替换为最新给定的命令,并将可选的 [arg] 附加到命令后。Vim 将过滤器命令的输出保存在一个临时文件中,然后将该文件读取到缓冲区 tempfile 中。Vim 使用 'shellredir' 选项将过滤器输出重定向到临时文件。但是,如果 'shelltemp' 选项关闭,则在可能的情况下使用管道(在 Unix 上)。当 'R' 标志包含在 'cpoptions' 中时,过滤行中的标记会被删除,除非使用了 :keepmarks 命令。示例
:keepmarks '<,'>!sort
当过滤后的行数少于过滤前的行数时,缺失行中的标记无论如何都会被删除。
=
={motion} 将 {motion} 行通过 'equalprg' 选项指定的外部程序进行过滤。当 'equalprg' 选项为空时(这是默认值),请使用内部格式化函数 C-indenting'lisp'。但是,当 'indentexpr' 不为空时,它将被使用 indent-expression
==
== 像 ={motion} 一样过滤 [count] 行。
v_=
{Visual}= 像 ={motion} 一样过滤突出显示的行。
tempdir tempfile setuid Nvim 使用临时文件进行过滤和生成差异。插件通常也使用 tempname() 来实现它们自己的目的。在第一次请求临时文件时,Nvim 会创建一个公共目录(“Nvim tempdir”),作为当前会话中所有临时文件(包括 stdpath("run") 文件 $XDG_RUNTIME_DIR)的存储空间。
Nvim tempdir 在第一个可用的系统 tempdir 中创建:Unix:$TMPDIR、/tmp、当前目录、$HOME。Windows:$TMPDIR、$TMP、$TEMP、$USERPROFILE、当前目录。
在 Unix 上,tempdir 以 0700 的权限创建(只有当前用户可以访问),以避免安全问题(例如符号链接攻击)。在退出时,Nvim 会删除 tempdir 及其内容。 E5431
如果您看到错误或 log 消息,例如
E5431: tempdir disappeared (2 times)
这意味着系统上的一个外部进程删除了 Nvim tempdir。通常,这是由“防病毒软件”或配置错误的清理服务造成的。
如果 Nvim 设置了 setuid 位,这可能会导致问题:temp 文件归 setuid 用户所有,但过滤器命令可能以原始用户身份运行。
4.2 替换 :substitute
:s :su :[range]s[ubstitute]/{pattern}/{string}/[flags] [count] 对于 [range] 中的每一行,将 {pattern} 的匹配项替换为 {string}。有关 {pattern},请参见 pattern{string} 可以是字面字符串,也可以是特殊内容;请参见 sub-replace-special。当 [range] 和 [count] 被省略时,仅在当前行中替换。当给出 [count] 时,从 [range] 中的最后一行开始,在 [count] 行中替换。当 [range] 被省略时,从当前行开始。 E939 E1510 [count] 必须是一个正数(最大 2147483647)。另请参见 cmdline-ranges
有关 [flags],请参见 :s_flags。分隔符不需要是 /,请参见 pattern-delimiter
:[range]s[ubstitute] [flags] [count] :[range]&[&][flags] [count] :&
使用相同的搜索模式和替换字符串重复上一次 :substitute 命令,但没有相同的标志。您可以添加 [flags],请参见 :s_flags。请注意,在 :substitute 后,'&' 标志无法使用,它被识别为模式分隔符。:substitute 和 'c'、'g'、'i'、'I' 和 'r' 标志之间的空格不是必需的,但在脚本中,最好保留它以避免混淆。另请参见下面用于重复 :substitute 的两个字母和三个字母的命令 :substitute-repeat
:[range]~[&][flags] [count] :~
使用相同的替换字符串但使用最后使用的搜索模式重复上一次替换。这与 :&r 相同。有关 [flags],请参见 :s_flags
&
& :s 的同义词(重复上一次替换)。请注意,标志不会被记住,因此它可能实际上工作方式不同。您可以使用 :&& 来保留标志。
&-default
默认映射到 ":&&<CR>"。 default-mappings
g&
g& :%s//~/& 的同义词(使用相同的标志在所有具有相同模式的行上重复上一次替换)。例如,当您首先使用 :s/pattern/repl/flags 进行替换,然后使用 /search 搜索其他内容时,g& 将执行 :%s/search/repl/flags。助记符:全局替换。
:snomagic :sno :[range]sno[magic] ... 与 :substitute 相同,但始终使用 'nomagic'
:smagic :sm :[range]sm[agic] ... 与 :substitute 相同,但始终使用 'magic'
:s_flags
您可以用于替换命令的标志
:&&
[&] 必须是第一个:保留上一次替换命令的标志。示例
:&&
:s/this/that/&
请注意,:s:& 不会保留标志。
[c] 确认每次替换。Vim 会突出显示匹配的字符串(使用 hl-IncSearch)。您可以键入: :s_c
'y' 替换此匹配 'l' 替换此匹配并退出 ("last") 'n' 跳过此匹配 <Esc> 退出替换 'a' 替换此匹配和所有剩余的匹配 'q' 退出替换 CTRL-E 向上滚动屏幕 CTRL-Y 向下滚动屏幕
:s_e
[e] 当搜索模式失败时,不要发出错误消息,特别是,在映射中继续执行,就像没有发生错误一样。这对于防止“无匹配”错误中断映射非常有用。但是,Vim 不会抑制以下错误消息:正则表达式不能以字母分隔 \ 应后跟 /、? 或 & 没有上一次替换正则表达式 尾随字符 中断
:s_g
[g] 替换行中的所有匹配项。如果没有此参数,替换仅对每一行中的第一个匹配项执行。如果 'gdefault' 选项处于打开状态,则此标志默认处于打开状态,并且 [g] 参数会将其关闭。
:s_i
[i] 忽略模式的区分大小写。不会使用 'ignorecase''smartcase' 选项。
:s_I
[I] 不要忽略模式的区分大小写。不会使用 'ignorecase''smartcase' 选项。
:s_n
[n] 报告匹配项的数量,不要实际替换。[c] 标志将被忽略。匹配项的报告方式与 'report' 为零时相同。有助于 count-items。如果使用 \= sub-replace-expression,则表达式将在每次匹配时在 sandbox 中求值。
[p] 打印包含上次替换的行的内容。 :s_p
[#] 像 [p] 一样,并在行号前添加行号。 :s_#
[l] 像 [p] 一样,但打印文本就像 :list 一样。 :s_l
:s_r
[r] 仅在与 :& 或没有参数的 :s 结合使用时才有用。:&r 的工作方式与 :~ 相同:当搜索模式为空时,使用以前使用的搜索模式,而不是上一次替换或 :global 命令中的搜索模式。如果最后执行搜索的命令是替换或 :global 命令,则不会产生任何影响。如果最后一个命令是搜索命令,例如 "/",则使用该命令的模式。对于带有参数的 :s 命令,这种情况已经发生
:s/blue/red/
/green
:s//red/   or  :~   or  :&r
最后的命令将把 "green" 替换为 "red"。
:s/blue/red/
/green
:&
最后的命令将把 "blue" 替换为 "red"。
请注意,没有标志可以更改模式的“神奇性”。相反,使用不同的命令,或者您可以使用 /\v 及其类似命令。原因是,只有跳过模式才能找到标志,而要跳过模式,必须知道“神奇性”。死循环!
如果替换命令的 {pattern} 为空,则该命令将使用上一次替换或 :global 命令的模式。如果没有,但存在之前的搜索模式,则将使用该模式。使用 [r] 标志,该命令将使用上一次替换、:global 或搜索命令的模式。
如果 {string} 被省略,则替换就像它是空的。因此,匹配的模式会被删除。{pattern} 后的分隔符也可以省略。示例
:%s/TESTING
这会从所有行中删除 "TESTING",但每行只删除一次。
为了与 Vi 保持兼容,允许以下两个例外:"\/{string}/" 和 "\?{string}?" 与 "//{string}/r" 相同。"\&{string}&" 与 "//{string}/" 相同。 pattern-delimiter E146 您可以使用另一个单字节字符,而不是围绕模式和替换字符串的 '/'。如果您要在搜索模式或替换字符串中包含 '/',这将非常有用。示例
:s+/+//+
您可以使用大多数字符,但不能使用字母数字字符、'\'、'"' 或 '|'。
有关模式的定义,请参见 pattern。在 Visual 块模式下,在模式中使用 /\%V 才能使替换仅在块中生效。否则,它会始终对整行生效。
sub-replace-special :s\={string} 以 “\=” 开头时,它会被评估为一个表达式,请参见 sub-replace-expression。您可以使用它进行复杂替换或特殊字符操作。
替换的递归深度限制为 4 级。 E1290
否则,{string} 中的这些字符具有特殊含义
magic nomagic action
& \& 被替换为整个匹配模式 s/\&
\& & 被替换为 & \0 被替换为整个匹配模式 \0 s/\0 \1 被替换为第一对 () 中的匹配模式 s/\1
\2 被替换为第二对 () 中的匹配模式 s/\2
.. .. s/\3
\9 被替换为第九对 () 中的匹配模式 s/\9
~ \~ 被替换为之前替换的 {string} s~
\~ ~ 被替换为 ~ s/\~
\u 将下一个字符转换为大写 s/\u
\U 将后续字符转换为大写,直到遇到 \E s/\U \l 将下一个字符转换为小写 s/\l
\L 将后续字符转换为小写,直到遇到 \E s/\L \e 结束 \u、\U、\l 和 \L 的操作(注意:不是 <Esc>!) s/\e
\E 结束 \u、\U、\l 和 \L 的操作 s/\E
<CR> 在此位置将行分割成两行(使用 CTRL-V <Enter> 输入 <CR>s<CR>
\r 同上 s/\r
\<CR> 插入回车符 (CTRL-M)(使用 CTRL-V <Enter> 输入 <CR>s/\<CR>
\n 插入一个 <NL> (在文件中表示 <NUL>)(不会换行) s/\n
\b 插入一个 <BS> s/\b
\t 插入一个 <Tab> s/\t
\\ 插入一个反斜杠 s/\\
\x 其中 x 是任何未在上述提到的字符:保留供将来扩展使用
特殊含义也适用于 substitute() 函数的第三个参数 {sub} 中,但以下情况除外
百分号 % 将直接插入百分号,不考虑 'cpoptions' 的设置。
magic 始终处于启用状态,不考虑 'magic' 的设置。
波浪号 ~ 将直接插入波浪号。
<CR> 和 \r 插入回车符 (CTRL-M)。
\<CR> 没有特殊含义。它只是 \x 中的一个字符。
示例
:s/a\|b/xxx\0xxx/g                 modifies "a b"             to "xxxaxxx xxxbxxx"
:s/\([abc]\)\([efg]\)/\2\1/g         modifies "af fa bg" to "fa fa gb"
:s/abcde/abc^Mde/                 modifies "abcde"    to "abc", "de" (two lines)
:s/$/\^M/                         modifies "abcde"    to "abcde^M"
:s/\w\+/\u\0/g                 modifies "bla bla"  to "Bla Bla"
:s/\w\+/\L\u\0/g                 modifies "BLA bla"  to "Bla Bla"
注意:“\L\u” 可用于将单词的首字母大写。这与 Vi 和旧版本的 Vim 不兼容,在这些版本中,"\u" 会抵消 "\L" 的作用。"\U\l" 也是如此。
注意:在以前的版本中,CTRL-V 的处理方式有所不同。由于这与 Vi 不兼容,因此已将其移除。请改用反斜杠。
command text result
:s/aa/a^Ma/ aa a<line-break>a :s/aa/a\^Ma/ aa a^Ma :s/aa/a\\^Ma/ aa a\<line-break>a
(您需要输入 CTRL-V <CR> 才能在此处得到 ^M)
“\1”、 “\2” 等的编号是根据模式中 “\(“ 的出现顺序(从左到右)确定的。如果一对括号组匹配多次,则最后一次匹配将用于 “\1”、 “\2” 等。例如
:s/\(\(a[a-d] \)*\)/\2/      modifies "aa ab x" to "ab x"
“\2” 用于 “\(a[a-d] \)”。它首先匹配 “aa ”,其次匹配 “ab ”。
当使用括号与 “|” 结合使用时,例如 \([ab]\)\|\([cd]\),括号中的第一个或第二个模式没有匹配,因此 \1 或 \2 为空。例如
:s/\([ab]\)\|\([cd]\)/\1x/g   modifies "a b c d"  to "ax bx x x"
这些命令使用给定的标志重复上一次执行的 :substitute 命令。第一个字母始终为 “s”,后面跟着一个或两个可能的标志字符。例如,:sce 等效于 :s///ce。表中列出了所有可能的组合,并非所有标志都可用,因为该命令是另一个命令的简写。
以下是 :substitute 命令的列表 | c e g i I n p l r | c :sc :sce :scg :sci :scI :scn :scp :scl | e | g :sgc :sge :sg :sgi :sgI :sgn :sgp :sgl :sgr | i :sic :sie :si :siI :sin :sip :sir | I :sIc :sIe :sIg :sIi :sI :sIn :sIp :sIl :sIr | n | p | l | r :src :srg :sri :srI :srn :srp :srl :sr
例外情况::scr 等效于 :scriptnames :se 等效于 :set :sig 等效于 :sign :sil 等效于 :silent :sn 等效于 :snext :sp 等效于 :split :sl 等效于 :sleep :sre 等效于 :srewind
使用表达式进行替换 sub-replace-expression
sub-replace-\= s/\= 当替换字符串以 “\=” 开头时,剩余部分将被解释为一个表达式。
前面在 sub-replace-special 中提到的字符特殊含义不适用,但 “<CR>” 除外。<NL> 字符用作换行符,您可以使用双引号字符串获取它:"\n"。在前面添加反斜杠可以获得真正的 <NL> 字符(在文件中表示 NUL)。
“\=” 符号也可以用在 substitute() 函数的第三个参数 {sub} 中。在这种情况下,前面在 sub-replace-special 中提到的字符特殊含义将完全不适用。尤其是,<CR><NL> 不被解释为换行符,而是分别被解释为回车符和换行符。
当结果为 List 时,列表项将使用换行符连接。因此,每个项目都成为一行,但它们本身可以包含换行符。
可以使用 submatch() 函数获取匹配的文本。可以使用 “submatch(0)” 访问整个匹配文本。可以使用 “submatch(1)” 访问第一对 () 中匹配的文本。其他子匹配的文本也可以用同样的方式访问。
请注意:分隔符不能出现在表达式中!建议使用 “@” 或 “:” 等字符。如果表达式的结果包含分隔符,则不会出现问题。
示例
:s@\n@\="\r" .. expand("$HOME") .. "\r"@
这将用包含 $HOME 值的新行替换行尾。
s/E/\="\<Char-0x20ac>"/g
这将用欧元符号替换每个 “E” 字符。有关更多信息,请参见 <Char->
4.3 更改制表符 change-tabs
:ret :retab :retab! :[range]ret[ab][!] [new_tabstop] 使用给定的新制表符大小值替换所有包含 <Tab> 的空白字符序列。如果您没有指定新的制表符大小值,或者该值是零,则 Vim 将使用当前的 'tabstop' 值。始终使用当前的 'tabstop' 值来计算现有制表符的宽度。使用 ! 时,Vim 还会在适当的位置将仅包含普通空格的字符串替换为制表符。如果启用了 'expandtab',Vim 会将所有制表符替换为适当数量的空格。该命令会将 'tabstop' 设置为给定的新值,并且如果对整个文件执行该命令(默认行为),则不应该进行任何可见的更改。注意:该命令会修改 C 程序中字符串内的任何 <Tab> 字符。使用 "\t" 来避免这种情况(这也是一个良好的习惯)。:retab! 可能会更改由 <Tab> 字符组成的空格序列,这可能会导致 printf() 出现问题。可以使用以逗号分隔的制表符宽度列表来代替单个制表符大小值。列表中的每个值都表示一个制表符的宽度,最后一个值将应用于所有后续制表符。
retab-example
使用自动命令和 “:retab” 编辑以 8 个制表符大小存储的文件,但在设置了 4 个制表符大小的环境中进行编辑的示例。警告:字符串内的空白字符可能会更改!另请参见 'softtabstop' 选项。
:auto BufReadPost        *.xx        retab! 4
:auto BufWritePre        *.xx        retab! 8
:auto BufWritePost        *.xx        retab! 4
:auto BufNewFile        *.xx        set ts=4

5. 复制和移动文本 copy-move

quote
"{register} 使用 {register} 进行下一次删除、粘贴或插入操作。使用大写字母进行删除和粘贴操作时,会将内容追加到寄存器。寄存器 “.”、 “%”、 “#” 和 “:” 只能与插入操作一起使用。
:reg :registers :reg[isters] 显示所有编号寄存器和命名寄存器的类型和内容。如果为 :redir 写入寄存器,则不会列出该寄存器。类型可以是以下之一:“c” 代表 逐字符 文本 “l” 代表 整行 文本 “b” 代表 块状视觉 文本
:reg[isters] {arg} 显示 {arg} 中提到的编号寄存器和命名寄存器的内容。例如
:reg 1a
显示寄存器 “1” 和 “a”。{arg} 中允许使用空格。
:di :dis :display :di[splay] [arg] 与 :registers 相同。
y yank ["x]y{motion} 将{motion} 文本 [放入寄存器 x 中] yank。当没有字符被 yank 时(例如,在第 1 列中 "y0"),当 'cpoptions' 包含 'E' 标志时,这是一个错误。
yy
["x]yy 将 [count] 行 [放入寄存器 x 中] 行方式 yank。
Y
["x]Y 将 [count] 行 [放入寄存器 x 中](与 yy 同义,行方式)。Y-default
默认映射到 "y$"。 default-mappings
zy
["x]zy{motion} 将{motion} 文本 [放入寄存器 x 中] yank。只有在选择文本块时与y 不同,请参阅 v_zy
v_y
{Visual}["x]y 将突出显示的文本 [放入寄存器 x 中] yank(有关{Visual},请参阅 Visual 模式)。
v_Y
{Visual}["x]Y 将突出显示的行 [放入寄存器 x 中] yank(有关{Visual},请参阅 Visual 模式)。
v_zy
{Visual}["x]zy 将突出显示的文本 [放入寄存器 x 中] yank。选定块的每行的末尾不会 yank 尾随空格。在与zp 组合使用时特别有用。(有关{Visual},请参阅 Visual 模式)
:y :yank E850 :[range]y[ank] [x] 将 [range] 行 [放入寄存器 x 中] yank。
:[range]y[ank] [x] {count}{count} 行 yank,从 [range] 中的最后一个行号开始(默认情况下:当前行 命令行范围),[放入寄存器 x 中]。
p put E353 E1240 ["x]p 将 [来自寄存器 x] 的文本 [count] 次放到光标之后。
P
["x]P 将 [来自寄存器 x] 的文本 [count] 次放到光标之前。
<MiddleMouse>
["x]<MiddleMouse> 将寄存器中的文本 [count] 次放到光标之前。使用 "*" 寄存器,除非指定了其他寄存器。将光标留在新文本的末尾。使用鼠标仅在 'mouse' 包含 'n' 或 'a' 时有效。如果您有滚轮并且经常意外粘贴文本,您可以使用这些映射来禁用使用鼠标中键粘贴文本
:map <MiddleMouse> <Nop>
:imap <MiddleMouse> <Nop>
您可能还想禁用多击版本,请参阅 双击
gp
["x]gp 与 "p" 相同,但将光标留在新文本之后。
gP
["x]gP 与 "P" 相同,但将光标留在新文本之后。
:pu :put :[line]pu[t] [x] 将 [来自寄存器 x] 的文本放到 [line] 之后(默认情况下为当前行)。这始终有效 行方式,因此此命令可用于将 yank 的块作为新行放入。如果未指定寄存器,则取决于 'cb' 选项:如果 'cb' 包含 "unnamedplus",则从 + 寄存器 quoteplus 粘贴。否则,如果 'cb' 包含 "unnamed",则从 * 寄存器 quotestar 粘贴。否则,从未命名寄存器 quote_quote 粘贴。寄存器也可以是 '=' 后跟一个可选表达式。表达式持续到命令结束。您需要转义 '|' 和 '"' 字符以防止它们终止命令。示例
:put ='path' .. \",/test\"
如果 '=' 后面没有表达式,Vim 将使用上一个表达式。您可以使用 ":dis =" 查看它。
:[line]pu[t]! [x] 将 [来自寄存器 x] 的文本放到 [line] 之前(默认情况下为当前行)。
["x]]p 或 ]p ]<MiddleMouse> ["x]]<MiddleMouse> 与 "p" 相同,但调整缩进以匹配当前行。使用鼠标仅在 'mouse' 包含 'n' 或 'a' 时有效。
["x][P 或 [P
["x]]P 或 ]P
["x][p 或 [p [<MiddleMouse> ["x][<MiddleMouse> 与 "P" 相同,但调整缩进以匹配当前行。使用鼠标仅在 'mouse' 包含 'n' 或 'a' 时有效。
["x]zp 或 zp zP ["x]zP 与 "p" 和 "P" 相同,除了在粘贴块时不会添加尾随空格。因此插入的文本并不总是矩形。在与 v_zy 组合使用时特别有用。
您可以使用这些命令将文本从一个地方复制到另一个地方。为此,首先使用 yank、delete 或 change 命令将文本放入寄存器,然后使用 put 命令插入寄存器内容。您也可以使用这些命令将文本从一个文件移动到另一个文件,因为 Vim 在更改缓冲区时会保留所有寄存器(CTRL-^ 命令是切换两个文件之间的快速方法)。
行方式寄存器 字符方式寄存器 您可以使用 "." 重复 put 命令(除了 :put)并撤消它们。如果用于将文本放入寄存器的命令是 行方式,Vim 会将文本插入到光标所在行的下方 ("p") 或上方 ("P")。否则 Vim 会将文本插入到光标之后 ("p") 或之前 ("P")。使用 ":put" 命令,Vim 始终将文本插入到下一行。您可以使用命令序列 "xp" 交换两个字符。您可以使用命令序列 "ddp" 交换两行。您可以使用命令序列 "deep" 交换两个单词(从第一个单词前面的空格处开始)。您可以在 put 命令之后使用 "']" 或 "`]" 命令将光标移动到插入文本的末尾,或者使用 "'[" 或 "`[" 将光标移动到开头。
put-Visual 模式 v_p v_P 在 Visual 模式中使用像 pP 这样的 put 命令时,Vim 将尝试用寄存器的内容替换选定的文本。这是否有效取决于选择的类型和寄存器中文本的类型。对于块方式选择,它还取决于块的大小以及角是否在现有字符上。(实现细节:它实际上是通过首先将寄存器放在选择之后,然后删除选择来实现的。)使用 p,之前选定的文本将被放入未命名的寄存器中(以及可能的选择和/或剪贴板)。如果您想将该文本放在其他地方,这很有用。但是您不能重复相同的更改。使用 P,未命名的寄存器不会改变(以及选择或剪贴板),您可以重复相同的更改。但是删除的文本不能使用。如果您确实需要它,您可以使用另一个寄存器 p。例如,将文本 yank 到副本中,Visually 选择要替换的文本并使用 "0p . 您可以根据需要重复此操作,未命名的寄存器将在每次操作时改变。块方式 put
当寄存器包含来自一行的文本(字符方式)时,使用块方式 Visual 选择,将该寄存器放到每个选定行中重复粘贴该文本,从而用寄存器文本的多个副本替换块方式选定的区域。例如
使用yw 将单词 "TEXT" yank 到寄存器中
选择一个视觉块,在本例中用 "v" 标记:aaavvaaa bbbvvbbb cccvvccc
按下p,结果是:aaaTEXTaaa bbbTEXTbbb cccTEXTccc
块方式寄存器
如果您使用块方式 Visual 模式命令将文本放入寄存器,则文本块将被插入到光标所在列之前 ("P") 或之后 ("p") 的当前行和下一行中。Vim 使整个文本块从同一列开始。因此插入的文本看起来与 yank 或删除时相同。Vim 可能会用空格替换一些<Tab> 字符以实现这一点。但是,如果块的宽度不是<Tab> 宽度 的倍数,并且插入块后的文本包含<Tab>,则该文本可能会错位。
使用 zP/|zp| 粘贴块方式 yank 的寄存器,而不附加尾随空格。
请注意,在字符方式 yank 命令之后,Vim 将光标留在最靠近缓冲区开头的第一个 yank 的字符上。这意味着 "yl" 不会移动光标,但 "yh" 会将光标向左移动一个字符。理由:在 Vi 中,"y" 命令后跟一个向后的动作有时不会将光标移动到第一个 yank 的字符,因为重新显示被跳过了。在 Vim 中,它始终移动到第一个字符,如 Posix 指定的。使用行方式 yank 命令,光标将被放在第一行,但列不会被修改,因此它可能不在第一个 yank 的字符上。
有十种类型的寄存器:寄存器 {register} E354 1. 未命名寄存器 "" 2. 10 个编号寄存器 "0 到 "9 3. 小删除寄存器 "-" 4. 26 个命名寄存器 "a 到 "z 或 "A 到 "Z 5. 三个只读寄存器 ":, "., "%" 6. 备用缓冲区寄存器 "#" 7. 表达式寄存器 "=" 8. 选择寄存器 "*" 和 "+" 9. 黑洞寄存器 "_" 10. 最后一个搜索模式寄存器 "/"
1. 未命名寄存器 "" quote_quote quotequote Vim 使用 "d"、"c"、"s"、"x" 命令删除或使用 yank "y" 命令复制的文本填充此寄存器,无论是否使用了特定寄存器(例如 "xdd)。这就像未命名寄存器指向最后一个使用的寄存器。因此,当使用大写寄存器名称进行追加时,未命名寄存器包含与命名寄存器相同的文本。"_" 寄存器是一个例外:"_dd 不会将删除的文本存储在任何寄存器中。Vim 使用未命名寄存器的内容进行任何未指定寄存器的 put 命令(p 或 P)。此外,您可以使用名称 '"' 访问它。这意味着您必须输入两个双引号。写入 "" 寄存器将写入寄存器 "0。
2. 编号寄存器“0 到 “9 quote_number quote0 quote1 quote2 quote3 quote4 quote9 Vim 用 yank 和 delete 命令中的文本填充这些寄存器。编号寄存器 0 包含最近一次 yank 命令的文本,除非命令使用 ["x] 指定了另一个寄存器。编号寄存器 1 包含最近一次 delete 或 change 命令删除的文本(即使命令指定了另一个寄存器),除非文本少于一行(在这种情况下使用小 delete 寄存器)。对以下移动命令的 delete 操作符例外:%()`/?nN{}。在这种情况下始终使用寄存器“1(与 Vi 兼容)。如果 delete 操作在同一行内,也会使用“- 寄存器。请注意,这些字符可能已被映射。例如,% 被 matchit 插件映射。在每次连续的删除或更改操作后,Vim 会将寄存器 1 的先前内容移至寄存器 2,将寄存器 2 的内容移至寄存器 3,以此类推,丢失寄存器 9 的先前内容。
3. 小 delete 寄存器“- quote_- quote- 此寄存器包含删除少于一行的命令的文本,除非命令使用 ["x] 指定了寄存器。
4. 命名寄存器“a 到 “z 或“A 到 “Z quote_alpha quotea Vim 仅在您指示的情况下填充这些寄存器。将它们指定为小写字母以替换其先前内容,或指定为大写字母以追加到其先前内容。当 'cpoptions' 中存在“>”标志时,会在追加文本之前插入换行符。
5. 只读寄存器“:, “。和 "%" 这些是 '%', ':' 和 '.'。您只能在使用 "p"、"P" 和 ":put" 命令以及 CTRL-R 时使用它们。 quote_. quote. E29 "。包含最后插入的文本(与使用插入模式命令 CTRL-ACTRL-@ 插入的文本相同)。 注意: 这不适用于命令行上的 CTRL-R。它的工作原理略有不同,就像插入文本而不是放入文本一样('textwidth' 和其他选项会影响插入的内容)。 quote_% quote% "% 包含当前文件的名称。 quote_: quote: E30 ": 包含最近执行的命令行。示例:使用 "@:" 重复上一个命令行命令。仅当键入命令行至少一个字符时,才会将命令行存储在此寄存器中。因此,如果命令完全来自映射,它将保持不变。
quote_# quote# 6. 备用文件寄存器“# 包含当前窗口的备用文件的名称。它将改变 CTRL-^ 命令的工作方式。此寄存器是可写的,主要用于在插件更改它后恢复它。它接受缓冲区号
let altbuf = bufnr(@#)
...
let @# = altbuf
如果您传递缓冲区号且该缓冲区不存在,则会给出错误 E86。它还可以接受与现有缓冲区名称匹配的项
let @# = 'buffer_name'
如果有多个缓冲区与给定名称匹配,则会给出错误 E93,或者如果没有任何缓冲区与给定名称匹配,则会给出错误 E94
7. 表达式寄存器"= quote_= quote= @= 这实际上不是一个存储文本的寄存器,而是在使用寄存器的命令中使用表达式的一种方式。表达式寄存器是可读写的。
在 " 或 CTRL-R 后键入“=”时,光标会移动到命令行,您可以在其中输入任何表达式(请参阅 expression)。所有正常的命令行编辑命令都可用,包括表达式专用的历史记录。当您键入 <CR> 结束命令行时,Vim 会计算表达式的结果。如果您键入 <Esc> 结束命令行,Vim 会放弃表达式。如果您没有输入表达式,Vim 会使用上一个表达式(就像使用“/”命令一样)。
表达式必须求值为字符串。数字始终会自动转换为字符串。对于 "p" 和 ":put" 命令,如果结果是浮点数,则将其转换为字符串。如果结果是列表,则每个元素都将转换为字符串并用作一行。字典将转换为字符串。Funcref 会导致错误消息(使用 string() 进行转换)。
如果 "= 寄存器用于 "p" 命令,则字符串将在 <NL> 字符处拆分。如果字符串以 <NL> 结尾,则将其视为行寄存器。
8. 选择寄存器“* 和 "+" 使用这些寄存器来存储和检索 GUI 的选定文本。请参阅 quotestarquoteplus。当剪贴板不可用或无法正常工作时,将改用无名寄存器。对于 Unix 系统和 Mac OS X,请参阅 primary-selection
9. 黑洞寄存器"_ quote_
写入此寄存器时,不会发生任何事情。这可以用来删除文本而不影响普通寄存器。从该寄存器读取时,不会返回任何内容。
10. 最后搜索模式寄存器"/ quote_/ quote/ 包含最近的搜索模式。这用于 "n" 和 'hlsearch'。它可以使用 :let 写入,您可以更改它以让 'hlsearch' 突出显示其他匹配项,而无需实际搜索。您无法将 yank 或 delete 内容放入该寄存器中。搜索方向在 v:searchforward 中可用。请注意,从函数 function-search-undo 返回时,该值会被恢复。
@/
您可以使用 :let 命令 :let-@ 写入寄存器。示例
:let @/ = "the"
如果您使用 put 命令而不指定寄存器,Vim 会使用最后填充的寄存器(这也是无名寄存器的内容)。如果您感到困惑,请使用 :dis 命令来找出 Vim 将要放置的内容(此命令会显示所有命名和编号寄存器;无名寄存器标记为“'”)。
接下来的三个命令始终作用于整行。
:[range]co[py] {address} :co :copy 将 [range] 指定的行复制到 {address} 指定行的下方。
:t
:t 是 copy 的同义词。
:[range]m[ove] {address} :m :mo :move E134 将 [range] 指定的行移动到 {address} 指定行的下方。

6. 格式化文本 formatting

:[range]ce[nter] [width] :ce :center 在 [width] 列(默认值为 'textwidth',或者当 'textwidth' 为 0 时为 80)之间将 [range] 中的文本居中。
:[range]ri[ght] [width] :ri :right 将 [range] 中的文本在 [width] 列(默认值为 'textwidth',或者当 'textwidth' 为 0 时为 80)处右对齐。
:le :left :[range]le[ft] [indent] 将 [range] 中的文本左对齐。将文本中的缩进设置为 [indent](默认值为 0)。
gq
gq{motion} 格式化 {motion} 移动到的行。格式化使用以下三种方法之一执行:1. 如果 'formatexpr' 不为空,则会计算表达式。这对于每个缓冲区可能有所不同。2. 如果 'formatprg' 不为空,则会使用外部程序。3. 否则,会使用内部格式化。
在第三种情况下,'textwidth' 选项控制每行的格式化长度(见下文)。如果 'textwidth' 选项为 0,则格式化后的行长为屏幕宽度(最大宽度为 79)。'formatoptions' 选项控制格式化类型 fo-table。光标保留在最后格式化行的第一个非空白字符上。 注意: "Q" 命令以前执行此功能。如果您仍然想使用 "Q" 进行格式化,请使用此映射
:nnoremap Q gq
gqgq gqgq gqq gqq 格式化当前行。使用计数格式化这么多行。
v_gq
{Visual}gq 格式化突出显示的文本。(有关 {Visual},请参阅 Visual-mode)。
gw
gw{motion} 格式化 {motion} 移动到的行。类似于 gq,但会将光标放回文本中的相同位置。但是,不会使用 'formatprg''formatexpr'
gwgw gwgw gww gww 使用 "gw" 格式化当前行。
v_gw
{Visual}gw 使用 "gw" 格式化突出显示的文本。(有关 {Visual},请参阅 Visual-mode)。
示例:要格式化当前段落,请使用:gqap
gqap
"gq" 命令将光标留在移动命令将光标移动到的行中。这使您可以使用 "." 重复格式化。这与 "gqj"(格式化当前行和下一行)和 "gq}"(格式化到段落末尾)配合良好。 注意: 当设置了 'formatprg' 时,"gq" 会将光标留在第一个格式化行上(就像使用过滤器命令一样)。
如果您想格式化当前段落并继续执行您之前的工作,请使用
gwap
如果您始终希望保持段落格式化,则可能希望将 'a' 标志添加到 'formatoptions' 中。请参阅 auto-format
如果 'autoindent' 选项已打开,则 Vim 会对后续行使用第一行的缩进。
格式化不会更改空行(但会更改仅包含空白的文本的行!)。
当行合并在一起时,会使用 'joinspaces' 选项。
您可以将'formatexpr'选项设置为表达式,或将'formatprg'选项设置为外部程序的名称,以便Vim用于文本格式化。 'textwidth'和其他选项对外部程序的格式化没有影响。
format-formatexpr
可以将'formatexpr'选项设置为执行缓冲区重新格式化的Vim脚本函数。这通常应该发生在ftplugin中,因为格式化高度依赖于文件类型。使用autoload脚本是有意义的,因此相应的脚本仅在实际需要时加载,并且脚本应命名为<filetype>format.vim。
例如,与Vim一起分发在$VIMRUNTIME目录中的XML文件类型插件将'formatexpr'选项设置为
setlocal formatexpr=xmlformat#Format()
这意味着,您将在以下目录中找到相应的脚本(定义了xmlformat#Format()函数):$VIMRUNTIME/autoload/xmlformat.vim
以下是一个从所选文本中删除尾随空格的示例脚本。将其放在您的autoload目录中,例如 ~/.vim/autoload/format.vim
func! format#Format()
  " only reformat on explicit gq command
  if mode() != 'n'
    " fall back to Vim's internal reformatting
    return 1
  endif
  let lines = getline(v:lnum, v:lnum + v:count - 1)
  call map(lines, {key, val -> substitute(val, '\s\+$', '', 'g')})
  call setline('.', lines)
  " do not run internal formatter!
  return 0
endfunc
然后,您可以通过执行以下命令来启用格式化:
setlocal formatexpr=format#Format()
注意:当从插入模式调用时,此函数显式返回非零值(这基本上意味着,文本插入超过了'textwidth'限制)。这会导致Vim回退到使用内部格式化程序重新格式化文本。
但是,如果使用gq命令重新格式化文本,该函数将接收所选行,从这些行中修剪尾随空格,并将它们放回原位。如果您要将单行拆分为多行,请注意不要覆盖任何内容。
如果您想允许从插入或替换模式重新格式化文本,则必须非常小心,因为该函数可能会递归调用。为了调试,设置'debug'选项会有所帮助。
右对齐
Vim中没有命令可以右对齐文本。您可以使用外部命令来实现,例如“par”(例如:“!}par”格式化为段落结束)或将'formatprg'设置为“par”。
格式化注释
用户手册的30.6节概述了注释格式化。
Vim可以以特殊方式自动插入和格式化注释。Vim通过行首的特定字符串(忽略空格)来识别注释。可以使用三种类型的注释
在每行开头重复的注释字符串。例如,在shell脚本中使用的注释类型,以“#”开头。
仅出现在第一行,而不会出现在后续行中的注释字符串。例如,这个带有破折号的列表。
具有开始字符串、结束字符串和可选的中间行的三部分注释。开始、中间和结束的字符串是不同的。例如,C风格的注释
/*
 * this is a C comment
 */
'comments'选项是一个逗号分隔的列表,其中包含各个部分。每个部分定义了一种类型的注释字符串。一个部分由以下内容组成:{flags}:{string}
{string}是要出现的文字文本。
{flags}: n 嵌套注释。允许与混合部分嵌套。如果'comments'为“n:),n:>”,则以“> ) >”开头的行是注释。
b 在{string}之后需要空格(<Space><Tab><EOL>)。
f 只有第一行包含注释字符串。不要在下一行重复注释,但保留缩进(例如,项目符号列表)。
s 三部分注释的开始
m 三部分注释的中间
e 三部分注释的结束
l 左对齐。与's'或'e'一起使用时,开始或结束的最左侧字符将与中间的最左侧字符对齐。这是默认值,可以省略。有关更多详细信息,请参见下文。
r 右对齐。与上述相同,但最右侧而不是最左侧。有关更多详细信息,请参见下文。
O 不要将此注释考虑在“O”命令中。
x 允许在中间注释字符串已自动插入的情况下,仅通过在新的行上键入结束注释字符串的最后一个字符作为第一个操作来结束三部分注释。有关更多详细信息,请参见下文。
{digits} 当与 's' 或 'e' 一起使用时:向自动插入的中间或结束注释引导添加{digit}数量的偏移量。偏移量从左对齐开始。有关更多详细信息,请参见下文。
-{digits} 类似于{digits},但减少缩进。这仅在开始或结束部分存在可以删除的缩进时才有效。
当字符串没有任何 'f'、's'、'm' 或 'e' 标志时,Vim 假设注释字符串在每行的开头重复。标志字段可以为空。
{string}前后文本中的任何空格都是{string}的一部分,因此不要包含前导或尾随空格,除非空格是注释字符串的必需部分。
当一个注释引导是另一个注释引导的一部分时,指定整个注释引导之后的那个部分。例如,要包含“-”和“->”,请使用
:set comments=f:->,f:-
三部分注释必须始终以开始、中间、结束的顺序给出,中间没有其他部分。三部分注释的示例是
sr:/*,mb:*,ex:*/
用于 C 注释。为了避免将“*ptr”识别为注释,中间字符串包括 'b' 标志。对于三部分注释,Vim 检查开始和中间字符串之后的文本,以查找结束字符串。如果 Vim 找到结束字符串,则注释不会在下一行继续。三部分注释必须具有中间字符串,因为否则 Vim 无法识别中间行。
请注意,在上面的三部分注释定义中使用“x”标志。当您在 C 注释中按回车键时,Vim 将为新行插入中间注释引导:“ * ”。要关闭此注释,您只需在新行键入任何内容之前键入“/”。这将用结束注释引导替换中间注释引导,并应用任何指定的对齐方式,只留下" */"。无需先按退格键。
当匹配到中间部分,但同时还匹配到更长的结束部分时,将使用结束部分。这使得 C 样式注释无需要求中间部分以空格结尾就能正常工作。
以下是对齐标志起作用以使注释脱颖而出的示例(有点像 1)。考虑注释字符串
:set comments=sr:/***,m:**,ex-2:******/
                                  /*** ~
                                    **<--right aligned from "r" flag ~
                                    ** ~
offset 2 spaces for the "-2" flag-->** ~
                                  ******/ ~
在这种情况下,第一个注释被键入,然后回车键被按下 4 次,然后按下“/”键结束注释。
以下是一些关于三部分注释的更细致的说明。在以下三种情况下,将考虑对齐和偏移标志:在开始注释后打开新行、在结束注释之前打开新行以及自动结束三部分注释。结束对齐标志具有反向视角;结果是,与“s”和“e”一起使用的相同对齐标志将导致开始和结束部分的缩进相同。每个注释部分仅打算使用一次对齐,但偏移数字将覆盖“r”和“l”标志。
启用'cindent'将在许多情况下覆盖对齐标志。使用不同的方法(如gq=)重新缩进也不咨询对齐标志。相同的行为可以在其他格式化选项中定义。一个考虑因素是,'cindent'具有用于基于上下文的注释缩进的附加选项,但不能复制许多三部分缩进对齐方式。但是,'indentexpr'能够更好地与三部分注释协同工作。
其他示例
"b:*"        Includes lines starting with "*", but not if the "*" is
             followed by a non-blank.  This avoids a pointer dereference
             like "*str" to be recognized as a comment.
"n:>"        Includes a line starting with ">", ">>", ">>>", etc.
"fb:-"        Format a list that starts with "- ".
默认情况下,会包含“b:#”。这意味着以“#include”开头的行不会被识别为注释行。但是以“# define”开头的行会被识别。这是一个折衷方案。
fo-table
您可以使用'formatoptions'选项来影响Vim格式化文本的方式。 'formatoptions'是一个字符串,可以包含以下任何字母。您可以用逗号分隔选项字母,以提高可读性。
字母 在'formatoptions'中存在时的含义
fo-t
t 使用'textwidth'自动换行文本 fo-c
c 使用'textwidth'自动换行注释,自动插入当前注释引导。 fo-r
r 在插入模式下按<Enter>键后,自动插入当前注释引导。 fo-o
o 在正常模式下按“o”或“O”键后,自动插入当前注释引导。如果在特定位置不需要注释,请使用CTRL-U快速删除它。 i_CTRL-U fo-/
/ 当包含 'o' 时:不要在语句之后插入 // 注释的注释引导,只有当 // 位于行首时才插入。 fo-q
q 允许使用“gq”格式化注释。请注意,格式化不会更改空行或仅包含注释引导的行。段落以这样的行结束,或者以注释引导更改结束。 fo-w
w 尾随空格表示段落在下一行继续。以非空格字符结尾的行结束段落。 fo-a
a 自动格式化段落。每次插入或删除文本时,都会重新格式化段落。参见auto-format。当存在 'c' 标志时,这仅适用于识别的注释。 fo-n
n 格式化文本时,识别编号列表。这实际上使用'formatlistpat'选项,因此可以使用任何类型的列表。数字后面的文本缩进用于下一行。默认情况下,查找一个数字,后面可以选择是“.”、“:”、“)”、“]”或“}”。请注意,'autoindent'也必须设置。与“2”一起使用效果不好。例如
1. the first item
   wraps
2. the second item
fo-2
2 格式化文本时,使用段落第二行的缩进作为段落的其余部分的缩进,而不是使用第一行的缩进。这支持段落中第一行的缩进与其余部分不同的情况。请注意,'autoindent'也必须设置。例如
        first line of a paragraph
second line of the same paragraph
third line.
这也适用于注释内部,忽略注释引导。 fo-v
v 与 Vi 兼容的插入模式下的自动换行:仅在您在当前插入命令期间输入的空格处换行。(注意:这与 Vi 不完全兼容。Vi 在这方面有一些“意外功能”或错误。它使用屏幕列而不是行列。) fo-b
b 类似于 'v',但只有当您在换行边距处或之前输入空格时才自动换行。如果该行在您开始插入时长度超过了'textwidth',或者您在插入期间没有在到达'textwidth'之前输入空格,则 Vim 不会执行自动换行。 fo-l
l 长行在插入模式下不会断开:当一行在插入命令开始时长度超过了'textwidth'时,Vim 不会自动格式化它。 fo-m
m 此外,在超过 255 的多字节字符处断行。这对每个字符都是一个独立词语的亚洲文字很有用。 fo-M
M 在连接行时,不要在多字节字符前后插入空格。覆盖 'B' 标志。 fo-B
B 在连接行时,不要在两个多字节字符之间插入空格。被 'M' 标志覆盖。 fo-1
1 不要在一字词后面断行。而是(如果可能)在它前面断行。 fo-]
] 严格遵守 'textwidth'。设置此标志后,除非换行禁止规则使之不可能,否则任何一行都不得超过 'textwidth'。主要用于 CJK 文字,仅当 'encoding' 为 "utf-8" 时有效。 fo-j
j 在有意义的地方,在连接行时删除注释前缀。例如,连接
int i; // the index
// in the list
变为
int i; // the index in the list
fo-p
p 不要在句点后面的单个空格处断行。这旨在与 'joinspaces'cpo-J 互补,用于句子之间用两个空格隔开的散文。例如,当 'textwidth' 设置为 28 时
Surely you're joking, Mr. Feynman!
变为
Surely you're joking,
Mr. Feynman!
而不是
Surely you're joking, Mr.
Feynman!
使用 't' 和 'c' 可以指定 Vim 何时执行自动换行
值 操作
"" 无自动格式化(您可以使用 "gq" 进行手动格式化) "t" 对文本进行自动格式化,但不对注释进行格式化 "c" 对注释进行自动格式化,但不对文本进行格式化(适合 C 代码) "tc" 对文本和注释进行自动格式化
请注意,当 'textwidth' 为 0 时,Vim 不会执行任何自动格式化(但会根据 'comments' 选项插入注释前缀)。例外情况是当 'a' 标志存在时。 auto-format
请注意,即使 Vim 从未执行自动换行,'textwidth' 也可以是非零值;'textwidth' 仍然对使用 "gq" 进行格式化有用。
如果 'comments' 选项包含 "/*", "*" 和/或 "*/",则 Vim 会内置一些东西来更智能地处理这些类型的注释。在 "/*" 或 "*/" 前后打开新行(在 'formatoptions' 中存在 'r' 或 'o')会自动给出正确的行首。格式化和自动换行也会发生这种情况。在以 "/*" 或 "*" 开头并包含 "*/" 的行后打开一行,将不会插入注释前缀,新行的缩进将从包含注释起点的行中获取。例如
/*
 * Your typical comment.
 */
The indent on this line is the same as the start of the above
comment.
所有这些都应该非常酷,特别是在与新的 :autocmd 命令结合使用时,该命令可以为不同类型的文件准备不同的设置。
一些例子:对于 C 代码(只格式化注释)
:set fo=croq
对于邮件/新闻(格式化所有内容,不要用 "o" 命令开始注释)
:set fo=tcrq
自动格式化 auto-format autoformat
'formatoptions' 中存在 'a' 标志时,在插入文本或删除文本时会自动格式化文本。这对于编辑文本段落很有用。关于如何使用它的几个提示
您需要正确定义段落。最简单的是用空行分隔的段落。当没有分隔空行时,请考虑使用 'w' 标志并在除最后一个段落以外的每个段落末尾添加空格。
您可以根据文件类型 filetype 设置 'formatoptions',或者使用 modeline 特定地为一个文件设置 'formatoptions'
'formatoptions' 设置为 "aw2tq" 以使文本具有如下缩进
bla bla foobar bla bla foobar bla foobar bla bla bla foobar bla bla foobar bla bla foobar
添加 'c' 标志以仅自动格式化注释。在源代码中很有用。
'textwidth' 设置为所需的宽度。如果为零,则使用 79,或者如果屏幕宽度更小,则使用屏幕宽度。
还有一些警告
当文本的一部分未正确地分隔成段落时,对该文本进行更改会导致对其进行格式化。考虑执行以下操作
:set fo-=a
当使用 'w' 标志(尾随空格表示段落继续)并使用 dd 删除段落的最后一行时,该段落将与下一段落合并。
已更改的文本将被保存以供撤消。格式化也是一种更改。因此,每个格式化操作都将保存文本以供撤消。这可能会消耗相当多的内存。
格式化长段落和/或包含复杂缩进的段落可能很慢。

7. 排序文本 sorting

Vim 有一个排序函数和一个排序命令。排序函数可以在此处找到:sort()uniq()
:sor :sort :[range]sor[t][!] [b][f][i][l][n][o][r][u][x] [/{pattern}/] 对 [range] 中的行进行排序。如果没有指定范围,则对所有行进行排序。
使用 [!] 将反转顺序。
使用 [i] 忽略大小写。
使用 [l] 排序将使用当前的整理区域设置。实现细节:使用 strcoll() 来比较字符串。请参阅 :language 以检查或设置整理区域设置。示例
:language collate en_US.UTF-8
:%sort l
v:collate 也可以用来检查当前的区域设置。使用区域设置进行排序通常会忽略大小写。这在 Mac 上无法正常工作。
选项 [n][f][x][o][b] 是互斥的。
使用 [n] 排序将在行中第一个十进制数(在 {pattern} 匹配之后或内部)上进行。包括一个前导 '-'。
使用 [f] 排序将在行中的浮点数上进行。浮点数的值与将文本(在 {pattern} 匹配之后或内部)传递给 str2float() 函数类似。
使用 [x] 排序将在行中第一个十六进制数(在 {pattern} 匹配之后或内部)上进行。将忽略前导 "0x" 或 "0X"。包括一个前导 '-'。
使用 [o] 排序将在行中第一个八进制数(在 {pattern} 匹配之后或内部)上进行。
使用 [b] 排序将在行中第一个二进制数(在 {pattern} 匹配之后或内部)上进行。
使用 [u](u 代表唯一)只保留一组相同行中的第一个(在使用 [i] 时忽略大小写)。如果没有此标志,一组相同的行将按其原始顺序保留。请注意,前导和尾随空格可能会导致行不同。
当指定 /{pattern}/ 且没有 [r] 标志时,将跳过与 {pattern} 匹配的文本,以便对匹配后的内容进行排序。 'ignorecase' 应用于模式,但 'smartcase' 不使用。可以将斜杠替换为任何非字母字符。例如,要根据第二个逗号分隔的字段排序
:sort /[^,]*,/
要根据虚拟列 10 处的文本进行排序(因此忽略制表符和空格之间的差异)
:sort /.*\%10v/
要根据行中的第一个数字进行排序,无论其前面是什么
:sort /.\{-}\ze\d/
(解释:".\{-}" 匹配任何文本,"\ze" 设置匹配的结束位置,\d 匹配数字。)使用 [r] 将根据匹配的 {pattern} 进行排序,而不是像上面描述的那样跳过它。例如,要根据每行的前三个字母进行排序
:sort /\a\a\a/ r
如果使用 {pattern},任何没有与 {pattern} 匹配的行都将保留其当前顺序,但与与 {pattern} 匹配的行分开。如果按反向顺序排序,它们将在排序后的行之后按反向顺序排列,否则它们将按其原始顺序排列,在排序后的行之前。
如果 {pattern} 为空(例如指定 //),则将使用最后一个搜索模式。这允许您先尝试一个模式。
请注意,将 :sort:global 一起使用不会对匹配的行进行排序,这毫无用处。
:sort 不会使用当前的区域设置,除非使用 l 标志。Vim 确实执行了“稳定”排序。
排序可以被打断,但是如果您在排序过程中过晚地中断它,您可能会得到重复的行。这也取决于使用的系统库函数。
主要
命令索引
快速参考