Hyppää sisältöön

Natiivin liitännäisen kirjoittaminen

Vähimmäismuotoinen natiivi liitännäinen on yksi luokka, yksi tehdasmakro, yksi JSON-tiedosto ja lyhyt CMakeLists.txt. Voit kirjoittaa sen kokonaan arkiston ulkopuolella liitännäis-SDK:ta vasten — MTE:n lähdekoodin ulosvientiä ei tarvita.

Natiivi vai Python?

Tämä sivu käsittelee natiiveja C++-liitännäisiä (käännettyinä .dll/.so/.dylib-tiedostoksi ja Qt-lataajan lataamina). Jos mieluummin toimitat kansiollisen .py-tiedostoja, jotka editori käynnistää aliprosessina, katso Python-liitännäiset — sama PluginApi-pinta, eri taustajärjestelmä, kääntäjää ei tarvita.

Luonnos

Tämä läpikäynti perustuu tiedostoon PLUGIN_ARCHITECTURE.md; tarkista SDK-paketin täsmällinen nimi ja funktion mte_add_plugin() argumentit toimitettua SDK:ta vasten, ennen kuin luotat niihin.

1. Toteuta 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. Vie tehdas (natiivi Qt-taustajärjestelmä)

#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. Kuvaa se tiedostossa 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 }
  ]
}

Täällä olevan apiVersion-arvon ja funktion info() palauttaman arvon täytyy molempien olla yhtä suuria kuin MTE_PLUGIN_API_VERSION, muutoin isäntä kieltäytyy lataamasta liitännäistä.

Sen rinnalla on kaksi valinnaista avainta:

  • apiMinorVersion (oletus 0) — isäntä-API:n pienin minor-versio, jota liitännäisesi tarvitsee. Isäntä, jonka MTE_PLUGIN_API_MINOR_VERSION on pienempi, näyttää liitännäisen tilana »Vaatii uudemman OctoEdit-version« eikä lataa sitä. Isäntä tarkistaa tämän manifestin arvon ennen kuin lataa mitään ja sen jälkeen vielä info()-funktion palauttaman PluginInfo::apiMinorVersion-arvon — sen oletus on niiden otsakkeiden minor-versio, joita vasten käänsit, joten älä koske siihen, ellet tiedä, ettet käytä mitään uudempaa. Katso Versiointi.
  • requires (oletus []) — niiden liitännäisten tunnisteet, joita ilman liitännäisesi ei voi toimia, esimerkiksi ["org.mte.lsp"]. Vain tunnisteita: versioväliä tai valinnaista muotoa ei ole — liitännäinen, jonka kanssa omasi vain toimii paremmin, ei kuulu tähän; keskustele sen kanssa ajon aikana tapahtumien ja toimittajarekisterien kautta. Editori alustaa riippuvuutesi ennen sinua order-arvosta riippumatta ja sammuttaa ne sinun jälkeesi. Jos jokin niistä puuttuu, on poistettu käytöstä, vaatii lisenssin, joka ei ole aktiivinen, tai jäi lataamatta, liitännäistäsi ei ladata lainkaan, ja Asetukset ▸ Liitännäiset kertoo, minkä liitännäisen se tarvitsee ja miksi (»Vaatii liitännäisen LSP Provider, joka on poistettu käytöstä«). Kehä estää jokaisen siihen kuuluvan liitännäisen. Sama avain tarkoittaa samaa Python-liitännäisen plugin.json-tiedostossa.

Mukana tulevien kirjastojen tunnustaminen — thirdParty

Jos liitännäisesi toimittaa tai linkittää kolmannen osapuolen komponentin, ilmoita se valinnaisessa thirdParty-taulukossa, jotta editori voi täyttää tunnustamisvelvoitteensa:

"thirdParty": [
  { "name": "Qt WebEngine", "license": "LGPL-3.0",
    "url": "https://doc.qt.io/qt-6/qtwebengine-index.html",
    "file": "QtWebEngine-LGPLv3.txt" }
]

Kukin kohta tarvitsee kentän name (kohdat ilman sitä pudotetaan); license, url ja file ovat valinnaisia. Liitännäisesi omistaa lisenssitekstit — toimita ne liitännäisen viereen kansioon Plugins/Licenses/<your-plugin-id>/, jossa file on tiedostonimi. Tietoja-ikkuna luettelee kunkin asennetun liitännäisen thirdParty-komponentit ja osoittaa käyttäjät tuohon kansioon; ydin ei koskaan kanna liitännäisen kolmannen osapuolen tekstejä sen puolesta. (Mukana tuleva HtmlPreviewPlugin, joka upottaa QtWebEnginen ja Chromiumin, on viite-esimerkki.)

4. Käännä se

Käytä SDK:n CMake-apuria:

find_package(MTEPluginSDK REQUIRED)
mte_add_plugin(NAME HelloWorldPlugin
    SOURCES Src/HelloWorldPlugin.cpp
    # TRANSLATIONS Translations/HelloWorld_en.ts ...
)

Käännösvaatimukset

Natiivi liitännäinen ladataan editorin prosessiin, joten se täytyy kääntää työkaluketjulla, joka on binääriyhteensopiva sen editorikäännöksen kanssa, jota se tavoittelee. Nämä ovat nykyisen julkaisun vaatimukset (käännetty Qt 6.11.2:lla):

Windows macOS
Kääntäjä Visual Studio 2022, MSVC-työkalusarja 14.44 tai vanhempi 14.x (VS 2015–2022 jakavat yhden C++-ABI:n); clang-cl toimii myös. MinGW- tai GCC-käännökset eivät voi latautua. Apple clang Xcodesta (Xcode 27, Apple clang 21.0.0); vain arm64
Käännöskokoonpano Release, dynaaminen ajonaikainen kirjasto (/MD, CMaken oletus). Lataaja hylkää Debug-liitännäisen; staattisen ajonaikaisen kirjaston (/MT) liitännäinen kaatuu, kun muisti ylittää liitännäisrajan Release; kohdeversio 14.4 (sama kuin editorilla)
Qt Qt 6.11, msvc2022_64-sarja. Vanhempaa 6.x-alaversiota vasten käännetty liitännäinen latautuu; uudempaa alaversiota vasten käännetty ei ehkä Qt 6.11, sama arkkitehtuuri
C++-standardi C++20 (API:n otsikkotiedostot käyttävät luokkaa std::span ja käsitteitä) C++20
CMake 3.16+ 3.16+
Liitännäis-API sen SDK:n MTE_PLUGIN_API_VERSION, joka toimitettiin tavoittelemasi editoriversion mukana sama

Kaksi seurausta, jotka kannattaa tietää Windowsissa:

  • Käyttäjän koneelle asennetun Visual C++ Redistributable -paketin täytyy olla vähintään yhtä uusi kuin uusin MSVC-työkalusarja, jota editori tai mikä tahansa ladattu liitännäinen käyttää. Liitännäisesi kääntäminen editoria uudemmalla työkalusarjalla nostaa tuota vaatimusta käyttäjillesi; editorin työkalusarjalla tai vanhemmalla kääntäminen ei.
  • Se Windows SDK -versio, jota vasten käännät, ei vaikuta yhteensopivuuteen editorin kanssa; se päättää vain, mitä Windows-API:ta liitännäisesi voi kutsua, ja editori tukee Windows 10 1809:ää ja uudempia.

Ja macOS:ssä:

  • Editori toimitetaan vain arm64:na; pelkkä x86_64-liitännäinen ei voi latautua (universaali binääri käy). Pidä kohdeversio arvossa 14.4: uudemmalle macOS-minimille käännetyn liitännäisen järjestelmälataaja hylkää vanhemmissa Maceissa, ja käyttöjärjestelmän oma libc++ on ajonaikainen kirjasto, joten kysymystä uudelleenjaeltavasta paketista ei synny.
  • Viittaa Qt-kehyksiin @rpath-polun kautta, jotta liitännäinen poimii OctoEdit.app-paketin sisään pakatut kopiot. Qt-sarjat, joiden kehyksillä on absoluuttiset asennusnimet (esimerkiksi Homebrew'n), vaativat komennon install_name_tool käännetylle liitännäiselle ennen toimittamista; muutoin liitännäinen etsii Qt:tä käännöskoneen polusta.

Mikään tästä ei koske Python-liitännäisiä: ne toimivat erillisessä prosessissa eivätkä jaa binääristä rajapintaa editorin kanssa.

5. Asenna ja aja

Joko pakkaa käännetty kirjasto ja plugin.json zipiksi nimellä <name>.mteplugin ja asenna se kohdasta Asetukset ▸ Liitännäiset ▸ Asenna liitännäinen... (paketti tarkistetaan — manifesti, arkiston turvallisuus ja binäärin upotetut metatiedot — ennen kuin mihinkään kosketaan), tai pudota tiedostot käsin etsittyyn liitännäishakemistoon (katso Arkkitehtuurin yleiskuva). Käynnistä editori uudelleen ja ota se käyttöön kohdassa Asetukset ▸ Liitännäiset, jos tarpeen.

Seuraavaksi