Skip to content

File picker alt+h / alt+i shortcuts not working on macOS inside sbx — Option key intercepted before reaching the sandbox #2611

@steilerDev

Description

@steilerDev

Summary

The file picker shortcuts for toggling hidden files (alt+h) and ignored files (alt+i) are silently inoperative when running in sbx, regardless of keyboard layout.

Environment

  • Host OS: macOS (any version, any keyboard layout)
  • Terminal: Terminal.app, GhosTTY (but probably others too)
  • Agent: Running inside Docker sandbox via sbx run

Steps to Reproduce

  1. Start the agent on macOS
  2. Trigger a file picker prompt
  3. Press Option+H or Option+I
  4. Observe that hidden/ignored file visibility does not toggle

Root Cause

On macOS, the OS intercepts Option+key combinations at the input system level — across all keyboard layouts — and substitutes Unicode characters before the terminal emulator ever receives the event. The terminal therefore sends UTF-8 bytes, not ESC+letter sequences.

Key combo What a Linux terminal sends What macOS actually sends
Option+H ESC h → decoded as alt+h ˙ (U+02D9)
Option+I ESC i → decoded as alt+i ˆ (U+02C6, dead key)

This is not specific to US International PC — the standard US layout produces the same characters. Every macOS keyboard layout uses Option as a compose/AltGr layer. The only exception is users who have explicitly enabled "Use Option as Meta key" in their terminal preferences, which breaks Option-layer character input for those users.

The Kitty keyboard protocol cannot help here: the OS-level substitution happens before the bytes reach the terminal, regardless of protocol.

In pkg/tui/dialog/file_picker.go, the current detection:

case msg.String() == "alt+h":
    d.toggleHidden()
case msg.String() == "alt+i":
    d.toggleIgnored()

…never matches because msg.String() returns "˙" / "ˆ" instead.

Why Ctrl and Cmd Don't Fix This

ctrl+h / ctrl+i — not viable. These are hardwired at the ASCII level: Ctrl+H = 0x08 (Backspace) and Ctrl+I = 0x09 (Tab). They cannot be distinguished from the Backspace and Tab keys in a standard terminal, and both are almost certainly already used by the file picker for navigation.

cmd+key — not viable. The Command key is intercepted by the macOS GUI event loop and is never written into the PTY input stream. It never reaches a process running in a terminal, Docker container, or SSH session.

Proposed Fix

Option A — Change to shortcuts with established prior art (recommended)

Replace alt+h / alt+i with modifier-free keys that the TUI file picker community has already converged on:

  • . (period) for toggle hidden — directly mirrors the dotfile convention; used by fzf, lf, ranger, broot, and macOS Finder (⌘⇧.). Highly discoverable.
  • ! or I (uppercase) for toggle ignored — conveys negation/exception semantically, no modifier ambiguity.

This approach is cross-platform, needs no dead-key workarounds, and is immediately intuitive to users familiar with Unix dotfiles.

Option B — Also accept the Unicode characters macOS actually sends

Keep alt+h / alt+i as the primary bindings (for Linux terminals and macOS users with "Option as Meta" enabled) and add the macOS-produced characters as aliases, using key.NewBinding() to follow the existing pickerKeyMap style:

// "˙" (U+02D9) = macOS Option+H; "ˆ" (U+02C6) = macOS Option+I
ToggleHidden:  key.NewBinding(key.WithKeys("alt+h", "˙"), key.WithHelp("alt+h", "toggle hidden"))
ToggleIgnored: key.NewBinding(key.WithKeys("alt+i", "ˆ"), key.WithHelp("alt+i", "toggle ignored"))

This is backward-compatible but hardcodes one specific character per layout — other national keyboard layouts produce different Unicode characters for Option+H/I, so this only fully fixes standard US and US International PC.

Option A is the cleaner long-term fix. Option B can be applied immediately as a low-risk patch while Option A is discussed.

Workaround

Until fixed, macOS users can:

  • Enable "Use Option as Meta key" in their terminal preferences (Terminal.app: Preferences → Profiles → Keyboard; iTerm2: Profiles → Keys → Left Option Key → Esc+). Note this disables Option-layer character input.
  • Supply the path directly using the @path/to/file argument syntax to bypass the file picker entirely.

References

Metadata

Metadata

Assignees

Labels

area/tuiFor features/issues/fixes related to the TUIeffort:smallIsolated change, clear solution, single areapriority:mediumNormal priority, standard sprint work

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions