VIM 参考手册 by Bram Moolenaar
译者: Dasn、tocer
Cmdline-mode Command-line-mode
命令行模式 Cmdline Command-line mode-cmdline :
命令行模式用于输入 Ex 命令 (":"),搜索匹配串 ("/" 和 "?") 以及过滤命令 ("!")。
用户手册第 20 章 usr_20.txt 介绍基本的命令行编辑功能。
1. 命令行编辑 cmdline-editing
2. 命令行补全 cmdline-completion
3. Ex 命令行 cmdline-lines
4. Ex 命令行范围 cmdline-ranges
5. Ex 命令行的标志位 ex-flags
6. Ex 特殊字符 cmdline-special
7. 命令行窗口 cmdline-window
8. 命令行自动补全 cmdline-autocompletion
1. 命令行编辑 cmdline-editing
字符通常在光标位置前插入。可用键盘上的左右键移动光标位置。也可用<Insert> 键在
"插入" 和 "替换" 两种模式之间切换。
注意,如果键盘的方向键或其他特殊键无法使用,可通过 :cnoremap 重新映射其他按
键。例如,可定义 tcsh 风格的一组光标移动键: tcsh-style
:cnoremap <C-A> <Home>
:cnoremap <C-F> <Right>
:cnoremap <C-B> <Left>
:cnoremap <Esc>b <S-Left>
:cnoremap <Esc>f <S-Right>
(<> 记法可见 <> ;所有内容均按本义输入)
cmdline-too-long
命令行长度超出屏幕宽度时,仅显示其中能容纳的部分。光标仅能在可视范围内移动,无
法编辑未显示的部分。
cmdline-history history
在命令行里输入的命令会存储在相应历史记录中,可用上下箭头键来翻阅历史命令。总共
有五个历史表:
- 一个用于 ':' 命令
- 一个用于搜索字符串
- 一个用于表达式
- 一个用于输入行、或 input() 函数键入的内容。
- 一个用于调试模式命令
各类历史表相互独立。不同类型的输入行,只能访问对应类型的历史记录。
'history' 选项用于设定历史记录的最大保存行数 (缺省值: 50)。
注意:
- 输入一条与历史记录中已有命令完全相同的命令时,会删除历史记录中该条旧命令 (以
避免历史列表被大量的重复指令占据)。
- 只会记录手动键入的命令。完全通过映射执行的命令不会。
- 所有搜索都会存入搜索历史,包括由 "*" 和 "#" 这类命令触发的搜索。但在一次映射
执行过程中,仅记录最后一次的搜索 (避免冗长映射污染历史记录)。
{仅当编译的时候加入 +cmdline_hist 特性才可用}
命令行有名字补全功能;见 cmdline-completion 。
c_CTRL-V
CTRL-V 按本义插入下一个非数位字符。否则,最多可输入三位数字形式,用于
表示单个字节的十进制值。这里非数位字符以及三个数位字符不会触发
映射。功能与插入模式下该键的工作方式一致 (见 i_CTRL-V )。
注意: 由于在 MS-Windows 系统上,CTRL-V 常被映射为 "粘贴文本",
此时请改用 CTRL-Q。
打开 modifyOtherKeys 后,特殊转义序列会被还原为未打开该选项
时的原始按键编码,除非同时按住 Shift 键,见 c_CTRL-SHIFT-V 。
c_CTRL-Q
CTRL-Q 与 CTRL-V 相同。但部分终端会将其用于流控制,而无法用于按本义插
入功能,此时请改用 CTRL-Q。
CTRL-SHIFT-V c_CTRL-SHIFT-V c_CTRL-SHIFT-Q
CTRL-SHIFT-Q 与 CTRL-V 类似,但打开 modifyOtherKeys 后,会插入带修饰符按
键的转义序列。
GUI 里会插入特殊键的 key-notation 且不经简化。
注意: 如果系统拦截了 CTRL-SHIFT-V (如用于粘贴文本),通常可改用
CTRL-SHIFT-Q。不过部分终端里 (如 Gnome Terminal),CTRL-SHIFT-Q
会直接退出终端且无确认提示。
c_<Left> c_Left
<Left> 光标左移。wildmenu 补全模式下的行为参见 'wildmenu'。
c_<Right> c_Right
<Right> 光标右移。wildmenu 补全模式下的行为参见 'wildmenu'。
c_<S-Left>
<S-Left> 或 <C-Left> c_<C-Left>
光标左移一个字串 ( WORD )。
c_<S-Right>
<S-Right> 或 <C-Right> c_<C-Right>
光标右移一个字串 ( WORD )。
CTRL-B 或 <Home> c_CTRL-B c_<Home> c_Home
光标跳转到命令行开头。
CTRL-E 或 <End> c_CTRL-E c_<End> c_End
光标跳转到命令行末尾。
wildmenu 补全模式下的行为参见 'wildmenu'。
c_<LeftMouse>
<LeftMouse> 将光标定位到鼠标点击位置。
c_<MiddleMouse>
<MiddleMouse> 粘贴剪贴板内容 (X11 而言是主选择区内容)。和 CTRL-R * 类似,但
行与行间不会插入 CR 字符。
CTRL-H c_<BS> c_CTRL-H c_BS
<BS> 删除光标前一个字符 (如果 <BS> 键无法正常工作,见 :fixdel )。
c_<Del> c_Del
<Del> 删除光标所在字符 (如果在行尾: 则删除光标前一个字符)
(如果 <Del> 键无法正常工作,见 :fixdel )。
c_CTRL-W
CTRL-W 删除光标前一个单词 ( word )。单词定义由 'iskeyword' 选项决定。
c_CTRL-U
CTRL-U 清空光标所在位置到行首之间的所有字符。旧版 vim 会清空整行。如
果需要旧版行为,可在 .vimrc 里加入:
:cnoremap <C-U> <C-E><C-U>
c_<Insert> c_Insert
<Insert> 在命令行插入和命令行替换模式之间切换。
{char1} <BS> {char2} 或 c_digraph
CTRL-K {char1} {char2} c_CTRL-K
输入二合字母 (见 digraphs )。如果 {char1} 是特殊键,只会插入
该键 <> 形式的编码,{char2} 不视作二合字母的一部分。
CTRL-R {register} c_CTRL-R c_<C-R>
插入编号或命名寄存器里的内容。按下 CTRL-R 时,屏幕会先显示 '"'
提示符,提示接下来应输入寄存器名。
插入文本的效果如同手动输入,但不会触发映射和缩写。同样也不会触
发 'wildchar' 命令行补全。能终止命令的特殊字符 (<Esc>,<CR>,
<NL>,<C-C>) 会被按本义插入。但 <BS> 或 CTRL-W 仍可能结束命令
行模式 (译者注: 因为可能会吃掉 : ),并使后续字符在其他模式下
解析,这可能并非用户的本意。
特殊寄存器包括:
'"' 无名寄存器,保存最近一次删除或复制的文本
'%' 当前文件名
'#' 轮换文件名
'*' 剪贴板内容 (对于 X11: 主选择区内容)
'+' 剪贴板内容
'/' 最近一次搜索模式
':' 最近一次命令行
'-' 最近一次小幅 (少于一行) 删除的内容
'.' 最近一次插入文本
c_CTRL-R_=
'=' 表达式寄存器: 提示用户输入表达式 (参见
expression ) 并插入计算结果 (不能在表达式提示
符下递归调用;为避免副作用,也不允许切换缓冲区
或者切换窗口等操作)。
返回 List 时,列表每项被当作单独一行,但列表
项内部也可包含换行。
返回浮点数时,会自动转为字符串。
注意 如果只需要移动光标而无需插入内容,请确保
表达式返回空串。例如:
<C-R><C-R>=setcmdpos(2)[-1]<CR>
关于寄存器,参见 registers 。
实现细节: 使用 expression 寄存器并调用 setcmdpos() 时,在
插入返回文本前设置光标位置。要在插入返回文本后设置光标位置,可
用 CTRL-R CTRL-R。
CTRL-R CTRL-F c_CTRL-R_CTRL-F c_<C-R>_<C-F>
CTRL-R CTRL-P c_CTRL-R_CTRL-P c_<C-R>_<C-P>
CTRL-R CTRL-W c_CTRL-R_CTRL-W c_<C-R>_<C-W>
CTRL-R CTRL-A c_CTRL-R_CTRL-A c_<C-R>_<C-A>
CTRL-R CTRL-L c_CTRL-R_CTRL-L c_<C-R>_<C-L>
插入光标所在的文本对象:
CTRL-F 光标所在的文件名
CTRL-P 光标所在的文件名,并像 gf 那样按 'path' 展开
CTRL-W 光标所在的单词 word
CTRL-A 光标所在的字串 WORD
CTRL-L 光标所在的整行
置位 'incsearch' 时,会以当前显示的匹配项末尾作为光标位置。使
用 CTRL-W 时,已经在命令行录入过的单词部分不再重复插入。
c_CTRL-R_CTRL-R c_<C-R>_<C-R>
c_CTRL-R_CTRL-O c_<C-R>_<C-O>
CTRL-R CTRL-R {{register} CTRL-F CTRL-P CTRL-W CTRL-A CTRL-L}
CTRL-R CTRL-O {{register} CTRL-F CTRL-P CTRL-W CTRL-A CTRL-L}
插入寄存器内容或光标所在的文本对象。与 c_CTRL-R 类似,但文本
会完全按本义插入。例如,如果寄存器 a 的内容为 "xy^Hz" (^H 代表
退格键),那么 "CTRL-R a" 会插入 "xz",而 "CTRL-R CTRL-R a" 会
按本义插入 "xy^Hz"。
CTRL-\ e {expr} c_CTRL-\_e
对表达式 {expr} 求值,并用计算结果替换整个命令行内容。屏幕会先
显示 '=' 提示符,提示接下来应输入表达式,按 <Enter> 键提交。这
项功能主要用于映射。参见 expression 。
要插入表达式结果而不是替换整行,可见 c_CTRL-R_= 。
常用配套函数: getcmdline() 、 getcmdline() 、 getcmdpos() 。
缺省不移动光标位置,除非光标在行尾,此时光标会跳到新的行尾。不
过,可用 setcmdpos() 手动设置光标位置。
在沙盘 sandbox 里计算表达式,避免产生意外副作用。
例如:
:cmap <F7> <C-\>eAppendSome()<CR>
:func AppendSome()
:let cmd = getcmdline() .. " Some()"
:" 将光标跳转到 )
:call setcmdpos(strlen(cmd))
:return cmd
:endfunc
该功能不支持递归调用,所以已处于表达式编辑状态时不能启用,但可
在映射中正常使用。
c_CTRL-Y
CTRL-Y 当存在无模式选区时,复制该选区内容至剪贴板。
modeless-selection
如果没有相应选区,CTRL-Y 会被当作普通字符插入。
wildmenu 补全模式下的行为参见 'wildmenu'。
CTRL-M 或 CTRL-J c_CTRL-M c_CTRL-J c_<NL> c_<CR> c_CR
<CR> 或 <NL> 执行已输入的命令行命令。
CTRL-[ c_CTRL-[ c_<Esc> c_Esc
<Esc> 'cpoptions' 选项中不包含 'x' 时,退出命令行模式而不执行命令。
在宏中出现或者 'cpoptions' 里包含 'x' 时,则执行已输入的命令。
备注: 如果键盘上输入 <Esc> 不便,可改用 CTRL-[。
c_CTRL-C
CTRL-C 退出命令行模式而不执行命令。
c_<Up> c_Up
<Up> 从历史记录中调取开头与当前命令行匹配的前一条命令 (见下)。
wildmenu 补全模式下的行为参见 'wildmenu'。
{仅当编译时加入 +cmdline_hist 特性才可用}
c_<Down> c_Down
<Down> 从历史记录中调用开头与当前命令行匹配的下一条命令 (见下)。
wildmenu 补全模式下的行为参见 'wildmenu'。
{仅当编译时加入 +cmdline_hist 特性才可用}
c_<S-Up> c_<PageUp>
<S-Up> 或 <PageUp>
从历史记录中调取前一条命令。
{仅当编译时加入 +cmdline_hist 特性才可用}
c_<S-Down> c_<PageDown>
<S-Down> 或 <PageDown>
从历史记录中调取下一条命令。
{仅当编译时加入 +cmdline_hist 特性才可用}
CTRL-D 命令行补全 (见 cmdline-completion )
'wildchar' 选项值
命令行补全 (见 cmdline-completion )
CTRL-N 命令行补全 (见 cmdline-completion )
CTRL-P 命令行补全 (见 cmdline-completion )
CTRL-A 命令行补全 (见 cmdline-completion )
CTRL-L 命令行补全 (见 cmdline-completion )
c_CTRL-_
CTRL-_ a - 切换希伯来语和英语键盘模式,仅作用于命令行模式,与 'hkmap'
无关 (后者只用于插入模式)。适用于在命令行、搜索、缩写等场景输
入希伯来文。
{仅当 Vim 编译时加入 +rightleft 特性且置位了 'allowrevins'
选项才可用}
参见 rileft.txt 。
b - 切换波斯语和英语键盘模式,仅作用于命令行模式,与 'fkmap'
无关。在波斯语键盘模式下,字符反向插入 (即从右至左)。适用于在
命令行、搜索、缩写等场景输入波斯语。
{仅当 Vim 编译时加入 +farsi 特性才可用}
参见 farsi.txt 。
c_CTRL-^
CTRL-^ 切换语言映射 :lmap 及输入法的启用状态。
输入搜索模式且 'imsearch' 不是 -1 时,VAL 为 'imsearch' 值,否
则,VAL 为 'iminsert' 值。
已定义语言映射时:
- VAL 为 1 (打开语言映射) 则变成 0 (关闭)。
- VAL 不为 1 则变成 1 (打开语言映射)。
未定义语言映射时:
- VAL 为 2 (打开输入法) 则变成 0 (关闭)。
- VAL 为其它值则变成 2 (打开输入法)。
语言映射一般用于输入键盘上不能直接键入的字符。可通过 'keymap'
选项安装完整映射表。
进行命令行时,语言映射缺省关闭,便于输入命令。即使用 CTRL-^ 手
动打开,新状态不会延续到下一条命令或搜索模式
(译者注: 此处的语言映射与 'langmap' 选项是不同的概念,后者只适
用于普通模式)。
c_CTRL-]
CTRL-] 激活缩写展开,且不额外插入任何字符。
要在命令行上实现 Emacs 风格的编辑操作,参见 emacs-keys 。
<Up> 和 <Down> 键会将当前命令行内容当作搜索字符串。匹配上下历史命令行的开头部
分。首个匹配行会被作为新命令行。重复这两个按键时,会沿用同一字符串继续匹配。例
如,要查找前一个替代命令: 可先输入 ":s" 再按 <Up>。也可以多次按 <S-Up> 往前翻
找,直至出现目标命令为止。(注意: Shift+箭头键在某些终端上不可用)
:his :history
:his[tory] 列出最近执行的命令历史。
{仅当编译时加入 +cmdline_hist 特性才可用}
:his[tory] [{name}] [{first}][, [{last}]]
列出 {name} 指定的历史记录内容,{name} 可选的类型是:
c[md] 或 : 命令行历史
s[earch] 或 / 或 ? 搜索模式历史
e[xpr] 或 = 表达式寄存器历史
i[nput] 或 @ 输入行历史
d[ebug] 或 > 调试命令历史
a[ll] 列出以上全部历史
如果指定 {first} 和 /或 {last},列出指定范围内的历史记录条目
(译者注: 只指定起始序号 {first} 时,只列出该条历史记录)。
这些数值可用的格式如下:
:history-indexing
正数代表出现在本命令列表中首列的绝对索引,即使其他条目被删除,
此编号保持固定 (见 E1510 )。
负数表示从最新条目 (其相对计数为 -1) 反向计算的相对计数。
示例:
列出搜索历史第 6 到 12 条记录:
:history / 6,12
列出全部历史的倒数第二条记录:
:history all -2
列出全部历史最近两条记录:
:history all -2,
:keepp[atterns] {command} :keepp :keeppatterns
执行 {command},不向搜索历史添加任何记录,如果执行的是 :s 或
:& ,也不会修改最近替代模式与替代字符串。
2. 命令行补全 cmdline-completion
在编辑命令行时,可使用若干命令对光标前的单词进行补全。支持以下的补全情景: - 命令名: 在命令行的开头位置。 - ++opt 选项值。 - 标签: 仅在 :tag 命令后。 - 文件名: 仅在接受文件名的命令或可设为文件名的选项后。这被称为文件名补全。 - 外壳命令名: 在 ":!cmd"、":r !cmd" 和 ":w !cmd" 后。会使用 $PATH 查找。 - 选项: 仅在 :set 命令后。 - 映射: 仅在 :map 等类似命令后。 - 变量和函数名: 仅在 :if , :call 等类似命令后。 帮助条目 (译者注: 也适用于所有的标签条目) 的匹配数目有上限 (目前是 300 个),以
避免过多匹配造成的延迟问题。
要在命令行输入时自动补全 (无需 <Tab> 等按键),见 cmdline-autocompletion 。
以下是可用的补全命令:
c_CTRL-D
CTRL-D 列出与光标前的模式匹配的名字。
列出文件名时,使用 hl-Directory | (见 'highlight' 选项) 高亮
其中的目录名。匹配 'suffixes' 的文件名会移到列表的最后。
要同时列出匹配标签的所在文件,可将选项 'wildoptions' 设为
"tagfile"。
c_CTRL-I c_wildchar c_<Tab> /_<Tab>
'wildchar' 选项值
用光标前的模式进行匹配补全。匹配项 (如有多项匹配,使用第一项)
会替换掉原模式 (注意: 在宏中无效,因为 <Tab> 或 <Esc> 通常用作
'wildchar',而这些键在部分宏里有特殊意义)。再次按下该键时,如
果存在多个匹配项,会依次切换到下一项。到达最后一项后,会循环回
到第一项 (回绕)。
在搜索上下文下,可用 <CTRL-V><Tab> 或 "\t" 来搜索按本义出现的
<Tab>,而不触发补全键。
可通过设置 'wildmode' 选项改变补全行为。
c_<S-Tab>
<S-Tab> 和 'wildchar' (缺省为 <Tab>) 类似,但从最后一个匹配项开始,依
次选择前一项。
<S-Tab> 并非所有系统都可用。
c_CTRL-N
CTRL-N 触发 'wildchar' 补全且存在多个匹配项时,切换到下一项。未触发该
补全时,从命令行历史调取更近的历史命令。
c_CTRL-P
CTRL-P 触发 'wildchar' 补全且存在多个匹配项时,切换到上一项。未触发该
补全时,从命令行历史调取更旧的历史命令。
c_CTRL-A
CTRL-A 用所有与光标前的模式匹配的项目替换原模式。
c_CTRL-L
CTRL-L 对光标前的模式进行匹配补全。如果仅有一个匹配项,替换原模式。如
果存在多个匹配项,用所有结果的最长公共前缀替换原模式。如果公共
前缀短于原模式,不执行补全。
/_CTRL-L
开启 'incsearch' 且正在使用 "/" 或 "?" 输入搜索模式时,在高亮
的当前匹配项上按 CTRL-L 会从当前高亮的匹配项后增补一个字符到搜
索模式。如果同时置位了 'ignorecase' 和 'smartcase' 且命令行中
没有大写字符,增补的字符会自动转换为小写。
c_CTRL-G /_CTRL-G
CTRL-G 开启 'incsearch' 且正在使用 "/" 或 "?" 输入搜索模式时,在高亮
的当前匹配项上按 CTRL-G 可跳转到下一个匹配项。按下 <CR> 时才会
应用 search-offset ,但该偏移不会影响匹配高亮。按 CTRL-T 可跳
转到前一个匹配项。提示: 标准键盘上,字母 G 在 T 下方。
c_CTRL-T /_CTRL-T
CTRL-T 开启 'incsearch' 且正在使用 "/" 或 "?" 输入搜索模式时,在高亮
的当前匹配项上按 CTRL-T 可跳转到前一个匹配项。按下 <CR> 时才会
应用 search-offset ,但该偏移不会影响匹配高亮。按 CTRL-G 可跳
转到下一个匹配项。提示: 标准键盘上,字母 T 在 G 上方。
选项 'wildchar' 的缺省值是 <Tab> (Vi 兼容模式使用 CTRL-E;旧版还曾经用过
<Esc>)。匹配文件名时,匹配模式可使用标准文件通配符 wildcards 。
连续按下 'wildchar' 或 CTRL-N 会循环切换下一个匹配项,遍历完所有匹配项后最终回
到最初原始的输入内容。如果第一个匹配项不符合预期,可按 <S-Tab> 或 CTRL-P 直接
回到刚输入的原始内容。
'wildmenu' 选项可用于在命令行正上方显示补全列表。
'wildoptions' 选项提供额外配置,可使 'wildmenu' 使用弹出菜单展示,或启用模糊匹
配。
置位 'wildignorecase' 选项可在文件名补全时忽略大小写。其他类型文本 (如命令名)
的补全,则由 'ignorecase' 选项控制 (但模糊匹配总是忽略大小写)。
要模拟 tcsh 的自动列出补全功能,可用以下映射:
:cnoremap X <C-L><C-D>
(X 是任何命令键,<C-L> 代表 CTRL-L,<C-D> 代表 CTRL-D) 这样就可以先补全最长公
共前缀,然后立即列出所有匹配项。
也可用 'wildmode' 选项模拟上述行为。例如,以下配置可模拟 autolist=ambiguous:
:set wildmode=longest,list
其作用是,输入首个 'wildchar' 后,补全最长公共前缀,再按一次会列出所有匹配项。
complete-script-local-functions
补全用户函数名时,可加上 "s:" 前缀以匹配局部于脚本的函数。
suffixes
文件名补全可通过 'suffixes' 选项,为名字相近的文件设定优先级。当存在多个匹配项
时,扩展名在 'suffixes' 列表中包含的文件会被忽略。
'suffixes' 的缺省值是 ".bak,~,.o,.h,.info,.swp,.obj"。也就是说,以 ".bak"、
"~"、".o"、".h"、".info"、".swp" 或 ".obj" 结尾的文件名在特定情况下会被忽略。
该选项里的空项目 (连续两个逗号),用于匹配不含 "." 的文件名,也就是无扩展名的文
件。这可用来忽略 "prog" 程序,而选择 "prog.c" 源代码。
例如:
模式: 文件: 匹配:
test* test.c test.h test.o test.c
test* test.h test.o test.h 和 test.o
test* test.i test.h test.c test.i 和 test.c
无法忽略包含两个句号的后缀名。
忽略了匹配 'suffixes' 选项的文件后,如果仍有多个文件匹配,会自动插入其中第一个
文件名。要确保只有一个匹配项,可连接按两次 'wildchar' 键,确定匹配项保持不变。
要切换到其他匹配项,可按 'wildchar'、CTRL-N 或 CTRL-P。此时,所有文件都会纳入
切换范围,包括那些扩展名与 'suffixes' 匹配、原本被忽略的文件。
要完全忽略若干文件扩展名,可用 'wildignore' 选项。
要只匹配以输入文本结尾的文件,附加 "$" 即可。例如,要匹配以 ".c" 结尾的文件:
:e *.c$
这样就不会匹配 ".cpp" 结尾的文件。如果不加 "$" 就会。
要在 xterm 里使用 <S-Tab> 实现 CTRL-P 功能,可在 .cshrc 里加入:
xmodmap -e "keysym Tab = Tab Find"
然后在 .vimrc 里加入:
:cmap <Esc>[1~ <C-P>
complete-set-option
用 :set= 设置选项时,在 '=' 后按下 'wildchar' 可插入选项的当前值。例如,在
`:set dir=` 后按下 'wildchar',会插入 'dir' 选项的当前值。对于支持文件名补全的
选项,这一行为优先于文件名补全。
用 :set= 、 :set+= 或 :set^= 时,对于有预定义名或语法的字符串选项 (如
'diffopt'、'listchars') 或单字符标志位列表选项 (如 'shortmess'),按下
'wildchar' 会自动列出所有可选值供用户选择。
用 :set-= 时,对于使用逗号分隔的选项 (如 'diffopt' 或 'backupdir'),按下
'wildchar' 会逐条显示每个可删除项。而对于标志位列表选项 (如 'shortmess'),则会
同时显示完整旧值并逐条显示每个可删除的标志位。对于其他选项,则只会填入完整的旧
值。
3. Ex 命令行 cmdline-lines
Ex 命令有以下特殊规则: :quote :comment Ex 命令支持以 '"' 开头的注释。'"' 出现在行首时,忽略整行。而在命令后使用 '"' 时,只忽略该行的剩余部分。可用于为命令添加注释。例如: :set ai "置位 'autoindent' 选项
外壳命令 ( :!cmd ) 或 ":map" 命令以及一些其他命令 (主要是接受表达式的命令) 不
支持添加注释,因为 Vim 会把 '"' 视为命令参数的一部分,见下:
:argdo
:autocmd
:bufdo
:cexpr (系列)
:cdo (系列)
:command
:cscope (系列)
:debug
:display
:echo (系列)
:elseif
:execute
:folddoopen
:folddoclosed
:for
:grep (系列)
:help (系列)
:if
:let
:make
:map (系列,含 :abbrev 诸命令)
:menu (系列)
:mkspell
:normal
:ownsyntax
:popup
:promptfind (系列)
:registers
:return
:sort
:syntax
:tabdo
:tearoff
:vimgrep (系列)
:while
:windo
:bar :\bar
'|' 可用于在一行内分隔多个命令,让它们依次执行。如果需要在参数里使用 '|',必须
在前面加上 '\' 转义。
以下这些命令总是把 '|' 视为自身参数的一部分,所以其后不能用 '|' 再接其他命令:
:argdo
:autocmd
:bufdo
:cdo
:cfdo
:command
:cscope
:debug
:eval
:folddoopen
:folddoclosed
:function
:global
:help
:helpfind
:helpgrep
:lcscope
:ldo
:lfdo
:lhelpgrep
:make
:normal
:perl
:perldo
:promptfind
:promptrepl
:pyfile
:python
:registers
:read !
:scscope
:sign
:tabdo
:tcl
:tcldo
:tclfile
:terminal
:vglobal
:windo
:write !
:[range]!
无 "-bar" 参数的用户自定义命令 :command
以及以下 Vim9-script 关键字:
:abstract
:class
:enum
:interface
注意: ":g" 会为 '|' 视作自身参数的一部分,但 ":s" 不会。这的确容易引起混淆 (继
承于 Vi)。
要强行在这些特殊命令后使用其他命令,可用 ":execute" 命令包裹。
例如 (先插入 "ls" 的输出结果,再跳转到第一行):
:execute 'r !ls' | '[
有一个例外: 'cpoptions' 选项包含 'b' 标志位时,":map" 和 ":abbr" 系列命令里需
要用 CTRL-V 代替 '\' 来转义 '|'。也可直接用 "<Bar>" 代替。参见 map_bar 。
例如:
:!ls | wc 运行管道连接的两个外部命令,并查看其输出结果
:r !ls | wc 同上,但将输出结果插入文本
:%g/foo/p|> 将所有匹配行右移一个 'shiftwidth'
:%s/foo/bar/|> 替代后只将当前行右移一个 'shiftwidth'
:map q 10^V| 将 "q" 映射为 "10|"
:map q 10\| map \ l 将 "q" 映射为 "10\" 并将 "\" 映射为 "l"
('cpoptions' 选项中包含 'b' 时)
也可用 <NL> 代替 '|' 来分隔命令。要插入 <NL>,可用 CTRL-V CTRL-J。Vim 会显示为
"^@"。一般情况下推荐使用 '|' 。但对于外部命令,必须使用 <NL>,因为 '|' 会被当
作外部命令的一部分 (用作管道)。要避免 <NL> 的特殊含义 (即将其作为普通字符),必
须在前面加上反斜杠转义。示例:
:r !date<NL>-join
会将当前日期写入当前缓冲区,再与上一行文本合并。
注意: 如果 '|' 前面的命令执行出错,后面的所有命令都不会执行。
为了兼容 Vi,Vim 也支持以下几个奇怪的命令:
:| 打印当前行 (同 ":p")
:3| 打印第 3 行 (同 ":3p")
:3 跳转至第 3 行
在行范围与命令之间可以加一个冒号。Vim 会自动将其忽略 (Vi 兼容)。例如:
:1,$:s/pat/string
在需要文件名的地方,可用字符 '%' 或 '#',它们分别会被扩展为当前文件名或轮换文
件名 (参见 "编辑文件" 一节 :_% :_# )。
在 Amiga 系统上,接受单个文件名的命令会接受文件名的内嵌空格。拖尾的空格一般会
被忽略,如需保留必须用反斜杠或 CTRL-V 转义。注意,":next" 命令使用空格分隔文件
名。文件名包含空格时,必须对其进行转义。例如:
:next foo\ bar goes\ to school\
会打开 "foo bar"、"goes to" 和 "school " 三个文件。
要在命令里使用特殊字符 '"' 或 '|',或在文件名里使用 '%' 或 '#',必须在这些字符
前加反斜杠进行转义。在行范围和 ":substitute" 命令里,这些字符不需要加反斜杠。
另见 `= 。
:_!
在 Ex 命令之后的 '!' (叹号) 会改变命令的行为。'!' 必须紧跟在命令之后,中间不能
添加任何空白字符。如果插入了空白字符,'!' 会被视为该命令参数的一部分,提供不同
的功能。例如:
:w! name 强制写入文件 "name"。覆盖已存在的文件。
:w !name 将当前缓冲区内容作为标准输入,发送给 "name" 外部命令。
4. Ex 命令行范围 cmdline-ranges [range] E16
许多 Ex 命令前面可以加上行范围 (译者注: 在不引起混淆的情况下,常简称为范围),
在文档中记为 [range]。由一个或多个由 ',' 或 ';' 分隔的行限定符组成。
基本用法说明可查阅用户手册 10.3 一节。
Vim9 脚本里要表示范围,必须加上冒号前缀,以免和表达式续行起歧义 (见
vim9-line-continuation )。例如,"+" 既可用作范围,也可作为表达式的继续:
var result = start
+ print
如果此处 "+" 用作范围,在 Vim9 脚本里必须加上冒号前缀 (否则会报错 E1050 ):
vim9script
:+ print
:, :;
使用 ';' 分隔时,会先将光标定位到前一个限定符指定的行,再解析下一个限定符。使
用 ',' 分隔则不会改变光标位置。例如:
4,/this line/
从第 4 行开始,到当前光标后首个匹配 "this line" 的行结束。
5;/that line/
从第 5 行开始,到第 5 行之后首个匹配 "that line" 的行结束。
大多数命令的缺省范围为光标所在行,但 :write 和 :global 命令的缺省范围为整
个缓冲区,(即 1,$ )。
如果行限定符的个数超过命令本身所需,使用逗号分隔时,则舍弃最左侧多余的行限定
符,例如:
:-2,+,-2,. print
其中的 -2,+ 会被舍弃。
使用分号分隔时,从最左侧到倒数第二个行限定符会进行累加合并,例如:
:-4;+3;-1;+2 print
其中的 -4 + 3 - 1 = -2,因此实际有效范围是 -2;+2 。
可用的行限定符如下: :range {address}
{number} 绝对行号 E1247
. 光标当前行 :.
$ 缓冲区末行 :$
% 相当于 1,$ (整个缓冲区) :%
* 相当于 '<,'> (最近一次可视选区的行范围;
见下 :star )
'x 位置标记 x 所在行 :'x
(其中 x 为任意 {a-z} 位置标记)
'X 位置标记 X 所在行 :'X
(其中 X 为任意 {A-Z0-9} 位置标记,但仅当 X
位于本缓冲区才可用)
'[ 上次改变或抽出操作的首行 :'[
'] 上次改变或抽出操作的末行 :']
'< 最近一次可视选区的首行 :'<
'> 最近一次可视选区的末行 :'>
'' 最近一次跳转之前,或是上次执行 m' / m` :''
标记命令时的光标所在行 (但如果该位置不在
当前缓冲区,则默认为第 1 行)
'" 上次离开本缓冲区时的光标所在行 :'quote
'^ 上次退出插入模式时的光标所在行 :'^
'. 上次缓冲区发生改变时的光标所在行 :'.
'( 当前句子首字符所在行 :'(
') 当前句子结尾位置后的首字符所在行 :')
'{ 光标所在段落之前的首个空行 :'{
'} 光标所在段落之后的首个空行 :'}
/{pattern}[/] 下一个匹配 {pattern} 的行 :/
另见下 :range-pattern
?{pattern}[?] 上一个匹配 {pattern} 的行 :?
另见下 :range-pattern
\/ 下一个匹配最近搜索模式的行
\? 上一个匹配最近搜索模式的行
\& 下一个匹配最近替代模式的行
注意: 上文中的 "下一个行" 与 "上一个行" 不包含出现在当前行内的匹配。
:range-offset
每个行限定符可后跟一个或多个 '+' 或 '-',以及一个可选数值。该偏移量会与前面的
行号相加或相减. (译者注: 为以下示例完整起见,此处使用英文句号) 例如, 'x+2 代
表位置标记 x 所在行的后两行。省略数值时,每个 '+' 代表 +1,而每个 '-' 代表
-1,因而 'x++ 和 'x+2 同义。如果 '+' 或 '-' 之前未给出行限定符,用于
[range] 里的第一个行号时,会使用当前行作为相对开始点。例如 -,. 代表 "当前行
的上一行到当前行"。用于 [range] 里的第二个行号时,则取决于分隔行号的是逗号还是
分号 (见 :, 或 :; ),使用当前行还是第一个行号作为相对开始点。
示例: 假定光标位于本行下方一行,以下任意命令都会显示标签行 ":range-offset" 以
及 "每个..." 这一行:
:-9;+1 print
:---------,-8 print
:?每个行?-;+ print
:'{+,'{+2 print
:'{+1;')-1 print
:range-closed-fold
当逗号之后的行号位于已关闭折叠的内部时,会被自动调整为折叠末行,从而使范围包含
整个折叠区域。
该行号带有偏移量时,会在调整为折叠末行后再计算偏移。这意味偏移后的行会额外被追
加到范围中。例如:
:3,4+2print
在以下文本上运行时:
1 one
2 two
3 three
4 four 已折叠
5 five 已折叠
6 six
7 seven
8 eight
其中第四、五两行位于已关闭折叠中,最终结果是显示第 3 到 7 行。7 来自范围指定的
"4",它先被调整为已关闭折叠的末行,也就是 5,然后再加上偏移量 2。
使用减法的例子 (一般不太有用):
:2,4-1print
在以下文本上运行时:
1 one
2 two
3 three 已折叠
4 four 已折叠
5 five 已折叠
6 six 已折叠
7 seven
8 eight
其中第三到六行位于已关闭折叠中,最终结果是显示第 2 到 6 行。6 来自范围指定的
"4",它先被调整为已关闭折叠的末行,也就是 6,然后减 1,结果又回到已关闭折叠的
内部,所以又被调整为折叠末行,也就是 6。
:range-pattern
{pattern} 之后的 "/" 或 "?" 是必需的,用于分隔匹配模式与其后续内容。
"/" 和 "?" 前面可以加上另一个地址。搜索会从该位置开始。此格式和使用分号的区别
是不会移动光标。例如:
/pat1//pat2/ 在包含 "pat1" 的行之后,搜索含有 "pat2" 的行,不移动光
标。
7;/pat2/ 从第 7 行开始,到该行之后含有 "pat2" 的行结束,光标停
留在第 7 行。
行号 {number} 必须在 0 到文件总行数之间。使用 0 (零) 时,大多数命令会将其解释
为 1。而用作计数的命令 (如 :tag , :pop 等) 则会真正当作零使用。有些命令会把
零解释为 "首行之前" 的位置 (如 :read ,搜索模式等)。
例如:
.+3 光标所在行往下三行
/that/+1 下一个匹配 "that" 的行的再下一行
.,$ 从当前行直至文件末尾
0;/that 到缓冲区首个匹配 "that" 的行,首行也能匹配
1;/that 到第一行之后 (即从第二行开始) 首个匹配 "that" 的行
部分命令允许在命令末尾指定计数。该计数指定从最后一个行限定符指定的行 (缺省为光
标行) 开始操作的行数。命令要能接受末尾计数的条件是,支持行范围,且不带文件名参
数 (因为文件名也可能是一个数值,这会产生歧义)。计数值不能为负。
例如:
:s/x/X/g 5 在当前行及后续四行内,将 'x' 全局替代为 'X'。
:23d 4 删除第 23、24、25 和 26 行。
折叠和范围
激活折叠功能时,Vim 会自动调整行号,确保已关闭折叠被完整纳入范围。见
fold-behavior 。
反向范围 E493
行范围要求小行号在前,大行号在后。如果顺序相反,Vim 会询问是否交换行号。
使用了逆向的范围,确定交换吗
但全局命令 :g 不会给出询问。
可在命令前用 :silent 跳过此询问,此时总会自动静默交换行号。
计数和范围 N:
在输入 ":" 前输入计数 {count},会被自动翻译成行范围:
:.,.+(count - 1)
也就是: 从光标行开始,共计 "count" 行。例如,删除三行:
3:d<CR> 被翻译成: .,.+2d<CR>
可视模式和范围
v_:
{Visual}: 在可视模式下按 ':' 启动命令行,会自动使用可视选区行范围。命令
行上会自动填入 :'<,'> 以代表此范围。这样就可从命令行历史中调
取相似命令,重复对其他可视选区执行的操作。
:* :star :star-visual-range
退出可视模式后,可用 :* 快速指代上次可视选区行范围。前提是
'cpo' 里不包含 "*",参见 cpo-star 。否则,只能手动输入
:'<,'> 。
关于 'cpo' 里包含 "*" 时的行为,可见 :star-compatible 。
5. Ex 命令行的标志位 ex-flags
部分 Ex 命令支持以下标志位。作用是在命令执行完毕后,显示光标最终所在行: l 以 :list 格式输出 # 额外显示行号,以 :number 格式输出 p 以 :print 格式输出 这些标志位可以组合使用,例如 "l#" 会同时显示行号并以 :list 风格输出。6. Ex 里的特殊字符 cmdline-special
注意: 以下字符是在 Ex 命令行中使用的特殊字符。如果想要在录入时直接插入特殊内
容,可以使用 CTRL-R 命令。例如,命令行中的 "%" 代表当前文件名,而 CTRL-R % 则
会立即插入当前文件名本身。见 c_CTRL-R 。
注意: 要在 Vim 脚本中取消特殊字符的效果,可用 fnameescape() 。另见 `= 。
在 Ex 命令中,凡是可以使用文件名的地方,都可用以下有特殊意义的字符。这些字符同
样可用于表达式函数 expand() 中。
% 替换为当前文件名。 :_% c_%
# 替换为轮换文件名。 :_# c_#
每个窗口都会分别记录轮换文件。
#n (n 为数值) 替换为第 n 号缓冲区的文件名。 :_#0 :_#n
"#0" 等同于 "#" (轮换文件名)。 c_#n
## 替换为参数列表里的所有文件名 (使用空格分隔)。 :_## c_##
文件名内部的空格会自动在前面加上反斜杠。
#<n (n 为正数) 替换为第 n 个旧文件名。 :_#< c_#<
可通过 :oldfiles 或 v:oldfiles 查看相应编号。 E809
{仅当编译时加入 +eval 和 +viminfo 特性才可用}
在 Vim9-script 里,因为 # 用于开始注释,因此改用 %% 代表轮换文件名:
% 替换为当前文件名。
%% 替换为轮换文件名。 :_%% c_%%
%%n (n 为数值) 替换为第 n 个缓冲区的文件名。 :_%%0 :_%%n
"%%0" 等同于 "%%" (轮换文件名)。 c_%%n
%%% 替换为参数列表里的所有文件名 (使用空格分隔)。 :_%%% c_%%%#
%%<n (n 为正数) 替换为第 n 个旧文件名。 :_%%< c_%%<
注意: 除 "#<n" 外,其余符号返回原始输入的文件名。如果需要绝对路径 (以便在其他
目录下使用这些文件名),需要加上 ":p" 后缀。见 filename-modifiers 。
"#<n" 项一般返回绝对路径,但在主目录下的文件名会以 "~/" 开头。
注意: 文件名内部的空格会自动在前面加上反斜杠,以便 Vim 命令能正确解析带空格的
文件名。但对于外壳命令,这不会自动发生。如果确有需要,可在特殊字符外加上引号包
围 (如果文件名本身含引号或通配符,此方式仍有缺陷)。示例:
:!ls "%"
:r !spell "%"
要取消 '%' 和 '#' 的特殊含义,可在前面加反斜杠转义。
细节: 只要有前置反斜杠 (无论多少层),都会取消其特殊含义。
输入: 解析结果
# 轮换文件名
\# #
\\# \#
另见 `= 。
E499 E500
注意: 以下字符串 (占位符) 不代表特殊键,需要逐个字符输入!
:<cword> <cword>
<cword> 替换为光标所在单词 (用法类似于 star )
:<cWORD> <cWORD>
<cWORD> 替换为光标所在字串 (见 WORD )
:<cexpr> <cexpr>
<cexpr> 替换为光标所在单词,并扩展补齐为完整 C 表达式。例如,当光标
落在 "ptr->arg" 的 "arg" 上时,本项返回 "ptr->arg";当光标
落在 "list[idx]" 的 "]" 上时,本项返回 "list[idx]"。用于
v:beval_text 。
:<cfile> <cfile>
<cfile> 替换为光标所在路径名 (用法类似于 gf )
:<afile> <afile>
<afile> 在执行自动命令时,替换为当前被操作缓冲区的文件名 (缓冲区相
关事件) 或正在读写的文件名 (文件相关事件)。 E495
:<abuf> <abuf>
<abuf> 在执行自动命令时,替换为当前生效的缓冲区编号。并非所有类型
的事件都会设置,如有需要可见 bufnr() 。 E496
执行 `:r file` 和 `:so file` 时,替换为当前缓冲区,因为被读
取/执行的文件此时并未对应到任何缓冲区。
:<amatch> <amatch>
<amatch> 在执行自动命令时,替换为触发本条自动命令的实际匹配项。
E497
在 FileType、Syntax 和 SpellFileMissing 这类不按文件名匹配
的事件中,与 <afile> 不同。
而按文件名匹配时,会被扩展为完整路径。
:<sfile> <sfile>
<sfile> 在执行 :source 命令时,替换为被加载执行的脚本文件名。
E498
执行老式函数时,替换为调用栈信息,同 <stack> (为后向兼容保
留,建议改用 <stack> 或 <script>)。
如果在 Vim9 脚本的函数内使用,会报错。 E1245
注意,不在脚本内使用时,文件名修饰符 ( filename-modifiers )
没有意义。
:<stack> <stack>
<stack> 替换为调用栈信息。各项之间以 ".." 分隔,每项格式如下
函数行: "function {函数名}[{行号}]"
脚本行: "script {文件名}[{行号}]"
项目与前项类型相同时,省略类型前缀 ("function" 等)。示例:
"function {函数名1}[{行号}]..{函数名2}[{行号}]"
如果没有调用栈可用,会报错。 E489
:<script> <script>
<script> 在执行 :source 命令时,替换为被加载执行的脚本文件名。执行
函数时,替换为定义该函数的脚本文件名。
如果无法确定文件名,会报错。 E1274
:<slnum> <slnum>
<slnum> 在执行 :source 命令时,替换为脚本内当前行号。
E842
执行函数时,替换为相对函数开始位置的行号。
:<sflnum> <sflnum>
<sflnum> 在执行脚本时,替换为脚本内当前行号。 E961
和 <slnum> 的区别在于,<sflnum> 在所有情况下都可获取脚本行
号。
:<client> <client>
<client> 替换为 server2client() 中最近一条接收信息的 {clientid}。
filename-modifiers
:_%: ::8 ::p ::. ::~ ::h ::t ::r ::e ::s ::gs ::S
%:8 %:p %:. %:~ %:h %:t %:r %:e %:s %:gs %:S
文件名修饰符可在 "%"、"#"、"#n"、"<cfile>"、"<sfile>"、"<afile>" 或 "<abuf>"
之后使用。也可用于 fnamemodify() 函数。
以下是可用的修饰符,使用多个修饰符时,必须按以下顺序依次给出:
:p 将文件名转为完整路径。必须是首个修饰符。也会将 "~/" (Unix 和
VMS 系统上还包括 "~user/") 展开为用户主目录。对于目录,会在末
尾追加路径分隔符。对于不存在且非绝对路径的文件名,结果不可预
测。MS-Windows 上 8.3 短文件名会被扩展为长文件名。
:8 将路径转换为 8.3 短格式 (目前仅适用于 MS-Windows)。只会对已存
在的路径部分进行转换,其余部分 (如有) 保持不变。
:~ 尽可能将文件名简化为相对于主目录的路径。不在主目录下的文件名保
持不变。
:. 尽可能将文件名简化为相对于当前目录的路径。不在当前目录下的文件
名保持不变。
要使路径最短,可使用 ":~:."。
:h 取文件名的头部 (移除最后一段路径部分,包含路径分隔符)。
不能与 :e、:r 或 :t 一起使用。
可重复使用,一次性移除末尾多层路径部分。
文件名以路径分隔符结尾时,仅删除该分隔符。因此,对目录名使用
":p:h" 会得到目录名本身 (但不带末尾斜杠)。
文件名为绝对路径时 (Unix 上以 "/" 开始;Win32 以 "x:\" 开始;
Amiga 以 "drive:" 开始),该绝对路径前缀不会被删除。没有头部时
(使用相对路径),结果为空。
:t 取文件名的尾部 (最后一段路径部分,即不含目录的文件名本身)。必
须放在 :r 或 :e 之前。
:r 取文件名的主干 (移除最后一项扩展名)。如果文件名只有扩展名 (即
以 '.' 开始的文件名,如 ".vimrc"),则不移除扩展名。
可重复使用,一次性移除多个扩展名 (从后到前)。
:e 取文件名的扩展名。只有单独使用时才有意义。
无扩展名时,结果为空。
如果文件名只有扩展名 (即以 '.' 开始的文件名),则结果为空。
可重复使用,包含多层扩展名 (从后到前)。如果没有足够多层的扩展
名 (但至少有一层),则包含尽可能多的部分。例如,对文件名
"a.b.c",":e" 返回 ".c",":e:e" 或 ":e:e:e" 都返回 ".b.c"。
:s?pat?sub?
将 "pat" 的首次匹配替代为 "sub"。用法和 :s 命令类似。"pat"
为正则表达式。可用不出现在 "pat" 或 "sub" 里的任意字符代替 "?"
作为定界符。
替代后可再次使用之前的各种修饰符 (如 ":p" 转为替代结果的完整路
径)。
:gs?pat?sub?
将 "pat" 的全部匹配替代为 "sub"。其余同 ":s"。
:S 为外壳命令转义特殊字符 (见 shellescape() )。必须是最后一个修
饰符。示例:
:!dir <cfile>:S
:call system('chmod +w -- ' .. expand('%:S'))
示例,假定文件名为 "src/version.c",当前目录为 "/home/mool/vim":
:p /home/mool/vim/src/version.c
:p:. src/version.c
:p:~ ~/vim/src/version.c
:h src
:p:h /home/mool/vim/src
:p:h:h /home/mool/vim
:t version.c
:p:t version.c
:r src/version
:p:r /home/mool/vim/src/version
:t:r version
:e c
:s?version?main? src/main.c
:s?version?main?:p /home/mool/vim/src/main.c
:p:gs?/?\\? \home\mool\vim\src\version.c
又例,假定文件名为 "src/version.c.gz":
:p /home/mool/vim/src/version.c.gz
:e gz
:e:e c.gz
:e:e:e c.gz
:e:e:r c
:r src/version.c
:r:e c
:r:r src/version
:r:r:r src/version
extension-removal :_%<
"%"、"#"、"#n" 或 "CTRL-V p" (译者注: 原文如此,似应为所有返回文件名的占位符)
后跟 "<" 时,会移除文件扩展名 (即最后一个 '.' 及其后所有内容)。保留该用法是为
了与 3.0 版本后向兼容,现在推荐使用 ":r" 形式。例如:
% 当前文件名
%< 当前主文件名,移除扩展名
# 当前窗口的轮换文件名
#< 同上,但移除扩展名
#31 缓冲区编号 31 的文件名
#31< 同上,但移除扩展名
<cword> 光标所在单词
<cWORD> 光标所在字串 (见 |WORD|)
<cfile> 光标所在路径名
<cfile>< 同上,但移除扩展名
注意: 在需要文件名的位置,会自动进行通配符展开。在 Unix 上,除非 Vim 可以内部
实现 (为了提升速度),一般会通过外壳执行此功能。
除非在 restricted-mode 下,否则也可用反引号扩展 ( backtick-expansion ) 代替
文件名参数,例如
:n `echo *.c`
通配符展开仅会在 '%','#' 等特殊字符被扩展之前执行。这样可以避免意外展开文件名
内部的通配符。如果确实希望展开 <cfile> 的结果,可在其后追加通配符。
示例: (假定轮换文件名为 "?readme?")
命令 展开为
:e # :e ?readme?
:e `ls #` :e {匹配 "?readme?" 的文件}
:e #.* :e {匹配 "?readme?.*" 的文件}
:cd <cfile> :cd {光标所在文件名}
:cd <cfile>* :cd {光标所在文件名加上 "*",然后进行通配符展开}
另见 `= 。
展开后的参数中包含 "!" 且用于外壳命令 (":!cmd",":r !cmd" 或 ":w !cmd") 时,
"!" 会被自动加上反斜杠转义,避免被扩展为前次外部命令 (见 :! )。'shell' 选项值
包含 "sh" 时,则会转义两次,以避免外壳对 "!" 进行扩展 (历史扩展)。
filename-backslash
对于使用反斜杠作为路径分隔符的文件系统 (MS-Windows),区分反斜杠作为路径分隔符
和作为转义符会比较困难。通用规则是: 如果反斜杠后跟普通字符,则不用作转义。如
"\file\foo" 为合法文件名,此时无需输入两次反斜杠。
'$' 符号是个例外。它虽然是文件名中的合法字符。但为了避免像 "$home" 这样的文件
名被解析为环境变量,必须在它前面加上反斜杠转义。因此,根目录下名为 "$home" 的
文件必须写作 "/\$home"。可见以下数例:
文件名 被解析为
$home 展开为环境变量 $home 的值
\$home 当前目录下的 "$home" 文件
/\$home 根目录下的 "$home" 文件
\\$home 名为 "\\" 加上展开后的 $home 变量值的文件
另见 `= 。
7. 命令行窗口 cmdline-window cmdwin
command-line-window 在命令行窗口里,可以像在普通窗口里编辑文本一样编辑命令行内容。这是一类特殊窗 口,无法用常规方式退出。{仅当编译时加入 +cmdwin 特性才可用}
开 启 c_CTRL-F q: q/ q?
有两种方法可以打开命令行窗口:
1. 从命令行模式,可按下 'cedit' 选项指定的按键。'compatible' 复位时,其缺省值
为 CTRL-F。
2. 从普通模式,可用 q: 、 q/ 或 q? 命令。
这些命令会分别进入 Ex 命令 ( q: ) 或搜索字符串 ( q/ 或 q? ) 编辑。注意,
正在录制宏时无法使用 (因为按下 "q" 会结束宏录制)。
窗口打开后,会自动载入命令行历史记录。最后一行是当前正在命令行输入的内容。窗口
首列字符代表正在编辑的命令行类型,见 cmdwin-char 。
除非置位 'insertmode' 选项,否则 Vim 打开命令行窗口默认进入普通模式。
E1292
同一时刻只能打开一个命令行窗口,无法同时开启多个。
窗口高度由 'cmdwinheight' 选项设定 (空间不足时会自动缩小高度)。窗口始终占据最
大可能宽度,固定显示在底部命令行的正上方。
编 辑
在命令行窗口里,可在普通模式和插入模式下,常规移动或者编辑窗口内文本。
可用 ":","/" 和其他命令正常打开并使用命令行,但无法嵌套打开另一个命令行窗口。
E11 E1188
命令行窗口不是普通窗口。不能切换到其他窗口、或编辑其他缓冲区。所有触发此类操作
的命令在命令行窗口中都被禁止。当然在命令行窗口里,通过回车执行任何命令是_完全
允许_ 的。关闭窗口时,窗口内所有未执行的文本编辑都会被舍弃。
关 闭 E199
有多种方式可以退出命令行窗口:
<CR> 执行光标所在行的命令。在插入和普通模式下都有效。
CTRL-C 回到命令行模式继续编辑。光标所在行的内容会被用作命令行。在插入
和普通模式下都有效。不会重绘屏幕,因此窗口仍保持可见。
:quit 放弃当前命令行,回到普通模式。 :close 、CTRL-W c、 :exit 、
:xit 和 CTRL-\ CTRL-N 命令同样有效。
:qall 除非某些缓冲区有未保存的更改,否则退出 Vim。
:qall! 退出 Vim,并放弃所有缓冲区的更改。
一旦命令行窗口关闭,原先的窗口大小会被恢复。待执行的命令会作用于最初打开命令行
窗口的窗口或缓冲区,效果相当于命令行窗口从未出现过一样,只是屏幕会多一次重绘。
用于命令行窗口的缓冲区会被删除。,除了通过 <CR> 执行的那一行以外,对其他行所做
的改动都会丢失。
如果希望执行光标所在的命令后再次自动打开命令行窗口,可用以下映射:
:autocmd CmdwinEnter * map <buffer> <F5> <CR>q:
杂 项
命令行窗口不能用在:
- 已经存在一个命令行窗口时 (不支持嵌套)
- 输入加密密钥或使用 inputsecret() 函数时
打开命令行窗口时,会自动设置以下选项:
'filetype' "vim",编辑 Ex 命令行时设置;开启语法高亮时,此设置会启用 Vim
语法高亮。
'rightleft' 关闭
'modifiable' 打开
'buftype' "nofile"
'swapfile' 关闭
允许将缓冲区内容写入文件。这是保存命令行历史并在日后读取的简便方法。
如果 'wildchar' 选项设为 <Tab>,且本命令行窗口用于执行 Ex 命令,那么会自动添加
两个使用 <Tab> 进行补全的映射,如下所示:
:inoremap <buffer> <Tab> <C-X><C-V>
:nnoremap <buffer> <Tab> a<C-X><C-V>
注意,在普通模式下按 <Tab> 键会在下一个字符上进行补全。这样可以在行尾正常工
作。
如果不想要这些映射,可用以下命令禁用:
au CmdwinEnter [:>] iunmap <Tab>
au CmdwinEnter [:>] nunmap <Tab>
可将这些命令放入 vimrc 文件。
在命令行窗口里,无法使用鼠标将光标移到另一个窗口,或拖动其他窗口的状态栏。但可
以拖动命令行窗口自身的状态栏及其上方窗口的状态栏。这样就可以调整命令行窗口的大
小,但其他窗口此时无法调整大小。
getcmdwintype() 函数返回正在编辑的命令行的类型,可用值见 cmdwin-char 。
自 动 命 令
命令行窗口使用两种自动命令事件: CmdwinEnter 和 CmdwinLeave 。这些 Cmdwin 事
件可用于对命令行窗口的特殊设置。请注意避免产生副作用!
例如:
:au CmdwinEnter : let b:cpt_save = &cpt | set cpt=.
:au CmdwinLeave : let &cpt = b:cpt_save
这会设置 'complete' 选项,以便 i_CTRL-N 使用当前窗口进行补全。
另一例:
:au CmdwinEnter [\/\?] startinsert
将使 Vim 在打开命令行窗口时直接切换到插入模式。
注意: "/" 和 "?" 需要转义,因为此处被看作是 file-pattern 。另见
cmdline-autocompletion 。
cmdwin-char
用于模式匹配的下列字符标识了命令行的类型:
: 普通 Ex 命令
> 调试模式命令 debug-mode
/ 正向搜索字符串
? 反向搜索字符串
= "= 表达式寄存器 expr-register
@ input() 函数输入的字符串
- :insert 或 :append 命令的文本
8. 命令行补全 cmdline-autocompletion
自动补全功能会在用户键入时自动弹出建议菜单,使命令行的使用更高效、更便捷。这既 适用于模式搜索 (/ 或 ?),也适用于命令输入 (:)。 基本设置是: autocmd CmdlineChanged [:\/\?] call wildtrigger()
set wildmode=noselect:lastused,full
set wildoptions=pum
配置生效后,输入时会立即弹出补全建议,可用 <Tab> 或方向键在候选列表中切换不同
选择。
要保留使用 <Up>/<Down> 键进行常规命令历史记录导航的功能:
cnoremap <expr> <Up> wildmenumode() ? "\<C-E>\<Up>" : "\<Up>"
cnoremap <expr> <Down> wildmenumode() ? "\<C-E>\<Down>" : "\<Down>"
也可设定只针对特定类型命令行的选项。如仅在搜索时使用更矮的弹出菜单:
autocmd CmdlineEnter [\/\?] set pumheight=8
autocmd CmdlineLeave [\/\?] set pumheight&
附 加 fuzzy-file-picker live-grep
命令行自动补全也可进行扩展,提供更高级的功能。
例如,可将原生的 :find 命令改造为一个提供模糊匹配的交互式文件选择器:
set findfunc=Find
func Find(arg, _)
if empty(s:filescache)
let s:filescache = globpath('.', '**', 1, 1)
call filter(s:filescache, '!isdirectory(v:val)')
call map(s:filescache, "fnamemodify(v:val, ':.')")
endif
return a:arg == '' ? s:filescache : matchfuzzy(s:filescache, a:arg)
endfunc
let s:filescache = []
autocmd CmdlineEnter : let s:filescache = []
:Grep 命令用于搜索匹配指定模式的文本行,并在用户键入时动态更新搜索结果 (输入
两个字符后触发;注意: 需要下一小节里提供的 CmdlineLeavePre 自动命令支持):
command! -nargs=+ -complete=customlist,<SID>Grep
\ Grep call <SID>VisitFile()
func s:Grep(arglead, cmdline, cursorpos)
if match(&grepprg, '\$\*') == -1 | let &grepprg ..= ' $*' | endif
let cmd = substitute(&grepprg, '\$\*', shellescape(escape(a:arglead, '\')), '')
return len(a:arglead) > 1 ? systemlist(cmd) : []
endfunc
func s:VisitFile()
let item = getqflist(#{lines: [s:selected]}).items[0]
let pos = '[0,\ item.lnum,\ item.col,\ 0]'
exe $':b +call\ setpos(".",\ {pos}) {item.bufnr}'
call setbufvar(item.bufnr, '&buflisted', 1)
endfunc
退出命令行时自动选中补全列表中的首个项目,并且对于 :Grep ,将输入的匹配模式添
加到命令行历史记录:
autocmd CmdlineLeavePre :
\ if get(cmdcomplete_info(), 'matches', []) != [] |
\ let s:info = cmdcomplete_info() |
\ if getcmdline() =~ '^\s*fin\%[d]\s' && s:info.selected == -1 |
\ call setcmdline($'find {s:info.matches[0]}') |
\ endif |
\ if getcmdline() =~ '^\s*Grep\s' |
\ let s:selected = s:info.selected != -1
\ ? s:info.matches[s:info.selected] : s:info.matches[0] |
\ call setcmdline(s:info.cmdline_orig) |
\ endif |
\ endif
关于插入模式下的自动补全功能,参见 ins-autocompletion 。
vim:tw=78:ts=8:noet:ft=help:norl: