π File detail
keybindings/reservedShortcuts.ts
π§© .tsπ 128 linesπΎ 3,610 bytesπ text
β Back to All Filesπ― Use case
This file lives under βkeybindings/β, which covers keyboard shortcuts and binding tables. On the API surface it exposes ReservedShortcut, NON_REBINDABLE, TERMINAL_RESERVED, MACOS_RESERVED, and getReservedShortcuts (and more) β mainly types, interfaces, or factory objects. It composes internal code from utils (relative imports).
Generated from folder role, exports, dependency roots, and inline comments β not hand-reviewed for every path.
π§ Inline summary
import { getPlatform } from '../utils/platform.js' /** * Shortcuts that are typically intercepted by the OS, terminal, or shell * and will likely never reach the application.
π€ Exports (heuristic)
ReservedShortcutNON_REBINDABLETERMINAL_RESERVEDMACOS_RESERVEDgetReservedShortcutsnormalizeKeyForComparison
π₯οΈ Source preview
import { getPlatform } from '../utils/platform.js'
/**
* Shortcuts that are typically intercepted by the OS, terminal, or shell
* and will likely never reach the application.
*/
export type ReservedShortcut = {
key: string
reason: string
severity: 'error' | 'warning'
}
/**
* Shortcuts that cannot be rebound - they are hardcoded in Claude Code.
*/
export const NON_REBINDABLE: ReservedShortcut[] = [
{
key: 'ctrl+c',
reason: 'Cannot be rebound - used for interrupt/exit (hardcoded)',
severity: 'error',
},
{
key: 'ctrl+d',
reason: 'Cannot be rebound - used for exit (hardcoded)',
severity: 'error',
},
{
key: 'ctrl+m',
reason:
'Cannot be rebound - identical to Enter in terminals (both send CR)',
severity: 'error',
},
]
/**
* Terminal control shortcuts that are intercepted by the terminal/OS.
* These will likely never reach the application.
*
* Note: ctrl+s (XOFF) and ctrl+q (XON) are NOT included here because:
* - Most modern terminals disable flow control by default
* - We use ctrl+s for the stash feature
*/
export const TERMINAL_RESERVED: ReservedShortcut[] = [
{
key: 'ctrl+z',
reason: 'Unix process suspend (SIGTSTP)',
severity: 'warning',
},
{
key: 'ctrl+\\',
reason: 'Terminal quit signal (SIGQUIT)',
severity: 'error',
},
]
/**
* macOS-specific shortcuts that the OS intercepts.
*/
export const MACOS_RESERVED: ReservedShortcut[] = [
{ key: 'cmd+c', reason: 'macOS system copy', severity: 'error' },
{ key: 'cmd+v', reason: 'macOS system paste', severity: 'error' },
{ key: 'cmd+x', reason: 'macOS system cut', severity: 'error' },
{ key: 'cmd+q', reason: 'macOS quit application', severity: 'error' },
{ key: 'cmd+w', reason: 'macOS close window/tab', severity: 'error' },
{ key: 'cmd+tab', reason: 'macOS app switcher', severity: 'error' },
{ key: 'cmd+space', reason: 'macOS Spotlight', severity: 'error' },
]
/**
* Get all reserved shortcuts for the current platform.
* Includes non-rebindable shortcuts and terminal-reserved shortcuts.
*/
export function getReservedShortcuts(): ReservedShortcut[] {
const platform = getPlatform()
// Non-rebindable shortcuts first (highest priority)
const reserved = [...NON_REBINDABLE, ...TERMINAL_RESERVED]
if (platform === 'macos') {
reserved.push(...MACOS_RESERVED)
}
return reserved
}
/**
* Normalize a key string for comparison (lowercase, sorted modifiers).
* Chords (space-separated steps like "ctrl+x ctrl+b") are normalized
* per-step β splitting on '+' first would mangle "x ctrl" into a mainKey
* overwritten by the next step, collapsing the chord into its last key.
*/
export function normalizeKeyForComparison(key: string): string {
return key.trim().split(/\s+/).map(normalizeStep).join(' ')
}
function normalizeStep(step: string): string {
const parts = step.split('+')
const modifiers: string[] = []
let mainKey = ''
for (const part of parts) {
const lower = part.trim().toLowerCase()
if (
[
'ctrl',
'control',
'alt',
'opt',
'option',
'meta',
'cmd',
'command',
'shift',
].includes(lower)
) {
// Normalize modifier names
if (lower === 'control') modifiers.push('ctrl')
else if (lower === 'option' || lower === 'opt') modifiers.push('alt')
else if (lower === 'command' || lower === 'cmd') modifiers.push('cmd')
else modifiers.push(lower)
} else {
mainKey = lower
}
}
modifiers.sort()
return [...modifiers, mainKey].join('+')
}