diff --git a/packages/cli/src/ui/contexts/KeypressContext.test.tsx b/packages/cli/src/ui/contexts/KeypressContext.test.tsx
index f5b303128b..d2107ff40b 100644
--- a/packages/cli/src/ui/contexts/KeypressContext.test.tsx
+++ b/packages/cli/src/ui/contexts/KeypressContext.test.tsx
@@ -956,127 +956,3 @@ describe('Drag and Drop Handling', () => {
});
});
});
-
-describe('Terminal-specific Alt+key combinations', () => {
- let stdin: MockStdin;
- const mockSetRawMode = vi.fn();
-
- const wrapper = ({ children }: { children: React.ReactNode }) => (
- {children}
- );
-
- beforeEach(() => {
- vi.clearAllMocks();
- stdin = new MockStdin();
- (useStdin as Mock).mockReturnValue({
- stdin,
- setRawMode: mockSetRawMode,
- });
- });
-
- // Terminals to test
- const terminals = ['iTerm2', 'Ghostty', 'MacTerminal', 'VSCodeTerminal'];
-
- // Key mappings: letter -> [keycode, accented character, shouldHaveMeta]
- // Note: µ (mu) is sent with meta:false on iTerm2/VSCode
- const keys: Record = {
- a: [97, 'å', true],
- o: [111, 'ø', true],
- m: [109, 'µ', false],
- };
-
- it.each(
- terminals.flatMap((terminal) =>
- Object.entries(keys).map(
- ([key, [keycode, accentedChar, shouldHaveMeta]]) => {
- if (terminal === 'Ghostty') {
- // Ghostty uses kitty protocol sequences
- return {
- terminal,
- key,
- kittySequence: `\x1b[${keycode};3u`,
- expected: {
- name: key,
- ctrl: false,
- meta: true,
- shift: false,
- paste: false,
- kittyProtocol: true,
- },
- };
- } else if (terminal === 'MacTerminal') {
- // Mac Terminal sends ESC + letter
- return {
- terminal,
- key,
- input: {
- sequence: `\x1b${key}`,
- name: key,
- ctrl: false,
- meta: true,
- shift: false,
- paste: false,
- },
- expected: {
- sequence: `\x1b${key}`,
- name: key,
- ctrl: false,
- meta: true,
- shift: false,
- paste: false,
- },
- };
- } else {
- // iTerm2 and VSCode send accented characters (å, ø, µ)
- // Note: µ comes with meta:false but gets converted to m with meta:true
- return {
- terminal,
- key,
- input: {
- name: key,
- ctrl: false,
- meta: shouldHaveMeta,
- shift: false,
- paste: false,
- sequence: accentedChar,
- },
- expected: {
- name: key,
- ctrl: false,
- meta: true, // Always expect meta:true after conversion
- shift: false,
- paste: false,
- sequence: accentedChar,
- },
- };
- }
- },
- ),
- ),
- )(
- 'should handle Alt+$key in $terminal',
- ({
- kittySequence,
- input,
- expected,
- }: {
- kittySequence?: string;
- input?: Partial;
- expected: Partial;
- }) => {
- const keyHandler = vi.fn();
- const { result } = renderHook(() => useKeypressContext(), { wrapper });
- act(() => result.current.subscribe(keyHandler));
-
- if (kittySequence) {
- act(() => stdin.sendKittySequence(kittySequence));
- } else if (input) {
- act(() => stdin.pressKey(input));
- }
-
- expect(keyHandler).toHaveBeenCalledWith(
- expect.objectContaining(expected),
- );
- },
- );
-});
diff --git a/packages/cli/src/ui/contexts/KeypressContext.tsx b/packages/cli/src/ui/contexts/KeypressContext.tsx
index b8b89dceeb..4930f7101d 100644
--- a/packages/cli/src/ui/contexts/KeypressContext.tsx
+++ b/packages/cli/src/ui/contexts/KeypressContext.tsx
@@ -45,36 +45,6 @@ export const DRAG_COMPLETION_TIMEOUT_MS = 100; // Broadcast full path after 100m
export const SINGLE_QUOTE = "'";
export const DOUBLE_QUOTE = '"';
-const ALT_KEY_CHARACTER_MAP: Record = {
- '\u00E5': 'a',
- '\u222B': 'b',
- '\u00E7': 'c',
- '\u2202': 'd',
- '\u00B4': 'e',
- '\u0192': 'f',
- '\u00A9': 'g',
- '\u02D9': 'h',
- '\u02C6': 'i',
- '\u2206': 'j',
- '\u02DA': 'k',
- '\u00AC': 'l',
- '\u00B5': 'm',
- '\u02DC': 'n',
- '\u00F8': 'o',
- '\u03C0': 'p',
- '\u0153': 'q',
- '\u00AE': 'r',
- '\u00DF': 's',
- '\u2020': 't',
- '\u00A8': 'u',
- '\u221A': 'v',
- '\u2211': 'w',
- '\u2248': 'x',
- '\u00A5': 'y',
- '\\': 'y',
- '\u03A9': 'z',
-};
-
export interface Key {
name: string;
ctrl: boolean;
@@ -357,9 +327,9 @@ export function KeypressProvider({
};
}
- // Ctrl+letters and Alt+letters
+ // Ctrl+letters
if (
- (ctrl || alt) &&
+ ctrl &&
keyCode >= 'a'.charCodeAt(0) &&
keyCode <= 'z'.charCodeAt(0)
) {
@@ -367,7 +337,7 @@ export function KeypressProvider({
return {
key: {
name: letter,
- ctrl,
+ ctrl: true,
meta: alt,
shift,
paste: false,
@@ -465,19 +435,6 @@ export function KeypressProvider({
return;
}
- const mappedLetter = ALT_KEY_CHARACTER_MAP[key.sequence];
- if (mappedLetter && !key.meta) {
- broadcast({
- name: mappedLetter,
- ctrl: false,
- meta: true,
- shift: false,
- paste: isPaste,
- sequence: key.sequence,
- });
- return;
- }
-
if (key.name === 'return' && waitingForEnterAfterBackslash) {
if (backslashTimeout) {
clearTimeout(backslashTimeout);