cmdline

cmdline.txt 适用于 Vim 9.2 版本。 最近更新: 2026年5月 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-QCTRL-V 相同。但部分终端会将其用于流控制,而无法用于按本义插 入功能,此时请改用 CTRL-QCTRL-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-RCTRL-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-MCTRL-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-NCTRL-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_#< 可通过 :oldfilesv: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 放弃当前命令行,回到普通模式。 :closeCTRL-W c、 :exit:xitCTRL-\ 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 。 自 动 命 令 命令行窗口使用两种自动命令事件: CmdwinEnterCmdwinLeave 。这些 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: