feat: ID-Vorschläge beim Tippen von Abhängigkeiten (:#) — D63
Wer :# tippt, bekommt die vergebenen IDs als Liste an der Schreibmarke: Präfix- vor Teilstring-Treffern, Knotentitel als Kontext, schon gelistete und die eigene ID ausgenommen. ↑/↓ wählt, Enter/Tab übernimmt (undo-fähig), Esc schließt; Live-Region für Screenreader. Eingabehilfe wie die Kurzform (D55) — der Parser sieht nie etwas davon. Regeln headless in autocomplete.js (20 Tests), app.js verdrahtet Popup, Tasten und Einfügen. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
9cb6ec1197
commit
1debb7d9da
@@ -19,6 +19,7 @@ reverse.
|
||||
|
||||
## 2026-08-24
|
||||
|
||||
- Typing `:#` suggests the document's ids — arrows choose, Enter inserts
|
||||
- When the caret's node is folded away, the nearest visible ancestor takes the highlight — also on Alt+click from the text
|
||||
- A size that cannot hold its sub-packages turns its badge amber and gets a warning — sizes are read as ranges, so only sure conflicts are reported
|
||||
- Fix: the exported SVG drew the assumed-M badge filled like a real size instead of inverted
|
||||
|
||||
@@ -4688,3 +4688,84 @@ disjunktive Gruppen summiert statt Minimum: genau zwei. Im Browser: Badge
|
||||
den Grund; im exportierten SVG das Konflikt-Badge bernstein und das implizite
|
||||
M weiß mit Petrol-Rand. Kanonisches Beispiel §10 und der mitgelieferte Plan:
|
||||
0 Warnungen.
|
||||
|
||||
## D63 — ID-Vorschläge beim Tippen von Abhängigkeiten (`:#`)
|
||||
Wer eine Abhängigkeit tippt, muss die Ziel-ID auswendig wissen oder im Text
|
||||
suchen — bei 180 IDs im mitgelieferten Plan keine Kleinigkeit. Jetzt öffnet
|
||||
`:#` eine Vorschlagsliste an der Schreibmarke: die vergebenen IDs, gefiltert
|
||||
nach dem getippten Fragment, mit dem Knotentitel als Kontext.
|
||||
|
||||
**Dieselbe Kategorie wie die ID-Kurzform (D55): Eingabehilfe, keine
|
||||
Notation.** Der Parser sieht nie etwas davon, SPEC-Syntax und `llms.md`
|
||||
bleiben unberührt; übernommen wird undo-fähig über das vorhandene `writeAt()`
|
||||
(D53). Die drei schwierigen Zutaten lagen schon im Haus: Die **Kandidaten**
|
||||
kommen aus dem Parse-Baum, der bei jedem Tastendruck ohnehin frisch ist; die
|
||||
**Pixel-Position der Schreibmarke** misst der Spiegel-`div` aus D25/D33 (ein
|
||||
Marker-Span, `offsetTop`/`offsetLeft` — seit `wrap="off"` (D49) trivial); das
|
||||
**Einfügen ohne Undo-Verlust** ist die D53-Lehre. Kein CodeMirror/Monaco —
|
||||
das wäre eine Laufzeit-Abhängigkeit (D11/D19) für etwas, das drei vorhandene
|
||||
Mechanismen zusammensetzen.
|
||||
|
||||
**Ausgelöst nur im Abhängigkeits-Kontext, nicht bei jedem `#`.** Ein
|
||||
alleinstehendes `#` *definiert* meist eine neue ID — dort wäre die Liste im
|
||||
Weg. Erkannt wird dieselbe Form, die der Parser liest: `(^|\s):#…` (§1) und
|
||||
die Kopf-Form `#auth:#…` (D36); `(:#a` bleibt Zitat, `Regel: #x` bleibt
|
||||
Label, im Kommentar und hinter `---` gibt es keinen Kontext. Die Erkennung
|
||||
(`depFragment`) und die Kandidaten-Auswahl (`collectIds`/`matchIds`) stehen
|
||||
headless in **`autocomplete.js`** — die Hausregel aus D54-Nachtrag 3; app.js
|
||||
verdrahtet nur Popup, Tasten und Einfügen.
|
||||
|
||||
**Angeboten wird alles, ausgenommen das Sinnlose.** Auch IDs verworfener und
|
||||
eingeklappter Knoten stehen in der Liste — eine Abhängigkeit darf dorthin
|
||||
zeigen (§1), und die Faltung ist nur Ansicht (D38). Ausgenommen sind die im
|
||||
Token **schon gelisteten** IDs und die **eigene ID der Zeile** (die
|
||||
Selbst-Abhängigkeit ist zulässig, aber nie das, was man tippen will).
|
||||
Sortierung: Präfix-Treffer vor Teilstring-Treffern, je in
|
||||
Dokumentreihenfolge, Groß-/Kleinschreibung egal — die IDs selbst bleiben, wie
|
||||
sie geschrieben sind. Ersetzt wird bis ans **Ende der ID-Zeichen** hinter der
|
||||
Schreibmarke, sonst ergäbe eine Übernahme mitten im Wort `#authth`.
|
||||
|
||||
**Die Tasten-Arbitrierung ist der heikle Teil, nicht das Popup.** ↑/↓, Enter,
|
||||
Tab und Esc gehören sonst dem Textfeld — abgefangen werden sie **nur bei
|
||||
offener Liste**, über einen Capture-Handler auf `document`: Die
|
||||
Textfeld-Handler (Tab rückt ein, Esc löst die Tab-Falle — beide D53) sind
|
||||
früher registriert und kämen sonst zuerst; `stopPropagation` hält sie heraus.
|
||||
Zwei Folgen, beide gemessen: Tab übernimmt bei offener Liste, **ohne**
|
||||
zusätzlich einzurücken, und rückt bei geschlossener unverändert ein; Esc
|
||||
schließt die Liste, ohne die Tab-Falle zu lösen. **Nach Esc und nach einer
|
||||
Übernahme bleibt derselbe Kontext zu** (`acSuppress`) — sonst öffnete ihn das
|
||||
nächste keyup sofort wieder; Weitertippen ändert das Fragment und hebt die
|
||||
Sperre.
|
||||
|
||||
**Ein Echo wird nicht angeboten:** Steht die ID schon vollständig da (der
|
||||
eine exakte Treffer, Schreibmarke am Token-Ende), bleibt die Liste zu — so
|
||||
schließt sie nach der Übernahme von selbst und meldet sich nicht bei jedem
|
||||
Cursor-Besuch einer fertigen Zeile.
|
||||
|
||||
**Barrierefreiheit als benannte Grenze, nicht als Behauptung.** Das saubere
|
||||
ARIA-Combobox-Muster passt nicht auf ein `<textarea>` (kein
|
||||
`aria-activedescendant` über Elementgrenzen). Das Popup ist deshalb
|
||||
`aria-hidden` wie das Knoten-Fenster (D57); eine höfliche **Live-Region**
|
||||
meldet die Trefferzahl beim Öffnen und die gewählte ID beim Blättern. Die
|
||||
Liste blockiert nie normales Tippen — wer sie nicht wahrnimmt, verliert
|
||||
nichts.
|
||||
|
||||
**Position wie das Knoten-Fenster:** `position:fixed` auf `<body>` — in
|
||||
einem Vorfahren mit `overflow` würde die Liste geklippt (D50), und `#out`s
|
||||
`zoom` geht sie nichts an. Verankert unter dem `#` des Fragments, nach oben
|
||||
ausweichend, wenn unten kein Platz ist; zu geht sie bei Blur, Scrollen des
|
||||
Textfelds, Fenstergröße — allem, was ihre Position hinfällig macht (die
|
||||
D52-Liste). In Pad-Dokumenten (schreibgeschützt, D31) öffnet sie nie.
|
||||
|
||||
**Nachgemessen** im Browser mit echten Ereignisfolgen: `:` allein öffnet
|
||||
nichts, `:#` zeigt alle vier IDs des Testbaums (verworfene eingeschlossen),
|
||||
`a` filtert auf drei, ↑/↓ wandert (Live-Region nennt die gewählte ID), Enter
|
||||
übernimmt (`- Frontend :#api`), `,#` öffnet ohne das schon gelistete `api`,
|
||||
Esc schließt und bleibt bei Cursorbewegung zu, `d` öffnet wieder, Klick
|
||||
übernimmt, und **jede** Übernahme ist ein einzelner Undo-Schritt. Tab: bei
|
||||
offener Liste übernehmen ohne Einrücken, danach einrücken wie immer. 20 neue
|
||||
Tests in `tests/autocomplete.test.js` (397 gesamt): Kontext-Erkennung
|
||||
(Kopf-Form, Zitier-Klammer, Kommentar, Beschreibungsteil, Fortsetzungszeile
|
||||
D59, Ersetzen über die Schreibmarke hinaus), Sammeln (Dokumentreihenfolge,
|
||||
verworfene, D60-Knoten ohne Titel) und Sortierung (Präfix vor Teilstring,
|
||||
case-insensitiv, exclude).
|
||||
|
||||
@@ -869,6 +869,30 @@ und `llms.md` (§13) bleibt unberührt. Angefasst wird nur die Zeile, in der auc
|
||||
bloßes Durchklicken ein fremdes Dokument um; Abhängigkeiten (`:#…`) und der
|
||||
Beschreibungsteil hinter `---` bleiben außen vor. Siehe D55.
|
||||
|
||||
### ID-Vorschläge beim Tippen von Abhängigkeiten (`:#`)
|
||||
Ebenfalls eine **Eingabehilfe**, keine Notation: Wer im Baumteil ein
|
||||
Abhängigkeits-Token beginnt (`:#`, auch in der Fortsetzung `,#` und in der
|
||||
Kopf-Form `#auth:#…`), bekommt an der Schreibmarke eine **Liste der vergebenen
|
||||
IDs** — gefiltert nach dem schon getippten Fragment (Präfix-Treffer zuerst,
|
||||
dann Teilstring-Treffer, je in Dokumentreihenfolge), mit dem Knotentitel als
|
||||
Kontext daneben. Angeboten werden **alle** IDs des Dokuments, auch die
|
||||
verworfener oder eingeklappter Knoten — eine Abhängigkeit darf überallhin
|
||||
zeigen (§1); nicht angeboten werden die im Token schon gelisteten IDs und die
|
||||
eigene ID der Zeile.
|
||||
|
||||
- **Bedienung:** ↑/↓ wählt, Enter oder Tab übernimmt (undo-fähig, ein
|
||||
Schritt), Esc schließt — Weitertippen öffnet wieder. Klick bzw. Tipp auf
|
||||
einen Eintrag übernimmt ebenso. Wer die Liste ignoriert, tippt einfach
|
||||
weiter: Sie fängt keine Taste ab, solange sie nichts anzeigt, und Tab rückt
|
||||
bei geschlossener Liste unverändert ein.
|
||||
- **Kein Vorschlag** bei bloßem `#` (das *definiert* eine ID), im Kommentar
|
||||
(`%%`), im Beschreibungsteil hinter `---` und in schreibgeschützten
|
||||
Pad-Dokumenten (§9).
|
||||
- Der Parser sieht nie etwas davon; `llms.md` (§13) bleibt unberührt. Für
|
||||
Screenreader meldet eine höfliche Live-Region die Trefferzahl und den
|
||||
gewählten Eintrag; das Popup selbst ist `aria-hidden`, normales Tippen
|
||||
bleibt unberührt. Siehe D63.
|
||||
|
||||
### Zeilennummern im Texteditor
|
||||
Links neben dem Textfeld steht ein schmaler Streifen mit den **Zeilennummern** —
|
||||
dieselben, die die Warnungen nennen („Zeile 12: …", §4). Ohne ihn muss man sie
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
- [^] #ed.jump: Jump between diagram and text (S)
|
||||
- [^] #ed.lineno: Line numbers in the text editor (XS) %% the warnings name them
|
||||
- [^] #ed.shortid: Type #.kc under #prod-stage, get #prod-stage.kc (XS) %% an input aid, not notation
|
||||
- [x] #ed.depcomplete: Typing :# suggests the known ids (S) %% arrows choose, Enter inserts
|
||||
- [^] #ed.showids: A # button shows the ids before the titles (XS) %% written as in the text, with a colon
|
||||
- [^] #ed.lineno.tip: The warning is the tooltip of its number (XS) %% no hunting in the list
|
||||
- [^] #ed.fold: Collapsible subtrees (L)
|
||||
@@ -526,6 +527,11 @@
|
||||
typing, not while parsing: the file keeps the full id, so it stays greppable
|
||||
and survives re-ordering, which is what the :#... references rely on.
|
||||
|
||||
#ed.depcomplete
|
||||
A dependency needs its target's id, and nobody remembers 180 of them. The
|
||||
list at the caret offers the document's ids filtered by what is typed, with
|
||||
the node title as context; an input aid like the shorthand, not notation.
|
||||
|
||||
#ed.showids
|
||||
The id is the address of a node, but the diagram only carried it in the
|
||||
tooltip. The switch writes it before the title the same way the text does,
|
||||
|
||||
Reference in New Issue
Block a user