Značky riadkov a kliknutie na okraj¶
Značka riadka je symbol v stĺpci záložiek editora a/alebo podfarbenie cez
celý riadok, pripojené k riadku dokumentu a prenášané s ním, kým používateľ
upravuje text. Zarážky (plné, prázdne, podmienené), šípka aktuálneho príkazu a
pásy zmien zo správy verzií sú všetko značky riadkov. K službe sa dostanete cez
IPluginContext::lineMarkers() (PluginApi/ILineMarkerService.h).
Modul opisuje, ako druh značky vyzerá a kde značky toho druhu stoja; vykresľovanie, okraj a sloty na značky v editačnom jadre patria editoru. Hranicu neprekračuje žiadna veľkosť v pixeloch, číslo jadra ani typ Qt.
Druhy¶
Každý druh značky zaregistrujte raz, v initialize(), a token si ponechajte:
enum class LineMarkerGlyph : std::int32_t {
None, Circle, CircleHollow, CircleBar, Arrow, Strip
};
struct LineMarkerKind {
LineMarkerGlyph glyph = LineMarkerGlyph::Circle;
std::string glyphColor; // a theme category you registered
std::string lineTint; // a theme category; empty = no tint
std::int32_t zOrder = 0; // higher draws above lower
};
m_breakpoint = ctx.lineMarkers().registerKind(kind); // LineMarkerKindToken
if (!m_breakpoint.valid()) { /* no slot left: see below */ }
- Farby sú id kategórií motívu, ktoré ste si sami zaregistrovali cez
ctx.themePalette(), takže značky sledujú aktívny motív a používateľ ich môže prefarbiť v Editore motívov; editor ich znova použije pri každej zmene motívu. - Symboly sú malá pevná sada, ktorú vie každý hostiteľ vykresliť v úzkom
okraji pri akomkoľvek priblížení:
Circle(zarážka),CircleHollow(vypnutá alebo neoverená zarážka),CircleBar(podmienená zarážka),Arrow(aktuálny príkaz),Strip(zmenený riadok).Nonevytvorí druh, ktorý iba podfarbuje. - zOrder rozhoduje, ktorá značka sa vykreslí navrchu, keď ich niekoľko zdieľa jeden riadok (šípka aktuálneho príkazu nad zarážkou, zarážka nad pásom zmien); pri rovnakých hodnotách je navrchu druh zaregistrovaný neskôr. Poradie platí aj naprieč modulmi.
- Registrácia môže zlyhať. Editačné jadro má malý pevný počet slotov na značky, ktorý zdieľajú všetky moduly — deväť; druh so symbolom aj podfarbením zaberá dva. Keď sa minú, token sa vráti prázdny a log povie prečo. Potrebné druhy registrujte raz a ponechajte si ich; nikdy neregistrujte druh pre každý dokument alebo každú značku.
- Zničenie tokenu odstráni všetky značky toho druhu zo všetkých dokumentov a druh stiahne.
Značky¶
using LineMarkerId = std::uint64_t; // 0 is never valid
LineMarkerId id = ctx.lineMarkers().addMarker(m_breakpoint.id(), doc, line);
std::int64_t now = ctx.lineMarkers().lineOf(id); // -1 = gone
auto all = ctx.lineMarkers().markers(m_breakpoint.id(), doc); // {id, line} by line
ctx.lineMarkers().removeMarker(id);
ctx.lineMarkers().clearMarkers(m_breakpoint.id(), 0); // 0 = every document
addMarker vráti 0 — a nič neumiestni — keď druh nežije, dokument nie je
otvorený alebo riadok leží mimo dokumentu. Riadok sa neorezáva: zarážka na
nesprávnom riadku je horšia ako žiadna. Popisovač je obyčajná hodnota, nie
token; držte ich, koľko potrebujete.
Čo sa so značkou deje potom:
- Úpravy ju posúvajú spolu s jej riadkom: riadky vložené alebo zmazané nad ňou ju posunú, písanie na riadku ju ponechá — tak zarážka sleduje kód.
- Jej riadok sa zmaže (je súčasťou odstráneného rozsahu): značka prežije a presunie sa na riadok, kde odstránený rozsah začínal. Dve značky tak môžu skončiť na jednom riadku.
- Nahradí sa celý buffer (opätovné načítanie po zmene zvonku,
IEditorService::setText): každá značka zostane na rovnakom čísle riadka; značka, ktorej riadok už neexistuje, sa odstráni. Editor starý a nový text neporovnáva. - Dokument sa zatvorí: jeho značky sa odstránia a ich popisovače prestanú
platiť. Editor značky nikdy neukladá — modul, ktorý si značky ponecháva aj po
zatvorení (zarážky), ich drží vo vlastnom modeli a pri
DocumentOpenedich pridá znova (znova otvorený súbor má novéDocumentId).
Značky patria dokumentu: raz umiestnené sa zobrazia v každom table
rozdeleného dokumentu. Minimapa, jej náhľad
pri najazdení a zobrazenie porovnania ich nikdy neukazujú. Záložky nie sú
značkami tejto služby; ponechávajú si vlastné volania IEditorService.
Kliknutie na okraj¶
Každé kliknutie ľavým tlačidlom do stĺpca záložiek editora sa zverejní ako
events::MarginClicked:
struct MarginClicked {
DocumentId doc;
std::int64_t line; // 0-based, level with the click
EditorMargin margin; // EditorMargin::Symbol
KeyModifiers modifiers; // key_modifier::kShift | kControl | kAlt | kMeta
};
Názvy modifikátorov zodpovedajú prenosným reťazcom skratiek: kControl je Ctrl
vo Windows a Linuxe a Command (⌘) v macOS, kAlt je Alt / Option (⌥), kMeta
je kláves Windows / Control (⌃) v macOS. Kliknutia do stĺpca zbaľovania
zbaľujú a kliknutia na čísla riadkov vyberajú; ani jedno sa nezverejňuje.
Predvolene editor navyše na kliknutom riadku prepne záložku, ako to robil vždy. Modul, ktorý kliknutiu dáva vlastný význam — ladiaci program, ktorý obyčajným kliknutím prepína zarážku a kliknutím s modifikátorom upravuje jej podmienku —, si ho nárokuje:
m_marginClaim = ctx.lineMarkers().claimMarginClick(); // MarginClickToken
m_clicks = ctx.events().subscribe<events::MarginClicked>(
[this](const events::MarginClicked& e) { onMarginClick(e); });
Kým žije aspoň jeden nárok — od ktoréhokoľvek modulu —, editor kliknutie prenechá modulom a iba zverejní udalosť; zničenie posledného tokenu vráti prepínanie záložiek. Udalosť sa zverejňuje bez ohľadu na to, či niekto drží nárok, takže modul, ktorý kliknutia iba sleduje, žiadny nepotrebuje. Príkazy záložiek a ich skratky sa nemenia. Nároky sa počítajú, neradia sa do frontu: dva moduly, ktoré si kliknutie oba nárokujú, ho oba dostanú a nesmú naň oba reagovať.
Python¶
Tá istá služba je ctx.line_markers pre
moduly v Pythone a kliknutie je
@ctx.events.on_margin_clicked.