Skip to content

PadIO: hidden modes, trim the mode picker list - #16

Merged
vgreg merged 1 commit into
mainfrom
10-hidden-modes
Aug 1, 2026
Merged

PadIO: hidden modes, trim the mode picker list#16
vgreg merged 1 commit into
mainfrom
10-hidden-modes

Conversation

@vgreg

@vgreg vgreg commented Aug 1, 2026

Copy link
Copy Markdown
Owner

Implements #10.

With modes driven by the app in the focused pane (#9), the mode list grows one entry per app, so the picker stops working as a manual switcher when only a few modes (e.g. media, zsh) are ever picked by hand. This lets modes be marked hidden.

Chosen form: hidden_modes denylist

Per the discussion in #10 I picked the denylist (list modes to hide) at two levels:

  • on ProfileConfig — hides per-profile modes
  • at top level of MappingConfig — hides cross-profile shared_modes

Both are optional, decodeIfPresent(...) ?? [], so existing configs list every mode exactly as before.

{
  "hidden_modes": ["media-alt"],
  "profiles": {
    "ghostty": {
      "hidden_modes": ["agent", "vim", "browser"],
      "modes": { "herdr-nav": {}, "agent": {}, "vim": {}, "browser": {} }
    }
  }
}

Implementation

allModeNames(profile:config:) is the single source feeding the picker and prev/next cycling (the manual switchers), so the filter lives in one place: it subtracts the union of profile.hidden_modes and top-level hidden_modes. Hidden modes stay reachable via setMode bindings, external context (#9), and default_mode — those resolve modes by name and never enumerate.

Degenerate guard: if hiding would leave zero visible modes, it falls back to the full set, so the picker is never an empty, inescapable panel.

Verified nothing else enumerates mode names for display: only ControllerManager calls allModeNames; HelpOverlay enumerates bindings for the active mode, not mode names; ModePickerOverlay just renders whatever list it is handed.

Verified

  • Builds clean via BuildProject.
  • Omitting the key lists every mode, as today.
  • The mode-change HUD still names a hidden mode when it activates (HUD takes a name, unaffected by the filter).

🤖 Generated with Claude Code

Once modes are driven by the app in the focused pane, the mode list
grows one entry per app and the picker becomes unusable as a manual
switcher. Let modes be marked hidden: excluded from the picker and
prev/next cycling, but still fully functional.

Add an optional hidden_modes ([String]) at two levels: on ProfileConfig
(per-profile modes) and at top level (for cross-profile shared modes),
both decoded with decodeIfPresent ?? []. allModeNames, the single source
feeding the picker and prev/next cycling, subtracts the union of the two
lists. Hidden modes stay reachable via setMode, external context, and
default_mode. If hiding would leave nothing, fall back to the full set
so the picker is never an empty, inescapable panel.

Closes #10

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vgreg
vgreg merged commit 74fb25f into main Aug 1, 2026
@vgreg
vgreg deleted the 10-hidden-modes branch August 1, 2026 21:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant