Saltar a contenido

Referencia de eventos

Todos los eventos que el anfitrión publica para los plugins nativos (PluginEvents.h) llegan también a Python, con una excepción que se indica más abajo. Cada tema entrega una pequeña dataclass tipada a tu manejador. Las dataclasses están definidas en Python/mte/events.py y se pueden importar desde el paquete mte de nivel superior.

Tabla de tema ↔ dataclass

Tema Dataclass de carga útil Campos Decorador
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 ("" = de todo el 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 (bits mte.MODIFIER_SHIFT / MODIFIER_CONTROL / MODIFIER_ALT / MODIFIER_META): un clic en la columna de marcadores, consulta ctx.line_markers on_margin_clicked
workspace.rootChanged mte.WorkspaceRootChanged root: str ("" = carpeta cerrada) 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 (sin campos) — una vez por ejecución, después del primer fotograma on_host_window_shown
app.aboutToQuit mte.AppAboutToQuit (sin campos) on_app_about_to_quit

document es un identificador entero opaco asignado por el anfitrión. Compara los identificadores con ==; no los conserves entre reinicios del editor. text.changed se dispara en cada edición: mantén ese manejador trivial.

Suscribirse con un decorador azucarado

Recomendado: el nombre del decorador coincide con el tema y el tipo de la carga útil se infiere.

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

Suscribirse con la API en bruto

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

handler_id = ctx.events.subscribe("document.saved", _saved)
  • Devuelve el handler_id asignado localmente (una cadena "py-ev/N").
  • Los temas desconocidos lanzan ValueError en el momento de la suscripción; no hay silencios.

Cancela la suscripción cuando ya no te interese:

ctx.events.unsubscribe(handler_id)

Nota: tras unsubscribe, el anfitrión deja de entregarte el tema, pero el despachador local del trabajador conserva su entrada hasta que el plugin se cierra. No confíes en unsubscribe para la limpieza de memoria: es una señal de política, no una primitiva de recolección de basura.

Semántica de entrega

  • Los eventos se disparan después de que la acción correspondiente se haya completado. En document.saved, el archivo ya está en el disco. En document.closed, el identificador del documento ya no es válido.
  • Si hay varios suscriptores a un mismo tema, se disparan todos, en un orden indefinido.
  • Las excepciones lanzadas en tu manejador las captura el trabajador y las escribe en stderr (visible en el registro del anfitrión como [worker stderr] …). Un manejador que se porta mal no impide que se disparen los demás suscriptores.
  • Las dataclasses de carga útil son inmutables; no modifiques los campos de ev.

Publicar

ctx.events.publish(topic, payload) pone un evento en el bus compartido, donde lo reciben por igual los suscriptores nativos y los de Python. Solo se aceptan los dos temas que un plugin debe publicar: la pareja del espacio de trabajo, que el plugin Espacio de trabajo difunde para Buscar en archivos y la paleta de comandos.

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

Cualquier otro tema lanza ValueError: los demás son afirmaciones de hecho del propio anfitrión (un documento fue guardado, el tema sí cambió) que un plugin no tiene por qué aseverar. Para mensajería entre plugins más allá de esto, registra un comando y haz que el otro lado lo invoque.

No disponible

Dos eventos del anfitrión no tienen tema en Python:

  • document.aboutToSave: el anfitrión lo publica de forma síncrona, con el guardado bloqueado hasta que todos los suscriptores devuelven el control, y respetar eso a través del RPC del trabajador requiere el mismo tratamiento de plazos que los proveedores de autocompletado antes de que sea seguro. Los plugins nativos sí pueden usarlo hoy.
  • DocumentAboutToClose: solo nativo, por diseño. Toda su promesa es que el documento aún se puede leer dentro del manejador, y la entrega a un plugin Python es asíncrona, así que el manejador se ejecutaría después del cierre. Usa document.closed en su lugar, y mantén al día lo que necesites de un documento a partir de los eventos anteriores en vez de leerlo al cerrarse.