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_idasignado localmente (una cadena"py-ev/N"). - Los temas desconocidos lanzan
ValueErroren el momento de la suscripción; no hay silencios.
Cancela la suscripción cuando ya no te interese:
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. Endocument.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. Usadocument.closeden 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.