5.5 KiB
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 (по умолчанию — текущий каталог). Его можно переопределить
аргументом командной строки:
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 разбит на группы. Методы вызываются через двоеточие:
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 |
api.panels |
Левая, правая и нижняя панели, верхняя панель редактора, блоки-деревья | panels.md |
api.path |
Файловая система: чтение, запись, создание и удаление | path.md |
api.window |
Окно и плавающее поле ввода | window.md |
api.keymap |
Глобальные привязки клавиш и режимы | keymap.md |
api.editor (LSP) |
Запуск серверов и обработка диагностики | 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.