refactoring

This commit is contained in:
2026-10-31 15:33:00 +03:00
parent e8e2d25600
commit 838627fb33
27 changed files with 2715 additions and 1259 deletions
+44 -15
View File
@@ -11,8 +11,8 @@
| `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/api.rs` | `AppApi` / `EditorApi` / `PanelsApi` / `PanelApi` / `ToolbarApi` / `TreeApi` / `PathApi` / `WindowApi` / `KeymapApi` — единственная поверхность управления |
| `src/script.rs` | Lua-движок, `api`, `include`, `require` |
| `src/prompt.rs` | Плавающее поле ввода: запрос из Lua и открытое окно |
| `src/keymap.rs` | `KeyBinding`, `KeyMap`, встроенные команды и Lua-обработчики |
| `src/app.rs` | GPUI-вид, отрисовка, события, автодополнение |
@@ -23,18 +23,41 @@
| `src/gutter.rs` | Иконки на полях слева от редактора |
| `src/icons.rs` | Каталог иконок Lucide |
| `src/lsp.rs` | Менеджер LSP-серверов, JSON-RPC, файловый вотчер |
| `DOCS.md`, `init.lua` | Пользовательская документация и пример конфигурации |
| `docs/*.md`, `init.lua` | Пользовательская документация и пример конфигурации |
## Главная идея: конструктор IDE
qode — не готовый редактор с фиксированным набором функций, а конструктор
своей IDE. Rust/GPUI даёт универсальные примитивы, Lua задаёт поведение:
- **Rust** отвечает за окно, вкладки, текстовый редактор, подсветку, gutter,
автодополнение, панели, абстрактное дерево, плавающее поле ввода, доступ к
файловой системе, клавиатуру и LSP-клиент.
- **Lua** отвечает за всё, что делает редактор именно этой IDE: файловое
дерево, дерево диагностики, команды, раскладки, статусы, проектные
сценарии, оформление панелей и последовательности действий.
Правило для изменений:
- В Rust добавляется только универсальный примитив, которым могут
пользоваться разные сценарии, или то, что нельзя выразить через уже
существующее API (доступ к GPUI, ОС, протоколу LSP).
- Если поведение выражается через API из Lua, оно должно жить в Lua, а не в
Rust: никаких проектных правил, готовых панелей с бизнес-данными,
демонстрационных виджетов и команд под конкретный workflow.
- Новый примитив сразу получает Lua-метод и описание в `docs/`.
## Главные принципы
### 1. `AppApi` — центр приложения
- Документы, вкладки, панели, дерево, окно, подсветка, LSP и привязки клавиш
меняются только через `AppApi`, `EditorApi` или `PanelApi` / `TreeApi` /
`ToolbarApi`.
меняются только через `AppApi`, `EditorApi`, `PanelsApi`, `PanelApi`,
`ToolbarApi`, `TreeApi`, `PathApi`, `WindowApi` или `KeymapApi`.
- Всё, что относится к редактору (вкладки, текст, gutter, сохранение, LSP и
привязки редактора), живёт в `app.editor`; окно, панели и глобальные
привязки — в `app`.
привязки редактора), живёт в `api.editor`; панели — в `api.panels`, файловая
система — в `api.path`, окно — в `api.window`, глобальные привязки — в
`api.keymap`.
- Состояние живёт в общих `Rc<RefCell<_>>` / `Arc`, чтобы UI, API и Lua
видели одни и те же объекты. Второй копии состояния быть не должно.
- Команды окна складываются в очередь и применяются в начале кадра
@@ -47,15 +70,21 @@
### 2. Lua повторяет возможности API
- Публичные методы `impl AppApi` / `impl EditorApi` с `#[mlua::userdata_impl]`
доступны как `app:method(...)` / `app.editor:method(...)`. Добавляя
возможность, сразу добавляйте и Lua-метод.
- Публичные методы `impl AppApi` / `impl EditorApi` / `impl PathApi` и других
`*Api` с `#[mlua::userdata_impl]` доступны из Lua через объект `api`:
`api.editor:method(...)`, `api.path:method(...)`, `api.panels.left:method(...)`.
Добавляя возможность, сразу добавляйте и Lua-метод.
- Имена — `snake_case`; вкладки и индексы нумеруются с нуля; панели —
`app.left_panel`, `app.right_panel`, `app.bottom_panel`; блоки панелей
получают свои объекты (`tree`).
`api.panels.left`, `api.panels.right`, `api.panels.bottom`,
`api.panels.toolbar`; блоки панелей получают свои объекты (`tree`).
- `AppApi` — только группа-навигатор: методы живут в `EditorApi`,
`PanelsApi`, `PathApi`, `WindowApi` или `KeymapApi`. Не добавляйте новый
метод прямо в `api`, если для него есть подходящая группа.
- Все методы `PathApi` принимают путь либо строкой `"foo/bar"`, либо
массивом сегментов `{ "foo", "bar" }`.
- Для методов, которые не должны попадать в Lua, используется `#[lua(skip)]`.
Для generic-методов добавляется тонкая не-generic Lua-обёртка.
- `DOCS.md` и комментарии в `init.lua` обновляются в том же изменении, что и
- `docs/*.md` и комментарии в `init.lua` обновляются в том же изменении, что и
публичный API. Документация описывает фактическое поведение, без
«запланированных» методов.
@@ -63,8 +92,8 @@
- Встроенные привязки (`Ctrl/Cmd+S`, `Ctrl/Cmd+Space`, навигация по списку
автодополнения) регистрируются в `KeyMap` и могут быть заменены или удалены
из Lua через `app:map_key` / `app.editor:map_key` /
`app:map_completion_key`.
из Lua через `api.keymap:map_key` / `api.editor:map_key` /
`api.keymap:map_completion_key`.
- У приложения, редактора и каждого блока панели своя `KeyMap` и свой текущий
режим (один символ; `-` — режим по умолчанию). Привязка хранит строку
режимов, в которых она действует: `""` — все, `"-iv"` — по умолчанию и