Przejdź do treści

Zdarzenia

Wtyczki reagują na aktywność edytora przez IEventBus. Zdarzenia to zwykłe struktury zdefiniowane w PluginEvents.h:

Zdarzenie Ładunek
DocumentOpened DocumentId, std::filesystem::path
DocumentAboutToClose DocumentId — użytkownik zamyka dokument i zamknięcie jest przesądzone; publikowane tuż przed zniknięciem jego ostatniego widoku, gdy dokument wciąż da się w pełni odczytać. Nie przy zakończeniu programu. Tylko wtyczki natywne; zobacz niżej
DocumentClosed DocumentId
DocumentSaved DocumentId
DocumentPrinted DocumentId, pages — publikowane po tym, jak zadanie wydruku dotarło do urządzenia (Plik ▸ Drukuj albo Drukuj z podglądu); pages liczy wydrukowane strony dokumentu, mniej niż ma dokument, gdy wybrano zaznaczenie lub zakres stron. Anulowany dialog nie publikuje nic. Na razie tylko dla wtyczek C++
DocumentAboutToSave DocumentId, path — synchronicznie, bufor wciąż edytowalny (obcięcie białych znaków, końcowy newline); bez dialogów
DocumentEncodingChanged DocumentId, DocumentEncoding — zmieniło się kodowanie, w którym host zapisze dokument (plik właśnie rozpoznany albo wywołano setDocumentEncoding)
DocumentLineEndingChanged DocumentId, LineEnding — zmieniło się zakończenie wiersza używane przez dokument (plik właśnie wczytany lub przeładowany, zadziałał end_of_line z .editorconfig przy zapisie albo wywołano setLineEnding)
DocumentModifiedChanged DocumentId, modified — przełączyła się flaga czysty/brudny (nie każdy klawisz)
TextChanged DocumentId, pos, addedBytes, removedBytes
SelectionChanged DocumentId
ActiveDocumentChanged DocumentId
HostWindowShown (brak) — raz na uruchomienie, po pierwszej klatce na ekranie; planuj tu wolną pracę startową
SettingsChanged scope — "" = ustawienia edytora, "plugins/<id>" = zastosowano stronę tej wtyczki
WorkspaceRootChanged root (pusty = folder zamknięty) — publikowane przez wtyczkę Obszar roboczy
WorkspaceFilesChanged files[] z {path, displayPath} — publikowane przez wtyczkę Obszar roboczy
ThemeChanged variant ("light" / "dark" / "")
AppAboutToQuit (brak)
CommandShortcutChanged commandId, sequence (nowy przenośny akord; "" = niezwiązane)
MarginClicked DocumentId, line, margin (EditorMargin::Symbol), modifiers — kliknięcie lewym przyciskiem w kolumnie zakładek edytora, przy każdym takim kliknięciu; zobacz Znaczniki wierszy

Wtyczki też mogą publikować zdarzenia (ctx.events().publish(e)) — tak wtyczka Obszar roboczy rozgłasza WorkspaceRootChanged / WorkspaceFilesChanged dla Znajdź w plikach i Palety poleceń.

Jeden dokument, jeden identyfikator

DocumentId nazywa dokument, a nie panel. Podziel dokument pokazuje jeden plik w dwóch panelach, a oba panele niosą ten sam DocumentId, więc:

  • DocumentOpened jest publikowane raz na plik — podział nie publikuje niczego;
  • DocumentClosed jest publikowane dopiero, gdy zamyka się ostatni widok dokumentu, więc zamknięcie jednego panelu nigdy nie usuwa stanu, którego drugi wciąż potrzebuje;
  • activeDocument() odpowiada tym jednym identyfikatorem niezależnie od tego, który panel jest z przodu, a openDocuments() wymienia dokument raz.

Celowo nie ma zdarzenia dotyczącego panelu ani sposobu, by zapytać, który panel jest aktywny: panele są sprawą hosta, a wszystko, co wtyczka może obserwować — tekst, karetka, zaznaczenie, kodowanie, koniec linii, stan modyfikacji — należy do dokumentu, który panele współdzielą.

DocumentAboutToClose

Publikowane raz na dokument, tuż przed zniknięciem jego ostatniego widoku, gdy zamknięcie jest przesądzone — pytanie o zapis padło i nie zostało anulowane. Wewnątrz obsługi dokument jest wciąż cały: text(), filePath(), caret(), bookmarkedLines() i kodowanie odpowiadają. Potem następuje sprzątanie, a po nim DocumentClosed. Publikuje je każdy sposób zamknięcia karty (Zamknij, Zamknij wszystko, Zamknij pozostałe / na prawo, kliknięcie środkowym przyciskiem, Zamknij folder, closeDocument() wywołane przez wtyczkę), także dla dokumentów bez nazwy; zamknięcie jednego panelu dokumentu widocznego jeszcze w innym — nie.

Zakończenie programu go nie publikuje. Aplikacja publikuje raz AppAboutToQuit, gdy wszystkie dokumenty są jeszcze otwarte, i żadnych zdarzeń zamknięcia poszczególnych dokumentów: wtyczka, która przechowuje stan dokumentów między sesjami, przechodzi po openDocuments() w obsłudze AppAboutToQuit. DocumentAboutToClose zawsze znaczy więc „ten dokument jest zamykany”, nigdy „program się kończy”.

Obsługa działa synchronicznie, wewnątrz zamykania: ma być szybka, nie może pokazywać okien dialogowych i musi traktować zbiór dokumentów jako tylko do odczytu — nie otwieraj, nie zamykaj i nie aktywuj dokumentów ani nie zmieniaj tekstu zamykanego dokumentu.

Zdarzenie jest z założenia tylko natywne: dostarczanie do wtyczek Pythona jest asynchroniczne, więc obietnicy „wciąż da się odczytać” nie dałoby się tam dotrzymać i zdarzenie nie jest im oferowane (zobacz Zdarzenia w Pythonie).

CommandShortcutChanged

CommandShortcutChanged odpala się, gdy zmienia się efektywny skrót polecenia — przemapowanie przez użytkownika w mapperze skrótów, import/reset mapy klawiszy albo włączenie/zdjęcie tłumienia konfliktu. Polecenia powiązane z menu nie potrzebują niczego (host przepina ich akcję); polecenia zarejestrowane ze scope = command_scope::kPluginWindow subskrybują i ponownie stosują sekwencję do własnych widżetów (zobacz Polecenia i menu).

Subskrypcja

subscribe to szablon zwracający Subscription (RAII). Trzymaj subskrypcję przy życiu jako pole składowe tak długo, jak callback ma się odpalać; jej zniszczenie wypisuje z subskrypcji.

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

Trzymaj każdą Subscription jako pole składowe wtyczki, aby wszystkie callbacki sprzątały się automatycznie w shutdown().