Zum Inhalt

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:

  • DocumentOpened wird einmal pro Datei veröffentlicht — das Teilen veröffentlicht nichts;
  • DocumentClosed wird 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, und openDocuments() 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.