-
Notifications
You must be signed in to change notification settings - Fork 8
Lua domain model ru
В основе архитектуры лежит жесткое разделение ответственности между политикой (Lua) и механизмом (MC Core).
- Единый Runtime: Lua в MC — это одна подсистема, а не набор отдельных плагинов. Она загружает пакеты, изолирует их от внутренних структур MC и предоставляет несколько независимых предметных API.
-
Архитектурная граница:
- Lua-пакет: Определяет поведение, преобразования и содержимое.
- Runtime adapter: Проверяет Lua-значения, переводит их в стабильный C ABI.
- Host services: Выполняют разрешённые операции MC.
- MC Core: Владеет виджетами, памятью, жизненным циклом, отрисовкой.
-
Правило нулевого доступа: Lua никогда не получает прямых указателей на внутренние структуры MC (
WPanel,WEdit, буферы, widget ID, VFS-объекты и т.д.). Взаимодействие идет только через Opaque handles и immutable snapshots.
flowchart TD
%% Nodes
P["1. Lua Package"]
RA["2. Lua Runtime Adapter / mc-lua"]
HS["3. MC Host Services"]
MC_W["Core: Editor, Panels, Viewer, Diff Viewer"]
MC_M["Core: Dialogs, Processes, Keymap, Events, Lifecycle"]
%% Edges
P <-->|"Domain API calls and Lua callbacks"| RA
RA <-->|"Validated, typed runtime ABI"| HS
HS <-->|"Host operations and callbacks"| MC_W
HS <-->|"Host operations and events"| MC_M
Стрелки двунаправленные: Lua вызывает host services через runtime adapter, а MC доставляет через тот же ABI события, действия и синхронные callbacks провайдеров. Это не означает, что Lua получает прямой доступ к подсистемам ядра.
Эти сущности пронизывают все домены API. Они обеспечивают стабильность и безопасность.
-
Runtime: Загруженный движок (
mc-lua). Регистрируется один раз, создает изолированные Lua-среды для пакетов. - Capability (Возможность): Именованная возможность хоста выполнить класс операций. Её доступность определяется сборкой, возможностями хоста, размером ABI, поддержкой рантайма, воркспейсом и активным контекстом. Текущий manifest пакета не является системой выдачи разрешений.
- Context: Краткоживущий контекст активного вызова MC. Определяет доступные объекты и мутации здесь и сейчас. Сам контекст нельзя использовать вне callback-функции. Handle можно сохранить между callbacks, если это допускает жизненный цикл соответствующего доменного объекта, но вызывать через него host-операции можно только в разрешённом активном контексте.
-
Opaque handle: Защищенная ссылка (
{kind, id, generation}) на объект, принадлежащий хосту. Не раскрывает адрес памяти. При закрытии объекта handle становится недействительным, операции возвращаютclosed, и ссылка никогда не "оживает" повторно. -
Snapshot & Revision: Неизменяемое описание состояния объекта на конкретной временной отметке (revision). Операции с устаревшими координатами завершаются ошибкой
stale_revision, не меняя данные. -
Error Model: На границе ABI используются стабильные машинные коды (
not_supported,closed,stale_revision,provider_busy) и диагностический текст. Lua-ошибки в callback изолируются и не роняют MC. - Source (Источник данных): Абстрактное описание откуда взять данные (bytes, локальный файл, процесс, pipeline). Хост сам материализует источник и передает его consumer'у.
API разделены по предметным областям. Workspace определяет область применения пакета и доступный контекст, но не является синонимом API-домена.
Сущности, описывающие жизненный цикл самого расширения.
-
Package: Единица загрузки. Имеет ID, имя, workspace, точку входа, состояние enabled/disabled и декларацию
provides. - Package Descriptor: Декларативное описание (метаданные) пакета. Проверяется до исполнения Lua-кода. Отдельного поля «класс пакета» или списка запрашиваемых host capabilities в текущем manifest нет.
- Workspace: Область применения (file manager, editor, viewer, terminal). Определяет контекст.
- Package Origin & Precedence: Системный или пользовательский каталог. Пакет с одинаковым ID в более приоритетном origin замещает менее приоритетный.
- Indicator: Именованный фрагмент постоянного UI-состояния, принадлежащий пакету.
Работа с открытым текстовым документом. MC владеет документом, Lua получает его снимок.
- Editor Document: Хостовый документ. Идентифицируется через handle.
- Document Info Snapshot: Состояние документа (path, readonly, modified, revision).
- Position & Range: Координаты в буфере. Завязаны на revision.
- Selection: Снимок выделения (режим + один или несколько ranges).
-
Edit & Transaction:
- Edit: Декларативная замена текста в range.
- Transaction: Атомарный набор edits, создающий одну запись undo.
Разделение на управление существующими панелями и провайдеры виртуальных пространств.
- Panel & Panel Reference: Временная ссылка на уже существующую активную или пассивную панель MC. Не дает владения виджетом.
-
Panel Provider: Глобальная регистрация логического пространства (например,
git:,arc:,ftp:). Определяет capabilities, callbacks, действия. - Connection: Сохраненное описание точки входа (например, конкретный URL).
- Provider Instance: Состояние одного открытия провайдера в конкретной панели. Живет пока открыта панель.
- Panel View: Revisioned snapshot текущего состояния панели (entries, columns, focus). Заменяется целиком после refresh.
- Panel Entry: Элемент view (snapshot, не файл). Может быть directory-like (навигация) или file-like (контент). Provider использует ID последовательно в пределах instance, а операции над entry дополнительно привязаны к revision текущего view.
- Column & Presentation: Семантическое поле entry и правила его отображения (хост решает, как рисовать).
- Panel Selection: Снимок current entry и отмеченных IDs. Передается в action как значение.
-
Content Contract: Механизм связи panel entry с consumer'ом содержимого. Lua callback
open_read()возвращает типизированный source (bytes, локальный файл, процесс или pipeline), а runtime bridge при необходимости преобразует его в общийmc_pp_input_stream_t. Благодаря этому штатный consumer, например arcmc, читает данные через stream API, хотя Lua не реализует низкоуровневые callbacksopen/read/closeсамостоятельно.
Просмотр данных в штатном viewer'е MC.
- Viewer Source Definition: Глобальное описание семейства источников (имя, callbacks, хелп).
-
Viewer Session: Состояние контроллера от момента
createдо закрытия. - Viewer Controller: Opaque объект, связывающий сессию с host viewer'ом.
- Viewer Source Specification: Подготовленный immutable snapshot источника для открытия в viewer.
Общие host-owned элементы интерфейса.
- Dialog Specification: Декларативное описание модального диалога. Lua не управляет виджетами напрямую.
- Dialog Control: Типизированный элемент формы (layout-контейнер, label, input, checkbox, radio/select, button, разделитель).
- Dialog Result: Immutable результат завершенного диалога.
- Help Reference: Ссылка на package-owned help system.
Контролируемый запуск системных команд.
-
Process Request: Текущий
mc.process.run()принимает shell-команду строкой и ограничениеmax_output. Структурированныеargv, рабочая директория и pipeline относятся к typed process source в viewer-source ABI. - Process Result: Результат завершения процесса (stdout, stderr, exit status, признаки truncation).
- Pipeline Source: Композиция process sources.
Механизм подписки на действия MC.
- Subscription: Регистрация пакета на событие.
- Event Snapshot: Неизменяемый снимок данных события. Не дает доступа к живому виджету.
Важно показать, как доменная модель работает в динамике.
- Нажатие клавиши в MC.
- Глобальный keymap преобразует её в MC Command (например,
CK_EditNew). - Плагин панели получает команду через
handle_key(). -
Runtime Adapter переводит вызов в Domain Operation (например, вызывает Lua callback
new_connection()у провайдера). - Lua-пакет выполняет логику и возвращает результат, предусмотренный конкретной операцией.
Пример:
Shift-F4 → CK_EditNew → runtime adapter → calls provider's Lua function `new_connection()`
F4 → CK_Edit → runtime adapter → calls `edit_connection(snapshot)`