Skip to content

Add a search box to the Settings → Keyboard Shortcuts page #58

Description

@DragonnZhang

Problem or Motivation

OpenWork's Settings → Keyboard Shortcuts page (ShortcutsPage.tsx) renders
every keyboard shortcut — the registry-driven actions grouped by category
(General, Navigation, View, Chat, …) plus three component-specific sections
(list navigation, session list, chat input). That's ~30 rows across many
sections, and there is no way to filter them. To find "the shortcut for
toggling the theme" or "what does ⇧ do here", you scroll and scan the whole
list.

Comparable desktop apps make their shortcut reference searchable. The Codex
app's Settings → Keyboard Shortcuts has "keypress search" (search by the key
you pressed) and a reset-all action; VS Code's Keyboard Shortcuts editor and
Claude Code's customizable keybindings both ship a search box at the top. The
settings navigator in OpenWork already got a search box (#39/#40) — the
shortcuts list, which is longer and denser, is the conspicuous remaining
un-filterable settings surface.

Proposed Solution

Add a search box at the top of the Shortcuts page that filters the shortcut rows
by both their action label and their key combination — so typing
theme narrows to the theme shortcut, and typing shift (or ) narrows to
every shortcut that uses Shift ("keypress search"). It:

  • filters case-insensitively across the registry-driven sections and the
    component-specific sections, hiding any section that has no remaining rows;
  • shows a "No results found" empty state when nothing matches;
  • has a clear (✕) button and clears on Esc;
  • mirrors the existing settings-navigator search styling (search icon, clear
    button, focus ring) for visual consistency.

Alternatives Considered

  • Label-only search: simpler, but it wouldn't satisfy the "find every
    shortcut that uses this key" use case that a keyboard-shortcuts reference is
    precisely for. Filtering on the rendered key tokens too (the <kbd> chips) is
    what makes it a real "keypress search."
  • Making shortcuts rebindable + a reset-all action (as Codex/VS Code also
    offer): larger and out of scope here — OpenWork's shortcuts are currently a
    fixed reference, so search is the high-value first step. Rebinding can be
    layered on later.
  • Command palette (Add a global command palette (⌘K / Ctrl+K) #42) already lets you run an action by searching, but
    it is a separate global surface; users looking at the shortcuts reference
    expect to filter the list they are looking at, the way the settings navigator
    already does.

Additional Context

Feasibility: frontend-only / doable. Verified against apps/electron — the
Shortcuts page is a pure renderer view over the centralized action registry
(actionsByCategory + useActionRegistry().getHotkeyDisplay), so filtering is
pure client-side React state. No backend / qwen-code change. No new i18n
keys
— the placeholder reuses common.search, the empty state reuses
common.noResultsFound, and the clear button reuses common.clear.

Acceptance criteria (CDP e2e assertion)

A new e2e/assertions/shortcuts-search.assert.ts drives the real built app over
CDP entirely in the draft (no-session) state — no seeded conversation and no
backend (the Shortcuts page is a pure registry view):

  1. Open Settings → Keyboard Shortcuts from the sidebar; the search box
    renders and the list shows more than one shortcut row.
  2. Type an action's label → the list narrows to exactly the predicted matches,
    every visible row actually contains the query, and the list shrinks.
  3. Type a key token read from a rendered <kbd> chip (e.g. /Ctrl) →
    the list narrows to exactly the rows that use that key, and every visible row
    contains it — proving key/"keypress" search works, not just label search.
  4. A no-match query (zzqqxxnomatchzzqqxx) shows the empty state and hides
    every row.
  5. Clearing the query restores the full list.

Part of the autonomous desktop-feature loop (loop-bot).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions