Aller au contenu

Référence des événements

Chaque événement que l'hôte publie pour les extensions natives (PluginEvents.h) atteint aussi Python, à une exception près notée plus bas. Chaque sujet livre une petite dataclass typée à votre gestionnaire. Les dataclasses sont définies dans Python/mte/events.py et importables depuis le paquet de premier niveau mte.

Table sujet ↔ dataclass

Sujet Dataclass de charge utile Champs Décorateur
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 ("" = tout l'éditeur, "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 (bits mte.MODIFIER_SHIFT / MODIFIER_CONTROL / MODIFIER_ALT / MODIFIER_META) — un clic dans la colonne des signets, voir ctx.line_markers on_margin_clicked
workspace.rootChanged mte.WorkspaceRootChanged root: str ("" = dossier fermé) 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 (aucun champ) — une fois par exécution, après la première image on_host_window_shown
app.aboutToQuit mte.AppAboutToQuit (aucun champ) on_app_about_to_quit

document est un identifiant entier opaque attribué par l'hôte. Comparez les identifiants avec == ; ne les persistez pas entre redémarrages de l'éditeur. text.changed se déclenche à chaque modification — gardez ce gestionnaire trivial.

S'abonner via le décorateur sucré

Recommandé — le nom du décorateur correspond au sujet et le type de la charge utile est inféré :

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")

S'abonner via l'API brute

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

handler_id = ctx.events.subscribe("document.saved", _saved)
  • Renvoie le handler_id alloué localement (une chaîne "py-ev/N").
  • Les sujets inconnus lèvent ValueError à l'abonnement — pas d'échec silencieux.

Désabonnez-vous quand cela ne vous intéresse plus :

ctx.events.unsubscribe(handler_id)

Remarque : après unsubscribe, l'hôte cesse de vous livrer le sujet, mais le répartiteur local du worker garde son entrée jusqu'à l'arrêt de l'extension. Ne comptez pas sur unsubscribe pour libérer de la mémoire — c'est un signal de politique, pas une primitive de ramasse-miettes.

Sémantique de livraison

  • Les événements se déclenchent après l'achèvement de l'action correspondante. Sur document.saved, le fichier est déjà sur le disque. Sur document.closed, l'identifiant du document est déjà invalide.
  • Plusieurs abonnés au même sujet se déclenchent tous, dans un ordre indéfini.
  • Les exceptions levées dans votre gestionnaire sont interceptées par le worker et écrites sur stderr (visibles dans le journal de l'hôte comme [worker stderr] …). Un gestionnaire défaillant n'empêche pas les autres abonnés de se déclencher.
  • Les dataclasses de charge utile sont immuables ; ne modifiez pas les champs de ev.

Publier

ctx.events.publish(topic, payload) dépose un événement sur le bus partagé, où les abonnés natifs et Python le reçoivent de la même façon. Seuls les deux sujets destinés à être publiés par une extension sont acceptés — la paire workspace, que l'extension Espace de travail diffuse pour Rechercher dans les fichiers et la palette de commandes :

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

Tout autre sujet lève ValueError : les autres sont des constats de l'hôte (un document a été enregistré, le thème a changé) qu'une extension n'a pas à affirmer. Pour la messagerie extension-à-extension au-delà de cela, enregistrez une commande et laissez l'autre côté l'invoquer.

Non disponible

Deux événements de l'hôte n'ont pas de sujet Python :

  • document.aboutToSave : l'hôte le publie de manière synchrone, l'enregistrement restant bloqué jusqu'au retour de chaque abonné, et l'honorer par la RPC du worker exige d'abord le même traitement d'échéance que les fournisseurs de complétion. Les extensions natives peuvent l'utiliser dès aujourd'hui.
  • DocumentAboutToClose — natif uniquement, par conception. Toute sa promesse est que le document reste lisible dans le gestionnaire, or la livraison à un plugin Python est asynchrone : le gestionnaire s'exécuterait après la fermeture. Utilisez plutôt document.closed, et tenez à jour ce dont vous avez besoin sur un document à partir des événements antérieurs au lieu de le lire au moment de la fermeture.