Skip to content
Ilia Maslakov edited this page Aug 22, 2026 · 3 revisions

Доменная модель Lua-расширений MC

1. Архитектурный обзор (Принципы)

В основе архитектуры лежит жесткое разделение ответственности между политикой (Lua) и механизмом (MC Core).

  • Единый Runtime: Lua в MC — это одна подсистема, а не набор отдельных плагинов. Она загружает пакеты, изолирует их от внутренних структур MC и предоставляет несколько независимых предметных API.
  • Архитектурная граница:
    1. Lua-пакет: Определяет поведение, преобразования и содержимое.
    2. Runtime adapter: Проверяет Lua-значения, переводит их в стабильный C ABI.
    3. Host services: Выполняют разрешённые операции MC.
    4. MC Core: Владеет виджетами, памятью, жизненным циклом, отрисовкой.
  • Правило нулевого доступа: Lua никогда не получает прямых указателей на внутренние структуры MC (WPanel, WEdit, буферы, widget ID, VFS-объекты и т.д.). Взаимодействие идет только через Opaque handles и immutable snapshots.

Иерархическая схема слоев

graph TD
    %% Nodes
    P[1. Lua Package]
    RA[2. Lua Runtime Adapter / mc-lua]
    HS[3. MC Host Services]
    MC_W[Core: Editor, Panels, Viewer]
    MC_M[Core: VFS, Memory, Events]

    %% Edges
    P -->|Domain API: mc.editor...| RA
    RA -->|Validated, Typed ABI| HS
    HS -->|Native public operations| MC_W
    HS -->|Native public operations| MC_M
Loading

2. Фундаментальные технические концепции

Эти сущности пронизывают все домены API. Они обеспечивают стабильность и безопасность.

  • Runtime: Загруженный движок (mc-lua). Регистрируется один раз, создает изолированные Lua-среды для пакетов.
  • Capability (Право): Именованное разрешение на класс операций. Эффективное право есть пересечение возможностей сборки, хоста, рантайма, воркспейса и контекста.
  • Context: Краткоживущий контекст активного вызова MC. Определяет доступные объекты и мутации здесь и сейчас. Хранить контекст для использования вне callback-функции нельзя.
  • Opaque handle: Защищенная ссылка ({kind, id, generation}) на объект, принадлежащий хосту. Не раскрывает адрес памяти. При закрытии объекта handle становится stale и никогда не "оживает" повторно.
  • Snapshot & Revision: Неизменяемое описание состояния объекта на конкретной временной отметке (revision). Операции с устаревшими координатами завершаются ошибкой stale_revision, не меняя данные.
  • Error Model: На границе ABI используются стабильные машинные коды (not_supported, closed, stale_revision, provider_busy) и диагностический текст. Lua-ошибки в callback изолируются и не роняют MC.
  • Source (Источник данных): Абстрактное описание откуда взять данные (bytes, локальный файл, процесс, pipeline). Хост сам материализует источник и передает его consumer'у.

3. Иерархия доменов API (Функциональные группы)

API разделены по предметным областям (workspaces). Пакет может требовать capabilities для нескольких доменов.

3.1. Управление пакетами (Package Model)

Сущности, описывающие жизненный цикл самого расширения.

  1. Package: Единица загрузки. Имеет ID, имя, точку входа и capabilities.
  2. Package Descriptor: Декларативное описание (метаданные) пакета. Проверяется до исполнения Lua-кода.
  3. Workspace: Область применения (file manager, editor, viewer, terminal). Определяет контекст.
  4. Package Origin & Precedence: Системный или пользовательский каталог. Пакет с одинаковым ID в более приоритетном origin замещает менее приоритетный.
  5. Indicator: Именованный фрагмент постоянного UI-состояния, принадлежащий пакету.

3.2. Домен Редактора (mc.editor)

Работа с открытым текстовым документом. MC владеет документом, Lua получает его снимок.

  • Editor Document: Хостовый документ. Идентифицируется через handle.
  • Document Info Snapshot: Состояние документа (path, readonly, modified, revision).
  • Position & Range: Координаты в буфере. Завязаны на revision.
  • Selection: Снимок выделения (режим + один или несколько ranges).
  • Edit & Transaction:
    • Edit: Декларативная замена текста в range.
    • Transaction: Атомарный набор edits, создающий одну запись undo.

3.3. Домен Панелей (mc.panel & mc.panel_provider)

Разделение на управление существующими панелями и провайдеры виртуальных пространств.

Базовое управление (существующие панели)

  • 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 (контент).
  • Column & Presentation: Семантическое поле entry и правила его отображения (хост решает, как рисовать).
  • Panel Selection: Снимок current entry и отмеченных IDs. Передается в action как значение.
  • Content Contract: Механизм связи panel entry с consumer'ом содержимого (custom view, source/stream).

3.4. Домен Просмотра (mc.ui - Viewer)

Просмотр данных в штатном viewer'е MC.

  • Viewer Source Definition: Глобальное описание семейства источников (имя, callbacks, хелп).
  • Viewer Session: Состояние контроллера от момента create до закрытия.
  • Viewer Controller: Opaque объект, связывающий сессию с host viewer'ом.
  • Viewer Source Specification: Подготовленный immutable snapshot источника для открытия в viewer.

3.5. Общие UI-средства (mc.ui - Dialogs, Alerts)

Общие host-owned элементы интерфейса.

  • Dialog Specification: Декларативное описание модального диалога. Lua не управляет виджетами напрямую.
  • Dialog Control: Типизированный элемент формы (label, input, checkbox и т.д.).
  • Dialog Result: Immutable результат завершенного диалога.
  • Help Reference: Ссылка на package-owned help system.

3.6. Внешние процессы (mc.process)

Контролируемый запуск системных команд.

  • Process Request: Команда (argv), рабочая директория, лимиты.
  • Process Result: Результат завершения процесса (stdout, stderr, exit status, признаки truncation).
  • Pipeline Source: Композиция process sources.

3.7. События (mc.on)

Механизм подписки на действия MC.

  • Subscription: Регистрация пакета на событие.
  • Event Snapshot: Неизменяемый снимок данных события. Не дает доступа к живому виджету.

4. Поток управления и жизненный цикл (Key Bindings Flow)

Важно показать, как доменная модель работает в динамике.

  1. Нажатие клавиши в MC.
  2. Глобальный keymap преобразует её в MC Command (например, CK_EditNew).
  3. Плагин панели получает команду через handle_key().
  4. Runtime Adapter перехватывает вызов и переводит его в Domain Operation (вызывает Lua-callback on_edit_new у провайдера).
  5. Lua-пакет выполняет логику и возвращает результат (например, NavigationRequest или EditTransaction).

Пример:

Shift-F4 → CK_EditNew → runtime adapter → calls provider's Lua function `new_connection()`
F4       → CK_Edit    → runtime adapter → calls `edit_connection(snapshot)`

Clone this wiki locally