sim にいまできること
sim がいまできることを、目的ごとにまとめました。各機能には、裏づけとなる仕様の要件 ID を添えています。予定の機能はロードマップにだけ載せています。
拒むべきものは拒み、テキストは失わない
明示的な操作なしには誰のテキストも失われず、ファイルがエディタの設定を書き換えることもできません。
モードラインも、設定ファイルも、プラグインもない
設定やコマンドをファイルの中身から読むことはないので、ファイルがエディタの設定を書き換えることはできません。リポジトリから読み込む設定ファイルも、プラグイン API もなく、sim は自分ではネットワーク接続を開きません。記憶するのは、見た目、アイコン、Markdown の表示方法の選択だけで、どれも 1 語です。
仕様: SAFE-9
書き込みが中途半端にならない保存
保存では、元のファイルと同じ場所に一時ファイル(モード 0600、O_EXCL)を作って書き込み、fsync し、元のファイルへ rename し、ディレクトリも fsync します。見えるのは古いファイルか新しいファイルのどちらかで、混ざることはありません。他人が所有するファイル、ハードリンクのあるファイル、書き込めないディレクトリのファイルは、復旧用コピーを作ったうえでその場で保存します。他人が所有するリンクをたどった書き込みは拒否します。編集せずに開いて保存した場合、出力はバイト単位で同一です。
仕様: SAFE-1, SAFE-2, SAFE-3, SAFE-5
クラッシュしてもテキストを失わない
未保存の変更は、最短で 1 秒おきに、他人から読めないステート用ディレクトリ(0700)へスナップショットとして保存します。クラッシュ、
kill -9、端末を閉じたあとにファイルを開き直すと、取り消し 1 回分として復元を提案します。失われる作業は最大でも 1 秒分です。仕様: 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は中核だけの sim です。calm の見た目、ファイルは 1 つ、パネルなし、そして自前のプログラムは一切実行しません。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 は開いたファイルを記憶し、直近さと頻度の両方で順位づけます。上位 5 つにはツリーで
•がつきます。.を押すと、変更されたファイル、開いているファイル、最近開いたファイルだけにツリーを絞り込みます。仕様: MARK-2, MARK-3
複数のファイル、それぞれが完全なエディタ
開いているファイルごとに、取り消し履歴、スナップショット、監視、保存を持ちます。タブバーに並び、未保存の変更には太字の
●がつきます。TabとShift-Tabで切り替えます。仕様: BUF-1, BUF-2, UI-4
気づかないほど速い
プロジェクト自身のベンチマーク(リリースビルド、10 万行のファイル、パネルを開いてハイライトを有効にした状態)で、1 キーの処理は 80×24 から 240×60 までの画面で、p99 が 1 ms 以内です。10 万ファイルのリポジトリでは、ファイル一覧を読む前に最初のフレームを描き、実測で 1.8〜8.7 ms(要件は 20 ms)でした。ツリーの走査、git への問い合わせ、ハイライトの構文解析など、時間のかかる処理はバックグラウンドのスレッドで行います。
仕様: SPEED-1, SPEED-2
バイナリは sim ひとつ
別々だった
siをsimに統合します。インストールするコマンドも、起動するコマンドも 1 つです。中核はライブラリのsim-editor-coreで、simはその上に作られています。sim --versionとsim --helpは、端末に触れずに表示して終了します。仕様:
文字でタブを選ぶ
<Space>bpで各タブに文字が付き、その文字を押すとそのファイルに移ります。<Space>bcは同じ方法でタブを閉じますが、変更のあるファイルは閉じません。2 つ目のファイルを開いたとき、TabとShift-Tabのヒントを、3 回使うまで表示します。仕様:
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
3 つの見た目
calm は素直な見た目で、4 つのスタイルと 1 色の背景だけを使います。flat は差分を緑と赤で見せ、行に淡い色をつけます。既定の depth は、枠、全体を見渡すルーラー、カーソルからの距離で文字を薄くするフォグを加えます。
zlで順に切り替えます。赤と緑の区別がつきにくい方には calm が向いています。仕様: LOOK-1, LOOK-2, LOOK-3
測って決めた読みやすさ
本文は |Lc| 90、副次的なテキストは |Lc| 60(APCA)で、端末の背景色から計算します。calm では、唯一の変更色が、protan(1 型)・deutan(2 型)・tritan(3 型)のどの色覚でも見分けられます。インターフェース全体で、1 つの色相は 1 つの意味だけを持ちます。グレーは構造、青は操作する場所、緑・琥珀・赤は変更、マゼンタは隠れているものか危険なものだけです。
仕様: 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 テキスト
全角文字は 2 桁として数え、文章は日本語の禁則処理で折り返し、単語移動は文字種が変わるところで CJK の文章を区切ります。IME がオンのままでも、全角のキーがコマンドとして働きます。
仕様: VIS-7, VI-10
色がなくても使え、色だけに頼らない
NO_COLORと、8 色未満の端末では、太さ・下線・反転だけで描き、端末に色を問い合わせることもしません。意味を色だけに頼らず、サイン列では変更行を┆、フォルダは配下でもっとも強い git ステータスの文字、ディスク上で変わったファイルのタブは↯で示します。アイコンをオフにしたときは、私用領域のグリフを一切描きません。仕様:
Nerd Font がありそうな端末で、アイコンを最初からオンに
アイコンには Nerd Font が必要ですが、端末は自分が持っているかを教えてくれません。そこで、Ghostty、kitty、WezTerm では最初からオン、ほかではオフにして、ステータス行に 1 度だけ
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、which-key のウィンドウつき
プレフィックス(
Space、g、z、Z、[、]、dのような演算子)で少し待つと、次に押せるキーを並べた小さなウィンドウが開きます。そのまま打ち続ければ、ウィンドウがないときとまったく同じに動きます。仕様:
:helpと F1: すべてのキーを検索できる一覧:helpとF1で、すべてのキーとコマンドを検索できる一覧が開き、それぞれが何をするかをプレビューで読めます。:help tabでTab、Shift-Tab、<Space>bpが見つかります。一覧は製品のキー表そのものなので、キーの実際とずれることはありません。仕様:
検索が今どこにいるかを教える
検索の一致が点灯しているあいだ、ステータス行にカーソルが何番目で全部でいくつかを
[3/12]の形で表示します。仕様:
Vim のレジスタ
"aから"zはテキストを保持し、"Aから"Zは追記します。"0は直前のヤンク、"1から"9は直前の削除、"_は何でも受け取って何も保持しません。:registersで内容を一覧できます。レジスタはメモリ上にだけあり、開いているすべてのファイルで共有されます。名前なしのヤンクは、これまでどおり OSC 52 でシステムのクリップボードに届き、削除は届きません。仕様: VI-15
マーク
maからmzで、ファイル内にマークを付けます。'aはマークのある行へ、バッククォートのキーはマークの正確な位置へ移動し、オペレータとも組み合わせられます(d'a)。''は、直前のジャンプの前にカーソルがあった場所へ戻ります。マークは、編集、アンドゥ、外部からの変更のあいだも、付けたテキストについていきます。:marksで一覧できます。マークはメモリ上にだけあります。仕様: VI-17
:tutor短いレッスンをスクラッチバッファで進める、約 15 分のチュートリアルです。言語はロケールで決まります(English、日本語、简体中文、繁體中文、한국어、Español、Português、Français、Deutsch、Русский。それ以外は English)。練習問題は、入力に合わせて ✗ と ✓ が自動で切り替わります。
仕様: TUTOR-1, TUTOR-2, TUTOR-3, TUTOR-4
ロードマップ
予定のもので、まだ提供していません。このリストのどれも、いまは使えず、順番は約束ではありません。
マクロ
予定
キー操作の記録と再生です。いまの sim にはありません。
クリップボードとの連携
予定
いまの OSC 52 によるヤンクより一歩進んだ連携です。
サンドボックス内の言語サーバー
予定
言語サーバーのクライアントです。サーバーはサンドボックスの中で動き、プロジェクトのルートを信頼しているかどうかをステータス行に表示します。
本物の奥行きをもつ GUI
予定
本物の影と高さ(エレベーション)をもつグラフィカルなフロントエンドです。プロトタイプの段階で、インストールできるものはまだありません。
ほかのインストール方法
予定
AUR、crates.io のパッケージは近日公開です。