What sim does today

What sim does today, grouped by what it is for. Each feature lists the requirement IDs in the project's spec that back it. Planned features are only under Roadmap.

Shows what is hidden

The core idea: a file is shown as what it is.

  • Invisible and bidirectional characters are shown

    A right-to-left override, a zero-width space or a control character is drawn as <U+202E>, <U+200B> or ^[ on a magenta block, in every state a cell can be in: selected, searched, on the cursor line, inside a change from outside, in the fog of a far row. None of them is ever sent raw to the terminal. The literal text <U+202E> in a file gets no block, so the two can be told apart.

    Spec: SAFE-8, UI-15

  • Blanks that look like nothing are marked

    Trailing blanks are drawn as ·, a no-break space as ⍽ and a tab as »: marks that no code uses, drawn over the text and never part of it. There is no mark at the end of a line, and - and % are not used, because they are ordinary characters of code.

    Spec: UI-6

  • Writes from outside are marked

    sim watches the open file. When another process rewrites it (a build, a formatter, a tool), the changed lines are marked in the text, the box says how many changes are on disk, the tab shows ↯, and the tree marks the file. A save compares the file's hash first and writes nothing if it changed since you read it. A write in the very same instant as that check can still slip through (see Security).

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

  • Changes against git HEAD at a glance

    Signs in the gutter for added, changed and deleted lines, a status letter on each file in the tree (M, A, U, D, R) and, on a folder, the letter of the strongest status below it, the branch and +n ~n -n in the status line. They come from git, run in the background and never on a key's path.

    Spec: UI-3, UI-5, UI-10

  • A repository's own config cannot make git run a command

    Before it runs git, sim asks git for the repository's own config. What a command line can stop is turned off: a file system monitor, hooks, filters, an external diff and a text conversion run nothing, and the tree says how many settings were turned off (2 git settings off). If the config could still run a command that nothing stops (core.sshCommand, an include that could bring one in, and more), git is not run: the tree shows no git marks and says git not run, and the status line names the key and the file. git runs without a shell, with no optional locks and no way to fetch.

    Spec: MARK-1, GIT-1, GIT-2, GIT-3, GIT-5

  • Everything that draws nothing is shown

    Beyond the right-to-left override and the zero-width space, sim shows tag characters (the way an instruction is smuggled to an AI assistant), variation selectors (the way code was hidden in published extensions), Hangul fillers, soft hyphens, line separators and every unassigned code point as <U+E0041>, wherever it draws text: the file, the status line, messages, and the names in the tree and the tabs. Emoji sequences, keycaps, the flags of England, Scotland and Wales, and Nerd Font icons stay as they are. A kanji followed by an ideographic variation selector shows the selector.

    Spec: SAFE-10, SAFE-11

  • The alert block marks more than characters

    Magenta means that something deserves a second look. Besides hidden characters, a Markdown link whose text looks like an address that its target is not ([https://good.example](https://evil.example)) has its target drawn on the block, and the tree says git not run on it for a repository where git was not run for safety.

    Spec: UI-15, MD-10, GIT-5

Refuses what it should, keeps your text

Nobody's text is lost without an explicit action, and files cannot reconfigure the editor.

  • No modelines, no config files, no plugins

    Settings and commands are never read from the contents of a file, so a file cannot reconfigure the editor. There is no config file to load from a repository, no plugin API, and sim opens no network connections. The only things it remembers are your look, your icon choice and your Markdown view, one word each.

    Spec: SAFE-9

  • Saves that cannot half-write

    A save writes a temporary file next to the original (created with mode 0600 and O_EXCL), fsyncs it, renames it over the original and fsyncs the directory, so you see the old file or the new one, never a mix. A file owned by someone else, with hard links, or in a read-only directory is saved in place after a recovery copy. sim refuses to write through a link that someone else owns. Opening and saving without editing gives byte-identical output.

    Spec: SAFE-1, SAFE-2, SAFE-3, SAFE-5

  • Nothing is lost in a crash

    Unsaved changes are snapshotted at most once per second into a private state directory (0700). After a crash, kill -9 or a closed terminal, opening the file again offers them back as one undo step. At most one second of work is lost.

    Spec: SAFE-6

  • Search never runs what the repository controls

    sim finds ripgrep itself in the absolute entries of PATH and runs it with an empty environment and --no-config, never with --pre, so a repository cannot make a search run its code. A search never writes anything and never follows a symlink out of the project.

    Spec: GREP-7, GREP-8

  • Files that are not text open read-only

    A file that is not valid UTF-8, or has a NUL in its first 8 KB, opens read-only with the reason shown, and invalid bytes are drawn as U+FFFD. Edits and writes are refused, because the text on screen would not be the file.

    Spec: SAFE-4

  • A conflicting save keeps both versions

    When a save finds the file changed on disk, nothing is lost on either side. :w! keeps your version after copying theirs to the state directory, and :e! takes theirs after a snapshot of yours.

    Spec:

  • --plain: no external processes

    sim --plain is the core alone: the calm look, one file, no panel, and no program of its own: no git, no ripgrep, no filter, no hook. It is the default as root and as the editor of sudoedit, and the status line says plain.

    Spec:

Reach and speed

The fewest steps from “that file” to reading it.

  • A project tree that never moves

    sim opens with the tree of the current directory. Directories come first, then files, each by name, always in the same order, and expansion stays as you left it, so you find files by place instead of reading. Directories are read in the background: entries appear when they arrive, without moving anything above them.

    Spec: TREE-1, TREE-3, TREE-4, TREE-5

  • Find files and text in a floating window

    Ctrl-p finds files by a fuzzy match on the path, ranked by match quality and by how likely you are to open each one. Ctrl-f searches the contents of every file as you type (with ripgrep if it is on PATH), results grouped by file, with a preview of the selected line. Esc puts everything back as it was.

    Spec: FIND-2, FIND-4, GREP-1, GREP-5, PICK-1

  • Likely files are marked where they are

    sim remembers which files you open and ranks them by recency and frequency together. The five likeliest are marked with • in the tree. One key, ., narrows the tree to the files that changed, are open or were opened recently.

    Spec: MARK-2, MARK-3

  • Several files, a complete editor for each

    Each open file has its own undo, snapshots, watcher and saves. A tab bar shows them, with a bold ● for unsaved changes. Tab and Shift-Tab switch.

    Spec: BUF-1, BUF-2, UI-4

  • Fast enough not to notice

    In the project's benchmark (release build, a 100,000-line file, panel open, highlighting on) a key takes at most 1 ms at p99, on screens from 80×24 to 240×60. In a repository of 100,000 files the first frame is drawn before the file list is read: 1.8 to 8.7 ms measured, against a requirement of 20 ms. Anything slow (walking a tree, asking git, parsing for highlighting) runs in a background thread.

    Spec: SPEED-1, SPEED-2

  • One binary: sim

    The separate si binary is folded into sim: one command to install and one to run. The core is a library, sim-editor-core, that sim is built on. sim --version and sim --help print and exit without touching the terminal.

    Spec:

  • Pick a tab by letter

    <Space>bp puts a letter on each tab, and the letter jumps to its file. <Space>bc does the same to close one, and never closes a modified file. A hint names Tab and Shift-Tab the first time a second file is open, until you have used them three times.

    Spec:

  • A tree of changes against git HEAD

    <Space>ge shows the tree with only the files that differ from HEAD, staged, unstaged and untracked, each with its status letter and +n −n, and each folder with the sums. Enter opens HEAD's version of a file, read-only.

    Spec: GIT-1, GIT-2, GIT-3, GIT-4, DIFF-1, DIFF-3, DIFF-4

Reading comfortably

Colors and layout that are computed, not guessed.

  • Syntax colors from your own palette

    Colors come from your terminal's palette (read with OSC 4). They keep their hue but move in lightness until text reaches |Lc| 75 against the background. Keywords are red, strings and numbers green, types yellow, functions cyan, comments gray italic; blue and magenta are never used for code. The language comes from the file name, extension or first line, using the syntax set of bat. zh turns the colors off.

    Spec: SYN-1, SYN-2, SYN-4

  • A Markdown reading view

    In a Markdown file every line but the cursor's is drawn as it reads: emphasis and code markers are not drawn, tables are aligned by display width, and callouts (> [!NOTE]) show the kind's word. Only those markers are ever hidden, never a #, a bracket, a URL or a character of text, and <Space>um shows the raw text.

    Spec: UI-8, MD-1, MD-10, MD-11

  • Three looks

    Calm is the plain one: four styles and one chromatic background. Flat shows a diff as green and red with tinted rows. Depth, the default, adds boxes, an overview ruler and a fog that fades text by its distance from the cursor. zl goes round them. Calm is the look for anyone who cannot tell red from green.

    Spec: LOOK-1, LOOK-2, LOOK-3

  • Readable by measurement

    Text is |Lc| 90 and secondary text |Lc| 60 (APCA), computed from your terminal's background. In calm, the one change color stays distinguishable under protan, deutan and tritan color vision. One hue means one thing across the interface: gray for structure, blue for where you act, green, amber and red for change, magenta only for what is hidden or dangerous.

    Spec: VIS-4, VIS-5, COLOR-1, UI-12

  • An editor you can live in

    Icons in the tree (a Nerd Font is needed; zi turns them off), a tab bar, a breadcrumb as the editor's title (src › sim.rs › leader_key), a status line with the mode, the branch, the changes against HEAD and the position (it names an encoding or a line ending only when it is not UTF-8 or LF), relative line numbers, indent guides, a scrollbar with marks, and a flash on what you just yanked.

    Spec: UI-2, UI-5, UI-6, UI-10, UI-11

  • Japanese and other CJK text

    Wide characters count two columns, prose wraps with Japanese kinsoku rules, word motions split CJK text where the script changes, and with an IME on, full-width keys work as commands.

    Spec: VIS-7, VI-10

  • Works without color, and never by color alone

    NO_COLOR and terminals with fewer than 8 colors draw with weight, underline and inverse video only, and sim asks the terminal for no colors. Meaning never depends on color alone: a changed line is ┆ in the sign column, folders show the letter of the strongest git status, and a tab shows ↯ for a file changed on disk. With icons off, no private-use glyph is drawn.

    Spec:

  • Icons start on where a Nerd Font is likely

    Icons need a Nerd Font, and a terminal cannot say whether it has one. They start on in Ghostty, kitty and WezTerm and off elsewhere, with a one-time hint on the status line: zi: icons (needs a Nerd Font). What zi chose last always wins.

    Spec:

  • Copying lights up, in every look

    What you just yanked is lit for 150 ms. Calm, the plain look, lights it too now: in the gray of a selection, or underlined where there is none. A line that another process has just written into the open file is lit for 400 ms.

    Spec: UI-13, UI-19

Keys

The vi grammar, minus vi's accidents.

  • The vi keys your hands know

    Motions, operators, text objects, counts, ., Visual mode, search with smartcase, :s and ranges, minus vi's accidents: Y yanks to the end of the line, U redoes, Ctrl-s saves and q quits. Arrows, Home, End and Delete work everywhere.

    Spec: VI-1, VI-2, VI-3, VI-4, VI-5, VI-6, VI-7

  • Yanks reach the system clipboard

    Every yank without a register name also goes to the system clipboard through OSC 52, inside tmux too. Deletes and changes fill only the register, so x and dd never overwrite what you copied.

    Spec: VI-8

  • The mouse, without surprises

    Click to open a file or place the cursor, wheel to scroll, drag to select. The mouse never edits, saves or snapshots by itself.

    Spec: PTR-1, PTR-2

  • Space is the leader key, with a which-key window

    A pause on a prefix (Space, g, z, Z, [, ] or an operator such as d) opens a small window that lists the keys that can come next. Typing on works exactly as it does without the window.

    Spec:

  • The search says where you are

    While the matches of a search are lit, the status line says which one the cursor is at and how many there are: [3/12].

    Spec:

  • Vim registers

    "a to "z hold text and "A to "Z add to it; "0 is the last yank, "1 to "9 the last deletes, and "_ takes anything and holds nothing. :registers lists them. They live in memory only, and every open file shares them. A yank without a name still goes to the system clipboard through OSC 52; a delete still does not.

    Spec: VI-15

  • Marks

    ma to mz set a mark in the file; 'a goes to its line and the backtick key to its exact place, with an operator too (d'a). '' goes back to where the cursor was before the last jump. A mark follows its text through edits, undo and changes from outside, and :marks lists them. Marks live in memory only.

    Spec: VI-17

  • :tutor

    About fifteen minutes of short lessons in a scratch buffer, in the language of your locale (English, 日本語, 简体中文, 繁體中文, 한국어, Español, Português, Français, Deutsch or Русский; English for any other). Exercises mark themselves with ✗ and ✓ as you type.

    Spec: TUTOR-1, TUTOR-2, TUTOR-3, TUTOR-4

Roadmap

Planned, not shipped. Nothing on this list is available yet, and the order is not a promise.

  • Macros

    Planned

    Recording and replaying keys. sim has none today.

  • Clipboard integration

    Planned

    More than today's yank through OSC 52.

  • Language servers, sandboxed

    Planned

    A language-server client whose server runs in a sandbox, and an indicator of whether the project root is trusted, in the status line.

  • A GUI with real depth

    Planned

    A graphical front end with real shadows and elevation. It has started as a prototype; there is nothing to install.

  • More ways to install

    Planned

    Packages for AUR and crates.io are coming soon.