Přeskočit obsah

Události

Zásuvné moduly reagují na dění v editoru prostřednictvím IEventBus. Události jsou obyčejné struktury definované v PluginEvents.h:

Událost Data
DocumentOpened DocumentId, std::filesystem::path
DocumentAboutToClose DocumentId — uživatel zavírá dokument a zavření je jisté; publikuje se těsně předtím, než zmizí jeho poslední zobrazení, dokud jde dokument ještě celý přečíst. Ne při ukončení programu. Jen nativní moduly; viz níže
DocumentClosed DocumentId
DocumentSaved DocumentId
DocumentPrinted DocumentId, pages — publikuje se poté, co tisková úloha dorazila k zařízení (Soubor ▸ Vytisknout, nebo Tisk uvnitř náhledu); pages počítá vytištěné stránky dokumentu, což je při zvoleném výběru či rozsahu stránek méně, než jich dokument má. Zrušené okno nepublikuje nic. Zatím pouze zásuvné moduly v C++
DocumentAboutToSave DocumentId, path — synchronní, buffer je stále upravitelný (ořezání bílých znaků, přidání závěrečného konce řádku); žádná okna
DocumentEncodingChanged DocumentId, DocumentEncoding — změnilo se kódování, v němž hostitel dokument zapíše zpět (soubor byl právě rozpoznán, nebo bylo zavoláno setDocumentEncoding)
DocumentLineEndingChanged DocumentId, LineEnding — změnilo se zakončení řádků, které dokument používá (soubor byl právě přečten či znovu načten, při uložení se uplatnilo end_of_line z .editorconfig, nebo bylo zavoláno setLineEnding)
DocumentModifiedChanged DocumentId, modified — přehodil se příznak čistý/změněný (nikoli při každém stisku klávesy)
TextChanged DocumentId, pos, addedBytes, removedBytes
SelectionChanged DocumentId
ActiveDocumentChanged DocumentId
HostWindowShown (žádná) — jednou za běh, poté co je první snímek na obrazovce; naplánujte od ní pomalou práci při spuštění
SettingsChanged scope — "" = v celém editoru, "plugins/<id>" = byla uplatněna stránka tohoto modulu
WorkspaceRootChanged root (prázdné = složka zavřena) — publikuje modul Pracovní prostor
WorkspaceFilesChanged files[] z {path, displayPath} — publikuje modul Pracovní prostor
ThemeChanged variant ("light" / "dark" / "")
AppAboutToQuit (žádná)
CommandShortcutChanged commandId, sequence (nová přenositelná kombinace; "" = bez vazby)
MarginClicked DocumentId, line, margin (EditorMargin::Symbol), modifiers — kliknutí levým tlačítkem do sloupce záložek editoru, při každém takovém kliknutí; viz Značky řádků

Zásuvné moduly mohou události i publikovat (ctx.events().publish(e)) — právě tak modul Pracovní prostor rozhlašuje WorkspaceRootChanged / WorkspaceFilesChanged, aby je Najít v souborech a Paleta příkazů mohly konzumovat.

Jeden dokument, jedno id

DocumentId pojmenovává dokument, nikoli panel. Rozdělit dokument ukazuje jeden soubor ve dvou panelech a oba panely nesou totéž DocumentId, takže:

  • DocumentOpened se publikuje jednou na soubor — rozdělení nepublikuje nic;
  • DocumentClosed se publikuje, teprve když se zavře poslední zobrazení dokumentu, takže zavření jednoho panelu nikdy nestrhne stav, který ten druhý ještě potřebuje;
  • activeDocument() odpoví tímto jedním id, ať je vpředu kterýkoli panel, a openDocuments() dokument vypíše jednou.

Záměrně neexistuje žádná událost na panel ani žádný způsob, jak se zeptat, který panel je aktivní: panely jsou věcí hostitele a vše, co může zásuvný modul pozorovat — text, kurzor, výběr, kódování, konec řádků, stav změněno — patří dokumentu, který panely sdílejí.

DocumentAboutToClose

Publikuje se jednou pro každý dokument, bezprostředně předtím, než zmizí jeho poslední zobrazení, když je zavření jisté — případný dotaz na uložení byl zodpovězen a nebyl zrušen. Uvnitř obslužné rutiny je dokument ještě celý: text(), filePath(), caret(), bookmarkedLines() i kódování odpovídají. Potom následuje úklid a nakonec DocumentClosed. Publikuje ji každý způsob zavření karty (Zavřít, Zavřít vše, Zavřít ostatní / Zavřít vpravo, kliknutí prostředním tlačítkem, Zavřít složku, closeDocument() volané modulem), včetně dokumentů bez názvu; zavření jednoho panelu dokumentu, který je ještě zobrazen v jiném, ne.

Ukončení programu ji nepublikuje. Aplikace jednou publikuje AppAboutToQuit, dokud jsou všechny dokumenty ještě otevřené, a žádné události zavření jednotlivých dokumentů: modul, který si mezi relacemi uchovává stav dokumentů, projde ve své obslužné rutině AppAboutToQuit seznam openDocuments(). DocumentAboutToClose proto vždy znamená »tento dokument se zavírá«, nikdy »program končí«.

Obslužné rutiny běží synchronně, uprostřed zavírání: buďte rychlí, nezobrazujte dialogová okna a s množinou dokumentů zacházejte jen pro čtení — neotevírejte, nezavírejte ani neaktivujte dokumenty a neupravujte text zavíraného dokumentu.

Je záměrně jen nativní: doručení modulům v Pythonu je asynchronní, takže by se tam slib »ještě jde přečíst« nedal dodržet, a událost se jim nenabízí (viz Události v Pythonu).

CommandShortcutChanged

CommandShortcutChanged se spustí, když se změní účinná zkratka příkazu — přemapování uživatelem v Mapování klávesových zkratek, import či obnovení mapy kláves, nebo zapnutí či zrušení potlačení při konfliktu. Příkazy vázané na nabídku nepotřebují nic (hostitel jejich akci přiřadí znovu); příkazy registrované se scope = command_scope::kPluginWindow odebírají událost a posloupnost znovu uplatní na své vlastní widgety (viz Příkazy a nabídky).

Odebírání

subscribe je šablona vracející Subscription (RAII). Udržujte odběr naživu jako člen tak dlouho, jak chcete, aby se zavolání spouštělo; jeho zničením odběr skončí.

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

Každý Subscription držte jako člen modulu, aby se všechna zavolání ve shutdown() strhla automaticky.