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. Цели дизайна¶
- Intent-first: пользователь вводит домен → объект → намерение (см. §3.2), а не координаты UI. Допускается сжатая форма из двух букв, когда объект подразумевается контекстом.
- Паритет поверхностей: тот же смысл доступен из палитры (строка), CascadeChord (
Ctrl+K→ буквы по 0060) и MCP (ide_execute_commandс тем жеcommand_id) — 0008. - Стабильность: при смене формулировки в UI alias может оставаться неизменным.
- Обход хрупкости глобальных жестов: ввод в палитре не зависит от того, что ОС/IME/фокус доставили одну сложную комбинацию модификаторов + букву в одном событии (см. §8).
- Частота → длина (эвристика): чем типичнее команда для рабочего дня разработчика, тем короче разумный 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: GS≡c: 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. Семантика¶
- Разбор
iml_line→ нормализованный хвост (напримерgsилиctc). - Поиск в реестре melody alias → ровно один
command_idили неоднозначность / отсутствие. - Исполнение — тот же путь, что для выбора команды из списка палитры: 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: gs↔Ctrl+K→G→S;c: ctc↔Ctrl+K→C→T→C(последовательность шагов — как в 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. Открытые вопросы (для обсуждения)¶
- Слот I и буква
s(Show): для высокочастотных команд §3.5 уже оправдывает короткийgsбез трёхбуквенного «формального» DOI; остаётся вопрос, нужен ли явный третий слот для редких read-команд внутри одного домена. - Явный разделитель между D/O/I в будущих версиях (
c: g.svsc: gs) — нужен ли для читаемости или вреден для скорости? - Числовые хвосты (
c: g1) — для дискретных подкоманд или только буквы? - Конфликт с вводом
c:как начала другого запроса — только внутри палитры или глобальный shortcut на палитру с префиксом? - Паритет отображения: всегда ли показывать тройку title /
c:alias / id в одной строке результата (0060)? - Chat / topic: закрепить
cкак domain для chat и цепочки видаct*(topic + intent), как вctc, и таблицу букв для topic-navigation intents (0072) — отдельным проходом по реестру.
11. История и нормативность¶
Нормативный источник по продукту — ADR 0060 §11 и реестр команд; этот документ уточняет грамматику и мотивацию. Детали реализации парсера палитры — в коде; при расхождении приоритет у ADR и реестра, затем обновление этого файла.