Skip to content

feat: unified hideable-state system for widgets #428

Description

@zachthedev

Problem

Hiding is implemented six different ways (hideNoGit, hideNoRemote, hideTitle/hideStatus, hideZero, hideWhenEmpty, hideIfDisabled), each with its own metadata key, keybind, and modifier text, while many comparable states have no hide option at all: speed widgets render with no data, tokens/cost/clock render 0/$0.00/0m at session start, timers render 0hr 0m with no active window, output-style can't be hidden when it equals default, and ahead/behind's 0/0 auto-hide is hardcoded with no opt-out. Decorative items (custom-symbol, custom-text) can't hide at all, so icon prefixes merged into a widget orphan whenever that widget hides (e.g. git icon prefixes outside a repo).

Proposed design

  1. Widget-declared states. Extend the Widget interface with getHideableStates(): { key: string; label: string }[]. Each widget declares which conditions it can detect, drawing from a shared vocabulary where applicable: no-git, no-upstream, no-remote, no-data, zero, empty, disabled, default-value, error.
  2. One metadata key. metadata.hide holds a comma-separated list of enabled state keys (metadata values are strings), e.g. "hide": "no-git,zero". A shared isHidden(item, key) helper replaces the six bespoke accessors.
  3. One editor surface. A single (h)ide… keybind opens a checklist of the widget's declared states; replaces the per-widget toggle keybinds. Modifier text renders as (hide: no-git, zero).
  4. Decorative items participate. custom-symbol/custom-text declare one state: merge-target-hidden; when enabled and the item they merge into renders null, they render null too (propagating through chains of merged items, so [ + icon + widget + ] collapses as a unit). This generalizes the icon-prefix case to every widget, not just git.
  5. Back-compat. Legacy keys are read as aliases (hideNoGit: "true"hide: "no-git", etc.) and migrated on next settings save; existing configs keep working unchanged.

Implementation notes

The shared helpers in src/widgets/shared/git-no-git generalize into src/widgets/shared/hideable; per-widget work is declaring states and replacing the existing ad-hoc checks with isHidden() calls. The hardcoded 0/0 auto-hide on ahead/behind becomes a declared default-on zero state for opt-out symmetry.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions