Referência de eventos¶
Todo evento que o host publica para plugins nativos (PluginEvents.h) chega também
ao Python, com uma exceção anotada abaixo. Cada tópico entrega uma pequena dataclass
tipada ao seu manipulador. As dataclasses são definidas em Python/mte/events.py e
podem ser importadas do pacote mte de nível superior.
Tabela de tópico ↔ dataclass¶
| Tópico | Dataclass da 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 o 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) — um clique na coluna de marcadores, veja ctx.line_markers |
on_margin_clicked |
workspace.rootChanged |
mte.WorkspaceRootChanged |
root: str ("" = pasta fechada) |
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 |
(sem campos) — uma vez por execução, depois do primeiro quadro | on_host_window_shown |
app.aboutToQuit |
mte.AppAboutToQuit |
(sem campos) | on_app_about_to_quit |
document é um id inteiro opaco atribuído pelo host. Compare ids com ==; não os
persista entre reinícios do editor. O text.changed dispara a cada edição —
mantenha aquele manipulador trivial.
Assinar por decorador açucarado¶
Recomendado — o nome do decorador coincide com o tópico e o tipo da carga útil é inferido:
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")
Assinar pela API bruta¶
def _saved(ev):
ctx.log.info(f"saved {ev.document}")
handler_id = ctx.events.subscribe("document.saved", _saved)
- Devolve o
handler_idalocado localmente (uma cadeia"py-ev/N"). - Tópicos desconhecidos levantam
ValueErrorna hora da assinatura — nada de silêncio.
Cancele a assinatura quando não se importar mais:
Observação: depois de unsubscribe, o host para de entregar o tópico a você, mas o
despachante local do trabalhador mantém a entrada dele até o plugin encerrar. Não
conte com o unsubscribe para limpeza de memória — ele é um sinal de política, não
uma primitiva de coleta de lixo.
Semântica de entrega¶
- Os eventos disparam depois que a ação correspondente foi concluída. No
document.saved, o arquivo já está no disco. Nodocument.closed, o id do documento já é inválido. - Vários assinantes do mesmo tópico disparam todos, em ordem indefinida.
- Exceções levantadas no seu manipulador são capturadas pelo trabalhador e escritas
em stderr (visíveis no log do host como
[worker stderr] …). Um manipulador que se comporta mal não impede que os outros assinantes disparem. - As dataclasses de carga útil são imutáveis; não altere os campos de
ev.
Publicando¶
ctx.events.publish(topic, payload) coloca um evento no barramento compartilhado,
onde assinantes nativos e Python o recebem igualmente. Apenas os dois tópicos que
devem ser publicados por um plugin são aceitos — o par do espaço de trabalho, que
o plugin Espaço de trabalho transmite para o Localizar em arquivos e a 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"},
]})
Qualquer outro tópico levanta ValueError: os demais são afirmações de fato do
próprio host (um documento foi salvo, o tema mudou) que um plugin não tem por que
declarar. Para mensagens entre plugins além dessas, registre um comando e faça o
outro lado invocá-lo.
Não disponível¶
Dois eventos do host não têm tópico em Python:
document.aboutToSave: o host o publica de forma síncrona, com o salvamento bloqueado até todo assinante retornar, e honrar isso pelo RPC do trabalhador exige o mesmo tratamento de prazos dos provedores de autocompletar antes de ser seguro. Plugins nativos podem usá-lo hoje.DocumentAboutToClose— só nativo, por projeto. Toda a sua promessa é que o documento ainda pode ser lido dentro do manipulador, e a entrega a um plugin Python é assíncrona, então o manipulador rodaria depois do fechamento. Usedocument.closedem vez disso e mantenha atualizado o que você precisa saber de um documento a partir dos eventos anteriores, em vez de lê-lo no fechamento.