files
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
# Lua API
|
||||
|
||||
Приложение выполняет `init.lua` при запуске и предоставляет сценариям объект `app`
|
||||
для управления окном, вкладками, подсветкой и LSP-серверами.
|
||||
для управления окном, вкладками, панелями, файловой системой, подсветкой и
|
||||
LSP-серверами.
|
||||
|
||||
## Запуск и каталог сценариев
|
||||
|
||||
@@ -26,7 +27,7 @@ cargo run -- main.go
|
||||
|
||||
| Метод | Описание |
|
||||
| --- | --- |
|
||||
| `app:tabs()` | Список вкладок: `{{ index = 0, title = "main.rs" }, ...}` |
|
||||
| `app:tabs()` | Список вкладок: `{{ index = 0, title = "main.rs", icon = "file" }, ...}` |
|
||||
| `app:active_tab()` | Индекс активной вкладки |
|
||||
| `app:set_active_tab(index)` | Сделать вкладку активной; `true`, если вкладка существует |
|
||||
| `app:next_tab()` | Переключить на следующую вкладку, вернуть индекс |
|
||||
@@ -34,6 +35,25 @@ cargo run -- main.go
|
||||
| `app:open_tab()` | Открыть пустую вкладку, вернуть индекс |
|
||||
| `app:open(path)` | Открыть файл с диска, вернуть индекс вкладки. Если файла нет — открывается пустой буфер с таким именем |
|
||||
| `app:close_tab(index)` | Закрыть вкладку; `true`, если вкладка закрыта |
|
||||
| `app:set_tab_icon(index, name)` | Назначить иконку вкладке; `false`, если вкладки нет или иконка неизвестна |
|
||||
| `app:clear_tab_icon(index)` | Вернуть иконку по умолчанию (`file`) |
|
||||
| `app:tab_icon(index)` | Имя иконки вкладки или `nil`, если вкладки нет |
|
||||
|
||||
### Иконки вкладок
|
||||
|
||||
Слева от названия вкладки показывается иконка; по умолчанию это `file`.
|
||||
Имя — название иконки [Lucide](https://lucide.dev/icons/), регистр не важен.
|
||||
Например:
|
||||
|
||||
```lua
|
||||
app:set_tab_icon(0, "file-code") -- main.rs
|
||||
app:set_tab_icon(1, "book-open") -- notes.md
|
||||
app:clear_tab_icon(1) -- снова "file"
|
||||
```
|
||||
|
||||
Подчёркивания и пробелы считаются дефисом, а `icons/` и `.svg` можно
|
||||
не писать: `file_code`, `file-code` и `icons/file-code.svg` равнозначны.
|
||||
Неизвестное имя не назначается — метод вернёт `false`.
|
||||
|
||||
### Текст
|
||||
|
||||
@@ -63,6 +83,24 @@ app:set_language(0, "rust")
|
||||
| --- | --- |
|
||||
| `app:save()` | Сохранить активную вкладку в её файл |
|
||||
|
||||
### Файловая система
|
||||
|
||||
| Метод | Описание |
|
||||
| --- | --- |
|
||||
| `app:list_dir(path)` | Содержимое каталога: `{{ id = "src/main.rs", name = "main.rs", is_dir = false }, ...}` |
|
||||
|
||||
Путь отсчитывается от текущего рабочего каталога процесса. Пустая строка или
|
||||
`"."` означают сам текущий каталог. Поле `id` — путь элемента относительно
|
||||
текущего каталога: его можно передать в `app:open(id)` и использовать как
|
||||
идентификатор узла дерева. Элементы уже отсортированы по имени без учёта
|
||||
регистра.
|
||||
|
||||
```lua
|
||||
for _, entry in ipairs(app:list_dir("src")) do
|
||||
print(entry.name, entry.is_dir)
|
||||
end
|
||||
```
|
||||
|
||||
### Привязка клавиш
|
||||
|
||||
`app:map_key(keys, fn)` назначает обработчик на нажатие или отпускание клавиши
|
||||
@@ -190,6 +228,100 @@ app.right_panel:toggle()
|
||||
app.bottom_panel:close()
|
||||
```
|
||||
|
||||
### Блоки панелей
|
||||
|
||||
Панель может содержать блоки. Блок создаётся через API панели и живёт вместе
|
||||
с ней; сейчас поддерживается один вид блока — абстрактное дерево.
|
||||
|
||||
```lua
|
||||
local tree = app.left_panel:add_tree()
|
||||
```
|
||||
|
||||
Редактор отвечает только за отрисовку дерева. Что означает каждый узел,
|
||||
решает сценарий: это могут быть файлы проекта, задачи, настройки — что угодно.
|
||||
Файловое дерево проекта в `init.lua` собирается из `app:list_dir`, но сам
|
||||
редактор о файловой системе в блоке ничего не знает.
|
||||
|
||||
| Метод | Описание |
|
||||
| --- | --- |
|
||||
| `tree:append(nodes, parent)` | Добавить узлы к `parent`; `parent = ""` — корень |
|
||||
| `tree:remove(id)` | Удалить узел и всех потомков рекурсивно; `false`, если узла нет |
|
||||
| `tree:on_toggle(fn)` | Обработчик раскрытия: `fn(expanded, id, loaded)` |
|
||||
| `tree:on_click(fn)` | Обработчик клика по конечной ноде: `fn(id)` |
|
||||
| `tree:selected()` | Идентификатор выбранной строки или `nil` |
|
||||
| `tree:focus(id)` | Раскрыть всех родителей, выбрать узел и передать фокус дереву |
|
||||
|
||||
Узел — таблица:
|
||||
|
||||
```lua
|
||||
{
|
||||
id = "src/main.rs", -- строковый идентификатор (путь файла)
|
||||
label = "main.rs", -- отображаемый текст
|
||||
icon = "file-code", -- имя иконки Lucide (необязательно)
|
||||
expandable = false, -- раскрываемая ли нода (папка)
|
||||
expanded = false, -- раскрыта ли она сейчас
|
||||
}
|
||||
```
|
||||
|
||||
`append` добавляет узлы, а не заменяет дерево. Повторная передача того же `id`
|
||||
обновляет описание узла, но не создаёт копию.
|
||||
|
||||
Дети каждого уровня сортируются по `label` без учёта регистра. Сначала идут
|
||||
раскрываемые узлы (`expandable = true`), затем конечные; внутри каждой группы —
|
||||
по алфавиту.
|
||||
|
||||
В обработчик `on_toggle` приходит `loaded = true`, если дочерние узлы уже
|
||||
добавляли в эту ноду; при первом раскрытии — `false`.
|
||||
|
||||
Клик по строке выбирает её. Выбранную строку можно перемещать стрелками
|
||||
`↑`/`↓`; `↑`/`↓` двигают выбор, `→` раскрывает папку или переходит к первому
|
||||
ребёнку, `←` сворачивает папку или выбирает родителя, `Enter` раскрывает папку
|
||||
или вызывает `on_click` для конечной ноды. Выбор сохраняется, пока панель
|
||||
закрыта; при повторном открытии панели фокус возвращается на выбранную строку.
|
||||
|
||||
Пример отложенной загрузки дерева:
|
||||
|
||||
```lua
|
||||
local tree = app.left_panel:add_tree()
|
||||
|
||||
local function load_dir(path)
|
||||
local nodes = {}
|
||||
for _, entry in ipairs(app:list_dir(path)) do
|
||||
nodes[#nodes + 1] = {
|
||||
id = entry.id,
|
||||
label = entry.name,
|
||||
icon = entry.is_dir and "folder" or "file",
|
||||
expandable = entry.is_dir,
|
||||
expanded = false,
|
||||
}
|
||||
end
|
||||
tree:append(nodes, path)
|
||||
end
|
||||
|
||||
tree:on_toggle(function(expanded, id, loaded)
|
||||
if expanded and not loaded then
|
||||
load_dir(id)
|
||||
end
|
||||
end)
|
||||
|
||||
tree:on_click(function(id)
|
||||
app:open(id)
|
||||
end)
|
||||
|
||||
app.left_panel:open()
|
||||
load_dir("")
|
||||
|
||||
-- При открытии панели вернуть фокус на последнюю выбранную строку.
|
||||
app:map_key("<C-b>", function()
|
||||
if app.left_panel:toggle() then
|
||||
local selected = tree:selected()
|
||||
if selected then
|
||||
tree:focus(selected)
|
||||
end
|
||||
end
|
||||
end)
|
||||
```
|
||||
|
||||
## Подключение других Lua-файлов
|
||||
|
||||
Файлы подключаются из каталога сценариев:
|
||||
|
||||
Reference in New Issue
Block a user