Files
qode/AGENTS.md
T
2026-10-31 01:50:35 +03:00

7.2 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 / PanelApi / TreeApi / ToolbarApi — единственная поверхность управления
src/script.rs Lua-движок, app, include, require
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/icons.rs Каталог иконок Lucide
src/lsp.rs Менеджер LSP-серверов, JSON-RPC, файловый вотчер
DOCS.md, init.lua Пользовательская документация и пример конфигурации

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

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

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

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

  • Публичные методы impl AppApi с #[mlua::userdata_impl] доступны как app:method(...). Добавляя возможность, сразу добавляйте и Lua-метод.
  • Имена — snake_case; вкладки и индексы нумеруются с нуля; панели — app.left_panel, app.right_panel, app.bottom_panel.
  • Для методов, которые не должны попадать в 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:map_completion_key.
  • KeyMap имеет два слоя: глобальный и completion. Обработчик может быть 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

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