Documentazione di plugin.json¶
Ogni plugin Python dichiara la propria identità, il punto di ingresso e la
collocazione nella barra dei menu in un file plugin.json accanto al proprio
main.py. È lo stesso schema che usa il lato C++; solo i campi entry e
module sono specifici di Python.
Esempio¶
{
"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 }
]
}
Campi¶
Obbligatori¶
| Campo | Tipo | Note |
|---|---|---|
id |
stringa | Identificatore univoco in DNS inverso. Usato ovunque: abilitazione / disabilitazione, righe di log, impostazioni per plugin. Non deve cambiare tra le versioni. |
apiVersion |
intero | Deve essere uguale a MTE_PLUGIN_API_VERSION dell'host. Attualmente 1. Una discordanza emerge nella pagina Plugin e il plugin viene elencato ma non caricato. |
entry |
stringa | Dev'essere "python" per passare dal backend Python. "native" o l'assenza del campo passano dal caricatore Qt. |
module |
stringa | Nome del modulo Python che contiene register(ctx). Se è "main", il worker cerca main.py dentro la cartella del plugin. I nomi di pacchetto con punti ("src.main") sono un'estensione futura: la fase 1 supporta solo nomi piatti. |
Consigliati¶
| Campo | Tipo | Note |
|---|---|---|
name |
stringa | Nome leggibile mostrato nella pagina Plugin. |
version |
stringa | Semver; per il resto forma libera. |
vendor |
stringa | Autore / organizzazione. Mostrato nella pagina Plugin. |
description |
stringa | Una o due righe. Mostrata nella pagina Plugin. |
Facoltativi¶
| Campo | Tipo | Note |
|---|---|---|
order |
intero | Ordine di caricamento tra i plugin; più basso carica prima. Predefinito 1000. I pari merito si risolvono con id. requires ha la precedenza. |
requires |
array di stringhe | Id dei plugin senza i quali questo plugin non può funzionare (nativi o Python indifferentemente), per esempio ["org.mte.lsp"] — non pacchetti pip, quelli vanno in pyRequires. Vengono avviati prima di questo plugin qualunque cosa dica order; se uno manca, è disattivato, bloccato dalla licenza o non è stato caricato, questo plugin non viene avviato affatto e Preferenze → Estensioni dice quale gli serve e perché. Stesso significato che per un plugin nativo. |
apiMinorVersion |
intero | La versione minor minima dell'API dell'host di cui questo plugin ha bisogno (predefinito 0). Un plugin Python non ha un info() compilato, quindi questa è la sua unica dichiarazione: indica la minor della chiamata più recente che usi. Un host più vecchio mostra il plugin come «Richiede una versione più recente di OctoEdit» e non lo avvia. |
menus |
array di oggetti | Vedi sotto. |
pyRequires |
array di stringhe | Stringhe di requisito pip (per esempio ["requests>=2.31"]). Al primo avvio del plugin l'editor predispone un ambiente virtuale per plugin, vi installa questi pacchetti con pip ed esegue il worker del plugin al suo interno (vedi Creazione dei pacchetti). Le voci non stringa e quelle vuote vengono saltate. |
permissions |
array di stringhe | Dichiarazioni grossolane di capacità (per esempio ["network"]), mostrate in sola lettura nella colonna Autorizzazioni di Preferenze → Estensioni, così che gli utenti possano vedere che cosa il plugin dice di fare. Solo dichiarazione: non ancora imposta. |
thirdParty |
array di oggetti | Componenti di terze parti che il plugin include, per l'attribuzione nella finestra Informazioni. Ogni voce: name (obbligatorio), license, url, file. Distribuisci il testo della licenza nominato da file accanto al plugin sotto Plugins/Licenses/<id>/. Vedi sotto. |
menus¶
Ogni voce dichiara un menu di primo livello a cui il plugin contribuisce e ne
stabilisce la posizione. Ripeti un oggetto per ciascun menu di primo livello che
tocchi (Tools, Plugins, Help, ecc.).
| Campo | Tipo | Note |
|---|---|---|
title |
stringa, obbligatorio | L'etichetta del menu di primo livello sotto cui vive la voce (Plugins, Tools, …). Deve corrispondere al segmento più a sinistra dei percorsi che passi a ctx.menus.add_item(). |
barPriority |
intero, facoltativo | Rango da sinistra a destra nella barra dei menu. Più basso = più a sinistra. I menu del nucleo hanno priorità fisse distanziate di 100 (File 100, Modifica 200, …, Finestra 600); 570 mette il tuo sottomenu vicino alla posizione di Plugins. Ripetuto tra i plugin che puntano allo stesso menu di primo livello; vince l'ultimo, e va bene perché è idempotente. |
itemPriority |
intero, facoltativo | Rango verticale dell'intero blocco del tuo plugin dentro il menu foglia. Predefinito 1000. Più basso = più in alto. |
Qui NON elenchi le singole voci: quelle vengono aggiunte da
ctx.menus.add_item() a tempo di esecuzione. menus riguarda soltanto la
collocazione nella barra dei menu.
thirdParty¶
Dichiara qualsiasi componente di terze parti che il tuo plugin include, così che la finestra Informazioni possa attribuirlo. Ogni voce:
"thirdParty": [
{ "name": "SomeLib", "license": "MIT",
"url": "https://example.com/", "file": "SomeLib-LICENSE.txt" }
]
| Campo | Tipo | Note |
|---|---|---|
name |
stringa, obbligatorio | Il componente. Le voci senza un nome non vuoto vengono scartate. |
license |
stringa, facoltativo | Etichetta in stile SPDX, per esempio MIT, LGPL-3.0. |
url |
stringa, facoltativo | Pagina del progetto / pagina iniziale. |
file |
stringa, facoltativo | Solo nome del file di licenza che distribuisci, risolto in Plugins/Licenses/<your-plugin-id>/<file>. |
I testi delle licenze sono tuoi: distribuiscili con il pacchetto del tuo
plugin sotto Plugins/Licenses/<id>/. L'editor elenca i componenti e indirizza
gli utenti a quella cartella; non conserva i testi di terze parti del tuo plugin
nella propria cartella Licenses/.
Sonda statica¶
Al momento dell'individuazione — e di nuovo quando viene installato un pacchetto
.mteplugin — l'host legge module, apre <pluginDir>/<module>.py e conferma
che contenga un def register(...) di primo livello: non viene eseguito alcun
codice. L'installer respinge un pacchetto che non supera il controllo con una
finestra di errore; l'individuazione salta il plugin in silenzio, con una riga di
errore nel log:
PythonPluginBackend: skipping 'org.example.wordcount': module
'.../main.py' does not declare a top-level `def register(...)`.
Tieni register alla colonna 0 di una riga che inizia con def register(.
Ordine di caricamento e collocazione nella barra dei menu¶
Se il tuo plugin contribuisce a Plugins con barPriority: 570, il menu compare
al rango 570 nella barra dei menu. Due plugin con valori di barPriority diversi
per lo stesso titolo si contendono la posizione: vince quello caricato per
ultimo, ma poiché di norma entrambi dichiarano lo stesso rango per un dato menu
la cosa non ha importanza. Vedi PLUGIN_ARCHITECTURE.md §13 per il modello di
ordinamento completo.
Che cosa NON va qui¶
L'host analizza i campi documentati sopra e ignora tutto il resto: non inventare campi, una chiave sconosciuta è silenziosamente peso morto.