refactoring
This commit is contained in:
@@ -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`.
|
||||
Reference in New Issue
Block a user