Repository navigation
feat(app): let users pick per-mode indicator colors - #70
Merged
Merged
Conversation
normal and visual (visual + v-line) get their own color, alpha included, chosen with two color pickers in the indicator tab; insert keeps the system accent. both are unset by default, so nothing changes for existing users. the colors live in userdefaults as sRGB #RRGGBBAA strings owned by ModeIndicatorController, and a color change repaints the panels on screen without an accessibility re-read: the presentation now carries the mode instead of the label so the controller knows which color a live panel needs. the pure ModeIndicatorColor layer (hex round-trip with sRGB clamping, mode-to-color table) is table-tested, the persistence tests keep the object(forKey:) != nil guard, and the architecture references describe the new state. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
the insert flash gets its own color next to normal and visual, chosen in the same colors section (normal / insert / visual order); reset clears all three. same storage format, unset default and repaint path as the other two. this follows the insert color decision that partially supersedes the morning's per-mode color decision. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
pilyang
added a commit
that referenced
this pull request
Sep 16, 2026
the plan reached its goal: four prs merged (#66 flash, #67 persistent badge, #68 caret anchor and border styles, #70 per-mode colors) and the roadmap item checked. its two open follow-ups moved to github issues so nothing is lost with the plan file: - #71 (cold-launched apps miss observer registration) - #72 (one unreproduced flash placement after a cross-display move) Co-Authored-By: Claude Fable 5.1 <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.
Summary
Appearance follow-up to the on-screen mode indicator (PRD §7.7, roadmap Stage 4): the pills and borders can now be colored per mode. Settled in decisions
20260916_mode-indicator-per-mode-colors.mdand20260916_mode-indicator-insert-color.md.ColorPickerwith opacity in the Settings Indicator tab, under a new "Colors" section, plus a Reset to system accent button. Insert has no persistent indicator, so its color only shows in the flash on a mode change. The whole section is disabled with the indicator toggle.onScreenModeIndicatorNormalColor/onScreenModeIndicatorInsertColor/onScreenModeIndicatorVisualColor, sRGB#RRGGBBAAstrings (uppercase,defaults write-friendly); a missing or unreadable value folds to unset, and resetting removes the key.Presentation(that would tripdesired != currentand cost an AX round trip for a purely visual change);normalColor/insertColor/visualColorpersist indidSetand push the color straight into the live flash, badge and border panels.Presentationnow carries themodeinstead of the label (label is derived), so the controller knows which color a panel on screen needs. Because the self-pid path leavescurrentand the previous app's persistent panel alone, picking a color with Settings open recolors that badge or border in place.New pure layer
ModeIndicatorColor(hex parse/serialize with sRGB clamping —ColorPickercan hand back Display P3 colors whose sRGB components fall outside 0…1 — and the mode→color table). The picker binding ignores a value whose hex equals the current effective color, so merely opening the color panel does not freeze the accent into a stored snapshot.Verification
xcodebuild test -only-testing:VimActionTests: pass, re-run independently by the supervising session. NewModeIndicatorColorTests(16): hex round-trip, case normalization, RGBA order, eight malformed inputs, out-of-gamut Display P3 color, mode→color table for all four modes, per-key persistence for each of the three keys with theobject(forKey:) != nilguard, reset removes all three keys, unreadable stored value, harmless without inputs, black text on a bright user color, alpha does not change the text verdict.xcodebuild build … CODE_SIGNING_ALLOWED=NO: 0 warnings.defaults write+ relaunch, window capture + pixel sampling): default badge = accent (0,122,255); Normal#FF0000FF→ badge (255,0,0) while the INSERT flash stays (0,122,255) when Insert is unset; Insert#8000FFFF→ INSERT flash (128,0,255) with no persistent panel afterwards; Visual#00A000FF→ VISUAL badge (0,160,0) and back to red on Esc; Normal#FF000080→ captured alpha 128; window-border and screen-border strokes and their corner labels red with white text; keys removed → accent again. Product defaults restored afterwards.Docs
mode-indicator-overlay.md(color flow, mode inPresentation, text-color rule, new pure layer, tests),profiles-and-config.md(three keys),app-shell.md(Colors section). Decisions recorded on main (the Insert color one partially supersedes the first, only the "Insert keeps the accent" clause).🤖 Generated with Claude Code