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
+99
View File
@@ -0,0 +1,99 @@
# qode — конструктор IDE на Lua
`qode` — настольный редактор кода на GPUI (`gpui-kit`), который расширяется
Lua-сценариями. При запуске приложение выполняет `init.lua` и предоставляет
сценарию объект `api`.
## Идея
Rust-часть даёт только базовые универсальные примитивы:
- окно и его элементы;
- вкладки, текстовый редактор, подсветка, gutter, автодополнение;
- панели и абстрактное дерево;
- плавающее поле ввода;
- файловая система;
- привязки клавиш;
- LSP-клиент по stdio.
Вся бизнес-логика IDE — файловое дерево, дерево диагностики, команды,
раскладки, проектные сценарии, оформление и поведение — живёт в Lua.
Если поведение зависит от проекта или рабочего процесса, его место в
`init.lua` или подключаемых модулях, а не в Rust.
Новую возможность в Rust стоит добавлять, только если это универсальный
примитив, нужный разным сценариям, или если её нельзя выразить через уже
существующее API (доступ к GPUI, ОС, протоколу LSP). Бизнес-правила
(какие файлы показывать, как создавать документы, что писать в статус,
какие команды запускать) остаются в Lua.
## Запуск и каталог сценариев
Каталог поиска `init.lua` задаётся константой `SCRIPT_DIR` в
`src/constants.rs` (по умолчанию — текущий каталог). Его можно переопределить
аргументом командной строки:
```sh
qode --config /path/to/project main.go
cargo run -- --config ./config
cargo run -- main.go
```
- В каталоге `--config` должны лежать `init.lua` и подключаемые им модули.
- Первый позиционный аргумент открывается после выполнения `init.lua`
через `api.editor:open(path)` — как `vim main.go` или `nano main.go`.
- `--config` меняет только каталог сценариев. Рабочий каталог процесса, а
вместе с ним пути `api.editor:open`, `api.editor:save`, `api.path:*` и
`root` у LSP не меняются.
## Объект `api`
Объект `api` разбит на группы. Методы вызываются через двоеточие:
```lua
api.editor:open("src/main.rs")
api.editor:save()
api.panels.left:open()
api.path:list("src")
api.window:close()
api.keymap:map_key("", "<C-s>", "save")
```
| Группа | Назначение | Документация |
| --- | --- | --- |
| `api.editor` | Вкладки, текст, gutter, подсветка, сохранение, LSP, привязки редактора | [editor.md](editor.md) |
| `api.panels` | Левая, правая и нижняя панели, верхняя панель редактора, блоки-деревья | [panels.md](panels.md) |
| `api.path` | Файловая система: чтение, запись, создание и удаление | [path.md](path.md) |
| `api.window` | Окно и плавающее поле ввода | [window.md](window.md) |
| `api.keymap` | Глобальные привязки клавиш и режимы | [keymap.md](keymap.md) |
| `api.editor` (LSP) | Запуск серверов и обработка диагностики | [lsp.md](lsp.md) |
Номера вкладок во всех методах нумеруются с нуля. Массив, который возвращает
`api.editor:tabs()`, остаётся обычной Lua-таблицей с индексами от 1, поэтому
поле `index` — единственный надёжный способ сослаться на вкладку.
## Подключение других Lua-файлов
Файлы подключаются из каталога сценариев:
| Способ | Описание |
| --- | --- |
| `include("tools.lua")` | Выполнить файл сразу |
| `require("tools")` | Выполнить один раз (как обычный Lua-модуль) |
## Добавление новых методов
Методы добавляются в `src/api.rs`. Публичные методы `impl`-блока с
`#[mlua::userdata_impl]` автоматически доступны из Lua:
- методы `AppApi` — у объекта `api`;
- методы `EditorApi` — у `api.editor`;
- методы `PanelApi` — у `api.panels.left`, `.right`, `.bottom`;
- методы `ToolbarApi` — у `api.panels.toolbar`;
- методы `PathApi` — у `api.path`;
- методы `WindowApi` — у `api.window`;
- методы `KeymapApi` — у `api.keymap`.
Чтобы не экспортировать метод, его помечают `#[lua(skip)]`.
Новый вид блока панели должен добавить методы в свой `*Api` и отдавать свою
`KeyMap`, как это делает `TreeApi`.