Skriva en inhemsk insticksmodul¶
En minimal inhemsk insticksmodul är en klass, ett fabriksmakro, en JSON-fil och
en kort CMakeLists.txt. Du kan skriva den helt utanför källkodsträdet mot
insticksmoduls-SDK:t — ingen utcheckning av MTE:s källkod krävs.
Inhemsk eller Python?
Den här sidan handlar om inhemska C++-insticksmoduler (kompilerade till en
.dll/.so/.dylib och inlästa av Qt-laddaren). Vill du hellre leverera en
mapp med .py-filer som redigeraren startar som en underprocess, se
Python-insticksmoduler — samma yta av PluginApi,
en annan backend, ingen kompilator behövs.
Utkast
Den här genomgången bygger på PLUGIN_ARCHITECTURE.md; kontrollera det exakta
SDK-paketnamnet och argumenten till mte_add_plugin() mot det levererade SDK:t
innan du förlitar dig på dem.
1. Implementera 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. Exportera fabriken (inhemsk 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 den 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 här och den som info() returnerar måste båda vara lika med
MTE_PLUGIN_API_VERSION, annars vägrar värden läsa in insticksmodulen.
Till den hör två valfria nycklar:
apiMinorVersion(standard0) — den lägsta minorversionen av värdens API som din insticksmodul behöver. En värd varsMTE_PLUGIN_API_MINOR_VERSIONär lägre visar modulen med «Kräver en nyare version av OctoEdit» och läser inte in den. Värden kontrollerar detta manifestvärde innan den läser in något, och därefterPluginInfo::apiMinorVersionfråninfo()en gång till — det värdet är som standard minorversionen för de headerfiler du kompilerade mot, så låt det vara om du inte vet att du inte använder något nyare. Se Versionshantering.requires(standard[]) — id:n för de insticksmoduler som din modul inte kan fungera utan, till exempel["org.mte.lsp"]. Bara id:n: det finns inget versionsintervall och ingen valfri form — en modul som din bara fungerar bättre med hör inte hit; prata med den under körning via händelser och leverantörsregister. Redigeraren initierar dina beroenden före dig, oavsett vadordersäger, och stänger ner dem efter dig. Om något av dem saknas, är inaktiverat, behöver en licens som inte är aktiv eller inte lästes in, läses din modul inte in alls, och Inställningar ▸ Insticksmoduler talar om vilken modul den behöver och varför («Kräver insticksmodulen LSP Provider, som är inaktiverad»). En cykel blockerar varje modul i den. Samma nyckel betyder samma sak iplugin.jsonför en Python-modul.
Ange medföljande bibliotek — thirdParty¶
Om din insticksmodul levererar eller länkar mot en tredjepartskomponent,
deklarera den i en valfri vektor thirdParty så att redigeraren kan uppfylla dess
angivelseskyldigheter:
"thirdParty": [
{ "name": "Qt WebEngine", "license": "LGPL-3.0",
"url": "https://doc.qt.io/qt-6/qtwebengine-index.html",
"file": "QtWebEngine-LGPLv3.txt" }
]
Varje post behöver ett name (poster utan sådant faller bort); license, url
och file är valfria. Licenstexterna tillhör din insticksmodul — leverera dem
bredvid modulen under Plugins/Licenses/<your-plugin-id>/, där file är det bara
filnamnet. Dialogrutan Om listar varje installerad insticksmoduls
thirdParty-komponenter och pekar användare mot den mappen; kärnan bär aldrig en
insticksmoduls tredjepartstexter åt den. (Den medföljande HtmlPreviewPlugin, som
bäddar in QtWebEngine + Chromium, är referensexemplet.)
4. Bygg den¶
Använd SDK:ts CMake-hjälpare:
find_package(MTEPluginSDK REQUIRED)
mte_add_plugin(NAME HelloWorldPlugin
SOURCES Src/HelloWorldPlugin.cpp
# TRANSLATIONS Translations/HelloWorld_en.ts ...
)
Byggkrav¶
En inhemsk insticksmodul läses in i redigerarens process, så den måste byggas med en verktygskedja som är binärkompatibel med det redigerarbygge den riktar sig mot. Det här är kraven för den aktuella utgåvan (byggd med Qt 6.11.2):
| Windows | macOS | |
|---|---|---|
| Kompilator | Visual Studio 2022, MSVC-verktygsuppsättning 14.44 eller en äldre 14.x (VS 2015–2022 delar ett C++-ABI); clang-cl fungerar också. Bygg med MinGW / GCC kan inte läsas in. |
Apple clang från Xcode (Xcode 27, Apple clang 21.0.0); enbart arm64 |
| Byggkonfiguration | Release, dynamisk runtime (/MD, CMake:s standard). En Debug-insticksmodul avvisas av laddaren; en insticksmodul med statisk runtime (/MT) kraschar när minne korsar modulgränsen |
Release; deployment target 14.4 (samma som redigeraren) |
| Qt | Qt 6.11, kitet msvc2022_64. En insticksmodul byggd mot en äldre 6.x-minor läses in; en byggd mot en nyare minor kanske inte gör det |
Qt 6.11, samma arkitektur |
| C++-standard | C++20 (API-headerna använder std::span och koncept) |
C++20 |
| CMake | 3.16+ | 3.16+ |
| Insticksmoduls-API | MTE_PLUGIN_API_VERSION för det SDK som följde med den redigerarversion du riktar dig mot |
detsamma |
Två följder värda att känna till på Windows:
- Den Visual C++ Redistributable som är installerad på användarens maskin måste vara minst lika ny som den nyaste MSVC-verktygsuppsättning som redigeraren eller någon inläst insticksmodul använt. Att bygga din insticksmodul med en nyare verktygsuppsättning än redigerarens höjer det kravet för dina användare; att bygga med redigerarens verktygsuppsättning eller en äldre gör det inte.
- Den version av Windows SDK du kompilerar mot påverkar inte kompatibiliteten med redigeraren; den avgör bara vilka Windows-API:er din insticksmodul kan anropa, och redigeraren stöder Windows 10 1809 och senare.
Och på macOS:
- Redigeraren levereras enbart som arm64; en insticksmodul som bara är
x86_64kan inte läsas in (en universell binär går bra). Håll deployment target på 14.4: en insticksmodul byggd för ett nyare minsta macOS avvisas av systemets laddare på äldre Mac-datorer, och eftersom operativsystemets egen libc++ är runtime uppstår ingen fråga om någon redistributable. - Hänvisa till Qt-ramverken genom
@rpathså att insticksmodulen plockar upp de kopior som medföljer inutiOctoEdit.app. Qt-kit vars ramverk bär absoluta installationsnamn (Homebrews, till exempel) behöverinstall_name_toolpå den byggda insticksmodulen före leverans; annars letar modulen efter Qt på byggmaskinens sökväg.
Inget av detta gäller Python-insticksmoduler: de körs i en separat process och delar inget binärt gränssnitt med redigeraren.
5. Installera och kör¶
Du kan komprimera det byggda biblioteket + plugin.json som <name>.mteplugin och
installera det via Inställningar ▸ Insticksmoduler ▸ Installera insticksmodul... (paketet
valideras — manifest, arkivets säkerhet och binärens inbäddade metadata — innan
något rörs), eller lägga filerna för hand i en upptäckt insticksmodulskatalog (se
Arkitekturöversikt). Starta om redigeraren och
aktivera den vid behov i Inställningar ▸ Insticksmoduler.
Nästa¶
- Översikt över insticksmoduls-API:t — livscykel, symboler och hela tjänstetabellen
- Kommandon och menyer
- Dockor, flikar och statusrad
- Inställningssidor
- Händelser
- Översättningar