["x]<Del>
或 <Del> x dl
["x]x 删除 [count]
个光标之下和之后的字符 [到寄存器 x 里]
(非 linewise 行动作)。和 "dl" 相同。
<Del>
键不使用 [count]
计数。相反,如果有计数,它删
除该计数的最后一位。
如果 <Del>
键的操作与你预期的不符,参见 :fixdel 。关
于如何删除换行符 (连接行),参见 'whichwrap' 。
X dh
["x]X 删除 [count]
个光标之前的字符 [到寄存器 x 里] (非
linewise 行动作)。和 "dh" 相同。另见 'whichwrap' 。
d
["x]d{motion}
删除 {motion}
动作跨越的文本 [到寄存器 x 里]。例外见
下。
dd
["x]dd 删除 [count]
行 [到寄存器 x 里], linewise 行动作。
D
["x]D 删除光标所在的字符到行尾及其后的 [count]
-1 行 [到寄
存器 x 里] (非 linewise 行动作)。和 "d$" 同义。
如果 'cpoptions' 里有 '#' 标志位,忽略计数。
{Visual}
["x]x 或 v_x v_d v_<Del>
{Visual}
["x]d 或
{Visual}
["x]<Del>
删除高亮文本 [到寄存器 x 里] (关于 {Visual}
见
Visual-mode )。
{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}
见
Visual-mode )。在可视列块模式里,"D" 删除高亮的文本直
到行尾。
:d :de :del :delete :dl :dp
:[range]
d[elete] [x]
删除 [range]
范围的行 (缺省: 当前行) [到寄存器 x 里]。
注意
这些奇异的缩写:
:dl 删除并列出 (list)
:dell 同上
:delel 同上
:deletl 同上
:deletel 同上
:dp 删除并显示 (print)
:dep 同上
:delp 同上
:delep 同上
:deletp 同上
:deletep 同上
:[range]
d[elete] [x]
{count}
从 [range]
指定的范围开始,删除 {count}
行 (缺省: 当前
行 cmdline-ranges ) [到寄存器 x 里]。
这些命令删除文本。你可以用 . 命令重复它们 (除了 :d ),也可以撤销它们。用可
视模式可以删除文本列块。关于寄存器的解释,参见 registers 。
d{motion}
命令的一个特例: 如果动作不面向行,动作的开始和结束处不在同一行,开始
位置之前只有空白,并且结束位置之后没有非空白的话,该删除会转为行动作。这意味着
删除命令可能删除你还想保留的空白行。 o_v 操作符强制该动作面向字符。
如果 'cpoptions' 包括 'E' 标志位,删除文本里的空区域 (例如,在首列上 "d0") 会
报错。
J
J 连接 [count]
行,但至少包含两行。删除缩进,插入不多于
两个的空格 (见下)。在缓冲区末行此操作会失败。[count]
如果过多,会自行缩减至余下可用的行。
v_J
{Visual}
J 连接高亮行,但至少包含两行。删除缩进,插入不多于两个的
空格 (见下)。
gJ
gJ 连接 [count]
行,但至少包含两行。不插入或删除任何空
格。
v_gJ
{Visual}
gJ 连接高亮行,但至少包含两行。不插入或删除任何空格。
:j :join
[range]
j[oin][!] [flags]
连接 [range]
范围的行。和 "J" 相同,但如有 [!] 时,连
接不插入或删除任何空格。如果 [range]
包括相同的开始和
结束行,该命令不做任何事。缺省行为是连接当前行与下一
行。
[flags]
部分可参见 ex-flags 。
:[range]
j[oin][!] {count}
[flags]
连接 [range]
开始的 {count}
行 (缺省: 当前行
cmdline-ranges )。和 "J" 相同,但如有 [!] 时,连接不
插入或删除任何空格。
[flags]
部分可参见 ex-flags 。
这些命令删除行间的 <EOL>
,即换行符,从而实际上使多行连接成一行。除了 :j 之
外,你可以重复这些命令或者撤销之。
这些命令,除了 "gJ" 以外,插入一个空格以代替 <EOL>
,除非当前行的结尾已经有空白
或者下一行以 ')' 开始。这些命令,除了 "gJ" 之外,也删除下一行所有开头的空白。
如果 'joinspaces' 选项打开,这些命令在 '.'、'!' 或者 '?' 之后插入两个空格 (但
如果 'cpoptions' 包括 'j' 标志位,只有在 '.' 之后插入两个空格)。
'formatoptions' 里的 'B' 和 'M' 标志位改变在多字节字符之前或者之后插入空格的行
为 fo-table 。
'[ 标记指向被连接的首行之原行尾处,'] 则指向合并后的行尾。
R
R 进入替换模式: 每个输入的字符替代一个现有的字符,从光标
所在的位置开始。重复输入的文本 [count]
- 1 次。参见
Replace-mode 以了解相关详情。
gR
gR 进入虚拟替换模式: 每个输入的字符替代屏幕位置一个现有的
字符。因而,一个 <Tab>
可以一次替换若干个字符。重复输
入的文本 [count]
-1 次。参见 Virtual-Replace-mode 以
了解相关详情。
c
["x]c{motion}
将 {motion}
跨过的文本删除 [到寄存器 x 里] 并开始插
入。如果 'cpoptions' 包括 'E' 标志位并且没有任何文本实
际需要删除时 (例如,"cTx" 而光标刚在 'x' 之后的时候),
报错并拒绝开始插入模式 (这与 Vi 兼容)。如果
'cpoptions' 没有 'E',"c" 命令总是启动插入模式,即使没
有文本要删除也是如此。
cc
["x]cc 删除 [count]
行 [到寄存器 x 里] 并开始插入。
linewise 行动作。如果置位 'autoindent',保留首行的缩
进。
C
["x]C 从当前光标位置删除到行尾,再删除 [count]
-1 行 [到寄存
器 x 里],并开始插入。和 c$ 等价 (非 linewise 行动
作)。
s
["x]s 删除 [count]
个字符 [到寄存器 x 里],并开始插入。(s 代
表替代 (Substitute))。和 "cl" 等价 (非 linewise 行动
作)。
S
["x]S 删除 [count]
行 [到寄存器 x 里] 并开始插入。和 "cc" 等
价 linewise 行动作。
{Visual}
["x]c or v_c v_s
{Visual}
["x]s 删除高亮文本 [到寄存器 x 里],并开始插入 (关于
{Visual}
参见 Visual-mode )。
v_r
{Visual}
r{char}
把所有高亮的字符替换成 {char}
。
v_C
{Visual}
["x]C 删除高亮行 [到寄存器 x 里] 并开始插入。在可视列块模式
下有所不同 v_b_C 。
v_S
{Visual}
["x]S 删除高亮行 [到寄存器 x 里] 并开始插入 (关于 {Visual}
参见 Visual-mode )。
v_R
{Visual}
["x]R 现在和 {Visual}
["x]S 相同。以后的版本可能会有所改变。
注意
:
- 你可以用 <Esc>
退出插入和替换模式。
- 参见 "插入和替换模式" 一节 mode-ins-repl 以了解其他这些模式下的特殊字符。
- [count]
的效果只有在 Vim 退出插入或替换模式时才会体现。
- 当 'cpoptions' 选项包含 '$' 并且所做的修改在一行之内,Vim 继续显示被删除的文
本,并在最后一个被删除的字符之后加上一个 '$'。
关于寄存器的解释,参见 registers 。
替换模式和插入模式类似,除了每输入一个字符同时删除一个字符以外。如果到达行尾,
Vim 把其后的字符插入在行尾 (和插入模式相同)。在替换模式下,退格键恢复原来的文
本 (如果有的话)。(参见 "插入和替换模式" 一节 mode-ins-repl )。
cw cW
特殊情况: 如果光标在单词内部,"cw" 和 "cW" 不包含单词后的空白而只修改到词尾。
这是因为 Vim 把 "cw" 解释为 修改-单词,而单词并不包括其后的空白。
{Vi: 在其后还有空白的空白字符上 "cw" 只修改第一个空白;这也许是一个漏洞,因为
"dw" 删除所有空白;用 'cpoptions' 里的 'w' 标志位来设置类似于 Vi 的工作方式}
如果你希望 "cw" 包括单词之后的空格,使用如下的映射:
:map cw dwi
或者,用 "caw" (见 aw )。
:c :ch :change
:{range}
c[hange][!] 用另外的文本替换若干文本行。输入只包含 "." 的行结束替
换。如果没有 {range}
,该命令只置换当前行。
加上 [!] 后,在本命令的执行期间切换 'autoindent'。
此命令在 Vim9 脚本里不支持,因为它太容易和变量名混淆
了。
r
r{char}
把光标下的字符换成 {char}
。如果 {char}
是 <CR>
或者
<NL>
,则把该字符变成换行符。要换成一个真正的 <CR>
,使
用 CTRL-V
<CR>
。CTRL-V
<NL>
则换成 <Nul>
。
若 {char}
为 CTRL-E
或 CTRL-Y
,使用下一行或上一行的
字符来代替,就像 i_CTRL-E 和 i_CTRL-Y 一样。这里
计数也适用,所以 10r<C-E>
从下一行复制 10 个字符。
如果你给出 [count]
,Vim 替换 [count]
个字符为 [count]
个 {char}
。不过如果 {char}
为 <CR>
或者 <NL>
,Vim 只插
入一个换行符: "5r<CR>
" 替换五个字符为一个换行符。
当 {char}
为 <CR>
或者 <NL>
,Vim 会自动缩进。这和先执
行删除要替换的字符再执行 "i<CR>
<Esc>
" 类似。
{char}
可以输入二合字母 digraph-arg 。
:lmap 映射会应用在 {char}
上。插入模式下的 CTRL-^
命
令可以切换这一功能 i_CTRL-^ 。
参见 utf-8-char-arg 以了解在 'encoding' 为 Unicode
编码时如果使用组合字符。
gr
gr{char}
替换光标下的虚拟字符。替换发生在屏幕位置而不是文件位置
上。参见 gR 和 Virtual-Replace-mode 以了解相关详
情。和 r 一样,可以使用计数。{char}
输入的方式也相
同。
digraph-arg
普通模式下的命令,像 r 和 t ,需要一个单字符的参数。如果 'cpo' 不包含 'D'
标志位,该字符可以用 digraphs 那样的方式输入: 先键入 CTRL-K
然后输入二合字母
的两个字符 {仅当编译时加入 +digraphs 特性有效}
。
case
下面的命令根据当前的 locale 改变字母的大小写。参见 :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}
用 Rot13 对 {motion}
跨越的文本进行编码。
v_g?
{Visual}
g? 用 Rot13 对高亮文本进行编码 (关于 {Visual}
见
Visual-mode )。
g?g? g?g? g??
g?? 用 Rot13 对当前行进行编码。
要以标题大写 (title cap) 方式改写一行,亦即使每个单词的首字母大写:
: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.",可视地选择后三行,按 g CTRL-A
会生
生成:
1.
2.
3.
4.
CTRL-X
CTRL-X
把当前光标之上或之后的数值或者字母减去 [count]
。
v_CTRL-X
{Visual}
CTRL-X
给高亮文本内的数值或者字母减去 [count]
。
MS-Windows 上,此键被映射到剪切可视文本
dos-standard-mappings 。要屏蔽该映射,可用:
silent! vunmap <C-X>
v_g_CTRL-X
{Visual}
g CTRL-X
给高亮文本内的数值或者字母减去 [count]
。如果高亮超过一
行,每行会减去额外的 [count]
(即生成 [count]
为增量的
递减数列)。
CTRL-A
和 CTRL-X
命令可用于:
- 带符号或无符号十进制数
- 无符号二进制、八进制和十六进制数
- 字母
这取决于 'nrformats' 选项:
- 当 'nrformats' 包括 "bin" 时,Vim 假设 '0b' 或 '0B' 开始的数值为二进制。
- 当 'nrformats' 包括 "octal" 时,Vim 假设 '0' 开始的数值为八进制,除非该数值
里包含 '8' 或 '9'。其他的数值为十进制,并可以在开始带一个可选的负号。
如果光标已经在数值上,命令应用于该数值;否则,应用于光标右侧的数值。
- 当 'nrformats' 包括 "alpha" 时,Vim 会改变光标之上或之后的字母。这可用于构造
字母编号的列表。
- 当 'nrformats' 包括 "hex" 时,Vim 假设 '0x' 或者 '0X' 开始的数值为十六进制。
这个数值最右端的字母决定所产生十六进制数值的大小写。如果当前数值没有字母,
Vim 使用上一次检测到的大小写。
增减操作会考虑十进制开始的负号。二进制、八进制和十六进制值则不会。要忽略正负
号,可视地选择数值本身。然后再应用 CTRL-A
或 CTRL-X
。
对零开头的数值 (包括八进制和十六进制的),Vim 尽可能保留相同数量的字符。CTRL-A
在 "0077" 上产生 "0100",CTRL-X
在 "0x100" 上产生 "0x0ff"。
有一个例外: 在发现某数值以零开始但不是八进制 (包含 '8' 或 '9'),而 'nrformats'
却包含 "octal" 的时候,引导的零会被删除,以免结果被误认为八进制。
注意
如果 'nrformats' 包括 "octal",开头有零的十进制数会产生错误,因为会和八进
制数产生混淆。
同样类似的要 注意
,如果 'nrformats' 包括 "bin",开头有 '0x' 或 '0X' 的二进制数
被认作十六进制,因为 '0b' 是合法的十六进制数字。
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' 列。
如果打开 'vartabstop' 特性且 'shiftwidth' 选项设为零,
缩进量在行中首个非空白字符处计算。
<<
<< 将 [count]
行左移 'shiftwidth' 列。
v_<
{Visual}
[count]
< 将高亮行左移 [count]
个 'shiftwidth' 列 (关于 {Visual}
见 Visual-mode )。
>
>{motion}
将 {motion}
跨越的多行右移 'shiftwidth' 列。
如果打开 'vartabstop' 特性且 'shiftwidth' 选项设为零,
缩进量在行中首个非空白字符处计算。
>>
>> 将 [count]
行右移 'shiftwidth' 列。
v_>
{Visual}
[count]
> 将高亮行右移 [count]
个 'shiftwidth' 列 (关于 {Visual}
见 Visual-mode )。
:<
:[range]
< 将 [range]
指定的多行左移 'shiftwidth' 列。多个 '<' 左
移多个 'shiftwidth' 列。
:[range]
< {count}
左移 [range]
开始的 {count}
行 'shiftwidth' 列 (缺省从
当前行 cmdline-ranges )。多个 '<' 左移多个
'shiftwidth' 列。
:[range]
le[ft] [indent]
左对齐 [range]
指定的多行。设置缩进距离为 [indent]
(缺
省为 0)。
:>
:[range]
> [flags]
将 [range]
指定的多行右移 'shiftwidth' 列。多个 '>' 右
移多个 'shiftwidth' 列。
[flags]
部分可参见 ex-flags 。
:[range]
> {count}
[flags]
右移 [range]
开始的 {count}
行 'shiftwidth' 列 (缺省从
当前行 cmdline-ranges 开始)。多个 '>' 右移多个
'shiftwidth' 列。
[flags]
部分可参见 ex-flags 。
">" 和 "<" 命令可以用来方便地调整程序的缩进。使用 'shiftwidth' 选项设置这些命
令增加或者减少的空白的数量。通常,'shiftwidth' 选项是 8,但你也可以设置为,比
如说,3,使得缩进更小些。如果已经没有缩进,左移命令会停止。另一方面,右移命令
则不会影响空白行。
如果打开 'shiftround' 选项,缩进距离被取整到 'shiftwidth' 的倍数。
如果打开 'smartindent' 选项,或者打开 'cindent' 并且 'cinkeys' 包含带零值的
'#',右移不影响 '#' 开始的行 (这些应该是 C 预处理行,它们应该保持在第一列)。
用 'cino' 选项可改变此行为,参见 cino-# 。
如果 'expandtab' 选项关闭 (这是缺省值), Vim 尽可能使用 <Tab>
来构成缩进。你可
以用 ">><<" 来把缩进尽可能从空格替换成同样缩进距离的 <Tab>
(如有需要,还有少量
的空格)。如果 'expandtab' 选项打开,Vim 只使用空格。这样你可以使用 ">><<" 把
<Tab>
替换成空格 (或者可以用 :retab! )。
要移动一行多个 'shiftwidth' 列,使用可视模式或者 : 命令。例如:
Vjj4> 右移三行四个缩进位
:<<< 左移当前行三个缩进位
:>> 5 右移五行两个缩进位
:5>> 右移第五行两个缩进位
4.1 过滤命令 filter
过滤程序是一个接受文本作为标准输入,作某些修改,并把结果放到标准输出的程序。你
可以用下面的命令把若干文本发送给过滤程序,然后用过滤的输出结果替换。一个过滤程
序的例子是 "sort",按字母顺序给行排序;还有 "indent",排版 C 程序文件 (你需要
一个能以过滤程序方式工作的版本,并非所有的版本都可以)。'shell' 选项指定 Vim 使
用的外壳程序,用以执行过滤程序 (另见 'shelltype' 选项)。你可以用 "." 重复过滤
命令。Vim 不会识别 :! 命令之后的注释 (用 '"' 开始)。
!
!{motion}
{filter}
用外部程序 {filter}
过滤 {motion}
跨越的多行。
!!
!!{filter}
用外部程序 {filter}
过滤 [count]
行。
v_!
{Visual}
!{filter}
用外部程序 {filter}
过滤高亮行。(关于 {Visual}
见
Visual-mode )。
:{range}
![!]{filter}
[!][arg]
:range!
用外部程序 {filter}
过滤 {range}
指定的多行。Vim 把可
选的感叹号替换成最后一次使用的命令,并附加上可选的参数
[arg]
。Vim 把过滤命令的输出保存到临时文件,并把文件内
容读到一个缓冲区里 tempfile 。Vim 使用 'shellredir'
选项把过滤程序的结果重定向到临时文件。
不过,如果关闭了 'shelltemp' 选项且可以的话,使用管道
机制 (Unix 上)。
如果 'cpoptions' 包含 'R' 标志位,过滤行里的位置标记被
删除,除非使用了 :keepmarks 命令。例如:
:keepmarks '<,'>!sort
如果过滤后的行数变少,删去的行里的位置标记无论如何不会
保存。
=
={motion}
用 'equalprg' 选项指定的外部程序过滤 {motion}
跨越的多
行。如果 'equalprg' 选项为空 (缺省),使用内部的排版机
制 C-indenting 和 'lisp' ,除非 'indentexpr' 非空,
此时使用 indent-expression 机制来代替。反之,如果
Vim 编译时没有包含内部排版机制,最后手段是使用外部的
"indent" 程序。
==
== 和 ={motion}
类似,过滤 [count]
行。
v_=
{Visual}
= 和 ={motion}
类似,过滤高亮行。
tempfile setuid
Vim 使用临时文件来处理过滤、执行比较和用于 tempname()。Unix 上,该文件会放在一
个私人的目录里 (只能被当前用户访问),以防堵安全上的漏洞 (例如,符号链接攻击或
文件被其他用户读取等)。Vim 退出时,自动删除该目录及之下的所有文件。如果 Vim 本
身设置了 setuid 位,这样或许会有问题。临时文件由 setuid 用户拥有,但过滤程序以
原来用户的权限执行。
在以下目录首个可用者建立存放临时文件的目录:
Unix: $TMPDIR、/tmp、当前目录、$HOME。
Windows: $TMP、$TEMP、c:\TMP、c:\TEMP
MS-Windows 上,使用 GetTempFileName() 系统函数。
其它系统上使用 tmpnam() 库函数。
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
[count]
必须为正数。另见 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]
:~
使用最后一次 :substitute 相同的替代字符串,但使用最近
使用的搜索模式作为匹配模式。这类似于 :&r
。
关于 [flags]
,参见 :s_flags 。
&
& 同 :s (重复上次的 substitute)。注意
这里不记住标志
位,所以实际工作方式可能不尽相同。你可以用 :&&
来保
持相同的标志位。
g&
g& 同 :%s//~/&
(在所有行上重复上次的 substitute 并使用
相同的标志位,但使用前次的匹配模式)。
例如,如果先用了替代 :s/pattern/repl/flags
然后
/search
搜索了其他模式, g&
会执行
:%s/search/repl/flags
。
助记: 全局 (global) 替代 (substitute)。
:snomagic :sno
:[range]
sno[magic] ... 同 :substitute ,但总使用 'nomagic'。
:smagic :sm
:[range]
sm[agic] ... 同 :substitute ,但总使用 'magic'。
:s_flags
你可以在 substitute 命令里使用以下标志位:
:&&
[&] 必须是首个使用的标志位: 保留和前次 substitute 相同的标志位。例如:
:&&
:s/this/that/&
注意
:s 和 :&
不保留标志位。
[c] 确认每个替代。Vim 高亮匹配的字符串 (如果使用了 hl-IncSearch )。你可以
输入: :s_c
'y' 来替代这次匹配
'l' 来替代这次匹配并退出 (助记: "last",最后)
'n' 来跳过这次匹配
<Esc>
来退出替代过程
'a' 来替代这次和以后所有的匹配
'q' 来退出替代过程
CTRL-E
来上卷屏幕
CTRL-Y
来下卷屏幕
如果 'edcompatible' 选项打开,Vim 记住 [c]
标志位并在每次使用它时切换
是否确认,但在给出一个新的匹配模式时复位。
:s_e
[e] 如果模式搜索不成功,不给出错误信息。因为没产生错误,映射的过程得以继
续。这主要用来防止在映射执行过程的无匹配 ("No match") 错误中断映射。
不过,Vim 不会抑制以下的错误信息:
Regular expressions can't be delimited by letters (正则表达式
不能以字母分隔)
\ should be followed by /, ? or & (\ 必须后面跟 /、? 或者 &)
No previous substitute regular expression (没有上次的替代正则
表达式)
Trailing characters (结尾有多余的字符)
Interrupted (中断)
:s_g
[g] 对行内所有的匹配进行替代。如果没有这个参数,替代只对每行的首个匹配进
行。如果 'edcompatible' 选项打开,Vim 记住这个标志并在你每次使用该标志
时切换,但在给出一个新的匹配模式时复位。如果 '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
和 :~ 工作的方式相同: 如果
匹配模式为空,使用上一次使用的搜索模式,而不是上一次的 substitute 或者
:global 所使用的模式。如果最近一次使用搜索的命令就是 substitute 或者
:global ,那就没有区别了。如果最近的命令的是 "/" 那样的搜索命令,使用
那个命令的搜索模式。
带参数的 :s ,则不论如何,总是如此:
:s/blue/red/
/green
:s//red/ 或 :~ 或 :&r
最后的命令把 "green" 替代成 "red"。
:s/blue/red/
/green
:&
最后的命令把 "blue" 替代成 "red"。
注意
这里没有标志位可以改变模式的 "魔术性" (magicness)。你可以用别的命令或
/\v 之类。原因是标志位只能在跳过模式之后才能找到,而要跳过模式,必须先知道模
式的 "魔术性"。第二十二条军规!
如果 substitute 命令所用的 {pattern}
为空,该命令使用上次的 substitute 或者
:global 命令用过的模式。如果不存在,但有上次搜索模式,使用之。如果有 [r]
标
志位,该命令使用上次 substitute、 :global 或者搜索命令使用的模式。
如果 {string}
省略,替代命令假定它为空。这样就把匹配文本删除了。这时,
{pattern}
之后的分隔符也可省略。例如:
:%s/TESTING
删除所有行上的 "TESTING",但每行只删一个。
E1270
为了和 Vi 的兼容性,老式脚本有两个例外:
"\/{string}
/" 和 "\?{string}
?" 等同于 "//{string}
/r"。
"\&{string}
&" 等同于 "//{string}
/"。
pattern-delimiter E146 E1241 E1242
除了用 '/' 来包围模式和替代字符串之外,你可以使用其它的单字节字符,用于 '/' 是
搜索模式或替代字符串一部分的场合。例如:
:s+/+//+
除了字母、数字、'\'、'"' 或 '|' 之外,可用大部分的字符。Vim9 脚本里也不能用
'#',因为它被识别为注释的开始。
关于模式的定义,参见 pattern 。在可视列块模式下,如果模式中使用了 /\%V ,那
么替代只在列块内进行,否则它作用于整行。
sub-replace-special :s\=
{string}
以 "\=" 开始时,它被作为表达式来执行,参见 sub-replace-expression 。
你可以用此功能实现复杂替换,也可用来使用特殊字符。
替代最多可以递归 4 层。 E1290
否则,{string}
字符串里的字符有如下的特殊含义:
:s%
如果 {string}
等于 "%",且 'cpoptions' 选项包含 '/',重复使用上次替代命令的
{string}
,见 cpo-/
magic nomagic 动作
& \& 替代为完整的匹配 s/\&
\& & 替代为 &
\0 替代为完整的匹配 \0 s/\0
\1 替代为匹配的第一个 () 里面的内容 s/\1
\2 替代为匹配的第二个 () 里面的内容 s/\2
.. .. s/\3
\9 替代为匹配的第九个 () 里面的内容 s/\9
~ \~ 替代为前一个 substitute 的替代字符串 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>
把该行在此位置一分为二
(<CR>
以 CTRL-V
<Enter>
方式输入) s<CR>
\r 同上 s/\r
\<CR>
插入一个回车 (CTRL-M
)
(<CR>
以 CTRL-V
<Enter>
方式输入) s/\<CR>
\n 插入一个 <NL>
(文件里的 <NUL>
)
(此处并不是换行) s/\n
\b 插入一个 <BS>
s/\b
\t 插入一个 <Tab>
s/\t
\\ 插入单个反斜杠 s/\\
\x 其中 x 是上面没提到的任何一个字符:
保留作将来的扩展
这里的特殊含义也用于 substitute() 函数的第三个参数 {sub}
,除了若干例外:
- % 总是插入百分号,与 'cpoptions' 无关。
- 总是假定有魔术性,与 'magic' 无关。
- ~ 总是插入波浪符。
- <CR>
和 \r 插入回车 (CTRL-M
)。
- \<CR>
没有特殊意义,只是 \x 之一。
示例:
:s/a\|b/xxx\0xxx/g 修改 "a b" 为 "xxxaxxx xxxbxxx"
:s/\([abc]\)\([efg]\)/\2\1/g 修改 "af fa bg" 为 "fa fa gb"
:s/abcde/abc^Mde/ 修改 "abcde" 为 "abc"、"de" (两行)
:s/$/\^M/ 修改 "abcde" 为 "abcde^M"
:s/\w\+/\u\0/g 修改 "bla bla" 为 "Bla Bla"
:s/\w\+/\L\u\0/g 修改 "BLA bla" 为 "Bla Bla"
注意
: "\L\u" 可用于使单词的首个字母变大写。此行为和 Vi 以及旧版 Vim 不兼容,那
里 "\u" 会抵消 "\L"。"\U\l" 亦然。
注意
: 在以前的版本里,CTRL-V
以特殊的方式处理。因为和 Vi 不兼容,该功能已经被
去掉了,现在用反斜杠来替代。
命令 文本 结果
: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/ 修改 "aa ab x" 为 "ab x"
"\2" 对应 "\(a[a-d] \)"。第一次匹配 "aa ",第二次匹配 "ab "。
如果括号和 '|' 组合使用,如 \([ab]\)\|\([cd]\),两者有一个会不匹配,所以 \1 或
者 \2 会为空。例如:
:s/\([ab]\)\|\([cd]\)/\1x/g 修改 "a b c d" 为 "ax bx x x"
:sc :sce :scg :sci :scI :scl :scp :sg :sgc
:sge :sgi :sgI :sgl :sgn :sgp :sgr :sI :si
:sic :sIc :sie :sIe :sIg :sIl :sin :sIn :sIp
:sip :sIr :sir :sr :src :srg :sri :srI :srl
:srn :srp :substitute-repeat
2-字母和 3-字母的 :substitute 命令
这些命令重复之前的 :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/\=
当替代字符串以 "\=" 开始时,其余部分被解释为一个表达式。
除了 "<CR>
" 以外, sub-replace-special 提到的字符的特殊含义这里不适用。<NL>
字符被用作换行符,双引号字符串 "\n" 也可以。在 <NL>
之前加上反斜杠得到一个真正
的 <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 搜索与替代 search-replace
:pro :promptfind
:promptf[ind] [string]
弹出搜索对话框。如果给出 [string]
,它被用作初始的搜索
字符串。
{仅适用于 Win32、Motif 和 GTK GUI 环境}
:promptr :promptrepl
:promptr[epl] [string]
弹出搜索/替代对话框。如果给出 [string]
,它被用作初始的
搜索字符串。
{仅适用于 Win32、Motif 和 GTK GUI 环境}
4.4 改变制表 change-tabs
:ret :retab :retab!
:[range]
ret[ab][!] [new_tabstop]
把所有包含 <Tab>
的空白序列替代成由新的制表位
[new_tabstop]
确定的空白序列。如果你不指定新的制表位,
或者它为 0,Vim 使用原来的制表位 'tabstop'。
已有的 Tab 的宽度总是用 'tabstop' 的当前值来计算。
如果有 !,Vim 也在合适的时候,把只包含正常空格的字符串
换成 Tab。
如果置位了 'expandtab',Vim 把所有的 Tab 换成相当的空
格。
该命令把 'tabstop' 设为新值。如果按照缺省的情况,在全
文件上进行处理,视觉上应该不会有任何改变。
小心: 该命令修改 C 程序中的字符串里的任何 <Tab>
字符。
要避免这一点,用 "\t" (无论如何,应该养成这个好的习
惯)。
:retab! 也把空格序列换成 <Tab>
,这可能会使 printf()
引起混淆。
如果打开 +vartabs 特性,可用以逗号分隔的制表宽度的列
表来代替单个制表位。列表的每个值代表一个制表位的宽度。
末值除外,该值适用于其后所有的制表位。
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
quote
"{a-zA-Z0-9.%#:-"} 指定下次的删除、抽出和放置命令使用的寄存器
{a-zA-Z0-9.%#:-"} (大写字符使得删除和抽出命令附加到该
寄存器) ({.%#:}
只能用于放置命令)。
"{register}
指定下次的删除、抽出和放置命令使用的寄存器
{register}
。大写字符使得删除和抽出命令附加到该寄存器。
寄存器 "."、"%"、"#" 和 ":" 只能用于放置命令。
:reg :registers
:reg[isters] 显示所有编号和命名寄存器的类型和内容。但不列出用于
:redir 目的地的寄存器。
类型可以是以下之一:
"c" 用于 characterwise 文本
"l" 用于 linewise 文本
"b" 用于 blockwise-visual 文本
:reg[isters] {arg}
显示 {arg}
里提到的编号和命名寄存器的内容。例如:
:reg 1a
显示寄存器 '1' 和 'a'。{arg}
里可以用空格。
:di :display
:di[splay] [arg]
和 :registers 相同。
y yank
["x]y{motion}
抽出 {motion}
跨越的文本 [到寄存器 x]。如果没有字符被
抽出 (例如,在第一列执行 "y0") 并且 'cpoptions' 里包括
'E' 标志位,这是一个错误。
yy
["x]yy 抽出 [count]
行 [到寄存器 x] linewise 行动作。
Y
["x]Y 抽出 [count]
行 [到寄存器 x] (同 yy, linewise 行动
作)。如果你想要 "Y" 执行从光标到行尾的操作 (更合乎逻
辑,但是与 Vi 不兼容),用 ":map Y y$"。
zy
["x]zy{motion}
抽出 {motion}
跨越的文本 [到寄存器 x]。 和 y 的仅有
不同是在选择文本列块时,见 v_zy 。
v_y
{Visual}
["x]y 抽出高亮文本 [到寄存器 x] (关于 {Visual}
见
Visual-mode )。
v_Y
{Visual}
["x]Y 抽出高亮行 [到寄存器 x] (关于 {Visual}
见
Visual-mode )。
v_zy
{Visual}
["x]zy 抽出高亮文本 [到寄存器 x]。不会抽出选中的列块的每行尾
部拖尾的空白。和 zp 的组合特别有用。(关于 {Visual}
见 Visual-mode )
:y :yank E850
:[range]
y[ank] [x]
抽出 [range]
所指定的行 [到寄存器 x]。仅当包含
+clipboard 特性时才可以抽出到 "* 或 "+ 寄存器。
:[range]
y[ank] [x]
{count}
从 [range]
的最后一行开始 (缺省: 当前行
cmdline-ranges ) 抽出 {count}
行 [到寄存器 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>
你也许还想要关闭多键击的功能。参见 double-click 。
gp
["x]gp 如同 "p",但光标停留在新文本之后。
gP
["x]gP 如同 "P",但光标停留在新文本之后。
:pu :put
:[line]
pu[t] [x]
放置文本 [从寄存器 x] 在行号 [line]
(缺省为当前行) 之
后。总是 linewise 行动作,此命令因而可用来把抽出的块
作为新行放置。
如果未指定寄存器,则取决于 '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 的组合特别有用。
你可以用这些命令把文本从一个地方复制到另一个地方。首先,把文本用抽出、删除或者
修改命令取到一个寄存器里,然后用放置命令把寄存器的内容插入。你可以用这些命令把
文本从一个文件移动到另一个文件,因为 Vim 在切换缓冲区时保留所有的寄存器
(CTRL-^
命令可用来快捷地切换文件)。
linewise-register characterwise-register
可用 "." 重复放置命令 (:put 除外),也可以撤销它们。如果保存到寄存器文本的命令
是 linewise 行动作,Vim 把文本插入在光标所在的行之下 ("p") 或之上 ("P")。不
然,Vim 把文本插入在光标之后 ("p") 或之前 ("P")。":put" 命令使得 Vim 总是把文
本放在下一行。可用命令序列 "xp" 来交换两个字母。用 "ddp" 命令序列来交换两行。
还可用 "deep" 命令交换两个单词 (光标在首个单词之前的空白上)。更可在放置命令之
后用 "']" 或者 "`]" 命令把光标移动到插入文本之后,或者用 "'[" 或 "`[" 把光标移
动到文本的开始处。
put-Visual-mode v_p v_P
在可视模式下使用如 p 或者 P 之类的放置命令时,Vim 试图把选择的文本替换成寄
存器的内容。这是否如你所愿取决于选择的类型和寄存器里文本的类型。对于列块选择而
言,也取决于列块的大小和头尾是否在已存在的字符上。(实现细节: 实际上先在选择区
之后放置寄存器的内容,然后再删除选择区的内容。)
用 p 时前次选择的文本被放在无名寄存器 (可能同时也在选择和/或剪贴板) 中。可用
于把该文本放置到他处。但不能重复相同操作。
用 P 时无名寄存器不改变 (同样选择或剪贴板也不会改变),可以重复相同的改变,但
删除的文本不能再用。如果需要,可以用 p 并选用其它寄存器。例如,先抽出要复制
的文本,再可视化选择要替换的文本,然后使用 "0p。重复任意多次均可,而每次无名寄
存器都会被改变。
blockwise-put
寄存器如果包含单行文本 (面向字符),使用面向列块的可视选择时,放置该寄存器时会
把该文本复制到选择的每一行上,也即,把选择的列块区域替代为寄存器文本的多个备
份。例如:
- 用 yw
抽出单词 "TEXT" 到某寄存器
- 选择可视列块,如下面文本里的 "v" 的部分:
aaavvaaa
bbbvvbbb
cccvvccc
- 按 p ,结果是:
aaaTEXTaaa
bbbTEXTbbb
cccTEXTccc
blockwise-register
如果你使用面向列块的可视模式命令把文本存到寄存器里,文本列块会被插入在当前和其
后的行的当前列之前 ("P") 或之后 ("p")。Vim 使得整个文本列块从同一列开始。这
样,插入的文本看上去和抽出或删除时看起来一样。为了使之可能,Vim 可能需要把一些
<Tab>
字符替换成空格。不过,如果列块的宽度不是 <Tab>
宽度的整数倍并且插入列块
之后文本里包含 <Tab>
的时候,那些文本可能就不会那么整齐。
用 zP / zp 来粘贴已抽出的面向列块的寄存器,而不附加拖尾的空白。
注意
在一个面向字符的抽出命令之后,Vim 把光标停留在最接近缓冲区开头的首个被抽
出的字符之上。这意味着 "yl" 不会移动光标,但是 "yh" 把光标向左移一格。
逻辑: 在 Vi 里 "y" 命令跟一个反向的动作有时不会把光标移动到首个被抽
出的字符之上,因为屏幕没有刷新。Vim 符合 Posix 的规范,总是把
光标移动到首个字符之上。
在一个面向行的抽出命令之后,光标放置在首行上,但是列保持不变,所以不必然在第一
个抽出的字符上。
共有十种类型的寄存器: registers {register} E354
1. 无名寄存器 ""
2. 10 个编号寄存器 "0 到 "9 (译者注
: 最近抽出、最近及更早跨行删除)
3. 行内删除寄存器 "-
4. 26 个命名的寄存器 "a 到 "z 或者 "A 到 "Z
5. 三个只读寄存器 ":、". 和 "% (译者注
: 最近命令行、最近插入文本、当前文件名)
6. 轮换缓冲区寄存器 "#
7. 表达式寄存器 "=
8. 选择和拖放寄存器 "*、"+ 和 "~ (译者注
: 主选择、剪切、拖放)
9. 黑洞寄存器 "_
10. 最近搜索模式寄存器 "/
1. 无名寄存器 "" quote_quote quotequote
用 "d"、"c"、"s"、"x" 等命令删除或者用 "y" 等抽出命令复制的文本都被 Vim 用来填
充该寄存器,不管是否用到别的专门寄存器 (例如 "xdd)。这就好像无名寄存器是指向最
近使用的那个寄存器的指针一样。使用大写寄存器进行添加时,无名寄存器包含和命名寄
存器相同的文本。'_' 寄存器是一个特例。"_dd 不把删除的文本存在任何寄存器里。
不指定寄存器的放置命令 (p 或 P) 使用无名寄存器的内容。你也可以用 '"' 作为名字
来访问该寄存器。这意味着要输入两个连续的双引号。写入 "" 寄存器将实际写到寄存器
"0 上。
{Vi: 寄存器内容在更换文件时丢失,没有 '"'}
2. 编号寄存器 "0 到 "9 quote_number quote0 quote1
quote2 quote3 quote4 quote9
Vim 把抽出和删除命令的文本保存在这些寄存器里。
编号寄存器 0 包含最近抽出的文本,除非该命令用 ["x] 指定了别的寄存器。
编号寄存器 1 包含了最近删除或者修改的文本,除非该命令用 ["x] 指定了别的寄存
器或者该文本小于一行 (该情况下使用行内删除寄存器)。以下移动命令在应用删除操作
符时例外: % 、 ( 、 ) 、 ` 、 / 、 ? 、 n 、 N 、 { 和 } 。它们总是使用寄
存器 "1 (这是 Vi 兼容行为)。如果文本小于一行,同时使用 "- 寄存器。
注意
这些字符可能会被映射。例如,matchit 插件会映射 % 字符。
每来一次新的删除和修改,Vim 把前一次的寄存器 1 的内容复制到寄存器 2,2 到
3,依此类推。而寄存器 9 的内容就丢失了。
{Vi: 编号寄存器的内容在更换文件时丢失;寄存器 0 不存在}
3. 行内删除寄存器 "- quote_- quote-
该寄存器保存删除不到一行内容的命令的文本,除非该命令用 ["x] 指定了寄存器。
4. 命名寄存器 "a 到 "z 或者 "A 到 "Z quote_alpha quotea
Vim 只有在你指定的时候才使用这些寄存器。指定为小写字母时替换原来的内容,指定为
大写字母时附加到原来的内容。如果 'cpoptions' 里有 '>' 标志位,在附加文本前插入
一个换行符。
5. 只读寄存器 ":、". 和 "%
它们是 '%'、':' 和 '.'。你只能在 "p"、"P"、":put" 命令和 CTRL-R
的时候使用它
们。
quote_. quote. E29
". 包含最近插入的文本 (和插入模式命令 CTRL-A
和 CTRL-@
插入的一
样)。注意
: 它不适用于命令行上的 CTRL-R
。后者的工作方式稍有不
同,例如,文本是被插入而不是放置的 ('textwidth' 和其它选项
影响插入的内容)。
quote_% quote%
"% 包含当前文件名。
quote_: quote: E30
": 包含最近执行过的命令行。例如: 用 "@:" 重复上次执行过的命令行命
令。只有当一个命令行中至少一个字符是键入的,该寄存器才会保存命
令行的内容。所以,如果命令行完全来自映射,该寄存器保持不变。
{仅当编译时加入 +cmdline_hist 特性才有效}
quote_# quote#
6. 轮换文件寄存器 "#
包含当前窗口轮换文件的名字。它影响 CTRL-^
的命令的工作方式。
该寄存器是可写的,主要用来帮助插件在改变其值后恢复原值。接受缓冲区号:
let altbuf = bufnr(@#)
...
let @# = altbuf
如果传递了不存在的缓冲区号,会报错 E86 。
也可接受现有缓冲区名的匹配:
let @# = 'buffer_name'
如果有多于一个缓冲区匹配该名,报错 E93 ,如果没有缓冲区匹配该名,也会报错
E94 。
7. 表达式寄存器 "= quote_= quote= @=
其实并没有这么一个寄存器可以储存文本,但是这是用来在使用寄存器的命令中使用表达
式的一个方式。表达式寄存器是可读写的。
" 或 CTRL-R
之后输入 '=' 时,光标移到命令行上,这时你可以输入任何的表达式 (见
expression )。可以使用所有正常的命令行编辑命令,还有一个表达式专门的历史表。
当你按回车结束命令行时,Vim 计算表达式的结果。如果你用 <Esc>
结束,Vim 中止表
达式。如果你不输入表达式,Vim 使用最近的表达式 (和 "/" 命令的处理相似)。
表达式的计算结果必须是一个字符串。数值结果会自动转化为字符串。对 "p" 和 ":put"
命令而言,浮点数结果也会被转化为字符串。如果结果为列表,每个成员被转成字符串,
然后被单独放在一行上。字典、函数引用类型的结果则产生错误信息 (通过 string() 转
化)。
如果 "= 寄存器被 "p" 命令使用,该字符串会在 <NL>
字符处断开。如果该字符串以
<NL>
结尾,则它被视为一个面向行的寄存器。
8. 选择和拖放寄存器 "*、"+ 和 "~
用这些寄存器来保存和取得 GUI 界面选择的文本。参见 quotestar 和 quoteplus 。
如果剪贴板不存在或者不工作,使用无名寄存器。Unix 上,仅当 +xterm_clipboard
特性存在时才可用剪贴板。
注意
"* 和 "+ 在 X11 系统上有分别。关于该差别的解释,参见 x11-selection 。在
MS-Windows 上,"* 和 "+ 的使用实际上是等价的,可见 gui-clipboard 。
quote_~ quote~ <Drop>
只读的 "~ 寄存器保存最近一次拖放操作放下的文本。如果有什么东西被放到 Vim 上,
"~ 寄存器被填充,<Drop>
虚拟键被激活。如果你需要,你可以重定义该键的映射;缺省
的动作 (适用于所有模式) 是把 "~ 寄存器的内容插入到当前光标位置。
{仅当编译时加入 +dnd 特性才有效,当前只适用于 GTK GUI 版本}
注意
: "~ 寄存器仅用于在 Vim 上拖放普通文本。URI 列表的拖放在内部处理。
9. 黑洞寄存器 "_ quote_
当写到这个寄存器时,什么都不会发生。这可以用来删除文本,而不影响任何正常的寄存
器。从该寄存器读时,什么都不会返回。
10. 最近搜索模式寄存器 "/ quote_/ quote/
含有最近搜索的模式。它被 "n" 和 'hlsearch' 使用。可以用 :let 来修改。你可以
改变它使得 'hlsearch' 不经过实际的搜索直接高亮某些匹配。你不能把抽出或者删除命
令的内容放到该寄存器上。搜索方向则可从 v:searchforward 得到。
注意
从函数返回时该值被复原 function-search-undo 。
@/
你可以用 :let 命令写到一个寄存器 :let-@ 。例如:
:let @/ = "the"
如果你用放置命令而不指定寄存器,Vim 使用上次填充的寄存器 (这也是无名寄存器的内
容)。如果你弄糊涂了,用 :dis
命令看看 Vim 会放置什么内容 (该命令显示所有的有
名和无名的寄存器;无名寄存器被标为 '"')。
下面三个命令总是针对整行工作。
:[range]
co[py] {address}
:co :copy
把 [range]
指定的行复制到 {address}
给出的行之下。
:t
:t 和 :copy 等价。
此命令在 Vim9 脚本里不支持,因为它太容易和变量名混淆
了。
:[range]
m[ove] {address}
:m :mo :move E134
把 [range]
指定的行移动到 {address}
给出的行之下。
:[range]
ce[nter] [width]
:ce :center
在 [range]
指定范围的行和 [width]
限定的列 (缺省为
'textwidth',如其为 0,则取 80) 范围内的文本居中对齐。
:[range]
ri[ght] [width]
:ri :right
在 [range]
指定范围的行和 [width]
限定的列 (缺省为
'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
如果你想使段落自动排版,可以在 'formatoptions' 里加入 'a' 标志位。参见
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()
" 只在显式的 gq 命令时重新排版
if mode() != 'n'
" 缺省使用 Vim 内部的重新排版方式
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)
" 不使用内部的排版方式!
return 0
endfunc
然后,如此打开此种排版方式:
setlocal formatexpr=format#Format()
注意
: 此函数在插入模式下 (一般这意味着文本的插入超出了 'textwidth' 限制) 显式
返回非零。这样,Vim 会使用缺省的内部排版方法。
反之,该 gq 命令会用于重新排版文本,此时,函数获取所选的行,删除这些行拖尾的
空白,并在原地放置。如果你需要把单行分割为多行,小心不要覆盖额外的部分。
如果在插入或替换模式下希望重排文本,分外小心,因为此时函数可能会被递归调用。调
试可用 'debug' 选项。
right-justify
Vim 没有靠右控制对齐 (right justify) 文本的命令。你可以用 "par" 这样的外部命令
来实现 (例如,"!}par" 对到段落尾的文本排版),或者设置 'formatprg' 为 "par"。
format-comments
用户手册的 30.6 一节给出注释排版的总览。
Vim 可以自动对注释的插入和排版进行特殊处理。Vim 把以特定字符串开头 (忽略空白)
的行识别为注释。以下是三种不同类型的注释:
- 在每行的开头都出现的注释字符串。例如,外壳脚本使用的注释行都以 "#" 开头。
- 只在首行出现的注释字符串。使用连字符 "-" 的本列表就是这样的一个例子,
- 由三部分组成的注释,包括起始字符串,结尾字符串,和两者之间可选的行的起始字符
串。三种字符串可分别指定。如下 C 风格的注释就是如此:
/*
* this is a C comment
*/
'comments' 选项是一个由逗号分隔的列表。每个部分定义一种类型的注释字符串。每个
部分的组成方式是:
{flags}
:{string}
{string}
是必须出现的字符串 (不作转义)。
{flags}
:
n 可嵌套的注释: 允许多个部分间的嵌套。例如,'comments' 为 "n:),n:>"。则
以 "> ) >" 开始的行视为注释。
b 在 {string}
之后必须有空白字符 (<Space>
、<Tab>
或 <EOL>
)。
f 该注释字符串只在首行出现。下一行不重复注释,但保留相同的缩进 (例如,带
符号的列表 (bullet-list))。
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:-
三段式注释必须以开始、中间和结尾三部分给出,而且不能间杂其它的部分。一个三段式
C 注释的例子是
sr:/*,mb:*,ex:*/
为了避免形如 "*ptr" 的内容被识别为注释,这里的中间字符串包含了 'b' 标志位。对
三段式注释而言,Vim 从开始和中间字符串之后查找结尾字符串。如果找到,注释就不会
再从下一行继续。三段式注释必须要有一个中间字符串,不然 Vim 无法识别中间的那些
行。
注意
上述三段式注释定义里的 "x" 标志位。当你在一个 C-注释里按回车时,Vim 会自
动在新行后插入中间字符串: " * "。要结束注释,你只需要在新行里首先键入 "/"。这
样就把中间字符串替换成结尾字符串并应用指定的对齐方式,成为了 " */"。从而省却了
先按退格键的麻烦。
如果同时匹配中间部分和结尾部分但结尾部分更长,使用结尾部分。这样 C 风格注释就
不需要中间部分后加空格了。
这里是一个关于用于对齐的标志位的例子,使得注释看起来很突出 (也很像一个 1 字)。
考虑注释字符串:
:set comments=sr:/***,m:**,ex-2:******/
/***
**<--右对齐,来自 "r" 标志位
**
2 个单位的位移,来自 "2" 标志位--->**
******/
该例中,第一行注释是键入的,然后按回车四次,最后按 "/" 以结束注释。
这里是三部分注释的一些细节。有三个时间点应用对齐和位移标志位: 输入起始字符串后
开启新行、在结尾字符串前开启新行、三部分注释的自动结束。而结尾部分的对齐标志位
要反过来看;这样,相同的对齐标志位在分别用于 "s" 和 "e" 时才会使起始和结尾部分
有相同的缩进。每个注释部分只应用一种对齐方式,但位移优先于 "r" 和 "l" 标志位。
打开 'cindent' 在很多情况下会覆盖对齐标志位。使用其它方法,如 gq 或 = 来重
新缩进也不会参考对齐标志位。这些其它的排版选择可以定义类似的行为。一个担心是
'cindent' 虽然有众多附加的选项来对注释进行基于上下文的缩进,但不能再现三部分注
释的缩进对齐。但 'indentexpr' 应该有能力很好地处理三部分注释。
其它示例:
"b:*" 包含 "*" 开头的行,但 "*" 后面不是空白的除外。这样避免指针取值
操作 "*str" 被识别为注释。
"n:>" 包含形如 ">"、">>"、">>>" 等开头的行。
"fb:-" 包含 "- " 开头的列表,可用来自动排版。
该选项的缺省值是 "b:#"。这意味着 "#include" 开头的行不会被认为是注释,但
"# define" 是。这是个不得不然的妥协。
fo-table
你可以使用 'formatoptions' 选项来控制 Vim 如何对文本进行排版。'formatoptions'
是一个字符串,它可以包含下列字符。缺省设置是 "tcq"。为了提高可读性,你可以用逗
号分隔选项字符。
字符 在 'formatoptions' 里代表的含义
fo-t
t 使用 'textwidth' 自动回绕文本
fo-c
c 使用 'textwidth' 自动回绕注释,自动插入当前注释前导符。
fo-r
r 在插入模式按回车时,自动插入当前注释前导符。
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. 第一项
回绕文字
2. 第二项
fo-2
2 在对文本排版时,将段落第二行而非第一行的缩进距离应用到其后的行上。这适
用于第一行有特殊缩进需要的段落。注意
'autoindent' 也必须置位。
示例:
first line of a paragraph
second line of the same paragraph
third line.
也适用于注释内部,并忽略注释前导符。
fo-v
v Vi-兼容的插入模式自动回绕: 只有在当前输入命令键入的空白上才会分行。
(注意
: 这并不能 100% Vi 兼容。Vi 在这方面有些 "意想不到的特性",换而言
之,漏洞。它使用屏幕列而非实际的列。)
fo-b
b 和 'v' 类似,但只有在键入空白时还没抵达或者刚到回绕边界的时候才会自动
回绕。如果一行在开始插入之前已经超过 'textwidth' 指定的长度,或者在到
达 'textwidth' 之时没有输入过空白,Vim 不会自动回绕。
fo-l
l 插入模式不分行: 当一行已经超过 'textwidth' 时,插入命令不会自动排版。
fo-m
m 可以在任何值高于 255 的多字节字符上分行。这对亚洲文本尤其有用,因为每
个字符都是单独的单位。
fo-M
M 在连接行时,不要在多字节字符之前或之后插入空格。优先于 'B' 标志位。
fo-B
B 在连接行时,不要在两个多字节字符之间插入空格。有 'M' 标志位时无效。
fo-1
1 不要在单字母单词后分行。如有可能,在它之前分行。
fo-]
] 严格遵循 'textwidth' 选项。置位此标志位时,除非断行禁则
(line-break-prohibition rules) 使得行长不可能保留在限定的文本宽度以
内,行长不允许超出限定的文本宽度。此标志位主要用于 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
注意
如果 'paste' 打开,Vim 也不会做任何排版。
注意
即使 Vim 不做自动回绕,仍然可以把 'textwidth' 设为非零。'textwidth' 对
"gq" 的排版依然有用。
如果 'comments' 选项包含 "/*"、"*" 和/或 "*/",Vim 有一套处理这些注释更加聪明
的内嵌方法。在 "/*" 或 "*/" 之前或之后开始一个新行 (在 'formatoptions' 里有
'r' 或者 'o' 的情况下),会自动给出正确的开始部分。排版或者自动回绕也会有相同的
处理。在以 "/*" 或者 "*" 开始并包含 "*/" 的行之后开启新行,就不会插入注释前导
符,而且新行的缩进由注释起始行决定。
例如:
/* ~
* 你的任何注释。
*/ ~
该行的缩进和以上注释的起始行相同。
上述这些应该已经十分够用了,尤其在与新的 :autocmd 命令协同使用时,可以为不同文
件类型提供不同的设置。
一些例子:
适用于 C 代码 (只对注释排版):
:set fo=croq
适用于邮件/新闻 (排版所有文本,"o" 命令不开始注释):
:set fo=tcrq
自动排版 auto-format autoformat
如果 'formatoptions' 里包含 'a' 标志位,在插入或者删除文本时会自动进行排版。这
对编辑文本段落很好用。以下对如何使用这一功能提供一些提示:
- 你需要正确定义何谓段落。最简单的方式是以空行分隔的为段落。如果没有分隔的空
行,考虑用 'w' 标志位并在段落中除了最后一行以外,每行结尾加上一个空格。
- 你可以根据文件类型 filetype , 或者用 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 删除了段落的末
行,这段落自动和下一个段落合并为一个段落。
- 改变的文本被保存以备可能的撤销之用。排版也是改变的一种。所以每次排版都会为撤
销保存文本。这会有相当的内存开销。
- 排版一个很长的段落和/或复杂的缩进也许会相当慢。
Vim 有排序函数和排序命令。排序函数可见: sort() , uniq() 。
:sor :sort
:[range]
sor[t][!] [b]
[f][i][l][n][o][r][u][x] [/{pattern}
/]
给 [range]
里的行排序。如果没有给出行范围,给所有行排
序。
带 [!] 则反向排序。
带 [i]
则忽略大小写。
带 [l]
时排序使用当前排序规则 locale。
实现细节: 用 strcoll() 来进行字符串比较。关于如何查看
或设置排序规则 locale,参见 :language 。例如:
:language collate en_US.UTF-8
:%sort l
v:collate 也可用于检查当前 locale。
按 locale 的排序通常忽略大小写。
Mac 上此功能不能正常工作。
选项 [n]
[f][x][o][b] 互斥。
带 [n]
则排序基于每行的首个十进制数 (在 {pattern}
匹配
之后或之内)。
数值包含前导的 '-'。
带 [f]
则排序基于每行内的浮点数。浮点值相当于在文本
({pattern}
匹配的之后或之内) 上调用 str2float() 函数的
结果。仅当 Vim 编译时加入浮点数支持时该标志位才有效。
带 [x]
则排序基于每行的首个十六进制数 (在 {pattern}
匹
配之后或之内)。忽略引导的 "0x" 或 "0X"。
数值包含前导的 '-'。
带 [o]
则排序基于每行的首个八进制数 (在 {pattern}
匹配
之后或之内)。
带 [b]
则排序基于每行的首个二进制数 (在 {pattern}
匹配
之后或之内)。
带 [u]
(u 代表 unique 唯一) 则只保留完全相同的行的第一
行 (如果带 [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 一起使用并不能对匹配的行进行排序,这样做没有意义。
除非使用 l 标志位, :sort 不使用当前 locale。Vim 保证 "稳定" 排序。
排序可以被中断,但在整个过程里如果中断得太晚,最后可能会出现重复的行。这取决于
使用的系统库函数。
vim:tw=78:ts=8:noet:ft=help:norl: