Что 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 работает без оболочки, без необязательных блокировок и без возможности что-либо загружать.

    Спецификация: MARK-1, GIT-1, GIT-2, GIT-3, GIT-5

  • Всё, что ничего не рисует, показывается

    Кроме переопределения направления письма «справа налево» и пробела нулевой ширины, sim показывает символы-теги (так ИИ-ассистенту тайно передают инструкцию), селекторы вариантов начертания (так прятали код в опубликованных расширениях), хангыльные заполнители, мягкие переносы, разделители строк и любой неназначенный кодовый пункт в виде <U+E0041> — везде, где sim рисует текст: в файле, в строке состояния, в сообщениях и в названиях в дереве и на вкладках. Последовательности эмодзи, кейкапы, флаги Англии, Шотландии и Уэльса и значки Nerd Font остаются как есть. Если за иероглифом идёт селектор иероглифического варианта, sim показывает этот селектор.

    Спецификация: 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

  • Сохранение, которое не бывает наполовину записанным

    При сохранении рядом с оригиналом создаётся временный файл (с режимом 0600 и O_EXCL), для него выполняется fsync, он переименовывается поверх оригинала, затем выполняется fsync каталога, поэтому вы видите либо старый файл, либо новый, но не смесь. Файл, принадлежащий другому пользователю, файл с жёсткими ссылками и файл в каталоге только для чтения сохраняются на месте после создания копии для восстановления. sim отказывается записывать через ссылку, принадлежащую другому пользователю. Если открыть файл и сохранить без правок, результат побайтово совпадает с исходным.

    Спецификация: SAFE-1, SAFE-2, SAFE-3, SAFE-5

  • При сбое ничего не пропадает

    Несохранённые изменения сохраняются снимками не чаще раза в секунду в приватный каталог состояния (0700). После сбоя, kill -9 или закрытия терминала при повторном открытии файла sim предлагает вернуть их одним шагом отмены. Теряется не больше секунды работы.

    Спецификация: SAFE-6

  • Поиск никогда не запускает то, чем управляет репозиторий

    sim сам находит ripgrep среди абсолютных записей PATH и запускает его с пустым окружением и --no-config, но никогда с --pre, поэтому репозиторий не может заставить поиск выполнить свой код. Поиск ничего не записывает и не переходит по символической ссылке за пределы проекта.

    Спецификация: GREP-7, GREP-8

  • Файлы, не являющиеся текстом, открываются только для чтения

    Файл, который не является корректным UTF-8 или содержит NUL в первых 8 КБ, открывается только для чтения с указанием причины, а некорректные байты рисуются как U+FFFD. Правки и запись отклоняются, потому что текст на экране не был бы файлом.

    Спецификация: SAFE-4

  • Сохранение при конфликте оставляет обе версии

    Если при сохранении оказывается, что файл на диске изменился, ничего не теряется ни с одной стороны. :w! оставляет вашу версию, предварительно скопировав чужую в каталог состояния, а :e! берёт чужую после снимка вашей.

    Спецификация:

  • --plain: никаких внешних процессов

    sim --plain — это одно лишь ядро: оформление calm, один файл, без панели, и sim сам не запускает никаких программ: ни git, ни ripgrep, ни фильтра, ни хука. Это режим по умолчанию от root и в роли редактора sudoedit, а строка состояния показывает plain.

    Спецификация:

Доступность и скорость

Минимум шагов от мысли «тот самый файл» до чтения.

  • Дерево файлов, которое никогда не прыгает

    sim открывается с деревом текущего каталога. Сначала идут каталоги, потом файлы, каждые по имени, всегда в одном и том же порядке, а раскрытые папки остаются раскрытыми так, как вы их оставили, поэтому файлы находятся по положению, а не чтением списка. Каталоги читаются в фоне: записи появляются по мере поступления и ничего выше себя не сдвигают.

    Спецификация: TREE-1, TREE-3, TREE-4, TREE-5

  • Поиск файлов и текста в плавающем окне

    Ctrl-p ищет файлы нечётким совпадением по пути и упорядочивает их по качеству совпадения и по вероятности, что вы откроете именно этот файл. Ctrl-f ищет по содержимому всех файлов по мере ввода (через ripgrep, если он есть в PATH), результаты сгруппированы по файлам, а выбранная строка показывается в предпросмотре. 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

  • Достаточно быстро, чтобы не замечать

    В бенчмарке проекта (релизная сборка, файл на 100 000 строк, панель открыта, подсветка включена) обработка клавиши занимает не более 1 мс на p99 на экранах от 80×24 до 240×60. В репозитории со 100 000 файлов первый кадр рисуется до того, как прочитан список файлов: измерено от 1,8 до 8,7 мс при требовании 20 мс. Всё медленное (обход дерева, запросы к 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 единственный цвет изменений остаётся различимым при протан-, дейтан- и тритан-типах цветового зрения. Один оттенок во всём интерфейсе означает одно: серый — структуру, синий — место, где вы действуете, зелёный, янтарный и красный — изменение, пурпурный — только скрытое или опасное.

    Спецификация: 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-текст

    Широкие символы занимают две колонки, проза переносится по японским правилам кинсоку, перемещения по словам разделяют CJK-текст там, где меняется система письма, а при включённом IME клавиши полной ширины работают как команды.

    Спецификация: VIS-7, VI-10

  • Работает без цвета и никогда не полагается только на цвет

    NO_COLOR и терминалы менее чем с 8 цветами рисуют только жирностью, подчёркиванием и инверсией, а sim не запрашивает у терминала никаких цветов. Смысл никогда не зависит только от цвета: изменённая строка — это ┆ на боковом поле, у папок видна буква самого сильного статуса git, а вкладка показывает ↯ для файла, изменённого на диске. При выключенных значках глиф из области частного использования не рисуется.

    Спецификация:

  • Значки по умолчанию включены там, где вероятен Nerd Font

    Для значков нужен Nerd Font, а терминал не может сообщить, есть ли он. В Ghostty, kitty и WezTerm они включены с самого начала, в остальных выключены, и в строке состояния один раз появляется подсказка: zi: icons (needs a Nerd Font). Последний выбор, сделанный через zi, всегда главнее.

    Спецификация:

  • Скопированное подсвечивается в любом оформлении

    То, что вы только что скопировали командой yank, подсвечивается на 150 ms. Calm, простое оформление, теперь тоже подсвечивает: серым цветом выделения или подчёркиванием там, где выделения нет. Строка, которую другой процесс только что записал в открытый файл, подсвечивается на 400 ms.

    Спецификация: UI-13, UI-19

Клавиши

Грамматика 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

  • Скопированное попадает в системный буфер обмена

    Всё скопированное (yank) без имени регистра также уходит в системный буфер обмена через OSC 52, в том числе внутри tmux. Удаление и замена заполняют только регистр, поэтому x и dd никогда не затирают то, что вы скопировали.

    Спецификация: VI-8

  • Мышь без сюрпризов

    Щелчок открывает файл или ставит курсор, колесо прокручивает, перетаскивание выделяет. Мышь сама никогда ничего не правит, не сохраняет и не создаёт снимков.

    Спецификация: PTR-1, PTR-2

  • Space — клавиша-лидер, с окном which-key

    Пауза на префиксе (Space, g, z, Z, [, ] или оператор вроде d) открывает небольшое окно, в котором перечислены клавиши, которые могут идти дальше. Если продолжать набирать клавиши, всё работает точно так же, как без окна.

    Спецификация:

  • Поиск показывает, где вы находитесь

    Пока совпадения поиска подсвечены, строка состояния показывает, на каком из них стоит курсор и сколько их всего: [3/12].

    Спецификация:

  • Регистры Vim

    "a — "z хранят текст, "A — "Z дописывают в него; "0 — последний yank, "1 — "9 — последние удаления, а "_ принимает что угодно и ничего не хранит. :registers перечисляет их. Они живут только в памяти, и все открытые файлы пользуются ими вместе. Yank без имени по-прежнему попадает в системный буфер обмена через 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.

  • Языковые серверы в песочнице

    Запланировано

    Клиент языкового сервера, чей сервер работает в песочнице, и индикатор в строке состояния: доверен ли корень проекта.

  • Графический интерфейс с настоящей глубиной

    Запланировано

    Графический интерфейс с настоящими тенями и возвышением (elevation). Он начат как прототип; устанавливать пока нечего.

  • Другие способы установки

    Запланировано

    Пакеты для AUR и crates.io скоро появятся.