ITADN
kyx0r/nextvi
README.md
以下内容由 AI 翻译,如有问题请点此提交 issue 反馈

Nextvi(1) 通用命令手册 Nextvi(1)

NAME Nextvi - 一个小型 vi/ex 终端文本编辑器

SYNOPSIS vi [-aemsv] [file ...]

DESCRIPTION Nextvi 是 vi(1) 命令行文本编辑器的现代克隆版本, 最初由 Bill Joy 于 1976 年为基于 Unix 的系统开发。 Nextvi 基于 vi(1) 的许多标准功能构建,包括 一种独特的模态界面,允许用户在 normal、 insert 和 command 模式之间切换,以高效地操作文本。 其他增强功能包括无限制的宏系统、 语法高亮、键位映射、双向 UTF-8 支持,以及 众多其他功能。Nextvi 依然保持高效、可移植 且易于修改,确保其在未来多年内持续相关且保持高质量。

OPTIONS -a 启用备用终端屏幕 -e 启动时进入 ex 模式 -m 禁用初始文件读取消息 -s 启动时进入原始 ex 模式 -v 取消设置所有选项

MANPAGE NOTATION 一个闭包,其中 x 表示字符字面量 [x] 一个闭包,其中 x 表示可选参数 {x} 一个闭包,其中 x 表示必需参数 "x" 一个闭包,其中 x 表示字符串 <^X> 表示 ctrl 键 X < > 空格分隔闭包中的替代项 # 闭包中的十进制表示 x-y 从 x 到 y 的范围

VI 普通模式 [#]j 向下移动 # 行 [#]k 向上移动 # 行 [#]+ [#]<^M> [#] 向下移动 # 行,光标位于缩进之后 [#]- 向上移动 # 行,光标位于缩进之后 [#]h 向左移动 # 列 [#]l 向右移动 # 列 [#]f{arg} 向前移动 # 次,定位到字符 arg [#]F{arg} 向后移动 # 次,定位到字符 arg [#]t{arg} 向前移动 # 次,直到字符 arg 之前 [#]T{arg} 向后移动 # 次,直到字符 arg 之后 [#], 向后重复上次 移动 # 次 [#]; 向前重复上次 移动 # 次 [#]E 向前移动 # 次,定位到单词末尾,跳过标点 [#]e 向前移动 # 次,定位到单词末尾 [#]B 向后移动 # 次,定位到单词开头,跳过标点 [#]b 向后移动 # 次,定位到单词开头 [#]W 向前移动 # 次,定位到单词开头,跳过标点 [#]w 向前移动 # 次,定位到单词开头 vw 切换 区域的单行模式 [#]( 向下移动 # 次,定位到下一个句子边界 [#]) 向上移动 # 次,定位到下一个句子边界 [#]{ 向下移动 # 次,定位到下一个 <{> 节 [#]} 向上移动 # 次,定位到下一个 <{> 节 [#][ 向下移动 # 次,定位到下一个 节 [#]] 向上移动 # 次,定位到下一个 节 ^ 移动到缩进后的行首 0 移动到行首 $ 移动到行尾 [#]| 跳转到第 # 列 [#] 向前移动 # 个字符 [#]<^H> [#] 向后移动 # 个字符 % 移动到最近的 <] ) } [ ( {> 对 {#}% 移动到第 # 百分比行号 '{} 移动到行标记 `{} 移动到带有光标位置的行标记 gg 跳转到缓冲区第一行 [#]G 跳转到缓冲区最后一行或第 # 行 H 移动到屏幕最高行 L 移动到屏幕最低行 M 移动到屏幕中间行 z. 以光标为中心居中屏幕 z<^M> z 以顶部行为中心居中屏幕 z- 以底部行为中心居中屏幕 [#]<^E> 向下滚动 1 或 # 行,保留 # 和光标位置 [#]<^Y> 向上滚动 1 或 # 行,保留 # 和光标位置 [#]<^D> 向下滚动半屏大小。如果 [#],将滚动设置为 # 行 [#]<^U> 向上滚动半屏大小。如果 [#],将滚动设置为 # 行 <^B> 向上滚动整屏大小 <^F> 向下滚动整屏大小 # 显示全局和相对行号 2# 永久切换显示全局行号 4# 永久切换显示缩进后的相对行号 8# 永久切换显示相对行号 V 切换显示隐藏字符: <^C> 为 切换显示行运动编号 {<1-5>}<^C> 选择行运动编号模式 1-5 <^V> 循环切换行运动编号模式 [#]<^R> 重做 # 次 [#]u 撤销 # 次 <^I> 打开从光标到行尾的文件路径 <^K> 将当前缓冲区写入文件。第二次尝试时强制写入 [#]<^W>{arg} 取消缩进 arg 区域 # 次 [#]<{arg} 向左缩进 arg 区域 # 次 [#]>{arg} 向右缩进 arg 区域 # 次 [#]"{}{cmd} 使用寄存器 arg 执行普通命令 cmd。# 应用于 cmd [#]"{}q 开始录制并将 rr ex 选项设置为 arg 寄存器。# 保留寄存器内容 q 停止录制并将 rr ex 选项设置为 0 R 打印寄存器及其内容 [#]&{} 以非阻塞模式执行 arg 寄存器宏 # 次 [#]@{} 以阻塞模式执行 arg 寄存器宏 # 次 [#]@@ 执行上一个宏 # 次,阻塞 [#]&& 执行上一个宏 # 次,非阻塞 [#]@: [#]&: 将 <:> 寄存器作为 ex 命令执行 # 次 [#]. 重复上一个普通命令 # 次。可重复的命令: x X D C s S Y p P r d c ~ gu gU g~ ! > < ^W i I a A o O ci di J K [#]v. 重复上一个向下移动 # 行的普通命令 [#]Q 递归进入 ex 模式。# 保留当前水平 滚动 : 进入 ex 提示符 [#]!{arg} 基于 # 或 arg 区域进入管道 ex 提示符 vv 进入 ex 提示符,使用历史缓冲区 b-1 中的最后一行 [#]vr 进入 %s/ ex 提示符。从光标处插入 # 个单词 [#]vt[#arg] 进入 .,.+0s/ ex 提示符。从光标处插入 # 行。 从光标处插入 #arg 个单词 [#]v/ 进入 re ex 提示符以设置正则表达式关键字。从光标处 插入 # 个单词 v; 进入 ! ex 提示符 [#]vi 进入 %s/ ex 提示符。包含将空格更改为 制表符的正则表达式。# 修改制表符宽度 [#]vI 进入 %s/ ex 提示符。包含将制表符更改为 空格的正则表达式。# 修改制表符宽度 vo 移除行尾空白和 <\r> 行尾符 <^G> 打印缓冲区状态信息 1<^G> 启用永久状态行 2<^G> 禁用永久状态行 ga 打印字符信息 1ga 启用永久字符信息行 2ga 禁用永久字符信息行 [#]gw 将一行硬换行到 # 列限制。默认:80 [#]gq 将缓冲区硬换行到 # 列限制。默认:80 [#]g~{arg} 切换 arg 区域的字符大小写 # 次 [#]gu{arg} 将 arg 区域转换为小写 # 次 [#]gU{arg} 将 arg 区域转换为大写 # 次 [#]~ 向前切换 # 次字符大小写 i 进入插入模式 I 在行首缩进后进入插入模式 A 在行尾进入插入模式 a 向前 1 个字符处进入插入模式 o 在下方创建新行并进入插入模式 O 在上方创建新行并进入插入模式 [#]s 删除 # 个字符并进入插入模式 [#]S 删除 # 行的所有内容并进入插入模式 [#]c{arg} 删除 arg 区域 # 次并进入插入模式 C 从光标处删除到行尾并进入插入模式 [#]d{arg} 删除 arg 区域 # 次 D 从光标处删除到行尾 [#]x 从光标处向前删除 # 个字符 [#]X 从光标处向后删除 # 个字符 [#]di{} 删除 arg 对内部内容,跳过 # 个匹配 [#]ci{} 删除 arg 对内部内容并进入插入模式。跳过 # 个匹配 [#]r{arg} 从光标处向前用 arg 替换 # 个字符 [#]K 拆分一行 # 次 [#]J 合并 # 行 [#]y{arg} 复制 arg 区域 # 次 [#]Y 复制 # 行 [#]p 在当前行下方或光标位置下方粘贴默认寄存器 # 次 [#]P 在当前行上方或光标位置上方粘贴默认寄存器 # 次 m{} 设置缓冲区局部行标记 <^T> 设置全局行标记 0。全局标记始终有效 {<0 2 4 6 8>}<^T> 设置全局行标记 # {<1 3 5 7 9>}<^T> 切换到全局行标记 # [#]<^7>{<0-9>} [#]<^_>{<0-9>} [#]<^/>{<0-9>} 显示缓冲区列表,并根据提示时的 # 或 0-9 索引进行切换 <^^> <^6> 切换到上一个缓冲区 [#]<^N> 切换到下一个缓冲区,# 在向前和向后之间切换方向 \ 切换到 /fm/ 缓冲区 b-2 {#}\ 刷新 b-2 中的次要目录列表 vb 递归进入 b-1 历史缓冲区。退出时将当前行插入 ex 提示符 z1 将备用键位映射设置为波斯语键位映射 z2 将备用键位映射设置为俄语键位映射 ze 切换到英语键位映射 zf 切换到备用键位映射 zL 将 td ex 选项设置为 2 zl 将 td ex 选项设置为 1 zr 将 td ex 选项设置为 -1 zR 将 td ex 选项设置为 -2 [#]/ 正则搜索提示符,向下移动 1 个或 # 个匹配项 [#]? 正则搜索提示,向上移动 1 或 # 个匹配项 [#]n 重复正则搜索,移动 1 或 # 个匹配项 [#]N 重复正则搜索,反向移动 1 或 # 个匹配项 <^A> 从光标处正则搜索 1 个单词,不居中,环绕移动 向上或向下 * 正则搜索,不居中,环绕移动向上或向下 {#}* {#}<^A> 正则搜索,将关键字设置为从光标处 # 个单词 <^]> 基于 b-2 中的目录列表向前进行文件系统正则搜索 为 <^P> 回退设置全局行标记 0 {#}<^]> 向前进行文件系统正则搜索,将关键字设置为从光标处 # 个单词 [#]<^P> 向后进行文件系统正则搜索 <^Z> 挂起 vi <^L> 强制重绘整个屏幕并更新终端尺寸 [#]Z{} 退出并清理终端,强制退出 # 个递归级别 [#]Zz 退出并提交历史命令,强制退出 # 个递归 级别 ZZ 退出并将未保存的更改写入文件 <ESC ^C> 取消任何待处理的输入或命令

VI 区域 区域是 vi 普通命令,用于定义 vi 运动的 [h v] 范围。 使用“move”一词描述的命令定义了一个区域。

 j + <^M> <Enter> - k h l f F t T , ; B E b e W w ( ) { } [ ] ^ 0 $
         <Space> <^H> <Backspace> % ' ` G H L M / ? n N * <^A>

所有区域

VI 运动 运动是 vi 普通模式命令,在 [h v] 范围内运行。 使用“区域”一词描述的命令会消耗一个区域。 运动可以前缀或后缀 [#]。

 <^W> > < ! c d y g~ gu gU
         所有运动

 dd yy cc g~~ guu gUU >> << <^W><^W> !!
         可以使用 [#] 作为行数的特殊运动

 示例:
 3d/int  删除文本直到第 3 个 "int" 关键字
 3dw     删除 3 个单词(前缀 [#])
 d3w     删除 3 个单词(后缀 [#])
 "ayl    将一个字符复制到 <a> 寄存器
 "Ayw    将一个单词追加到 <a> 寄存器

VI/EX 插入模式 <^H> 删除一个字符,为空时重置 ex 模式 <^U> 删除至 <^X> 标记或全部 <^W> 删除一个单词 <^T> 增加缩进 <^D> 减少缩进 <^]> 在 0-9 寄存器中循环选择粘贴寄存器 <^>{} 选择粘贴寄存器参数。<^> 选择默认寄存器 <^P> 粘贴一个寄存器 <^X> 标记自动补全和 <^U> 起始位置。<^X> 重置 标记 <^G> 为自动补全索引当前缓冲区 <^Y> 重置所有已索引的自动补全数据 <^R> 向后循环自动补全选项 <^N> 向前循环自动补全选项 <^B> 在 vi 插入模式下打印自动补全选项 <^B> 在 ex 提示符中递归进入 b-1 历史缓冲区。退出时 将当前行插入 ex 提示符 <^A> 在历史缓冲区 b-1 中循环行 <^Z> 挂起 vi/ex <^L> 在 vi 模式下重绘屏幕,在 ex 模式下清理终端 <^O> 递归地在 vi 和 ex 模式之间切换 <^E> 切换到英文键盘映射 <^F> 切换到备用键盘映射 <^V>{} 读取一个字面字符参数 <^K>{arg} 读取一个双字符序列参数 <^C> 在 vi 中退出插入模式,在 ex 中重置 <^M> 在 vi 中插入 ,在 ex 中提交命令

EX Ex 是 Unix 系统上的一款强大行编辑器,最初由 Bill Joy 于 1976 年开发。这一基本工具是 vi 的骨干,使其能够执行命令、宏,甚至根据需要转换为纯命令行界面 (CLI)。

EX PARSING 解析遵循以下结构: [][prefix][cmd][][args] Ex 命令由 发起并分隔。字段可以由 填充。[prefix] 是被 [cmd] 消耗的字段,它接受 [range] 结构字符。[prefix] 结构内部的填充会被折叠,嵌套块内部除外。[cmd] 和 [args] 之间只能有一个填充。为了避免脚本中的歧义,建议在 [cmd] 和 [args] 之间始终使用一个填充。

 示例:
 :evi.c
         解析为 ":e vi.c"
 :efbc
         解析为 ":ef bc" 而非 ":e fbc"
 :e  vi.c
         编辑 " vi.c"。需要 <pad>

EX ESCAPES [args] 和 [prefix] 块中的特殊字符在通过 <> 转义后会变为普通字符。转义遵循非 POSIX 奇偶规则:紧邻特殊字符之前的转义会被减半,奇数个转义使特殊字符变为普通字符,其他位置的转义则为字面量。

 ( ^ ] -
         正则表达式 "[]" 表达式中的特殊字符
 ( ) { + * ? ^ $ [ | \ . \< \>
         正则表达式中的特殊字符
 \ : % !
         ex 中的特殊字符

EX 扩展 <%> 在 [args] 中展开为当前缓冲区的路径名,或者当其后跟随相应的缓冲区编号时,展开为该缓冲区的路径名。 %# 展开为最近交换的缓冲区的路径名。 %@ 展开为指定的寄存器。

 示例:复制当前文件并编辑它
 :!cp % %_:e %_
 示例:插入当前缓冲区的路径名
 :&i%
 示例:回显 <a> 寄存器的值
 :!echo %@97

 <!> 在 [args] 中开始并可选地结束一个包含外部命令的块。该块执行并展开为产生的 stdout 和 stderr。

 示例:用 $RANDOM 的值替换 "int"
 :%s/int/!printf "%s" $RANDOM!
 示例:插入 ls shell 命令的输出
 :&i!ls
 示例:更高效地插入 ls 的输出
 :;c!ls!<^V><ESC>

EX 范围 某些 ex 命令可以带有范围前缀。 [range] 前缀实现垂直和水平范围。 [vrange] 前缀实现垂直范围和水平位置。 如果没有 [cmd],[vrange] 替换 [prefix]。

 [% |][, ;][#][. $ ' > <][- + * / %][#num]
         所有范围结构
 {|}{cmd}[|]
         Ex 子命令结构
 {>}[regex][>]
         向前搜索结构
 {<}[regex][<]
         向后搜索结构
 '{#mark}
         标记结构

% 从第一行到最后一行的范围 | 开始 ex 子命令块 , 垂直范围分隔符 ; 水平范围分隔符 # 回退到范围结构中的前一个值 . 当前位置 $ 缓冲区最后一行或行尾 ' 开始标记结构 > 开始向前搜索块 < 开始向后搜索块 - 减去后续数字 + 加上后续数字 * 乘以后续数字 / 除以后续数字 % 对后续数字取模 #num 数字或位置

示例: :1,5p 打印第 1 行和第 5 行 :.-5,.+5p 打印当前位置上下各 5 行 :>int>p 打印 "int" 的第一次出现 :<int<p 反向打印 "int" 的第一次出现 :.,>int>p 打印直到找到 "int" :<int<,.p 反向打印直到找到 "int" :> 使用之前设置的正则表达式关键字进行搜索 :'100,'97p 打印从标记 到标记 的行 :%p 打印缓冲区中的所有行 :$p 打印缓冲区中的最后一行 :$*50/100+1 跳转到文件的 50% 处 :;50 跳转到字符偏移量 50 :10;50 跳转到第 10 行字符偏移量 50 :10;.+5 跳转到第 10 行 +5 字符偏移量 :'97;'97 跳转到标记 行偏移量标记 :;$ 跳转到行尾 :5;>int> 在第 5 行搜索 "int" :.;<int< 在当前行反向搜索 "int" :;5;+10= +10 是相对于初始当前偏移量,而不是 5 :;5;#+10= +10 是相对于 5 :;>int>+3;#>>p 打印当前行中由 "int" 包围的文本 :|grp1|;>(a)+>+1|grp|;#>>p 打印由非确定性模式 "a+" 包围的文本

EX 命令 [range]f>[regex] [vrange]f<[regex] 范围搜索

         如果未找到目标,则返回错误。

示例:未指定范围,仅当前行 :f>int 示例:反向 :f<int 示例:指定范围 :10,100f>int

 [range]f+[regex]
 [vrange]f-[regex]
         递增范围搜索

         等效于 :f> 和 :f< 命令,但后续命令
         会越过匹配边界前进。不能原地匹配。

 [vrange]f[regex]
         模糊搜索提示

         进入带有匹配列表的模糊搜索提示。
         匹配项前缀为选择编号和行号。
         如果匹配项少于 10 个,可以使用数字 0-9 选择匹配项。
         <^C> 或 <ESC> 用于中止。
         <^M> 或 <Enter> 用于输入大于 9 的选择编号。

         未指定范围时评估为 <%> 范围。
         未指定范围时最多显示 xrows * 3 个匹配项。

 [vrange]g[<Delim>][regex][<Delim>][cmd]
         全局命令

         对匹配指定正则表达式的行范围执行 ex 命令。
         如果没有行匹配该模式,则返回错误。

         未指定范围时评估为 <%> 范围,嵌套时评估为 <.> 范围。

         示例:删除所有空行
         :g/^$/d

         示例:打印匹配之前设置的正则表达式的行
         :g//p

可以在一个全局命令中链接多个 ex 命令。 要链接命令,必须对 ex 分隔符 <:> 转义一次。

         示例:打印并追加匹配 "int" 的行到寄存器 <a>
         :g/int/p\:ya+ 97

         可以在全局命令内部嵌套全局命令。
         第一个全局命令不会在由嵌套全局命令修改的行上执行。

         示例:嵌套全局命令
         向所有包含 "int" 且以 <;> 结尾的行追加 "has a semicolon"。
         :g/int/g/;$/& A has a semicolon

         示例:提取/打印 "()" 内的数据
         :grp1:err4:g/./;0\:;>(\().+\)>;#>.+(\))>+1p:err1:grp

 [vrange]g![<Delim>][regex][<Delim>][cmd]
         反转全局命令

 [range]re[regex]
         设置正则表达式关键字

         Range 会转义其文本并将其用作正则表达式。

         示例:将关键字设置为 "int"
         :re int
         示例:从第 1 行到第 3 行设置关键字
         :1,3re

 [vrange]i[str]
         进入 ex 插入模式

         [str] 指定插入缓冲区中的初始输入。
         在原始 ex 模式下,[str] 会被直接注入并绕过交互模式。

示例:在 vi/ex 中插入 "hello" :i hello<^M> 示例:在 vi/ex 中插入 "hello" 并去除首尾空白 :i hello<^M><^M> 示例:在 vi/ex 中丢弃更改 :i hello<^M><^C> 示例:立即插入 "hello" :i hello<^V> 示例:在指定位置之前插入 "hello" :-1i hello<^V> 示例:在第 1 行之前插入 "hello"(特殊情况) :0i hello<^V> 示例:在原始 ex 模式中插入 "hello" i hello 示例:在原始 ex 模式中插入两行 i hello<^M>world 示例:在原始 ex 模式中插入 "hello"(交互式) i<^M>hello<^M>.<^M>

 [range]c[str]
         进入 ex 更改模式

         结合 seq 和 lim ex 选项,此命令最适合修改非常长的行。
         在 32 位构建中,最大插入缓冲区约为 1.33GB。
         在 32 位构建中,最大可寻址行大小为 2.0GB。

示例:用 "hello" 替换当前行 :c hello<^M> 示例:用 "hello" 替换第 1-5 行 :1,5c hello<^M> 示例:在当前字符偏移处插入 "hello" :;c hello<^M> 示例:在行尾插入 "hello" :;$c hello<^M> 示例:在第 5 行行尾插入 "hello" :5;$c hello<^M> 示例:从当前位置删除 5 个字符 :;;+5c<^M>

 [range]d
         删除行

         示例:从当前位置删除到缓冲区开头
         :1,.;0;d
         示例:从当前位置删除到缓冲区末尾
         :.,$;;$d

 [vrange]j[any]
         合并行

         任何参数都会激活填充模式。
         如果没有可合并的内容,则返回错误。

         示例:合并所有行
         :%-1j
         示例:用空格填充合并所有行
         :%-1j x

 [range]s[<Delim>][regex][<Delim>][str][<Delim>][<g>][<m>][#reg]
         替换

         在指定范围的行中,查找并替换与
         括号内的正则表达式匹配的文本,替换为括号内的替换字符串。
         如果没有执行替换,则返回错误。

         示例:范围限定
         :1,5;5;5s/term1/term2/

示例:替换之前设置的匹配正则表达式 :%s//term2/

         [str] 中的替换反向引用会插入由 \# 指定的匹配组的文本,其中 # 是组号。数字会贪婪地消耗到最高存在的组,其余部分为字面量。

         示例:替换反向引用
         this is an example text for subs and has int or void
         :%s/(int)|(void)/pre\0after
         this is an example text for subs and has preintafter or void
         :%s/(int)|(void)/pre\2after/g
         this is an example text for subs and has prepreafterafter or prevoidafter

         示例:使用 <g> 进行全局替换
         :%s/term1/term2/g

         示例:多行模式 <m>
         :.,+1s/term1<^V><^M>term2/term3/m

         示例:原地编辑寄存器 <a>
         :s/term1/term2/97g

 ud      撤销

         如果没有可撤销的内容,则返回错误。

 rd      重做

         如果没有可重做的内容,则返回错误。

 [range]p[str]
         从缓冲区打印行

         无范围时,根据 left ex 选项的值打印一行。
         参数打印求值后的参数。

示例:使用字符偏移范围 :1,10;5;5p 示例:交错字符偏移范围 :1;5,10;5p 示例:从偏移 5 到 10 打印当前行 :.;5;10p 示例:打印缓冲区路径名 :p %

 [range]=[<0-3 Any>][any]
         打印范围编号

         参数 0-3 选择特定编号。
         任何非<0-3>或额外参数将绕过缓冲区范围检查。
         无参数时打印所有范围编号。

         示例:仅打印当前字符偏移
         :;= 2
         示例:打印标记 <a> 的值
         :'97=
         示例:计算 75 - 100
         :,75-100=1p

 =?[any]
         打印最后错误

         任何参数都会转发错误状态。

 [range]m{#marks}
         设置行标记

         标记是由空格分隔的 ID,在范围的起始和结束之间交替设置。

         示例:将范围存储在 <a> 和 <s> 中,以便在 :f> 中稍后重用
         :>top>,#>bottom>m 97 115:'97,'115f>middle

 [range]ya[#reg]
         复制到寄存器

         无参数时复制到默认寄存器。

         示例:使用范围复制到 <a>
         :1,5;5;5ya 97

 [range]ya+[#reg]
         复制并追加到寄存器

         示例:追加到寄存器 <1>
         :ya+ 49

ya![#reg] 释放寄存器

 [range]pu[#reg][any][\!{cmd}]
         粘贴或管道传输寄存器

         示例:在第 1 行字符偏移 5 处粘贴 <a>
         :1;5pu 97
         示例:在第 1 行之前粘贴 <a>(特殊情况)
         :0pu 97
         示例:将默认寄存器复制到 X11 剪贴板
         :pu \!xclip -selection clipboard
         示例:将寄存器 <a> 复制到 X11 剪贴板
         :pu 97 \!xclip -selection clipboard

 [#reg]reg[str]
         打印寄存器或放入寄存器

         前缀选择寄存器,参数替换其内容。
         无参数的前缀重新分配默认寄存器。

         示例:移动打印位置以查看屏幕外的寄存器部分
         :1left:reg
         示例:将 "hello" 放入寄存器 <1>
         :49reg hello

 [#reg]reg+[str]
         打印寄存器或追加到寄存器

 e[path]
         在指定路径打开文件

         无参数打开 "unnamed" 缓冲区。
         在 32 位构建中,大于 2.0GB 的文件会被截断。
         换行发生在第一个空终止符或 EOF 之前。

 e![path]
         强制在指定路径打开文件

         无参数从文件系统重新读取当前缓冲区。

 [vrange]ef[regex]
         使用模糊搜索提示打开文件

要求 b-2 缓冲区已回填目录列表。

         示例:使用 :fd 回填 b-2
         :fd
         示例:使用 find 回填 b-2
         :b-2:%!find .

         提示行为与 :f 命令等效。

         示例:进入提示并打印整个列表
         :ef
         示例:搜索包含 "v" 的路径名
         :ef v

 [vrange]ef![regex]
         :ef 的强制版本

 [range]r[path]
 [range]r[\!{cmd}]
         读取文件或管道

         范围基于目标计算。
         无范围时求值为 <%> 范围。
         无参数时求值为当前缓冲区路径。

         示例:读取文件
         :r vi.c
         示例:通过管道输入所有数据
         :r \!ls
         示例:仅通过管道输入第 3、5 行
         :3,5r \!ls

 [range]w[path]
 [range]w[\!{cmd}]
         写入文件或管道

         无范围时求值为 <%> 范围。
         无参数时求值为当前缓冲区路径。

         示例:写入文件
         :w vi.c
         示例:通过管道输出所有数据到 less
         :w \!less
         示例:仅通过管道输出前 10 行
         :1,10w \!less

 [range]w![path]
         强制写入文件

 [range]wq[path]
 [range]wq[\!{cmd}]
         写入文件或管道并退出

[range]wq![path] [range]wq![!{cmd}] 强制写入文件或管道并强制退出

 [range]x[path]
         写入未保存的更改并退出

 [range]x![path]
         强制写入未保存的更改并强制退出

 [#lvl]q[0-255]
         退出

         前缀退出 [#lvl] 个 ex 递归层级。
         参数指定 shell 退出码。

         示例:条件性地退出当前层级及其上方 1 层
         :%f>marker:??!p no marker\:1q:s/old/new/g:w

 [#lvl]q![0-255]
         强制退出

         前缀强制退出 [#lvl] 个递归层级。
         无前缀则退出所有递归层级。

         示例:将寄存器 <#0> 在 3 层深处设置为 "hello",强制退出
         当前层级及其上方 2 层,并在外部打印该寄存器
         :&Q&Q\\\:&Q0reg hello\\\\\\\:2q\\\\\\\!:p %@0

 b[#index]
         打印缓冲区或切换到某个缓冲区

         临时缓冲区与主缓冲区是分开的,
         并通过负索引进行选择。

         示例:切换到第 5 个缓冲区
         :b5
         示例:切换到 /hist/ ex 历史缓冲区
         :b-1
         示例:切换到 /fm/ 目录列表缓冲区
         :b-2
         示例:切换到 /sc/ 草稿缓冲区
         :b-3

 bp[path]
         设置当前缓冲区路径

 bs[any]
         设置当前缓冲区已保存

参数重置会清除撤销/重做历史

 bx[#]   设置允许的最大缓冲区数量

         如果指定的数量小于当前正在使用的缓冲区数量,
         多余的缓冲区将被释放。
         无参数时重置为默认值 10。

 cd[path]
         设置工作目录

         无参数时,如果当前目录已被删除
         或卸载,则重新链接当前目录。

         当前打开缓冲区的文件路径将自动调整,
         以反映新设置的工作目录。

 fp[path]
         清除或设置次要目录路径

 fd[path]
         在 b-2 缓冲区中计算目录列表

         无参数时使用次要目录或工作目录路径。

 inc[regex]
         用于 :fd 计算的包含正则表达式

         无参数时禁用该过滤器。

         示例:仅包含以 .c 结尾的子模块目录中的文件
         :inc submodule.*\.c$
         示例:排除 .git 和 submodule 文件夹
         :inc (^(?\:(?\!^\.git|^submodule).)+[^/]+$)

 [range]![cmd]
         运行外部程序

         当指定范围时,缓冲区的数据会被管道传输到外部
         程序。随后,产生的 stdout 和 stderr 会被管道传回
         缓冲区,替换原始范围的内容。
         无范围时,如果 shell 退出码不为零,则返回错误。

示例:以臭名昭著的方式对缓冲区进行排序 :%!sort 示例:使用 sed 将 "int" 替换为 "uint" :%!sed -e 's/int/uint/g' 示例:将 ls 命令的结果通过管道输入,不进行行替换 :;$+1!ls 示例:使用 tr 将当前位置的单词大写 :;;>\>>!tr '[:lower:]' '[:upper:]'

 &{macro}
         全局非阻塞宏

         执行原始 vi 输入序列。
         非阻塞宏在到达序列末尾时不应等待输入。执行其他
         宏的非阻塞宏总会到达终止点。

         示例:执行 vi 插入语句
         :& ihello
         示例:执行 :hello
         :& \:hello<^V><^M>
         示例:执行 vi "ci(int" 宏
         :& ci(int
         示例:在非阻塞宏中嵌套阻塞宏
         :& \:@ \\\:blocking<^V><^M>i continue in non-blocking
         示例:启用永久 vi 行号
         :& 2#

 @{macro}
         全局阻塞宏

         执行原始 vi 输入序列。
         阻塞宏在到达序列末尾时应等待输入。执行其他宏的
         阻塞宏可能导致输入拥塞。

示例:执行 vi 插入语句 :@ ihello 示例:在 <:> vi 提示符中插入 "hello" :@ :hello 示例:执行 vi "ci(int" 宏 :@ ci(int 示例:执行 "ci(int" 并退出插入模式 :@ ci(int<^V><^C> 示例:将 "ci)INT" 作为后续操作执行 :@ ci(int<^V><^C>ci)INT 示例:在用户退出插入模式后执行 vi "dw" 命令 :@i:@dw

 [#count <$>]?[cond]
         当型循环

         重复 [cond] [#count] 次,或使用 [<$>] 无限循环。
         一旦 [cond] 返回错误或超出计数,当型循环即被中断。
         [cond] 的错误状态会被转发。
         无前缀时,[#count] 默认为 1。

         示例:尝试使用任意计数连接文件中的每一行
         :10000? & J
         示例:撤销所有操作
         :$? ud
         示例:重复执行 ex 命令链 10 次
         :10? 1p\:5p\:10p

 [#count <$>]?![cond]
         反向当型循环

 [prefix]??[then]
 {prefix}??
         条件分支

         分支取决于上一条命令的错误状态。
         [then] 的错误状态会被转发。
         无前缀且无参数时,转发上一条命令的错误状态。

不带参数的前缀会将命令链中该点的当前错误状态 捕获到指定的 id 标签中。 Id 标签在所有嵌套命令上下文中是全局的。

         带参数的前缀基于对每个引用 id 的最新捕获值的
         DNF 布尔表达式进行分支。
         如果 id 没有捕获值,则跳过该分支。

         前缀运算符:
         数值型 id 标签
         , AND(优先级较高)
         ; OR(优先级较低)

         示例:仅当 :cd 成功时计算目录
         :cd /blah:?? fd
         示例:仅当第 5 个偏移量包含 "int" 时打印该行
         :;5;#>^int>:?? p
         示例:仅当 vi.c 存在时编辑它
         :![ -f ./vi.c ]:??e ./vi.c:mpt1
         示例:在 id 5 处捕获错误状态,稍后分支
         :>int>:5??:;=:5??p
         示例:如果标签从未设置则跳过
         :2??.=
         示例:AND -- 仅当两个 id 都捕获成功时分支
         :f>int:1??:f>void:2??:1,2??p found both
         示例:OR -- 如果任一 id 捕获成功则分支
         :f>int:1??:f>void:2??:1;2??p found one
         示例:DNF -- (1 AND 2) OR (3 AND 4)
         :1,2;3,4??p then

 [prefix]??![then]
 {prefix}??!
         反向条件

         示例:反向捕获
         :f>int:1??!:1??p int was absent

{prefix}??? 评估前缀标签

         这是一个空操作命令,用于在评估前缀时计算一个布尔表达式
         并返回结果。

         示例:控制 while 循环
         :$? \%f+int\:1??\:\%f+void\:2??\:1,2??p\:1,2???

 ft[filetype]
         设置文件类型

         无参数时打印当前文件类型。
         重新加载高亮 ft,这使得可以重置由 "hlw" 等选项创建的动态
         高亮。

 cm[keymap]
         设置键位映射

         无参数时打印当前键位映射名称。

 cm![keymap]
         设置替代键位映射

 ac[regex]
         设置自动补全过滤正则表达式

         无参数时重置为 led.c 中定义的默认单词过滤正则表达式。

         示例:使用缓冲区中的整行进行自动补全
         :ac .+

 [<0-3>]sc[<esc>][<sep>][<exp>][<exe>]
         设置 ex 特殊字符

         前缀选择要更改的特定字符。
         缺失的参数默认为 <\ : % !>。

         示例:将 <%> 更改为 <a>
         :2sc a
         示例:在单个命令链中使用新设置的分隔符
         :|1sc a|: p cmd1 a p cmd2 a|sc|a0?:p cmd3

 [<0-3>]sc![<esc>][<sep>][<exp>][<exe>]
         设置 ex 特殊字符

         缺失的参数默认为 <#0>。

示例:禁用 :sc! \:

 uc      切换多字节 UTF-8 解码

         此命令在编辑具有混合编码、二进制文件,或终端不支持 UTF-8 或缺少显示 UTF-8
         字符所需字体时特别有用。它通常与 :ph 命令配合使用,以实现
         类似十六进制编辑器的功能。

 uz      切换零宽字符占位符

         隐藏零宽字符,而不是将其渲染为占位符。

 ub      切换多码点序列占位符

         将表情符号等多码点序列传递给终端进行原生渲染,而不是替换为占位符。

 ph[#clow] [#chigh] [#width] [#blen][<Space>][str]
         重新定义占位符

         此命令替换 conf.c 中定义的占位符,
         后续的 :ph 命令会扩展占位符列表。

         示例:将 8 位 ascii (Extended ASCII) 渲染为 <~>
         :ph 128 255 1 1~
         示例:完美支持 ISO/IEC 8859-1 (latin-1)
         :uc:ph 128 160 1 1~
         示例:将控制字节 03 渲染为 "^C"
         :ph 3 3 2 1^C
         示例:重置为 conf.c 中的默认值
         :ph
         示例:禁用 conf.c 中的默认占位符
         :ph:ph0

EX OPTIONS Ex 选项是用于修改全局变量的 ex 命令。 变量存储一个带符号整数。参数设置其值。非数字 参数将返回其第一个字节。未提供参数时,会反转当前 值,除非另有说明。 默认值在下方的参数表示法中显示。

 ai[1]   缩进新行

         这是一个最大缩进长度乘数:值 * 128

 ic[1]   在正则表达式中忽略大小写

 ish[0]  交互式 shell

         通过交互式 shell 执行每个 <!> 命令。
         shell 会在命令执行前加载 .rc 文件。
         这使得可以使用 .rc 文件中预定义的函数、别名
         和 ENV 变量。
         前提条件 1:
                 .rc 指的是特定 shell 的文件名,例如 Bash 中的 .bashrc
                 或 Zsh 中的 .zshrc。
         前提条件 2:
                 环境变量 $SHELL 决定默认
                 shell,否则默认为 /bin/sh。
         前提条件 3:
                 .rc 文件不得产生任何 stdout 或 stderr 输出,
                 否则 <!> 命令将无法返回预期结果。

 grp[0]  正则搜索组

为任何正则搜索操作定义目标搜索组。 当正则搜索的结果需要基于某个组而非默认匹配组时, 这一点变得必要。

         示例:位于 "int" 前缀字符之后的位置
         :grp 1:%f+int(.):grp

 hl[1]   基于 conf.c 中定义的规则高亮文本
 hlr[0]  反向高亮文本
 hll[0]  基于文件类型 hl 高亮当前行
 hlp[0]  基于文件类型 hl 高亮 "[]" "()" "{}" 对
 hlw[0]  基于文件类型 hl 高亮当前单词
 led[1]  启用所有终端输出

 vis[0]  控制启动标志

         bit 1: raw ex 模式
         bit 2: ex 模式
         bit 3: 禁用 :e 消息
         bit 4: 备用终端屏幕

         示例:启用 raw ex 模式
         :vis 3
         示例:禁用 raw ex 模式
         :vis 2

 mpt[0]  控制 vi 提示

         当从 vi 调用 ex 命令后设置为 0 或 1 时,禁用
         "[按任意键继续]" 提示。
         如果 mpt 为负数,提示将保持禁用状态。

         示例:阻止提示和最后一次打印
         :p:p:p:mpt 0
         示例:阻止提示但不阻止最后一次打印
         :p:p:p:mpt 1

order[1] 根据 conf.c 中定义的规则重新排列字符 shape[1] 执行阿拉伯文字母连写 pac[0] 即时打印自动补全建议 ts[8] 用于表示制表符的空格数 td[1] 当前文本方向上下文

         value  2: 仅从左到右
         value  1: 遵循 conf.c 中的 dctxs[],默认从左到右
         value -1: 遵循 conf.c 中的 dctxs[],默认从右到左
         value -2: 仅从右到左

 pr[0]   打印寄存器

         使用字符或数字设置一个特殊寄存器。
         一旦寄存器被设置,所有传入 ex_print 的数据
         都将存储在该寄存器中。

         如果寄存器为大写,则添加 <Newline> 个字符
         以匹配所打印的确切输出。

         当寄存器被分配时,无法使用 R 或 :reg 命令
         显示打印寄存器的内容(自引用问题)。

         示例:精确粘贴当前缓冲区列表,如同 :b 命令
         :pr A:ya! 65: b:pu 65
         示例:存储使用 :p 打印的一行
         :pr A:ya! 65:p

 fr[0]   查找寄存器

使用字符或数字设置寄存器。 寄存器设置后,:f> 和 :f+ 命令将对寄存器的内容 而非当前缓冲区执行多行向前搜索。Range 将匹配映射到 当前缓冲区中的位置。不执行原地匹配的 Range 测试。

         示例:在寄存器 <a> 中搜索 "int"
         :fr a:f>int:??p yes:??!p no:fr
         示例:搜索 "int" 后下一行跟随 "void"
         :%ya97:fr 97:%f>int.void:fr

 rr[0]   记录寄存器

         使用字符或数字设置寄存器。
         寄存器设置后,从终端读取的每个字节都会
         追加到寄存器中。从寄存器重放的输入不会
         被记录,因此重放已记录的寄存器无法记录自身。

         示例:将按键记录到寄存器 <a>
         :rr a
         示例:停止记录
         :rr
         示例:从寄存器 <a> 重放记录
         :& %@97

 lim[-1]
         行长度渲染限制

         设置 vi 模式下非光标行以及 ex 模式下所有行
         的渲染截断长度。

         在编辑包含一行或多行超长行(每行 1MB+)的文件时,
         可提升重绘性能。

示例:合理值 :lim 5000 示例:仅渲染光标行 :lim 0 示例:禁用限制 :lim -1

 seq[1]  控制 Undo/Redo

         当 seq 为 0 时,多个不同的操作将在单步中执行 undo/redo。

         为了在繁重工作负载下优化内存使用,可以通过将 seq 设置为负值来禁用 undo/redo 跟踪。

         示例:在单步中测试 undo/redo 操作
         :&ocontrol test:seq 0:&a step1:&a step2:&a step3:seq
         示例:完全禁用 undo/redo
         :seq -1

 [hscroll]left[0]
         控制水平滚动

         无参数时,使用当前字符偏移量计算值。
         hscroll 使用以下公式计算值:xcols / 2 * hscroll

 err[1]  控制 ex 错误

         位 1:打印错误
         位 2:提前返回
         位 3:忽略错误

         示例:静默并忽略错误
         :err 4
         示例:报告并在第一个错误时返回
         :err 3
         示例:报告且仅考虑最后一个命令的错误状态
         :err 1

EXINIT 环境变量 EXINIT 定义了一组在启动时执行的 ex 命令链, 在所有文件打开后执行一次。这是在 C 或 Unix 管道之外 对 Nextvi 进行脚本化和自定义的唯一方式。 许多标准文本处理工具,如 grep、awk、sed, 都可以用带有 EXINIT 的 Nextvi 来替代。

 使用 printf 配合八进制转义是向 EXINIT 中嵌入控制
 字符的标准方式。

 示例:

 export EXINIT='td 2:order 0:lim 5000'
         设置 ex 选项以优化长行性能

 export EXINIT='b-1:r ./vi.c:b-1'
         将 vi.c 加载到历史缓冲区

 export EXINIT="$(printf 'e ./vi.c:& i\007\003:bx 1:bx')"
         为 vi.c 建立索引以用于自动补全

 export EXINIT="$(printf '97reg o{\n}\003kA\n\t')"
         在寄存器 <a> 中设置 @ 宏

         @a 宏在光标下方创建 <{> 和闭合的 <}>,
         并将光标留在花括号之间的插入模式。

 export EXINIT='98reg \:mpt-1\:;;$w \\\!xclip -selection clipboard\:mpt'
         在寄存器 <b> 中设置 @ 宏

         @b 宏将当前行管道传输到 X11 剪贴板。

 export EXINIT='rr z:vis 2:&Q:b-3:pu 122:wq! bugreport.txt'
         捕获会话以用于错误报告

录制开始写入寄存器 。设置 vis 2 使 直接切换到一个常规 vi 会话,由用户接管。 使用 :q 退出该会话将恢复宏,并将 录制内容写入 bugreport.txt。

REGEX Pikevm 是为 Nextvi 开发的一个快速非回溯 NFA 模拟正则表达式引擎。 它确保正则表达式在恒定空间和 O(n * k) 时间复杂度内求值,其中 是 输入字符串的长度, 表示正则表达式的结构 复杂度(例如,状态转换或交替)。虽然 这并不保证严格的 O(n) 线性运行时性能, 但它确保计算和内存资源在输入上 线性且均匀地分布, 直接影响 常数因子。这一原理类似于 基数排序算法中使用的概念。

 Pikevm 的语法类似于 Plan 9 中的 regexp(7)。
 请忽略本节中的手册页符号。

. 匹配任意单个字符 [N-M] 匹配 N 到 M 的备选范围集合 {N,M} 匹配 N 到 M 次 () 捕获分组 (?:) 非捕获分组 * 重复零次或多次 + 重复一次或多次 | 并集,备选分支 ? 一次或零次匹配,贪婪 ?? 一次或零次匹配,懒惰 ^ 断言行首 $ 断言行尾 < 断言词首 > 断言词尾 (?=) 断言正向先行 (?!) 断言负向先行 (?>) 断言正向后行 (?<) 断言负向后行 (?#) 后行偏移量(字节)

环视表达式使得创建没有它们就无法构建的正则表达式成为可能。它们可以用在正则表达式的任何位置,但必须考虑一些因素。 方面 1: 环视包含一个完整的正则表达式。 方面 2: 环视可以嵌套环视。 方面 3: 像 (?=^word) 这样的静态环视会被优化,绕过正则表达式引擎。 方面 4: 环视最适合用于断言复杂模式的末尾附近,此时引擎已经缩小了潜在匹配的范围。 方面 5: 没有偏移量或偏移量为 0 的环视从上一个字符开始。 偏移量从当前位置减去指定值开始扫描。负偏移量从字符串的开头开始。

SPECIAL MARKS * 上一个 ex 命令的位置 [ 上一个更改的第一个位置 ] 上一个更改的最后一个位置 ' 上一个行区域的位置 ` 上一个行区域的位置

SPECIAL REGISTERS / 上一个正则表达式关键字 : 上一个 ex 命令 <#0> 默认寄存器 <0> 默认寄存器的上一个值(原子) 原子意味着该操作不包含 。 <1-9> 默认寄存器的上一个值(非原子)

代码地图 +--------------+----------------------+ | 537 kmap.h | 键位映射转换 | | 550 vi.h | 定义/辅助 | +--------------+----------------------+ | 351 term.c | 底层 IO | | 372 conf.c | hl/ft/td 配置 | | 460 ren.c | 定位/语法 | | 615 uc.c | UTF-8 支持 | | 666 lbuf.c | 文件/行缓冲区 | | 735 led.c | 插入模式/输出 | | 751 regex.c | pikevm | | 1897 vi.c | 普通模式/通用 | | 1930 ex.c | ex 选项/命令 | | 7777 total | wc -l *.c|sort | +--------------+----------------------+

编译 export CC='g++ -x c' 设置编译器,g++ 示例 export CFLAGS='-s' 设置 CFLAGS,strip 示例 ./cbuild.sh 构建一次 ./cbuild.sh build 构建 ./cbuild.sh debug 带符号构建,静态分析,动态分析,且无 优化 ./cbuild.sh pgobuild PGO 构建在某些 特定应用任务上可带来显著的性能提升 ./cbuild.sh install 将 vi 安装到 $DESTDIR$PREFIX/bin ./cbuild.sh fetch 合并来自上游仓库的提交 ./cbuild.sh bench 性能基准测试:在 vi.c 上删除 2000 个单词

PHILOSOPHY 大多数文本编辑器都积累了大量的技术债务。它们 无法被快速掌握、深入理解或轻松修改。 Nextvi 围绕三大支柱设计:基础、精简和 灵活。基础意味着一套完整而最小的命令集, 用于无限的文本转换。精简意味着简洁、高效、 连贯的实现,且巴士因子为零。灵活意味着 深度可组合性以及通用、可扩展的 C 代码库。按照 传统观念,这三大支柱会被视为 自相矛盾。同时维持这三者挑战了 文本编辑器必须牺牲其一以成全另一者的观念。Nextvi 证明了 共存不仅是可能的,而且是伟大 文本编辑器所必需的。

 “所有软件都很糟糕,但有些比其他更糟糕。”
         - Kyryl Melekhin

SEE ALSO 新功能可以通过 patches 分支中提供的 可选补丁获得。如果你有有意义的贡献 并希望将其公开,补丁可以通过 电子邮件或 GitHub pull request 提交。 https://github.com/kyx0r/nextvi/tree/patches

 Patch2vi 支持工具
 https://github.com/kyx0r/nextvi/tree/patch2vi

 单元测试
 https://github.com/kyx0r/nextvi/tree/test

 用于生成此手册的脚本
 https://github.com/kyx0r/nextvi/tree/manual

统一的带标签发布 https://github.com/kyx0r/nextvi/tree/release

 原始 Neatvi 仓库
 https://github.com/aligrudi/neatvi

 Posix vi(1)
 https://pubs.opengroup.org/onlinepubs/9699919799/utilities/vi.html

 Posix ex(1)
 https://pubs.opengroup.org/onlinepubs/9699919799/utilities/ex.html

 Russ Cox 的 NFA 正则表达式
 https://swtch.com/~rsc/regexp/regexp1.html

 Plan 9 regexp(7)
 https://man.cat-v.org/p9p/7/regexp

AUTHORS Nextvi 由 Kyryl Melekhin k.melekhin@gmail.com 编写。它基于 neatvi(1),后者由 Ali Gholami Rudi ali@rudi.ir 编写。本 手册页受 nepeta nepeta@canaglie.net 启发。

Nextvi 7.4 2026 年 8 月 7 日 Nextvi 7.4