plugin.json-Referenz¶
Jedes Python-Plugin deklariert seine Identität, seinen Einstiegspunkt und
seine Platzierung in der Menüleiste in einer plugin.json neben seiner
main.py. Es ist dasselbe Schema, das die C++-Seite verwendet; nur die
Felder entry und module sind Python-spezifisch.
Beispiel¶
{
"id": "org.example.wordcount",
"name": "Word Count",
"version": "1.0.0",
"vendor": "Example, Inc.",
"description": "Counts words and characters in the active document.",
"apiVersion": 1,
"entry": "python",
"module": "main",
"pyRequires": [],
"order": 900,
"menus": [
{ "title": "Plugins", "barPriority": 570, "itemPriority": 100 }
]
}
Felder¶
Erforderlich¶
| Feld | Typ | Hinweise |
|---|---|---|
id |
string | Eindeutiger Reverse-DNS-Bezeichner. Wird überall verwendet — Aktivieren / Deaktivieren, Logzeilen, Pro-Plugin-Einstellungen. Darf sich über Versionen hinweg nicht ändern. |
apiVersion |
integer | Muss der MTE_PLUGIN_API_VERSION des Hosts entsprechen. Derzeit 1. Eine Abweichung wird auf der Plugins-Seite angezeigt; das Plugin wird gelistet, aber nicht geladen. |
entry |
string | Muss "python" sein, um über das Python-Backend zu laufen. "native" oder weggelassen läuft über den Qt-Loader. |
module |
string | Name des Python-Moduls, das register(ctx) enthält. Bei "main" sucht der Worker nach main.py im Plugin-Ordner. Gepunktete Paketnamen ("src.main") sind eine künftige Erweiterung — Phase 1 unterstützt nur flache Namen. |
Empfohlen¶
| Feld | Typ | Hinweise |
|---|---|---|
name |
string | Für Menschen lesbarer Anzeigename, der auf der Plugins-Seite angezeigt wird. |
version |
string | Semver; ansonsten frei wählbar. |
vendor |
string | Autor / Organisation. Wird auf der Plugins-Seite angezeigt. |
description |
string | Ein oder zwei Zeilen. Wird auf der Plugins-Seite angezeigt. |
Optional¶
| Feld | Typ | Hinweise |
|---|---|---|
order |
integer | Ladereihenfolge über Plugins hinweg; niedriger lädt früher. Standard 1000. Gleichstände werden über die id aufgelöst. |
menus |
Array von Objekten | Siehe unten. |
pyRequires |
Array von Strings | Pip-Requirement-Strings (z. B. ["requests>=2.31"]). Beim ersten Start des Plugins richtet der Editor eine virtuelle Umgebung pro Plugin ein, installiert diese per pip hinein und führt den Worker des Plugins darunter aus (siehe Paketierung). Nicht-String- und leere Einträge werden übersprungen. |
permissions |
Array von Strings | Grobe Fähigkeitsdeklarationen (z. B. ["network"]), nur lesend in der Permissions-Spalte unter Einstellungen → Plugins angezeigt, damit Benutzer sehen, was ein Plugin über sich aussagt. Nur Deklaration — noch nicht durchgesetzt. |
thirdParty |
Array von Objekten | Drittanbieter-Komponenten, die das Plugin bündelt, zur Attribution im About-Dialog. Jeder Eintrag: name (erforderlich), license, url, file. Liefern Sie den durch file benannten Lizenztext neben dem Plugin unter Plugins/Licenses/<id>/ aus. Siehe unten. |
menus¶
Jeder Eintrag deklariert ein Top-Level-Menü, zu dem das Plugin beiträgt, und
legt dessen Position fest. Wiederholen Sie ein Objekt pro Top-Level-Menü,
das Sie berühren (Tools, Plugins, Help usw.).
| Feld | Typ | Hinweise |
|---|---|---|
title |
string, erforderlich | Die Top-Level-Menübeschriftung, unter der der Eintrag lebt (Plugins, Tools, …). Muss dem linkesten Segment der Pfade entsprechen, die Sie an ctx.menus.add_item() übergeben. |
barPriority |
integer, optional | Rang von links nach rechts in der Menüleiste. Niedriger = weiter links. Kernmenüs haben feste Prioritäten im Abstand von 100 (Datei 100, Bearbeiten 200, …, Window 600); 570 platziert Ihr Untermenü nahe der Plugins-Position. Wird über Plugins hinweg wiederholt, die dasselbe Top-Level-Menü ansteuern; Last-wins ist in Ordnung, weil es idempotent ist. |
itemPriority |
integer, optional | Vertikaler Rang des gesamten Blocks Ihres Plugins innerhalb des Blattmenüs. Standard 1000. Niedriger = weiter oben. |
Einzelne Einträge listen Sie hier NICHT auf — die werden zur Laufzeit von
ctx.menus.add_item() hinzugefügt. menus betrifft nur die Platzierung in
der Menüleiste.
thirdParty¶
Deklarieren Sie jede Drittanbieter-Komponente, die Ihr Plugin bündelt, damit der About-Dialog sie attribuieren kann. Jeder Eintrag:
"thirdParty": [
{ "name": "SomeLib", "license": "MIT",
"url": "https://example.com/", "file": "SomeLib-LICENSE.txt" }
]
| Feld | Typ | Hinweise |
|---|---|---|
name |
string, erforderlich | Die Komponente. Einträge ohne nicht-leeren Namen werden verworfen. |
license |
string, optional | SPDX-artige Kennung, z. B. MIT, LGPL-3.0. |
url |
string, optional | Projekt-/Homepage. |
file |
string, optional | Basisname des mitgelieferten Lizenztexts, aufgelöst als Plugins/Licenses/<your-plugin-id>/<file>. |
Sie sind Eigentümer der Lizenztexte: Liefern Sie sie mit Ihrem
Plugin-Paket unter Plugins/Licenses/<id>/ aus. Der Editor listet die
Komponenten auf und verweist die Benutzer auf diesen Ordner; er hält die
Drittanbieter-Texte Ihres Plugins nicht in seinem eigenen
Licenses/-Ordner vor.
Statische Prüfung¶
Zum Erkennungszeitpunkt — und erneut bei der Installation eines
.mteplugin-Pakets — liest der Host module, öffnet
<pluginDir>/<module>.py und bestätigt, dass sie ein Top-Level
def register(...) enthält — es läuft kein Code. Der Installer weist ein
durchfallendes Paket mit einem Fehlerdialog ab; die Erkennung überspringt
das Plugin still, mit einer Fehlerzeile im Log:
PythonPluginBackend: skipping 'org.example.wordcount': module
'.../main.py' does not declare a top-level `def register(...)`.
Halten Sie register in Spalte 0 einer Zeile, die mit def register(
beginnt.
Ladereihenfolge und Platzierung in der Menüleiste¶
Wenn Ihr Plugin mit barPriority: 570 zu Plugins beiträgt, erscheint das
Menü an Rang 570 in der Menüleiste. Zwei Plugins mit unterschiedlichen
barPriority-Werten für denselben Titel konkurrieren: Das zuletzt geladene
gewinnt, aber da beide für ein bestimmtes Menü in der Regel denselben Rang
deklarieren, spielt es keine Rolle. Siehe PLUGIN_ARCHITECTURE.md §13 für
das vollständige Ordnungsmodell.
Was hier NICHT hineingehört¶
Der Host parst die oben dokumentierten Felder und ignoriert alles andere — erfinden Sie keine Felder; ein unbekannter Schlüssel ist stiller Ballast.