106 lines
7.2 KiB
Markdown
106 lines
7.2 KiB
Markdown
# 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` и уже подключённых крейтов.
|
||
- Изменения должны быть локальными и в стиле окружающего кода. Не добавляйте
|
||
параллельные пути управления и не оставляйте мёртвый код.
|
||
|
||
## Проверка
|
||
|
||
Перед завершением изменения:
|
||
|
||
```sh
|
||
cargo fmt
|
||
cargo test
|
||
cargo build
|
||
```
|
||
|
||
Если какую-то команду выполнить нельзя, это нужно явно указать в ответе.
|