reservedShortcuts.ts
keybindings/reservedShortcuts.ts
No strong subsystem tag
128
Lines
3610
Bytes
6
Exports
1
Imports
10
Keywords
What this is
This page documents one file from the repository and includes its full source so you can read it without leaving the docs site.
Beginner explanation
This file is one piece of the larger system. Its name, directory, imports, and exports show where it fits. Start by reading the exports and related files first.
How it is used
Start from the exports list and related files. Those are the easiest clues for where this file fits into the system.
Expert explanation
Architecturally, this file intersects with general runtime concerns. It contains 128 lines, 1 detected imports, and 6 detected exports.
Important relationships
Detected exports
ReservedShortcutNON_REBINDABLETERMINAL_RESERVEDMACOS_RESERVEDgetReservedShortcutsnormalizeKeyForComparison
Keywords
reasonseverityctrllowershortcutsmacosmodifiersreservedshortcutpushplatform
Detected imports
../utils/platform.js
Source notes
This page embeds the full file contents. Small or leaf files are still indexed honestly instead of being over-explained.
Full source
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('+')
}