At skrive et indbygget udvidelsesmodul¶
Et minimalt indbygget udvidelsesmodul er én klasse, én fabriksmakro, én JSON-fil
og en kort CMakeLists.txt. Du kan skrive det helt uden for arkivet mod
udvidelsesmodul-SDK'et — der kræves ingen udtjekning af MTE's kildekode.
Indbygget eller Python?
Denne side handler om indbyggede C++-udvidelsesmoduler (kompileret til en
.dll/.so/.dylib og indlæst af Qt-indlæseren). Vil du hellere levere en
mappe med .py-filer, som editoren starter som en underproces, så se
Python-udvidelsesmoduler — samme PluginApi-flade,
anden backend, ingen compiler nødvendig.
Udkast
Denne gennemgang bygger på PLUGIN_ARCHITECTURE.md; kontrollér det nøjagtige
navn på SDK-pakken og argumenterne til mte_add_plugin() mod det leverede SDK,
inden du bygger videre på dem.
1. Implementér 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. Eksportér fabrikken (den indbyggede Qt-backend)¶
#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. Beskriv det i 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 }
]
}
apiVersion her og den, info() giver tilbage, skal begge være lig med
MTE_PLUGIN_API_VERSION, ellers nægter værten at indlæse udvidelsesmodulet.
To valgfrie nøgler hører med:
apiMinorVersion(standard0) — den laveste minor-version af værtens API, som dit udvidelsesmodul har brug for. En vært med lavereMTE_PLUGIN_API_MINOR_VERSIONviser modulet med »Kræver en nyere version af OctoEdit« og indlæser det ikke. Værten kontrollerer denne manifestværdi, før den indlæser noget, og derefterPluginInfo::apiMinorVersionfrainfo()én gang til — den er som standard minor-versionen af de headerfiler, du kompilerede mod, så lad den være, medmindre du ved, at du ikke bruger noget nyere. Se Versionering.requires(standard[]) — id'erne på de udvidelsesmoduler, som dit ikke kan fungere uden, for eksempel["org.mte.lsp"]. Kun id'er: der er intet versionsinterval og ingen valgfri form — et modul, som dit blot fungerer bedre sammen med, hører ikke til her; tal med det under kørslen via hændelser og leverandørregistre. Editoren initialiserer dine afhængigheder før dig, uanset hvadordersiger, og lukker dem ned efter dig. Mangler en af dem, er den slået fra, kræver den en licens, der ikke er aktiv, eller blev den ikke indlæst, bliver dit modul slet ikke indlæst, og Indstillinger ▸ Udvidelsesmoduler fortæller, hvilket modul det mangler og hvorfor (»Kræver udvidelsesmodulet LSP Provider, som er slået fra«). En cyklus blokerer hvert modul i den. Den samme nøgle betyder det samme iplugin.jsonfor et Python-modul.
At kreditere medleverede biblioteker — thirdParty¶
Leverer eller lænker dit udvidelsesmodul en tredjepartskomponent, så erklær den i en
valgfri thirdParty-tabel, så editoren kan leve op til sine forpligtelser om
kreditering:
"thirdParty": [
{ "name": "Qt WebEngine", "license": "LGPL-3.0",
"url": "https://doc.qt.io/qt-6/qtwebengine-index.html",
"file": "QtWebEngine-LGPLv3.txt" }
]
Hver post skal have et name (poster uden bliver droppet); license, url og
file er valgfrie. Dit udvidelsesmodul ejer licensteksterne — lever dem ved
siden af modulet under Plugins/Licenses/<your-plugin-id>/, hvor file er
filnavnet. Vinduet Om opregner thirdParty-komponenterne for hvert installeret
udvidelsesmodul og peger brugerne mod den mappe; kernen bærer aldrig et moduls
tredjepartstekster for det. (Det medleverede HtmlPreviewPlugin, som indlejrer
QtWebEngine og Chromium, er referenceeksemplet.)
4. Byg det¶
Brug SDK'ets CMake-hjælper:
find_package(MTEPluginSDK REQUIRED)
mte_add_plugin(NAME HelloWorldPlugin
SOURCES Src/HelloWorldPlugin.cpp
# TRANSLATIONS Translations/HelloWorld_en.ts ...
)
Byggekrav¶
Et indbygget udvidelsesmodul indlæses i editorens proces, så det skal bygges med en værktøjskæde, der er binært forenelig med den editorbygning, det er rettet mod. Dette er kravene til den nuværende udgave (bygget med Qt 6.11.2):
| Windows | macOS | |
|---|---|---|
| Compiler | Visual Studio 2022, MSVC-værktøjssæt 14.44 eller et ældre 14.x (VS 2015–2022 deler én C++-ABI); clang-cl virker også. Bygninger med MinGW eller GCC kan ikke indlæses. |
Apple clang fra Xcode (Xcode 27, Apple clang 21.0.0); kun arm64 |
| Byggeopsætning | Release, dynamisk kørselsbibliotek (/MD, CMakes standard). Et Debug-modul afvises af indlæseren; et modul med statisk kørselsbibliotek (/MT) går ned, når hukommelse krydser modulgrænsen |
Release; implementeringsmål 14.4 (samme som editoren) |
| Qt | Qt 6.11, kittet msvc2022_64. Et modul, der er bygget mod en ældre 6.x-underversion, indlæses; et, der er bygget mod en nyere underversion, gør det måske ikke |
Qt 6.11, samme arkitektur |
| C++-standard | C++20 (API'ens headerfiler bruger std::span og koncepter) |
C++20 |
| CMake | 3.16+ | 3.16+ |
| Udvidelsesmodul-API | den MTE_PLUGIN_API_VERSION, der fulgte med SDK'et til den editorversion, du retter dig mod |
samme |
To følger er værd at kende på Windows:
- Den Visual C++ Redistributable, der er installeret på brugerens maskine, skal være mindst lige så ny som det nyeste MSVC-værktøjssæt, editoren eller et indlæst udvidelsesmodul er bygget med. Bygger du dit modul med et værktøjssæt, der er nyere end editorens, hæver du det krav for dine brugere; bygger du med editorens værktøjssæt eller et ældre, gør du ikke.
- Den version af Windows SDK, du kompilerer mod, påvirker ikke foreneligheden med editoren; den afgør kun, hvilke Windows-API'er dit udvidelsesmodul kan kalde, og editoren understøtter Windows 10 1809 og senere.
Og på macOS:
- Editoren leveres kun som arm64; et udvidelsesmodul, der kun er
x86_64, kan ikke indlæses (et universelt binært program er fint). Hold implementeringsmålet på 14.4: et modul, der er bygget til et nyere mindste-macOS, afvises af systemets indlæser på ældre Mac-maskiner, og styresystemets egen libc++ er kørselsmiljøet, så spørgsmålet om et videredistribuerbart bibliotek opstår ikke. - Henvis til Qt-rammerne gennem
@rpath, så udvidelsesmodulet bruger de kopier, der er lagt ind iOctoEdit.app. Qt-kit, hvis rammer bærer absolutte installationsnavne (Homebrews, for eksempel), kræverinstall_name_toolpå det byggede modul, inden det leveres; ellers leder modulet efter Qt på byggemaskinens sti.
Intet af dette gælder for Python-udvidelsesmoduler: de kører i en selvstændig proces og deler ingen binær grænseflade med editoren.
5. Installér og kør¶
Enten pakker du det byggede bibliotek og plugin.json som en zip ved navn
<name>.mteplugin og installerer den via Indstillinger ▸ Udvidelsesmoduler ▸
Installér udvidelsesmodul... (pakken efterprøves — manifestet, arkivets sikkerhed og programfilens
indlejrede metadata — inden noget som helst røres), eller også lægger du filerne i en
opdaget udvidelsesmodulmappe i hånden (se
Arkitekturoversigt). Genstart editoren, og slå modulet
til under Indstillinger ▸ Udvidelsesmoduler, hvis det er nødvendigt.
Videre herfra¶
- Oversigt over udvidelsesmodul-API'en — livscyklus, symboler og hele tjenestetabellen
- Kommandoer og menuer
- Paneler, faneblade og statuslinje
- Indstillingssider
- Hændelser
- Oversættelser