sim 现在能做什么

sim 现在能做什么,按用途分组。每项功能都列出了项目规格中支撑它的需求编号。计划中的功能只在“路线图”下列出。

显示被隐藏的东西

核心理念:文件是什么样,就显示成什么样。

  • 显示不可见字符和双向字符

    从右到左覆盖字符、零宽空格或控制字符,会以品红色块显示为 <U+202E>、<U+200B> 或 ^[。无论单元格处于什么状态都一样:被选中、被搜索命中、位于光标行、处于外部改动之内,或在远处行的雾化之中。它们没有一个会原样发送给终端。文件中字面的文本 <U+202E> 没有色块,因此两者可以区分。

    规格: SAFE-8, UI-15

  • 看起来什么都没有的空白也会标出来

    行尾空白显示为 ·,不间断空格显示为 ⍽,制表符显示为 »:这些标记没有任何代码会使用,绘制在文本之上,不属于文本本身。行尾没有标记,也不使用 - 和 %,因为它们是代码中的普通字符。

    规格: UI-6

  • 标出来自外部的写入

    sim 会监视打开的文件。当另一个进程(构建、格式化工具或其他工具)改写它时,改动的行会在文本中被标出,边框会显示磁盘上有多少处改动,标签页显示 ↯,文件树也会标出该文件。保存时先比较文件的哈希,如果它在你读取之后发生了变化,就不会写入任何内容。在与该检查完全同一时刻发生的写入,仍有可能漏过(见“安全”页)。

    规格: DISK-1, DISK-2, DISK-6, SAFE-5, UI-4, MARK-1

  • 一眼看清相对 git HEAD 的改动

    行号旁的标记表示新增、修改和删除的行;文件树中每个文件有一个状态字母(M、A、U、D、R),文件夹则显示其下最强的那个状态的字母;状态栏显示分支名和 +n ~n -n。这些信息来自 git,在后台运行,绝不会占用按键的处理路径。

    规格: UI-3, UI-5, UI-10

  • 仓库自身的配置无法让 git 运行命令

    运行 git 之前,sim 会先向 git 询问仓库自身的配置。命令行能挡住的都会被关闭:文件系统监视器、钩子、过滤器、外部 diff 和文本转换都不会执行任何东西,文件树会写出被关闭的设置数量(2 git settings off)。如果配置里仍有挡不住的、可能运行命令的项(core.sshCommand、可能引入这类项的 include 等),就不运行 git:文件树不显示 git 标记,并写出 git not run,状态栏会指明相关的键和文件。git 不经过 shell 运行,不使用可选锁,也无法拉取。

    规格: MARK-1, GIT-1, GIT-2, GIT-3, GIT-5

  • 所有不显示任何内容的字符,都会被显示出来

    除了从右到左覆盖字符和零宽空格,sim 还会把标签字符(把指令偷偷传给 AI 助手的手法)、变体选择符(在已发布的扩展中隐藏代码的手法)、谚文填充符、软连字符、行分隔符以及所有未分配的码位,显示为 <U+E0041> 这样的形式,凡是 sim 绘制文本的地方都一样:文件、状态栏、消息,以及文件树和标签页中的名称。表情符号序列、键帽、英格兰、苏格兰和威尔士的旗帜,以及 Nerd Font 图标保持原样。汉字后面跟着表意文字变体选择符时,会显示该选择符。

    规格: SAFE-10, SAFE-11

  • 警示块标记的不只是字符

    品红色表示某处值得再看一眼。除了隐藏字符,文字看起来像某个地址、而链接目标并不是该地址的 Markdown 链接([https://good.example](https://evil.example)),其目标会画在这个色块上;出于安全考虑没有运行 git 的仓库,文件树里会在色块上写出 git not run。

    规格: UI-15, MD-10, GIT-5

该拒绝的拒绝,你的文本不丢

没有你的明确操作,任何人的文本都不会丢失,文件也无法重新配置编辑器。

  • 没有 modeline,没有配置文件,没有插件

    设置和命令绝不会从文件内容中读取,因此文件无法重新配置编辑器。没有可从仓库加载的配置文件,没有插件 API,sim 也不会打开任何网络连接。它记住的只有你选择的外观、图标和 Markdown 视图,各一个词。

    规格: SAFE-9

  • 不会写到一半的保存

    保存时,sim 会在原文件旁写入一个临时文件(以 0600 权限和 O_EXCL 创建),对其执行 fsync,再用 rename 覆盖原文件,并对目录执行 fsync,所以你看到的要么是旧文件,要么是新文件,绝不会是二者的混合。属于他人的文件、有硬链接的文件,或位于只读目录中的文件,会在生成恢复副本后原地保存。sim 拒绝通过他人拥有的链接写入。打开后不做编辑直接保存,输出与原文件逐字节相同。

    规格: SAFE-1, SAFE-2, SAFE-3, SAFE-5

  • 崩溃时不丢文本

    未保存的更改最多每秒生成一次快照,存入私有的状态目录(0700)。崩溃、kill -9 或关闭终端之后,再次打开该文件时,会提示恢复它们,作为一次撤销步骤。最多丢失一秒钟的工作。

    规格: SAFE-6

  • 搜索绝不运行仓库所能控制的东西

    sim 自己在 PATH 的绝对路径条目中查找 ripgrep,并以空环境和 --no-config 运行它,绝不使用 --pre,所以仓库无法让搜索运行它的代码。搜索从不写入任何内容,也从不跟随符号链接走出项目。

    规格: GREP-7, GREP-8

  • 非文本文件以只读方式打开

    不是有效 UTF-8 的文件,或前 8 KB 中含有 NUL 的文件,会以只读方式打开并显示原因,无效字节显示为 U+FFFD。编辑和写入都会被拒绝,因为屏幕上的文本并不等于文件本身。

    规格: SAFE-4

  • 保存冲突时保留两个版本

    当保存时发现文件在磁盘上已被改动,双方的内容都不会丢失。:w! 在把对方的版本复制到状态目录之后保留你的版本,:e! 在为你的版本创建快照之后采用对方的版本。

    规格:

  • --plain:不运行外部进程

    sim --plain 只有核心:calm 外观、单个文件、没有面板,也不运行任何外部程序(不用 git,不用 ripgrep,不用过滤器,不用钩子)。以 root 身份运行或作为 sudoedit 的编辑器时,这是默认行为,状态栏会显示 plain。

    规格:

触达与速度

从“那个文件”到读到它,步骤最少。

  • 从不乱动的项目树

    sim 启动时会打开当前目录的文件树。目录在前,文件在后,各自按名称排序,顺序始终不变,展开状态也保持你离开时的样子,所以你是凭位置而不是靠阅读来找到文件。目录在后台读取:条目到达时才出现,不会挪动它上方的任何内容。

    规格: TREE-1, TREE-3, TREE-4, TREE-5

  • 在浮动窗口中查找文件和文本

    Ctrl-p 按路径做模糊匹配来查找文件,按匹配程度和你打开每个文件的可能性排序。Ctrl-f 随着你的输入搜索所有文件的内容(PATH 中有 ripgrep 时使用它),结果按文件分组,并预览所选的那一行。Esc 会让一切恢复原样。

    规格: FIND-2, FIND-4, GREP-1, GREP-5, PICK-1

  • 可能要打开的文件就地标出

    sim 会记住你打开过哪些文件,并综合最近使用和使用频率对它们排序。最可能的五个文件在文件树中以 • 标出。只需一个键 .,就能把文件树收窄到有改动、已打开或最近打开过的文件。

    规格: MARK-2, MARK-3

  • 多个文件,每个都是完整的编辑器

    每个打开的文件都有各自的撤销、快照、监视和保存。标签栏会显示它们,未保存的更改用粗体 ● 表示。Tab 和 Shift-Tab 用来切换。

    规格: BUF-1, BUF-2, UI-4

  • 快到你察觉不到

    在项目的基准测试中(release 构建、100,000 行的文件、面板打开、语法高亮开启),在 80×24 到 240×60 的屏幕上,单次按键在 p99 下至多耗时 1 ms。在有 100,000 个文件的仓库中,第一帧会在读取文件列表之前就绘制出来:实测 1.8 到 8.7 ms,而要求是 20 ms。任何慢的操作(遍历目录树、询问 git、为高亮做解析)都在后台线程中运行。

    规格: SPEED-1, SPEED-2

  • 只有一个可执行文件:sim

    原先独立的 si 可执行文件已并入 sim:安装只需一个命令,运行也只需一个命令。核心是一个库 sim-editor-core,sim 构建于其上。sim --version 和 sim --help 会打印信息后直接退出,不会触碰终端。

    规格:

  • 按字母选择标签页

    <Space>bp 会给每个标签页标上一个字母,按下该字母即可跳到对应的文件。<Space>bc 用同样的方式关闭标签页,并且绝不会关闭已修改的文件。第一次打开第二个文件时,会有提示告诉你 Tab 和 Shift-Tab,直到你用过它们三次为止。

    规格:

  • 与 git HEAD 对比的变更树

    <Space>ge 会打开只包含与 HEAD 不同的文件的树,已暂存、未暂存和未跟踪的都包括,每个文件带状态字母和 +n −n,每个文件夹带合计。按 Enter 以只读方式打开该文件在 HEAD 中的版本。

    规格: GIT-1, GIT-2, GIT-3, GIT-4, DIFF-1, DIFF-3, DIFF-4

舒适阅读

颜色与布局靠计算得出,而不是凭感觉。

  • 取自你自己调色板的语法颜色

    颜色取自终端的调色板(通过 OSC 4 读取)。色相保持不变,只调整明度,直到文本相对背景达到 |Lc| 75。关键字为红色,字符串和数字为绿色,类型为黄色,函数为青色,注释为灰色斜体;蓝色和品红色从不用于代码。语言根据文件名、扩展名或第一行判断,使用 bat 的语法集。zh 可关闭这些颜色。

    规格: SYN-1, SYN-2, SYN-4

  • Markdown 阅读视图

    在 Markdown 文件中,除光标所在行外,每一行都按阅读时的样子绘制:强调和代码标记不画出来,表格按显示宽度对齐,标注块(> [!NOTE])显示该类型的名称。被隐藏的只有这些标记,绝不会隐藏 #、括号、URL 或任何文本字符,<Space>um 可显示原始文本。

    规格: UI-8, MD-1, MD-10, MD-11

  • 三种外观

    calm 是最朴素的一种:只用四种样式和一种彩色背景。flat 把差异显示为绿色和红色,并给行着上淡色。depth 是默认外观,加入了边框、概览标尺,以及按与光标的距离让文字渐淡的雾化。zl 可在它们之间循环切换。分不清红色和绿色的人适合使用 calm。

    规格: LOOK-1, LOOK-2, LOOK-3

  • 靠测量保证可读

    正文为 |Lc| 90,次要文本为 |Lc| 60(APCA),根据终端背景计算。在 calm 外观中,唯一的改动颜色在 protan(红色觉异常)、deutan(绿色觉异常)和 tritan(蓝色觉异常)三类色觉下仍然可以分辨。整个界面中,一种色相只表示一件事:灰色表示结构,蓝色表示你操作的位置,绿、琥珀、红表示改动,品红色只表示被隐藏或有危险的东西。

    规格: VIS-4, VIS-5, COLOR-1, UI-12

  • 能长住的编辑器

    文件树中的图标(需要 Nerd Font;zi 可关闭)、标签栏、作为编辑器标题的面包屑(src › sim.rs › leader_key)、显示模式、分支、相对 HEAD 的改动和位置的状态栏(只有编码不是 UTF-8、换行符不是 LF 时才会写出)、相对行号、缩进参考线、带标记的滚动条,以及刚复制的内容上的一次闪烁。

    规格: UI-2, UI-5, UI-6, UI-10, UI-11

  • 日文及其他 CJK 文本

    宽字符占两列,文章按日文禁则(kinsoku)规则折行,按词移动会在文字种类变化处切分 CJK 文本,开着输入法(IME)时,全角按键也能当作命令使用。

    规格: VIS-7, VI-10

  • 没有颜色也能用,而且从不只靠颜色

    NO_COLOR 和少于 8 种颜色的终端只用粗细、下划线和反显来绘制,sim 也不会向终端请求任何颜色。含义从不只靠颜色传达:改动的行在符号列中是 ┆,文件夹显示其下最强的 git 状态的字母,标签页用 ↯ 表示文件在磁盘上已改动。关闭图标后,不会绘制任何私有区(private-use)字形。

    规格:

  • 可能装有 Nerd Font 的终端中,图标默认开启

    图标需要 Nerd Font,而终端无法告知自己有没有。图标在 Ghostty、kitty 和 WezTerm 中默认开启,在其他终端中默认关闭,并在状态栏给出一次性的提示:zi: icons (needs a Nerd Font)。你用 zi 做的最后一次选择永远优先。

    规格:

  • 复制时亮起,在每种外观中都一样

    刚刚复制的内容会亮 150 ms。最朴素的 calm 外观现在也会亮:用选区的灰色,没有选区的地方用下划线。另一个进程刚刚写进已打开文件的行,会亮 400 ms。

    规格: UI-13, UI-19

按键

vi 的语法,去掉 vi 的怪癖。

  • 你的手已经熟悉的 vi 按键

    移动命令、操作符、文本对象、计数、.、可视模式、支持 smartcase 的搜索、:s 和范围,但去掉了 vi 的怪癖:Y 复制到行尾,U 是重做,Ctrl-s 保存,q 退出。方向键、Home、End 和 Delete 在任何地方都能用。

    规格: VI-1, VI-2, VI-3, VI-4, VI-5, VI-6, VI-7

  • 复制的内容会进入系统剪贴板

    每次没有指定寄存器名的复制也会通过 OSC 52 送入系统剪贴板,在 tmux 里同样如此。删除和修改只会填充寄存器,所以 x 和 dd 永远不会覆盖你复制的内容。

    规格: VI-8

  • 不出意外的鼠标

    点击可打开文件或放置光标,滚轮滚动,拖动选择。鼠标自己绝不会编辑、保存或创建快照。

    规格: PTR-1, PTR-2

  • Space 是 leader 键,附带 which-key 窗口

    在前缀键(Space、g、z、Z、[、],或 d 这样的操作符)上稍等片刻,会打开一个小窗口,列出接下来可以按的键。继续输入的效果与没有这个窗口时完全一样。

    规格:

  • 搜索会告诉你当前位置

    搜索的匹配项高亮显示时,状态栏会显示光标位于第几个匹配项,以及一共有多少个:[3/12]。

    规格:

  • Vim 的寄存器

    "a 到 "z 保存文本,"A 到 "Z 在其后追加;"0 是最近一次复制,"1 到 "9 是最近的几次删除,"_ 接收任何内容却什么也不保存。:registers 会列出它们。寄存器只存在于内存中,所有打开的文件共用。没有指定名称的复制仍会通过 OSC 52 送入系统剪贴板;删除仍不会。

    规格: VI-15

  • 标记

    ma 到 mz 在文件中设置标记;'a 跳到标记所在的行,反引号键跳到它的确切位置,也可以和操作符搭配(d'a)。'' 回到最近一次跳转之前光标所在的位置。标记会跟着它所在的文本,经过编辑、撤销和来自外部的改动,:marks 会列出它们。标记只存在于内存中。

    规格: VI-17

  • :tutor

    约十五分钟的简短课程,在一个临时缓冲区里进行,语言取决于你的区域设置(English、日本語、简体中文、繁體中文、한국어、Español、Português、Français、Deutsch 或 Русский;其他情况用 English)。练习题会在你输入时自动在 ✗ 和 ✓ 之间切换。

    规格: TUTOR-1, TUTOR-2, TUTOR-3, TUTOR-4

路线图

计划中,尚未发布。此列表中的任何内容目前都不可用,顺序也不是承诺。

  • 宏

    计划中

    录制并回放按键。sim 目前没有。

  • 剪贴板集成

    计划中

    比目前通过 OSC 52 复制更进一步。

  • 沙箱中的语言服务器

    计划中

    一个语言服务器客户端,其服务器运行在沙箱中;状态栏里还有一个指示项,显示项目根目录是否受信任。

  • 真正有层次感的 GUI

    计划中

    带有真实阴影和高度层次的图形前端。目前已作为原型起步,没有任何可安装的东西。

  • 更多安装方式

    计划中

    AUR和crates.io 的软件包即将推出。