Ядро компактное и ничего не знает о GUI. Форматы, подсветка, темы и инструменты подключаются к нему через API на чистом C. Одно это скучное решение и позволяет расширению работать между компиляторами и языками.
01 · зачем c abi
C++ ABI нестабилен между компиляторами, стандартными библиотеками и даже флагами сборки. Редактор, отдающий плагинам C++-классы, заставил бы каждого автора расширения повторять свой тулчейн — и ломал бы их при следующем обновлении компилятора.
Поэтому граница описана на C: непрозрачные хендлы, простые структуры и указатели на функции. Плагин, собранный MSVC, загружается в сборку от Clang; плагин на C или Rust живёт рядом с плагином на C++.
Ядро при этом остаётся без GUI. Плагин формата не тянет интерфейсных зависимостей — именно это делает ядро тестируемым, а поведение редактора на больших файлах предсказуемым.
02 · виды плагинов
Учит редактор типу файла: как он читается, показывается и записывается. Такого вида csv (табличный режим) и epub (WYSIWYG).
Поставляет грамматику и правила отступов. Таков плагин tree-sitter из комплекта: шесть языков на одном рантайме.
Добавляет возможность поверх документа или проекта: git, clangd, unreal.
Поставляет палитру и параметры оформления внутри существующих дизайн-направлений.
03 · форма
Он экспортирует одну функцию, которая возвращает статическое описание: кто он, под какую версию ABI собран, что умеет и колбэки для этого.
/* editor/PluginAPI.h — сокращённо */ typedef struct EditorPluginInfo { int api_version; /* должен быть равен EDITOR_PLUGIN_API_VERSION */ const char* id; /* обратный DNS, "com.example.format.foo" */ const char* name; const char* version; /* semver */ const char* author; /* может быть NULL */ const char* description; /* может быть NULL */ uint32_t capabilities; /* битовая маска EDITOR_CAP_* */ EditorPluginInit initialize; EditorPluginShutdown shutdown; /* … дальше колбэки каждой возможности */ } EditorPluginInfo; /* единственный символ, который ищет хост */ EDITOR_PLUGIN_EXPORT const EditorPluginInfo* editor_plugin_register(void);
04 · сборка
Шаблон зависит только от публичных заголовков и собирает одну разделяемую библиотеку. Ядро не пересобирается и не линкуется в плагин.
# CMakeLists.txt шаблона, CMake 3.27 или новее find_package(ThePluginSDK REQUIRED) the_add_format_plugin(my_format SOURCES my_format.c) $ cmake -S . -B build -DCMAKE_PREFIX_PATH=/path/to/sdk $ cmake --build build # → my_format.dll · my_format.dylib
05 · установка
# Windows, папка установки по умолчанию C:\Program Files\The\bin\plugins\my_format.dll # macOS, внутри пакета приложения /Applications/The.app/Contents/PlugIns/my_format.dylib
06 · совместимость
| Гарантия | Что это значит для вас |
|---|---|
| Независимость от компилятора | Сборки MSVC, Clang и GCC совместимы; подбирать вариант стандартной библиотеки не нужно. |
| Независимость от языка | Подходит всё, что умеет экспортировать символы C: C, C++, Rust и другие. |
| Версионированная граница | Плагин объявляет версию ABI, хост её проверяет: несовместимый плагин падает громко, а не роняет редактор. |
| Без пересборки ядра | Плагин подключается к выпущенной сборке The. |
07 · чего нет
Сторонний плагин работает в процессе редактора с его правами. Песочница WASM запланирована, без даты.
Ни каталога, ни лицензирования расширений — установка ручная.
Граница ещё может меняться; изменения будут перечислены в списке изменений.
Пока песочницы нет, запускайте только те плагины, чей исходник вы прочитали.