ADR 0040: LSP (C# / Markdown) — командная строка в settings.toml: пресеты, опциональные ключи, переопределение через окружение¶
Статус: Accepted · Implemented (как §Решение ниже)
Дата: 2026-04-13; обновлено 2026-04-25 — канон TOML: [languages.csharp] / [languages.markdown] + mode + вложенные профили
Связанные ADR¶
| ADR | Роль |
|---|---|
| 0028 | где лежит settings.toml, snake_case, модель CascadeIdeSettings |
| 0029 | TOML как канон; UI — фасад |
| 0023 | краткие подсказки по LSP без дампа environ |
| 0023 | Markdown как first-class; LSP в долгой перспективе |
Контекст¶
- В
%LocalAppData%\CascadeIDE\settings.tomlязыковые LSP настраиваются в[languages.csharp]и[languages.markdown]: дискриминаторmode(напримерParseOnly/OmniSharp/Marksman) и вложенные таблицы профилей сexecutable/argumentsдля stdio. - Для встроенных пресетов пользователь часто не дублирует в файле пустые строки «как в примере» — достаточно
modeи при необходимости переопределений в соответствующей вложенной таблице. - Отдельная потребность — не хранить абсолютные пути к инструментам в
settings.toml(общий репозиторий dotfiles, CI, разные машины), но иметь предсказуемый способ подставить их из окружения без «магии» в значенииexecutable.
Решение¶
1. Канон на сегодня (реализовано): mode и вложенные профили¶
- Разрешение пары файл процесса + аргументы берётся из активного профиля по
mode(см.ResolveForRuntime()вCSharpLanguageServerSettings/MarkdownLanguageServerSettings). - Для пресетов с разумным дефолтом на PATH пустой или пробель-only
executableв профиле означает: использовать встроенное имя команды (напримерmarksman,csharp-ls,OmniSharpс фиксированным префиксом аргументов--languageserver— см. код), а не «ошибка конфигурации». - Пустой
argumentsдопустим: дополнительные аргументы добавляются к пресету только если пользователь задал непустую строку. - Профиль
[languages.csharp.custom](и аналог Markdown) по-прежнему требует непустогоexecutable, если нет встроенного дефлета для этого пути; это не меняется данным ADR.
2. Канон на сегодня: опциональность ключей в TOML¶
- Ключи
executableиargumentsне обязаны присутствовать в вложенной таблице профиля, если устраивают значения по умолчанию из модели (пустые строки) и выбранныйmodeподдерживает пресет из п. 1. - Пример минимальной конфигурации Markdown LSP:
[languages.markdown]
mode = "Marksman"
(таблица [languages.markdown.marksman] с пустыми executable/arguments — по желанию для явности.)
- Пример с C# (ParseOnly — дефолт, можно не указывать
modeв файле, если устраивает):
[languages.csharp]
mode = "ParseOnly"
[languages.csharp.parse_only]
executable = ""
arguments = ""
3. Предложение на будущее (не обязатель реализовано): явный флаг «из окружения»¶
Цель: дать опцию не дублировать путь в TOML и при этом явно сказать IDE «бери из переменных окружения», а не полагаться на случайно пустую строку.
- В профиле (или в общем блоке LSP) вводится булево поле, например
launch_from_environment(snake_case в файле, PascalCase в модели — как у остальногоsettings.tomlпо 0028). - При
launch_from_environment = true: executableиargumentsв TOML могут отсутствовать или быть пустыми без потери смысла;- IDE читает согласованные имена переменных (префикс, например
CASCADE_IDE_…, и суффиксы по виду LSP), документированные в этом ADR и в краткой подсказке readiness (0023). - Приоритет после реализации должен быть зафиксирован в коде и здесь же; рекомендуемый порядок: значения из окружения только если флаг true; иначе — как сейчас (TOML → пресет). При флаге true и отсутствующих переменных — либо откат к пресету как к п. 1 (с явной строкой в readiness), либо «не стартуем» с явной причиной; не молчаливое смешивание.
- Имена переменных окружения задаются отдельным подпунктом этого ADR при первой реализации (чтобы не блокировать принятие п. 1–2); до реализации статус расширения остаётся Proposed.
4. Отклонённые альтернативы¶
- Магические подстановки внутри строки
executable($ENV,${VAR}без отдельного флага) — отклонены: хуже объяснять, сложнее валидировать и показывать в readiness. - Один глобальный флаг на оба LSP без привязки к секции — отклонён: путаница с именами переменных и сценариями «только Markdown на CI».
Последствия¶
- Документация и примеры
settings.tomlсокращают секции LSP доmodeи при необходимости одной вложенной таблицы профиля; полныеexecutable/argumentsостаются валидными для явности. - При добавлении
launch_from_environment— обновить моделиCSharpLanguageServerSettings/MarkdownLanguageServerSettings(и при необходимости обёрткиResolveForRuntime), хосты запуска, Environment readiness и пример вdocs/samples/settings.toml; статус расширения в шапке ADR сменить на Accepted после ревью. - 0028 не дублирует семантику LSP — для деталей командной строки и env ссылка сюда.
Статус реализации (сверка)¶
| Часть ADR | Код / артефакты |
|---|---|
Пресеты, пустой executable |
CSharpLspProviderIds, MarkdownLspProviderIds, LanguageServerLaunchProfile |
| Опциональные ключи в TOML | Десериализация CascadeIdeSettings + значения по умолчанию в CSharpLanguageServerSettings / MarkdownLanguageServerSettings |
launch_from_environment |
Пока нет в модели и резолвере — Proposed |