Перейти к содержанию

Intent-based Melody Language (IML) v1

Документ фиксирует язык ввода команд в палитре с префиксом c: — тот же контракт, что в ADR 0060 §11 (Command Melody). Здесь — формальное описание, мотивация и открытые вопросы для эволюции.

Связь: 0060 (норматив продукта и паритет с аккордом), 0030 (command_id), 0072 (chat-topic navigation как частный случай intent-first входов), 0109 (каталог корней [[melody_root]] в TOML, параметрические сигнатуры хвоста), chord-notation-cascadeide.md (физические клавиши и Vim-нотация — другой слой).


1. Назначение

IML — это не нотация клавиш, а текстовый язык намерений в строке палитры: короткие мнемоники, однозначно привязанные к command_id в реестре. Он дополняет fuzzy-поиск по human title и не заменяет канонический идентификатор команды.

Три представления одной команды (как в 0060):

Слой Пример
Human title Git: Status
Melody (IML) c: gs (см. §3.2)
Canonical id git.status

2. Цели дизайна

  1. Intent-first: пользователь вводит домен → объект → намерение (см. §3.2), а не координаты UI. Допускается сжатая форма из двух букв, когда объект подразумевается контекстом.
  2. Паритет поверхностей: тот же смысл доступен из палитры (строка), CascadeChord (Ctrl+K → буквы по 0060) и MCP (ide_execute_command с тем же command_id) — 0008.
  3. Стабильность: при смене формулировки в UI alias может оставаться неизменным.
  4. Обход хрупкости глобальных жестов: ввод в палитре не зависит от того, что ОС/IME/фокус доставили одну сложную комбинацию модификаторов + букву в одном событии (см. §8).
  5. Частота → длина (эвристика): чем типичнее команда для рабочего дня разработчика, тем короче разумный alias в реестре (см. §3.5). Пока закрепляем базу вручную по консенсусу; пересортировка по данным (в т.ч. телеметрия) — отложенная идея, после стабилизации реестра и палитры.

3. Лексика и синтаксис (v1)

3.1. Префикс namespace

  • c: — единственный вход в режим melody в строке палитры (регистр: c латинская нижняя; в v1 не допускается C: как синоним без отдельного решения).

3.2. Токены после префикса: domain → object → intent

Базовая ментальная модель (канон для проектирования alias):

Слот Смысл Роль
D domain Подсистема или крупная область (Git, Chat, Build, …)
O object Сущность внутри домена (topic, submodule, …); иногда неявна
I intent Действие или тип запроса (create, show, test, …)

Полная форма — три буквы подряд DOI, без разделителей: первая = domain, вторая = object, третья = intent.

Домен первым (намерение), не слой «Pages». Первая буква хвоста кодирует подсистему / зону заботы пользователя: chat, environment (готовность), terminal, git, build, … — «хочу в чат», «хочу readiness», «хочу терминал». Искусственный префикс P = «Pages» для всех переходов во вторичный контур (pcs, pes, …) не используется: он описывает топологию IDE, а не намерение. Показ страницы внутри домена кодируется в слотах O/I (например cps = Chat → Page → Show, а не Pages → Chat → Show). Замечание: в таблице «семейств» одной буквы (ADR 0060) e = Editor; в трёхбуквенном DOI вроде ers (Environment → Readiness → Show) смысл задаёт целиком зарегистрированная мнемоника, а не первая буква по отдельности.

Примеры:

Хвост Разбор Human title (ориентир)
ctc chat + topic + create Chat Topic Create
gs git + (object не назван) + status Git Status — естественное сокращение: репозиторий как контекст уже дан

Сжатые формы (2 буквы): допустимы, когда object очевиден из домена и привычной практики — и/или когда команда высокочастотная (§3.5). Реестр может хранить синонимы (длинная и короткая форма одной команды).

Обсуждаемое единообразие для глаголов: для операций «показать / прочитать» можно завести в слоте I букву s = Show (read-only обзор), чтобы однотипно с c = Create и т.д. Тогда часть команд осознанно становится трёхбуквенной, например g?s с явным средним слотом — либо оставить gs как устоявшийся короткий канон для Git Status. Окончательное правило — не зафиксировано; см. §10.

Четвёртая и далее буквы: уточнение, подкоманда или снятие коллизии — по реестру (§6).

3.3. Регистр

  • В v1 токены case-insensitive для сопоставления с реестром (c: GSc: gs), отображение в UI — по канону реестра (обычно lower).

3.4. Пробелы

  • Пробелы после c: до первого значимого символа хвоста допускаются (c: gs) — нормализуются к c:gs при разборе.
  • Пробелы внутри хвоста в v1 не являются разделителями токенов (всё одна строка-мнемоника, если не введён другой режим в будущей версии языка).

3.5. Частота использования и длина alias (аналогия с кодами Хаффмана)

Идея префиксных кодов (у Д. А. Хаффмана и в родственных схемах): символы с большей вероятностью получают более короткие коды — так минимизируется средняя длина сообщения. В IML «вероятность» заменяется на ожидаемую частоту команды в типичном дне разработчика: то, что дергают постоянно, должно набираться двумя буквами, реже — три и более, редкое — длинный хвост или только human title / command_id.

Оси с высоким трафиком (ориентир, не жёсткий закон): Git, сборка, отладка, тесты, запуск, чат (страница Chat, экспорт, ветка) — первыми получают короткие мнемоники в реестре.

Иллюстративный набор (конкретные буквы — в 0060 §11 и в IdeCommands; таблица согласована с частотным принципом):

Хвост (без c:) Смысл
br Build → Run
bt Build → Test
da Debug → Attach
dl Debug → Launch (debug_launch)
dc Debug → Continue
dn Debug → next (шаг с обходом, debug_step_over)
di Debug → into (шаг с заходом, debug_step_into)
df Debug → finish (шаг с выходом из кадра, debug_step_out)
dx Debug → eXit / остановить сессию (debug_stop)
gs Git → Status
gc Git → Commit
gp Git → Push
gm Git → Merge
gsu Git → Submodules (трёхбуквенное — реже, чем merge/push; освобождает gm под merge)
so Solution → Open (диалог выбора .sln / .slnx)
cps Chat → Page → Show (страница чата Mfd, show_chat_page)
cs Chat → Send — отправить текущий черновик в поле ввода как сообщение user (send_chat без message; если поле пусто — команда не выполняется)
cex Chat → экспорт в читаемый Markdown (chat_export_readable, без write_file по умолчанию)
ctf Chat → Thread → Fork (fork_chat_thread, без parent; DOI, см. ADR 0060 §11)
ers Environment → Readiness → Show (show_environment_readiness_page)
ts Terminal → Show (show_terminal_panel)

Единый каталог intent в поставке — IntentMelody/intent-catalog.toml (встроенный ресурс + оверлей рядом с exe, как Hotkeys/hotkeys.toml; устаревшее имя файла: intent-melody-aliases.toml).

Сейчас: короткие коды задаются реестром и ревью (качественный консенсус по Git / build / debug / test), без сбора частот из продукта.

Отложено: автоматическая перераздача alias по измеренной частоте (локальная аналитика, opt-in сеть и т.д.) — вернуться после того, как база IML, палитры и command_id будут в стабильном минимуме; любая миграция alias — с заметкой в release notes и при необходимости дублированием старых alias на переходный период.


4. Грамматика (EBNF, черновик v1)

Нотация для документации; парсер в IDE может быть проще (regex + lookup).

(* IML строка в палитре *)
iml_line       ::= "c:" iml_tail ;

iml_tail       ::= ws_opt mnemonic_body ws_opt;
mnemonic_body  ::= letter { letter | digit } ;  (* минимум 2 символа; для новых команд предпочтительна форма DOI (§3.2), для частых — короткий alias по §3.5 *)

letter         ::= "a" |  | "z" | "A" |  | "Z" ;
digit          ::= "0" |  | "9" ;
ws_opt         ::= { " " | "\t" } ;

Примечание: в v1 нет явного разделителя между D/O/I — тело целиком ключ в таблице alias → command_id. Семантика domain → object → intent задаётся соглашением реестра и документации, не парсером скобок.


5. Семантика

  1. Разбор iml_lineнормализованный хвост (например gs или ctc).
  2. Поиск в реестре melody alias → ровно один command_id или неоднозначность / отсутствие.
  3. Исполнение — тот же путь, что для выбора команды из списка палитры: dispatch по command_id, без прямой адресации контролов.

Инвариант: IML никогда не означает «нажать эти физические клавиши» — только выбор команды.


6. Реестр, конфликты, расширение

Файл IntentMelody/intent-catalog.toml — канонический command-first каталог (intent_catalog_schema_version = 1; ключ версии файла, не «IML v2»).

IML v2 (смысл языка, ADR 0109) — надстройка над IML v1: тот же wire c:…, но shape, tail_signature, [[tail_wire_class]], детерминированная сборка args; параметрические корни (eld, els, wai-url, …) уже живут в этом каталоге. Отдельного intent_catalog_schema_version = 2 для этого нет — это не версия языка.

Раскладка TOML (читаемость, без смены номера схемы):

  • Якорь: command_id на [[command]].
  • Melody (0–1): поля melody_* на [[command]] или legacy [command.melody].
  • Slash (0..N): [[command.form.slash]] (или legacy [[command.slash]]); args — [command.form.slash.args] (page, surface).
  • slash_group, enabled, секции-комментарии, cookbook в шапке файла.

При необходимости [[tail_wire_class]] (см. также ADR 0119).

Slash-паритет (параметрика каталога): для каждой команды с melody_shape = parametric — curated slash-путь и хвост по wire_class (редактор: /editor line select|delete …; портал: /portal open [url]). Сборка args — те же binders, что у c:ADR 0124.

Slash workspace/file: /file open, /solution new, динамические подсказки по файлам solution — ADR 0125 (ортогонально параметрике 0124).

В tail_signature для числовых слотов: :int — обобщённое целое; :ln или :linenumber — номер строки редактора (1-based, inclusive-диапазон как в продуктовой семантике диапазона строк). Загрузчик и разбор хвоста учитывают оба вида; для диапазонов строк в каталоге предпочтительно ln.

Правила совпадают с 0060 §11:

  • Один alias в workspace → один command_id.
  • Заголовок и command_id остаются всегда валидными путями поиска.
  • При конфликте: уточнение третьей буквой, ветвление в реестре или пометка alias как invalid до разруливания.

Слот D (domain): стартовый набор букв согласован с «семействами» в 0060 §11 (g/b/d/r/e/m/…); для чата и topic-навигации — отдельные соглашения по 0072. Буквы слотов O и I — в реестре; типичные I: c create, s show (обсуждается), t test, и т.д.


7. Связь с физическим аккордом (CascadeChord)

  • Ментальная модель: те же буквы, что в хвосте IML, идут после префикса CascadeChord: c: gsCtrl+KGS; c: ctcCtrl+KCTC (последовательность шагов — как в 0060; таймауты и overlay учитывают длину цепочки).
  • Реализация: разные конвейеры ввода (текст палитры vs машина состояний аккорда), один command_id.
  • Детали таймаута, Esc, overlay — 0060 §5–§6.

8. Почему это не «лечит» модификаторы напрямую, но снимает класс проблем

Проблема: глобальные жесты вида Ctrl+Shift+буква проходят через цепочку ОС → хост → фокус → IME/редактор, и в части сценариев буква не доходит до приложения как ожидается (Avalonia и не только).

IML в палитре: пользователь вводит c: и символы без удержания сложных модификаторов в одном системном chord; ввод идёт в контроллер строки поиска, где семантика — текст, а не KeyGesture с модификаторами на уровне окна.
То же намерение можно вызвать аккордом пошагово (префикс → буквы), что снова не требует одного атомарного Ctrl+Shift+O.

Итог: не замена глобальных хоткеев, а предпочтительный канон для команд, где платформенная доставка chord нестабильна; прямой хоткей при необходимости остаётся в hotkeys.toml с другой, более доставляемой комбинацией.


9. Не-цели v1

  • Полноценный DSL для скриптов (c: pipe / c: $(…)).
  • Локализация мнемоник под язык UI (alias developer-first, EN-буквы; отдельное обсуждение).
  • Замена human title и command_id в поиске.

10. Открытые вопросы (для обсуждения)

  1. Слот I и буква s (Show): для высокочастотных команд §3.5 уже оправдывает короткий gs без трёхбуквенного «формального» DOI; остаётся вопрос, нужен ли явный третий слот для редких read-команд внутри одного домена.
  2. Явный разделитель между D/O/I в будущих версиях (c: g.s vs c: gs) — нужен ли для читаемости или вреден для скорости?
  3. Числовые хвосты (c: g1) — для дискретных подкоманд или только буквы?
  4. Конфликт с вводом c: как начала другого запроса — только внутри палитры или глобальный shortcut на палитру с префиксом?
  5. Паритет отображения: всегда ли показывать тройку title / c: alias / id в одной строке результата (0060)?
  6. Chat / topic: закрепить c как domain для chat и цепочки вида ct* (topic + intent), как в ctc, и таблицу букв для topic-navigation intents (0072) — отдельным проходом по реестру.

11. История и нормативность

Нормативный источник по продукту — ADR 0060 §11 и реестр команд; этот документ уточняет грамматику и мотивацию. Детали реализации парсера палитры — в коде; при расхождении приоритет у ADR и реестра, затем обновление этого файла.