Skip to content

Conversation

@wanbok
Copy link

@wanbok wanbok commented Jan 3, 2026

feat: Support physical keycode-based keybindings for non-English keyboard layouts

Summary

Add support for physical key position matching in keybindings, enabling shortcuts to work correctly with non-English keyboard layouts (Korean, Japanese, Chinese, AZERTY, Dvorak, etc.).

Problem

When using non-English input methods, keybindings fail because OpenCode matches by character name:

  • User configures ctrl+x
  • In Korean mode, Ctrl + X key produces ctrl+ㅌ
  • Keybind doesn't match → shortcut fails

Solution

Leverage OpenTUI's existing Kitty keyboard protocol support (baseCode field) for physical key matching.

Changes

File Change
src/util/keybind.ts Add baseCode to Info type, update match() with MatchOptions
src/cli/cmd/tui/context/keybind.tsx Pass usePhysicalKeys config to match()
src/config/config.ts Add usePhysicalKeys keybind option
test/keybind.test.ts Add 18 tests for physical key matching

Usage

{
  "keybinds": {
    "usePhysicalKeys": true
  }
}

Compatibility

  • Opt-in: Default false for backward compatibility
  • Graceful fallback: Falls back to character matching when baseCode unavailable
  • Terminal support: Works with Kitty, Ghostty, WezTerm, iTerm2, Alacritty

Testing

Added tests for:

  • Physical key matching with Korean input (한글)
  • AZERTY layout simulation
  • Fallback behavior
  • Modifier key handling with physical keys
  • Leader key combinations

Related

  • Closes #XXXX (if issue exists)

Add support for physical key position matching in keybindings,
enabling shortcuts to work correctly with non-English keyboard
layouts (Korean, Japanese, Chinese, AZERTY, Dvorak, etc.).

- Add baseCode to Keybind.Info type
- Update Keybind.match() with usePhysicalKeys option
- Add usePhysicalKeys config option (opt-in, default false)
- Add 18 tests for physical key matching
- Graceful fallback for terminals without Kitty protocol
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