Vai al contenuto

Eventi

I plugin reagiscono all'attività dell'editor tramite IEventBus. Gli eventi sono semplici struct definiti in PluginEvents.h:

Evento Contenuto
DocumentOpened DocumentId, std::filesystem::path
DocumentAboutToClose DocumentId — l'utente sta chiudendo il documento e la chiusura è certa; pubblicato subito prima che scompaia la sua ultima vista, quando è ancora leggibile per intero. Non all'uscita. Solo plugin nativi; vedi sotto
DocumentClosed DocumentId
DocumentSaved DocumentId
DocumentPrinted DocumentId, pages — pubblicato dopo che un lavoro di stampa ha raggiunto il dispositivo (File ▸ Stampa, oppure Stampa dentro l'anteprima); pages conta le pagine del documento stampate, meno di quelle che il documento ha quando è stata scelta una selezione o un intervallo di pagine. Una finestra annullata non pubblica nulla. Per ora solo plugin C++
DocumentAboutToSave DocumentId, path — sincrono, il buffer è ancora modificabile (rifilare gli spazi, aggiungere l'a capo finale); niente finestre di dialogo
DocumentEncodingChanged DocumentId, DocumentEncoding — è cambiata la codifica con cui l'host riscriverà il documento (file appena identificato, oppure setDocumentEncoding chiamata)
DocumentLineEndingChanged DocumentId, LineEnding — è cambiato il terminatore di riga usato dal documento (file appena letto o ricaricato, un end_of_line di .editorconfig applicato al salvataggio, oppure setLineEnding chiamata)
DocumentModifiedChanged DocumentId, modified — il contrassegno pulito/modificato si è ribaltato (non a ogni battuta)
TextChanged DocumentId, pos, addedBytes, removedBytes
SelectionChanged DocumentId
ActiveDocumentChanged DocumentId
HostWindowShown (nessuno) — una volta per esecuzione, dopo che il primo fotogramma è sullo schermo; pianifica su questo il lavoro lento di avvio
SettingsChanged scope — "" = tutto l'editor, "plugins/<id>" = è stata applicata la pagina di quel plugin
WorkspaceRootChanged root (vuoto = cartella chiusa) — pubblicato dal plugin Area di lavoro
WorkspaceFilesChanged files[] di {path, displayPath} — pubblicato dal plugin Area di lavoro
ThemeChanged variant ("light" / "dark" / "")
AppAboutToQuit (nessuno)
CommandShortcutChanged commandId, sequence (nuovo accordo portabile; "" = non associato)
MarginClicked DocumentId, line, margin (EditorMargin::Symbol), modifiers — un clic sinistro nella colonna dei segnalibri di un editor, a ogni clic di questo tipo; vedi Marcatori di riga

Anche i plugin possono pubblicare eventi (ctx.events().publish(e)): è così che il plugin Area di lavoro trasmette WorkspaceRootChanged / WorkspaceFilesChanged perché Trova nei file e la tavolozza dei comandi li consumino.

Un documento, un id

Un DocumentId nomina un documento, non un riquadro. Dividi il documento mostra un file in due riquadri, ed entrambi portano lo stesso DocumentId, quindi:

  • DocumentOpened viene pubblicato una volta per file: dividere non pubblica nulla;
  • DocumentClosed viene pubblicato solo quando si chiude l'ultima vista del documento, così chiudere un riquadro non smonta mai uno stato che all'altro serve ancora;
  • activeDocument() risponde con quell'unico id qualunque sia il riquadro in primo piano, e openDocuments() elenca il documento una sola volta.

Deliberatamente non esiste alcun evento per riquadro né alcun modo di chiedere quale riquadro sia attivo: i riquadri sono un affare dell'host, e tutto ciò che un plugin può osservare — testo, cursore, selezione, codifica, fine riga, stato di modifica — appartiene al documento, che i riquadri condividono.

DocumentAboutToClose

Pubblicato una volta per documento, immediatamente prima che scompaia la sua ultima vista, quando la chiusura è certa: un'eventuale richiesta di salvataggio ha avuto risposta e non è stata annullata. Dentro il gestore il documento è ancora intero: text(), filePath(), caret(), bookmarkedLines() e la codifica rispondono tutti. Poi segue lo smontaggio e infine DocumentClosed. Ogni modo di chiudere una scheda lo pubblica (Chiudi, Chiudi tutto, Chiudi gli altri / Chiudi quelli a destra, un clic centrale, Chiudi cartella, il closeDocument() di un plugin), compresi i documenti senza titolo; chiudere un riquadro di un documento ancora mostrato in un altro non lo pubblica.

L'uscita dal programma non lo pubblica. L'applicazione pubblica AppAboutToQuit una volta, mentre tutti i documenti sono ancora aperti, e nessun evento di chiusura per documento: un plugin che conserva uno stato per documento tra una sessione e l'altra scorre openDocuments() nel proprio gestore di AppAboutToQuit. DocumentAboutToClose significa quindi sempre «questo documento viene chiuso», mai «il programma sta terminando».

I gestori vengono eseguiti in modo sincrono, nel mezzo della chiusura: sii veloce, non mostrare finestre di dialogo e tratta l'insieme dei documenti come di sola lettura: non aprire, chiudere o attivare documenti e non modificare il testo del documento che si sta chiudendo.

È solo nativo per scelta progettuale: la consegna ai plugin Python è asincrona, quindi lì la promessa «ancora leggibile» non potrebbe essere mantenuta, e l'evento non viene offerto loro (vedi Eventi Python).

CommandShortcutChanged

CommandShortcutChanged scatta quando la scorciatoia effettiva di un comando cambia: una riassegnazione dell'utente nella Mappatura delle scorciatoie, l'importazione o l'azzeramento di una mappa di tasti, oppure l'attivarsi o il venir meno di una soppressione per conflitto. Ai comandi legati a un menu non serve nulla (l'host riassocia la loro azione); i comandi registrati con scope = command_scope::kPluginWindow si sottoscrivono e riapplicano la sequenza ai propri widget (vedi Comandi e menu).

Sottoscrizione

subscribe è un template che restituisce una Subscription (RAII). Mantieni viva la sottoscrizione come membro per tutto il tempo in cui vuoi che la callback scatti; distruggerla annulla la sottoscrizione.

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

Conserva ogni Subscription come membro del plugin, così che tutte le callback vengano smontate automaticamente in shutdown().