# 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("", "", "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`.