feat(widgets): add editable label prefix to text-label widgets - #601
Open
tough-griff wants to merge 3 commits into
Open
tough-griff wants to merge 3 commits into
tough-griff wants to merge 3 commits into
Conversation
Widgets that prepend a text label when raw value is off ("Model: ",
"Ctx: ", "In: ", ...) now accept a per-item override stored in
metadata.label. The override replaces every label variant of a widget
verbatim; an empty override drops the label.
Widgets opt in via Widget.getLabelPrefix(item). Rendering goes through
formatRawOrLabeledValue, which inline-label widgets now use too. The
items editor offers a shared la(b)el… keybind (hidden in raw value
mode) that opens a new LabelEditor, and lists overrides as
(label: "...").
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Extract CustomText's inline cursor handling into useTextCursor (src/widgets/shared/text-cursor.ts) and use it from both the Custom Text and label editors, giving the label editor cursor movement and forward delete. Ctrl+Left/Right now jump to the start/end as the editor hint says. The old checks compared input to 'ArrowLeft', which Ink never sends, and ran after the plain-arrow branch, so they were unreachable. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
axisrow
added a commit
to axisrow/ccstatusline
that referenced
this pull request
Sep 26, 2026
…es (#10) * feat(widgets): compact label presets with global and per-widget toggles Add abbreviated label presets for labeled widgets, complementary to the free-form label editing proposed upstream (sirmalloc#601): - New `compactLabels` settings flag (default off). Additive v4 key: old configs parse unchanged and render identically, no version bump needed. - Presets live in one map (`Model:` -> `M:`, `Context:` -> `Ctx:`, `Cost:` -> `` — the value's own `$` is the glyph) inside `formatRawOrLabeledValue`, so every widget routed through the helper picks them up with no per-widget changes. Model, Session Cost, and Context Bar moved onto the helper. - One-click global toggle in Global Overrides `(j)`; per-widget override via `(j) compact label` in the items editor (metadata `compactLabel`), which wins over the global setting in both directions. Capability for the editor keybind is derived from a cached preview probe of the widget registry. - Extend the Git Branch width-cap pattern to Current Working Dir and Session Name (`w` max-width keybind). - Document per-widget padding/separator/label width overhead in docs/USAGE.md; defaults unchanged. Tests: preset resolution, toggle metadata, global injection precedence, migration parity (v1->v4 and schema-less v4 parse), registry-wide `j` keybind reservation, capable-type probe sanity, Global Overrides `(j)` keystroke test. bun test 2400 pass; bun run lint clean. Co-Authored-By: Claude Code <noreply@anthropic.com> * fix(tui): compact-label toggle cycles over the effective state The per-widget (j) toggle only wrote/removed 'true', so with the global Compact Labels setting on it became a visual no-op: the render-time injection re-compactified the widget after the key was removed, and no row marker showed the effective state. - toggleCompactLabel now takes the settings and cycles the EFFECTIVE state: compact (saved 'true' or inherited global on) -> write 'false'; forced off -> drop the key and inherit; otherwise -> write 'true'. - getCompactLabelModifierText reports the effective state: '(compact label)' / '(compact label: on)' / '(compact label: off)'. - ItemsEditor/input-handlers pass settings through to both. - docs/USAGE.md: fix preset savings arithmetic (Model -4, Context -4). Co-Authored-By: Claude Code <noreply@anthropic.com> * test(renderer): cover (j) toggle forcing labels off while global compact is on Co-Authored-By: Claude Code <noreply@anthropic.com> * style: fix import order in compact-labels renderer test Co-Authored-By: Claude Code <noreply@anthropic.com> --------- Co-authored-by: axisrow <axisrow@users.noreply.github.com> Co-authored-by: Claude Code <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #600
Adds a per-widget label override for widgets that show a text label (
Model:,Ctx:,In:, …). Select the widget in the line editor and pressb(la(b)el…).Changes
metadata.labeland used exactly as typed. An empty string removes the label, and a value equal to the default isn't stored, so untouched items stay minimal. No schema change or migration.formatRawOrLabeledValuenow uses the override, so every widget that already went through it gets the feature from one change. Widgets that built their label inline now use the helper too: Model, Session ID, Account Email, Context Length/Window/Bar, Memory Usage, Output Style, Session Clock/Name/Cost, Thinking Effort, Terminal Width, Git Staged/Unstaged/Untracked Files, and Current Working Dir (its optional glyph still comes before the label).Widget.getLabelPrefix(item), which returns their default label for the item's current mode (Context % givesCtx Used:orCtx Left:). The usage and speed families get theirs from their shared config.Block:vsBlockbefore a bar) use the same override in all modes.ItemsEditor, the same way(h)ide…is, and is hidden while raw value is on.LabelEditor. The value is shown in quotes so trailing spaces are visible, and Tab restores the default.(label: "M ")while an override is set.lwould be the natural key, but the reset timers already use it for(l)ocale.useTextCursor(src/widgets/shared/text-cursor.ts), which the label editor and Custom Text now both use. This also makes Ctrl+←/→ jump to the start/end as Custom Text's hint says. The old checks comparedinputto'ArrowLeft', which Ink never sends, and ran after the plain-arrow branch, so they never matched.(g)lyph. Widgets whose prefix is really part of the value (Version, Git PR, Sandbox/Voice/Remote Control status, Git Is Fork, Link) aren't changed.docs/USAGE.mdcovers the keybind in the raw value section and in the editor keybind list.Testing
bitself in any mode, next to the existinghcheckItemsEditortest coveringb→ edit → save →(label: "M "), with the keybind and row tag hidden in raw value modebun testandbun run lintpasssettings.json
{ "version": 4, "lines": [ [ { "id": "1", "type": "model", "metadata": { "label": "M " } }, { "id": "2", "type": "separator" }, { "id": "3", "type": "model" }, { "id": "4", "type": "separator" }, { "id": "5", "type": "terminal-width", "metadata": { "label": "" } } ] ] }🤖 Generated with Claude Code