Dokumentacja zdarzeń¶
Każde zdarzenie, które host publikuje dla wtyczek natywnych
(PluginEvents.h), dociera też do Pythona — z jednym wyjątkiem opisanym
niżej. Każdy temat dostarcza do Twojego handlera mały typowany dataclass.
Dataclassy zdefiniowane są w Python/mte/events.py i są importowalne z
pakietu najwyższego poziomu mte.
Tabela temat ↔ dataclass¶
| Temat | Dataclass ładunku | Pola | Dekorator |
|---|---|---|---|
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 ("" = cały edytor, "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 (bity mte.MODIFIER_SHIFT / MODIFIER_CONTROL / MODIFIER_ALT / MODIFIER_META) — kliknięcie w kolumnie zakładek, zobacz ctx.line_markers |
on_margin_clicked |
workspace.rootChanged |
mte.WorkspaceRootChanged |
root: str ("" = folder zamknięty) |
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 |
(brak pól) — raz na uruchomienie, po pierwszej klatce | on_host_window_shown |
app.aboutToQuit |
mte.AppAboutToQuit |
(brak pól) | on_app_about_to_quit |
document to nieprzezroczyste całkowitoliczbowe id przydzielane przez hosta.
Porównuj id operatorem ==; nie utrwalaj ich między restartami edytora.
text.changed odpala się przy każdej edycji — ten handler trzymaj trywialny.
Subskrypcja przez dekorator (sugar)¶
Zalecana — nazwa dekoratora odpowiada tematowi, a typ ładunku jest wnioskowany:
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")
Subskrypcja przez surowe API¶
def _saved(ev):
ctx.log.info(f"saved {ev.document}")
handler_id = ctx.events.subscribe("document.saved", _saved)
- Zwraca lokalnie przydzielony
handler_id(string postaci"py-ev/N"). - Nieznane tematy rzucają
ValueErrorw momencie subskrypcji — bez cichego no-op.
Wypisz się z subskrypcji, gdy przestaje Cię interesować:
Uwaga: po unsubscribe host przestaje dostarczać Ci ten temat, ale lokalny
dyspozytor workera zachowuje swój wpis aż do zamknięcia wtyczki. Nie polegaj
na unsubscribe przy sprzątaniu pamięci — to sygnał polityki, a nie prymityw
odśmiecania pamięci.
Semantyka dostarczania¶
- Zdarzenia odpalają się po zakończeniu odpowiadającej im akcji. Przy
document.savedplik jest już na dysku. Przydocument.closedid dokumentu jest już nieprawidłowe. - Wielu subskrybentów tego samego tematu odpala się wszystkich, w niezdefiniowanej kolejności.
- Wyjątki rzucone w Twoim handlerze są łapane przez workera i zapisywane na
stderr (widoczne w logu hosta jako
[worker stderr] …). Wadliwy handler nie powstrzymuje odpalania pozostałych subskrybentów. - Dataclassy ładunków są niemutowalne; nie modyfikuj pól
ev.
Publikowanie¶
ctx.events.publish(topic, payload) kładzie zdarzenie na wspólnej szynie,
gdzie odbierają je zarówno subskrybenci natywni, jak i pythonowi.
Akceptowane są tylko dwa tematy, które mają być publikowane przez wtyczkę
— para workspace, którą wtyczka Obszar roboczy rozgłasza dla Znajdź w plikach i
Palety poleceń:
ctx.events.publish("workspace.rootChanged", {"root": "/home/me/project"})
ctx.events.publish("workspace.filesChanged", {"files": [
{"path": "/home/me/project/a.txt", "displayPath": "a.txt"},
]})
Każdy inny temat rzuca ValueError: pozostałe to stwierdzenia faktów należące
do hosta (dokument został zapisany, motyw się zmienił), których wtyczka
nie ma prawa ogłaszać. Do komunikacji wtyczka–wtyczka poza tym zarejestruj
polecenie i pozwól drugiej stronie je wywołać.
Niedostępne¶
Dwa zdarzenia hosta nie mają tematu w Pythonie:
document.aboutToSave: host publikuje je synchronicznie, blokując zapis do powrotu każdego subskrybenta, a honorowanie tego przez RPC workera wymaga takiego samego limitu czasu jak providery uzupełniania, zanim będzie bezpieczne. Wtyczki natywne mogą go używać już dziś.DocumentAboutToClose— z założenia tylko natywne. Cała jego obietnica to to, że dokument da się jeszcze odczytać wewnątrz obsługi, a dostarczanie do wtyczki Pythona jest asynchroniczne, więc obsługa uruchomiłaby się już po zamknięciu. Używajdocument.closedi na bieżąco utrzymuj to, czego potrzebujesz o dokumencie, na podstawie wcześniejszych zdarzeń, zamiast odczytywać to przy zamknięciu.