Events¶
Plugins reagieren auf Editor-Aktivität über IEventBus. Events sind einfache
Structs, die in PluginEvents.h definiert sind:
| Event | Payload |
|---|---|
DocumentOpened |
DocumentId, std::filesystem::path |
DocumentAboutToClose |
DocumentId — der Benutzer schließt das Dokument, und das Schließen steht fest; veröffentlicht unmittelbar bevor seine letzte Ansicht verschwindet, solange es noch vollständig lesbar ist. Nicht beim Beenden. Nur native Plugins; siehe unten |
DocumentClosed |
DocumentId |
DocumentSaved |
DocumentId |
DocumentPrinted |
DocumentId, pages — veröffentlicht, nachdem ein Druckauftrag das Gerät erreicht hat (Datei ▸ Drucken oder Drucken aus der Vorschau); pages zählt die gedruckten Dokumentseiten, weniger als das Dokument hat, wenn eine Auswahl oder ein Seitenbereich gewählt wurde. Ein abgebrochener Dialog veröffentlicht nichts. Vorerst nur für C++-Plugins |
DocumentAboutToSave |
DocumentId, path — synchron, Puffer noch editierbar (Whitespace trimmen, letzte Zeile ergänzen); keine Dialoge |
DocumentEncodingChanged |
DocumentId, DocumentEncoding — die Kodierung, in der der Host das Dokument zurückschreibt, hat sich geändert (Datei gerade erkannt oder setDocumentEncoding aufgerufen) |
DocumentLineEndingChanged |
DocumentId, LineEnding — das vom Dokument verwendete Zeilenende hat sich geändert (Datei gerade gelesen oder neu geladen, ein end_of_line aus der .editorconfig beim Speichern angewendet, oder setLineEnding aufgerufen) |
DocumentModifiedChanged |
DocumentId, modified — das Flag sauber/geändert kippte (nicht jeder Tastendruck) |
TextChanged |
DocumentId, pos, addedBytes, removedBytes |
SelectionChanged |
DocumentId |
ActiveDocumentChanged |
DocumentId |
HostWindowShown |
(keine) — einmal pro Lauf, nachdem der erste Frame gezeichnet ist; langsame Startarbeit hier einplanen |
SettingsChanged |
scope — "" = editorweit, "plugins/<id>" = die Seite dieses Plugins wurde übernommen |
WorkspaceRootChanged |
root (leer = Ordner geschlossen) — vom Arbeitsbereich-Plugin veröffentlicht |
WorkspaceFilesChanged |
files[] aus {path, displayPath} — vom Arbeitsbereich-Plugin veröffentlicht |
ThemeChanged |
variant ("light" / "dark" / "") |
AppAboutToQuit |
(keine) |
CommandShortcutChanged |
commandId, sequence (neues portables Kürzel; "" = unbelegt) |
MarginClicked |
DocumentId, line, margin (EditorMargin::Symbol), modifiers — ein Linksklick in die Lesezeichenspalte eines Editors, bei jedem solchen Klick; siehe Zeilenmarkierungen |
Plugins können ebenfalls Events veröffentlichen (ctx.events().publish(e)) —
so sendet das Arbeitsbereich-Plugin WorkspaceRootChanged /
WorkspaceFilesChanged an In Dateien suchen und die Befehlspalette.
Ein Dokument, eine Id¶
Eine DocumentId benennt ein Dokument, kein Fensterteil. Dokument
teilen zeigt eine Datei in zwei Bereichen, und beide tragen dieselbe
DocumentId, also:
DocumentOpenedwird einmal pro Datei veröffentlicht — das Teilen veröffentlicht nichts;DocumentClosedwird erst veröffentlicht, wenn die letzte Ansicht des Dokuments geschlossen wird; das Schließen eines Bereichs reißt damit nie Zustand ab, den der andere noch braucht;activeDocument()antwortet mit dieser einen Id, gleich welcher Bereich vorn ist, undopenDocuments()listet das Dokument einmal.
Es gibt bewusst kein Event pro Bereich und keine Möglichkeit zu fragen, welcher Bereich aktiv ist: Bereiche sind Sache des Hosts, und alles, was ein Plugin beobachten kann — Text, Cursor, Auswahl, Kodierung, Zeilenende, Änderungsstatus — gehört zum Dokument, das sich die Bereiche teilen.
DocumentAboutToClose¶
Wird einmal pro Dokument veröffentlicht, unmittelbar bevor seine letzte
Ansicht verschwindet, wenn das Schließen feststeht — eine etwaige
Speichern-Rückfrage wurde beantwortet und nicht abgebrochen. Im Handler ist
das Dokument noch vollständig: text(), filePath(), caret(),
bookmarkedLines() und die Kodierung antworten alle. Danach folgt der Abbau,
dann DocumentClosed. Jede Art, einen Tab zu schließen, veröffentlicht es
(Schließen, Alle schließen, Andere schließen / Rechts davon schließen, ein
Mittelklick, Ordner schließen, closeDocument() eines Plugins), unbenannte
Dokumente eingeschlossen; das Schließen eines Bereichs, während das Dokument
noch in einem anderen angezeigt wird, nicht.
Das Beenden veröffentlicht es nicht. Die Anwendung veröffentlicht einmal
AppAboutToQuit, solange noch alle Dokumente offen sind, und keine
Schließ-Events pro Dokument: Ein Plugin, das Zustand pro Dokument über
Sitzungen hinweg aufbewahrt, durchläuft in seinem AppAboutToQuit-Handler
openDocuments(). DocumentAboutToClose bedeutet deshalb immer „dieses
Dokument wird geschlossen“, nie „das Programm wird beendet“.
Handler laufen synchron, mitten im Schließen: Seien Sie schnell, zeigen Sie keine Dialoge und behandeln Sie die Menge der Dokumente als schreibgeschützt — öffnen, schließen oder aktivieren Sie keine Dokumente und bearbeiten Sie nicht den Text des Dokuments, das gerade geschlossen wird.
Es ist absichtlich nur nativ: Die Zustellung an Python-Plugins ist asynchron, das Versprechen „noch lesbar“ ließe sich dort also nicht halten, und das Event wird ihnen nicht angeboten (siehe Python-Events).
CommandShortcutChanged¶
CommandShortcutChanged feuert, wenn sich der effektive Shortcut eines
Commands ändert — ein Benutzer-Remap im Shortcut-Mapper, ein
Keymap-Import/-Reset oder eine Konfliktunterdrückung, die greift oder
aufgehoben wird. Menügebundene Commands brauchen nichts (der Host bindet ihre
Action neu); Commands, die mit scope = command_scope::kPluginWindow
registriert sind, abonnieren das Event und wenden die Sequenz erneut auf ihre
eigenen Widgets an (siehe Commands & Menüs).
Abonnieren¶
subscribe ist ein Template, das eine Subscription (RAII) zurückliefert.
Halten Sie die Subscription als Member am Leben, solange der Callback feuern
soll; ihre Zerstörung hebt das Abonnement auf.
m_sub = ctx.events().subscribe<MTE::plugin::DocumentSaved>(
[this](const MTE::plugin::DocumentSaved& e) {
// react to e.id ...
});
class IEventBus {
public:
template <class Event>
Subscription subscribe(std::function<void(const Event&)> cb);
// Forwards to a type-erased subscribeRaw(std::type_index, ...) internally.
};
Tip
Halten Sie jede Subscription als Plugin-Member, damit alle Callbacks in
shutdown() automatisch abgebaut werden.