Files
qode/AGENTS.md
T
2026-10-31 12:18:07 +03:00

8.3 KiB
Raw Blame History

AGENTS.md

qode — настольный редактор кода на GPUI (gpui-kit) с расширением поведения через Lua и клиентом LSP по stdio. Этот файл описывает архитектуру и принципы, которые нужно сохранять при изменениях.

Модули

Путь Ответственность
src/main.rs Точка входа, окно, аргументы командной строки
src/constants.rs Константы окна, CLI и каталог сценариев
src/editor.rs Доменная модель: документы, вкладки, языки
src/api.rs AppApi / EditorApi / PanelApi / TreeApi / ToolbarApi — единственная поверхность управления
src/script.rs Lua-движок, app, include, require
src/prompt.rs Плавающее поле ввода: запрос из Lua и открытое окно
src/keymap.rs KeyBinding, KeyMap, встроенные команды и Lua-обработчики
src/app.rs GPUI-вид, отрисовка, события, автодополнение
src/completion.rs Всплывающий список, CaretPopup, преобразования LSP-элементов
src/panel.rs PanelState и блоки панелей
src/toolbar.rs Состояние верхней панели: лейблы и кнопки
src/tree.rs Абстрактное дерево для панелей
src/gutter.rs Иконки на полях слева от редактора
src/icons.rs Каталог иконок Lucide
src/lsp.rs Менеджер LSP-серверов, JSON-RPC, файловый вотчер
DOCS.md, init.lua Пользовательская документация и пример конфигурации

Главные принципы

1. AppApi — центр приложения

  • Документы, вкладки, панели, дерево, окно, подсветка, LSP и привязки клавиш меняются только через AppApi, EditorApi или PanelApi / TreeApi / ToolbarApi.
  • Всё, что относится к редактору (вкладки, текст, gutter, сохранение, LSP и привязки редактора), живёт в app.editor; окно, панели и глобальные привязки — в app.
  • Состояние живёт в общих Rc<RefCell<_>> / Arc, чтобы UI, API и Lua видели одни и те же объекты. Второй копии состояния быть не должно.
  • Команды окна складываются в очередь и применяются в начале кадра (apply_window_commands); UI и Lua не вызывают Window напрямую.
  • Если действие пользователя меняет состояние, оно выражается методом API, а не логикой внутри обработчика UI. Отрисовка состояние только читает.
  • Исключение — системные кнопки окна внутри gpui-kit::TitleBar: их поведение принадлежит библиотеке.

2. Lua повторяет возможности API

  • Публичные методы impl AppApi / impl EditorApi с #[mlua::userdata_impl] доступны как app:method(...) / app.editor:method(...). Добавляя возможность, сразу добавляйте и Lua-метод.
  • Имена — snake_case; вкладки и индексы нумеруются с нуля; панели — app.left_panel, app.right_panel, app.bottom_panel; блоки панелей получают свои объекты (tree).
  • Для методов, которые не должны попадать в Lua, используется #[lua(skip)]. Для generic-методов добавляется тонкая не-generic Lua-обёртка.
  • DOCS.md и комментарии в init.lua обновляются в том же изменении, что и публичный API. Документация описывает фактическое поведение, без «запланированных» методов.

3. Клавиатура — только через KeyMap

  • Встроенные привязки (Ctrl/Cmd+S, Ctrl/Cmd+Space, навигация по списку автодополнения) регистрируются в KeyMap и могут быть заменены или удалены из Lua через app:map_key / app.editor:map_key / app:map_completion_key.
  • У приложения, редактора и каждого блока панели своя KeyMap и свой текущий режим (один символ; - — режим по умолчанию). Привязка хранит строку режимов, в которых она действует: "" — все, "-iv" — по умолчанию и i/v.
  • Глобальные привязки обрабатываются всегда; затем, если фокус в редакторе, дополнительно привязки редактора, а если фокус на блоке панели — привязки этого блока. Обработчик может быть Lua-функцией или встроенной командой.
  • Перехватчик клавиш выполняется раньше действий редактора и используется только для слоя автодополнения. Этот порядок менять нельзя.
  • Текстовый ввод редактора — не привязка клавиши.

4. Модель отделена от GPUI

  • editor.rs, panel.rs и tree.rs не знают о Window и Context.
  • Вид переносит изменения модели в виджет по Workspace::revision; набор текста в редакторе ревизию не трогает, чтобы не сбрасывать курсор.
  • Инвариант Workspace: открыт хотя бы один документ. Поэтому active() возвращает документ без Option.
  • Встроенный старт — одна пустая вкладка. Примеры и демонстрационные документы не должны попадать в код приложения; init.lua — единственное место для примеров.

5. LSP работает в фоне

  • LspManager общий (Arc) для вида, API и фоновых задач.
  • Процессы, чтение stdout/stderr и файловый вотчер живут в отдельных потоках; ответы приходят через каналы и ожидаются в background_executor, а не в кадре UI.
  • Какие серверы запускать, решает Lua; менеджер отвечает только за жизненный цикл, JSON-RPC и синхронизацию документов.

Соглашения

  • Код, комментарии и пользовательская документация — на русском.
  • Публичные элементы Rust документируются ///.
  • Новые зависимости добавляются только при реальной необходимости; сначала используются возможности gpui-kit, mlua и уже подключённых крейтов.
  • Изменения должны быть локальными и в стиле окружающего кода. Не добавляйте параллельные пути управления и не оставляйте мёртвый код.

Проверка

Перед завершением изменения:

cargo fmt
cargo test
cargo build

Если какую-то команду выполнить нельзя, это нужно явно указать в ответе.