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

ADR 0081: Параметрические Intent Melody — диапазоны строк редактора (:start:end)

Статус: Accepted · Implemented
Дата: 2026-04-20

Связанные ADR

ADR Роль
0060 Command Melody, CascadeChord, keyboard-first
0030 command_id и слои UI
0013 палитра и discoverability
0070 палитра как overlay
0079 IDS — композиция оверлея ввода
0072 intent-first входы в домене чата
0075 зоны внимания / MFD
0039 Навигация по workspace — несколько представлений и «текущий файл + связанные»
0080 якоря на код — смежная тема, не дублирует этот ADR
0110 Рефакторинги Roslyn по диапазону — мост Intent Melody / IDE и Roslyn MCP

Резюме

  • Параметрические Intent Melody: суффикс :startLine:endLine для операций над текстом.
  • Валидация диапазона; мост к Roslyn — 0110.

Вне ADR

Документ Роль
intent-melody-language-v1.md IML v1: грамматика c: и реестр alias
IntentMelody/intent-melody-aliases.toml оверлей alias → command_id
Roslyn MCP Roslyn MCP

Контекст

В IML v1 хвост после c: — это мнемоника, резолвящаяся в command_id через реестр (intent-melody-aliases.toml, ADR 0060 §11). Для команд уровня «Git status» или «открыть страницу Chat» этого достаточно: контекст задаётся фокусом и текущим решением.

Операции над текстом активного редактора (выделить диапазон строк, удалить диапазон, Extract Method и другие рефакторинги Roslyn по диапазону) принципиально требуют параметра — хотя бы диапазон строк — иначе одна и та же мнемоника неоднозначна или вынуждена опираться только на текущее выделение, что хуже для сценариев «знаю номера строк».


Проблема

  1. Разрыв «намерение → команда»: без параметров пользователь вынужден сначала выделить текст мышью/клавиатурой, затем вызывать команду; для power-user с номерами из лога/диффа это медленнее, чем одна строка ввода с диапазоном.
  2. Паритет поверхностей: если параметр доступен только через меню или отдельный диалог, страдает принцип те же command_id и те же входы, что палитра и Melody (0060, 0008).
  3. Ошибки ввода: диапазон вне файла или start > end не должны приводить к молчаливому разрушительному эффекту или к правке не того фрагмента.

Решение (предлагаемое)

1. Суффикс диапазона строк

После зарегистрированного короткого alias (корень мелодии без c: в терминах реестра) допускается опциональный суффикс вида :startLine:endLine:

  • startLine, endLine — целые числа, 1-based, включительно (согласовано с номерами строк в редакторе и типичными сообщениями компилятора).
  • Разделитель полей — :; парсер после матча базового alias сначала резолвит префикс в command_id / доменную операцию, затем, если хвост продолжается шаблоном :digits:digits, интерпретирует пару как диапазон строк.

Иллюстративные примеры (финальные мнемоники и привязка к command_id — решение реестра и продукта, не жёстко зашитые в парсер):

Ввод (фрагмент после c:) Намерение (ориентир)
els:5:15 Editor → Line → Select строки 5–15 в активном документе
eld:5:15 Editor → Line → Delete в указанном диапазоне

Канон этой ADR-ветки:

  • Для операций над диапазоном строк использовать модель Editor → Line (el*), без legacy/синонимов es*.
  • Семейство мелодий Refactor → … по диапазону (rmx, rix, …) и связка с Roslyn / Roslyn MCP (roslyn_get_code_actions / roslyn_apply_code_action) не входят в обязательный минимум этого ADR — см. 0110.

Расширение IML v1 в intent-melody-language-v1.md (новый подпункт про параметрический хвост) — отдельным шагом после стабилизации формата; до тех пор этот ADR — норматив направления для реализации и документации.

2. Валидация и отказ

  • Диапазон обязан укладываться в текущую длину документа (в строках); при нарушении — явная обратная связь (строка состояния палитры, краткий annunciator в IDS — по 0079), без применения деструктивного действия «как получится».
  • Условие startLine <= endLine; иначе — тот же класс ошибки, что и выход за границы.

3. Рефакторинги Roslyn (Extract Method и аналоги)

Команды, которые в IDE уже ожидают выделение в редакторе (в т.ч. Roslyn: roslyn_get_code_actions с диапазоном для Extract method и аналогов), должны вести себя предсказуемо:

  • Если есть непустое выделение в активном документе — возможен приоритет выделения над числовым суффиксом (продуктовое правило: «явный жест побеждает») или однозначная политика «суффикс всегда задаёт диапазон» — зафиксировать при реализации и отразить в help.
  • Если выделения нет — синтетическое выделение по строкам startLineendLine (целые строки, включая переводы строк по принятому в редакторе правилу) перед вызовом того же пути, что и из UI.

4. UX: discoverability и режим ввода

  • Индикатор распознанной мелодии: при активном command mode / вводе в палитре показывать краткий разбор: базовый alias + числовой диапазон (и при ошибке — причину). Цель — снизить ошибки «я думал, что ввёл другое» без обязательного длинного лога.
  • Chord vs только палитра: открытый вопрос — разрешать ли параметрический хвост в CascadeChord (Ctrl+K → последовательность букв) или ограничить палитрой ради меньшего числа опечаток без превью. Решение — отдельно; этот ADR допускает оба варианта как реализации.

Последствия

  • Расширение разборщика строки палитры / Melody и связки с VM: команды редактора, принимающие диапазон, получают единый контракт из IML, а не только из pointer.
  • Реестр intent-melody-aliases.toml может ссылать те же command_id, что и без параметров; семантика «с параметром / без» — в обработчике команды или тонком адаптере.
  • Документация MCP / IdeCommands: для соответствующих команд при необходимости уточняются args или параллельный путь «из палитры с диапазоном».

Отклонённые альтернативы

  • Только MCP с явными аргументами — ломает keyboard-first и единую строку намерения в IDE для человека.
  • Только пробел как разделитель (5 15) — конфликтует с направлением IML v1 «пробелы внутри хвоста не режут токены» (§3.4); суффикс с : после полного матча alias воспроизводимее.
  • Привязка только к mouse / gutter — не отменяется, но не заменяет параметрический ввод для пользователей без указателя на строке.

Открытые вопросы

  1. Ограничить параметрические формы только палитрой на первом релизе или сразу разрешить chord-ввод.
  2. Нужны ли в следующей итерации столбцы или поддиапазоны внутри строки — вынести за пределы минимального :start:end по строкам.
  3. Синхронизация с будущими якорями на код из 0080 (deep link): общий слой «диапазон в документе» или отдельные контракты.