Vai al contenuto

Documentazione degli eventi

Ogni evento che l'host pubblica per i plugin nativi (PluginEvents.h) raggiunge anche Python, con un'unica eccezione indicata più sotto. Ogni argomento consegna al tuo gestore una piccola dataclass tipizzata. Le dataclass sono definite in Python/mte/events.py e sono importabili dal pacchetto di primo livello mte.

Tabella argomento ↔ dataclass

Argomento Dataclass del contenuto Campi Decoratore
document.opened mte.DocumentOpened document: int, path: str on_document_opened
document.closed mte.DocumentClosed document: int on_document_closed
document.saved mte.DocumentSaved document: int on_document_saved
document.encodingChanged mte.DocumentEncodingChanged document: int, encoding: mte.DocumentEncoding on_document_encoding_changed
document.lineEndingChanged mte.DocumentLineEndingChanged document: int, ending: mte.LineEnding on_document_line_ending_changed
document.modifiedChanged mte.DocumentModifiedChanged document: int, modified: bool on_document_modified_changed
document.activeChanged mte.ActiveDocumentChanged document: int on_active_document_changed
text.changed mte.TextChanged document, position, added_bytes, removed_bytes on_text_changed
selection.changed mte.SelectionChanged document: int on_selection_changed
settings.changed mte.SettingsChanged scope: str ("" = tutto l'editor, "plugins/<id>") on_settings_changed
theme.changed mte.ThemeChanged variant: str ("light" / "dark" / "") on_theme_changed
margin.clicked mte.MarginClicked document: int, line: int, margin: str ("symbol"), modifiers: int (bit mte.MODIFIER_SHIFT / MODIFIER_CONTROL / MODIFIER_ALT / MODIFIER_META) — un clic nella colonna dei segnalibri, vedi ctx.line_markers on_margin_clicked
workspace.rootChanged mte.WorkspaceRootChanged root: str ("" = cartella chiusa) on_workspace_root_changed
workspace.filesChanged mte.WorkspaceFilesChanged files: list[mte.WorkspaceFile] (path, display_path) on_workspace_files_changed
command.shortcutChanged mte.CommandShortcutChanged command_id: str, sequence: str on_command_shortcut_changed
host.windowShown mte.HostWindowShown (nessun campo) — una volta per esecuzione, dopo il primo fotogramma on_host_window_shown
app.aboutToQuit mte.AppAboutToQuit (nessun campo) on_app_about_to_quit

document è un id intero opaco assegnato dall'host. Confronta gli id con ==; non renderli persistenti tra un riavvio dell'editor e l'altro. text.changed scatta a ogni modifica: mantieni quel gestore banale.

Sottoscriversi con il decoratore zuccherino

Consigliato: il nome del decoratore corrisponde all'argomento e il tipo del contenuto viene dedotto:

import mte

def register(ctx):

    @ctx.events.on_document_saved
    def _saved(ev: mte.DocumentSaved):
        ctx.log.info(f"saved doc {ev.document}")

    @ctx.events.on_document_opened
    def _opened(ev: mte.DocumentOpened):
        ctx.log.info(f"opened {ev.document} at {ev.path}")

    @ctx.events.on_app_about_to_quit
    def _quit(_ev: mte.AppAboutToQuit):
        ctx.log.info("editor is closing")

Sottoscriversi con l'API grezza

def _saved(ev):
    ctx.log.info(f"saved {ev.document}")

handler_id = ctx.events.subscribe("document.saved", _saved)
  • Restituisce l'handler_id allocato localmente (una stringa "py-ev/N").
  • Gli argomenti sconosciuti sollevano ValueError al momento della sottoscrizione: niente operazioni nulle silenziose.

Annulla la sottoscrizione quando non ti interessa più:

ctx.events.unsubscribe(handler_id)

Nota: dopo unsubscribe l'host smette di consegnarti l'argomento, ma il distributore locale del worker conserva la propria voce finché il plugin non si spegne. Non contare su unsubscribe per ripulire la memoria: è un segnale di politica, non una primitiva di garbage collection.

Semantica della consegna

  • Gli eventi scattano dopo che l'azione corrispondente si è conclusa. Su document.saved il file è già su disco. Su document.closed l'id del documento è già non valido.
  • Se allo stesso argomento sono sottoscritti più gestori scattano tutti, in ordine indefinito.
  • Le eccezioni sollevate nel tuo gestore vengono catturate dal worker e scritte su stderr (visibili nel log dell'host come [worker stderr] …). Un gestore che si comporta male non impedisce agli altri sottoscrittori di scattare.
  • Le dataclass del contenuto sono immutabili; non modificare i campi di ev.

Pubblicazione

ctx.events.publish(topic, payload) mette un evento sul bus condiviso, dove lo ricevono allo stesso modo i sottoscrittori nativi e quelli Python. Vengono accettati solo i due argomenti che devono essere pubblicati da un plugin: la coppia dell'area di lavoro, che il plugin Area di lavoro trasmette per Trova nei file e per la tavolozza dei comandi:

ctx.events.publish("workspace.rootChanged", {"root": "/home/me/project"})
ctx.events.publish("workspace.filesChanged", {"files": [
    {"path": "/home/me/project/a.txt", "displayPath": "a.txt"},
]})

Qualsiasi altro argomento solleva ValueError: gli altri sono constatazioni di fatto dell'host (un documento è stato salvato, il tema è cambiato) che un plugin non ha titolo per affermare. Per la messaggistica da plugin a plugin che vada oltre questi, registra un comando e fa' che l'altra parte lo invochi.

Non disponibile

Due eventi dell'host non hanno un argomento Python:

  • document.aboutToSave: l'host lo pubblica in modo sincrono con il salvataggio bloccato finché ogni sottoscrittore non è tornato, e onorarlo attraverso l'RPC del worker richiede lo stesso trattamento con scadenza dei fornitori di completamento prima di essere sicuro. I plugin nativi possono usarlo già oggi.
  • DocumentAboutToClose — solo nativo, per scelta progettuale. Tutta la sua promessa è che il documento si possa ancora leggere dentro il gestore, e la consegna a un plugin Python è asincrona, quindi il gestore verrebbe eseguito dopo la chiusura. Usa invece document.closed e tieni aggiornato ciò che ti serve sapere di un documento a partire dagli eventi precedenti, invece di leggerlo alla chiusura.