Písanie natívneho zásuvného modulu¶
Minimálny natívny zásuvný modul je jedna trieda, jedno továrenské makro, jeden súbor JSON
a krátky CMakeLists.txt. Môžete ho napísať úplne mimo stromu projektu, oproti sade SDK pre
zásuvné moduly — bez potreby stiahnuť zdrojové kódy MTE.
Natívny, alebo v Pythone?
Táto stránka sa venuje natívnym zásuvným modulom v C++ (preloženým do .dll/.so/
.dylib a načítaným zavádzačom Qt). Ak by ste radšej dodali priečinok so súbormi .py,
ktorý editor spustí ako podproces, pozrite si
Zásuvné moduly v Pythone — tá istá plocha PluginApi, iný
backend, bez potreby prekladača.
Koncept
Tento návod vychádza z dokumentu PLUGIN_ARCHITECTURE.md; presný názov balíka SDK
a argumenty mte_add_plugin() si pred ich použitím overte oproti dodávanej sade SDK.
1. Implementujte IPlugin¶
#include <PluginApi/IPlugin.h>
#include <PluginApi/IPluginContext.h>
class HelloWorldPlugin : public MTE::plugin::IPlugin {
public:
MTE::plugin::PluginInfo info() const override {
return { "org.mte.helloworld", "Hello World", "1.0.0",
"Example Vendor", "Says hi.", MTE_PLUGIN_API_VERSION };
}
bool initialize(MTE::plugin::IPluginContext& ctx) override {
m_cmd = ctx.commands().registerCommand(
{ "helloworld.sayHi", "Say Hi", "Ctrl+Alt+H", "Hello" },
[&ctx] { ctx.log().log(MTE::plugin::LogLevel::Info, "Hi!"); });
m_menu = ctx.menus().addItem("Plugins/Say Hi", "helloworld.sayHi");
return true;
}
void shutdown() noexcept override {} // tokens tear down automatically
private:
MTE::plugin::CommandToken m_cmd;
MTE::plugin::MenuToken m_menu;
};
2. Vyexportujte továreň (natívny backend Qt)¶
#include <PluginApi/Qt/PluginQtGlue.h>
class HelloWorldFactory : public QObject, public MTE::plugin::IPluginFactory {
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.mte.IPluginFactory/1" FILE "plugin.json")
Q_INTERFACES(MTE::plugin::IPluginFactory)
public:
std::unique_ptr<MTE::plugin::IPlugin> create() override {
return std::make_unique<HelloWorldPlugin>();
}
};
3. Opíšte ho v súbore plugin.json¶
{
"id": "org.mte.helloworld",
"name": "Hello World",
"version": "1.0.0",
"apiVersion": 1,
"entry": "native",
"requires": [],
"order": 600,
"menus": [
{ "title": "Plugins", "barPriority": 570, "itemPriority": 100 }
]
}
Hodnota apiVersion tu aj tá, ktorú vracia info(), sa musia rovnať
MTE_PLUGIN_API_VERSION, inak hostiteľ zásuvný modul odmietne načítať.
Patria k nej dva voliteľné kľúče:
apiMinorVersion(predvolene0) — najnižšia minor verzia API hostiteľa, ktorú váš modul potrebuje. Hostiteľ, ktoréhoMTE_PLUGIN_API_MINOR_VERSIONje nižšia, zobrazí modul so stavom „Vyžaduje novšiu verziu aplikácie OctoEdit“ a nenačíta ho. Hostiteľ túto hodnotu z manifestu skontroluje skôr, než čokoľvek načíta, a potom ešte razPluginInfo::apiMinorVersionzinfo()— tá má predvolene minor verziu hlavičiek, voči ktorým ste kompilovali, takže na ňu nesiahajte, pokiaľ neviete, že nepoužívate nič novšie. Pozri Verzovanie.requires(predvolene[]) — ID zásuvných modulov, bez ktorých váš modul nemôže fungovať, napríklad["org.mte.lsp"]. Iba ID: neexistuje rozsah verzií ani voliteľná forma — modul, s ktorým váš iba funguje lepšie, sem nepatrí; komunikujte s ním počas behu cez udalosti a registre poskytovateľov. Editor inicializuje vaše závislosti pred vami bez ohľadu naordera ukončuje ich po vás. Keď niektorá z nich chýba, je vypnutá, vyžaduje licenciu, ktorá nie je aktívna, alebo sa nenačítala, váš modul sa vôbec nenačíta a Predvoľby ▸ Zásuvné moduly povedia, ktorý modul potrebuje a prečo („Vyžaduje zásuvný modul LSP Provider, ktorý je vypnutý“). Cyklus zablokuje každý modul, ktorý doň patrí. Rovnaký kľúč znamená to isté vplugin.jsonmodulu v Pythone.
Uvedenie dodávaných knižníc — thirdParty¶
Ak váš zásuvný modul so sebou nesie alebo linkuje komponent tretej strany, deklarujte ho vo
voliteľnom poli thirdParty, aby editor mohol splniť povinnosti týkajúce sa uvádzania autorstva:
"thirdParty": [
{ "name": "Qt WebEngine", "license": "LGPL-3.0",
"url": "https://doc.qt.io/qt-6/qtwebengine-index.html",
"file": "QtWebEngine-LGPLv3.txt" }
]
Každá položka potrebuje name (položky bez neho sa zahodia); license, url a file sú
voliteľné. Licenčné texty vlastní váš zásuvný modul — dodajte ich vedľa neho v priečinku
Plugins/Licenses/<your-plugin-id>/, pričom file je názov súboru bez cesty. Dialóg
O aplikácii vypisuje komponenty thirdParty každého nainštalovaného zásuvného modulu
a nasmeruje používateľov do tohto priečinka; jadro nikdy nenesie texty tretích strán za zásuvný
modul. (Referenčným príkladom je dodávaný HtmlPreviewPlugin, ktorý obsahuje QtWebEngine
a Chromium.)
4. Zostavte ho¶
Použite pomocníka CMake zo sady SDK:
find_package(MTEPluginSDK REQUIRED)
mte_add_plugin(NAME HelloWorldPlugin
SOURCES Src/HelloWorldPlugin.cpp
# TRANSLATIONS Translations/HelloWorld_en.ts ...
)
Požiadavky na zostavenie¶
Natívny zásuvný modul sa načíta do procesu editora, takže musí byť zostavený nástrojovým reťazcom, ktorý je binárne kompatibilný so zostavou editora, na ktorú cieli. Toto sú požiadavky pre aktuálne vydanie (zostavené s Qt 6.11.2):
| Windows | macOS | |
|---|---|---|
| Prekladač | Visual Studio 2022, nástrojová sada MSVC 14.44 alebo staršia 14.x (VS 2015 – 2022 zdieľajú jedno ABI pre C++); funguje aj clang-cl. Zostavy z MinGW či GCC sa načítať nedajú. |
Apple clang z Xcode (Xcode 27, Apple clang 21.0.0); iba arm64 |
| Konfigurácia zostavenia | Release, dynamický runtime (/MD, predvoľba CMake). Zásuvný modul v konfigurácii Debug zavádzač odmietne; modul so statickým runtimeom (/MT) spadne, keď pamäť prekročí hranicu modulu |
Release; cieľová verzia nasadenia 14.4 (rovnako ako editor) |
| Qt | Qt 6.11, kit msvc2022_64. Zásuvný modul zostavený voči staršej menšej verzii 6.x sa načíta; modul zostavený voči novšej menšej verzii nemusí |
Qt 6.11, rovnaká architektúra |
| Štandard C++ | C++20 (hlavičky API používajú std::span a koncepty) |
C++20 |
| CMake | 3.16+ | 3.16+ |
| API zásuvných modulov | hodnota MTE_PLUGIN_API_VERSION sady SDK dodanej s cieľovou verziou editora |
to isté |
Vo Windows sa oplatí vedieť o dvoch dôsledkoch:
- Visual C++ Redistributable nainštalovaný na počítači používateľa musí byť aspoň taký nový ako najnovšia nástrojová sada MSVC použitá editorom alebo ktorýmkoľvek načítaným zásuvným modulom. Zostavením vášho modulu novšou nástrojovou sadou, než akú má editor, túto požiadavku pre vašich používateľov zvýšite; zostavením sadou editora alebo staršou nie.
- Verzia Windows SDK, voči ktorej prekladáte, neovplyvňuje kompatibilitu s editorom; určuje iba to, ktoré rozhrania Windows môže váš zásuvný modul volať, a editor podporuje Windows 10 1809 a novšie.
A na macOS:
- Editor sa dodáva iba ako arm64; zásuvný modul len pre
x86_64sa načítať nedá (univerzálny binárny súbor je v poriadku). Cieľovú verziu nasadenia ponechajte na 14.4: zásuvný modul zostavený pre novšiu minimálnu verziu macOS odmietne na starších Macoch systémový zavádzač a runtimeom je vlastná knižnica libc++ operačného systému, takže otázka redistribuovateľných balíkov nevzniká. - Na frameworky Qt sa odkazujte cez
@rpath, aby zásuvný modul prevzal kópie dodané vnútriOctoEdit.app. Kity Qt, ktorých frameworky nesú absolútne inštalačné názvy (napríklad tie z Homebrew), vyžadujú pred dodaním spustenieinstall_name_toolna zostavenom module; inak ho bude modul hľadať na ceste zostavovacieho počítača.
Nič z toho sa netýka zásuvných modulov v Pythone: bežia v samostatnom procese a s editorom nezdieľajú žiadne binárne rozhranie.
5. Nainštalujte a spustite¶
Buď zabaľte zostavenú knižnicu a plugin.json do súboru <name>.mteplugin a nainštalujte ho
cez Predvoľby ▸ Zásuvné moduly ▸ Nainštalovať zásuvný modul... (balík sa pred akýmkoľvek zásahom overí —
manifest, bezpečnosť archívu aj metaúdaje vložené v binárnom súbore), alebo súbory ručne vložte
do niektorého z prehľadávaných priečinkov zásuvných modulov (pozri
Prehľad architektúry). Reštartujte editor; ak treba, zapnite modul
v Predvoľby ▸ Zásuvné moduly.
Ďalej¶
- Prehľad API zásuvných modulov — životný cyklus, tokeny a úplná tabuľka služieb
- Príkazy a ponuky
- Panely, karty a stavový riadok
- Stránky nastavení
- Udalosti
- Preklady