Merge pull request #98 from Vasanthdev2004/windows-csiu-input-fix
fix: support CSI-u printable input on Windows
This commit is contained in:
49
src/ink/parse-keypress.test.ts
Normal file
49
src/ink/parse-keypress.test.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { expect, test } from 'bun:test'
|
||||
|
||||
import {
|
||||
INITIAL_STATE,
|
||||
parseMultipleKeypresses,
|
||||
type ParsedKey,
|
||||
} from './parse-keypress.ts'
|
||||
import { InputEvent } from './events/input-event.ts'
|
||||
|
||||
function parseInputEvent(sequence: string): InputEvent {
|
||||
const [items] = parseMultipleKeypresses(INITIAL_STATE, sequence)
|
||||
|
||||
expect(items).toHaveLength(1)
|
||||
|
||||
const item = items[0]
|
||||
expect(item?.kind).toBe('key')
|
||||
|
||||
return new InputEvent(item as ParsedKey)
|
||||
}
|
||||
|
||||
test('treats CSI-u modifier 0 as unmodified printable input', () => {
|
||||
const event = parseInputEvent('\x1b[47;0u')
|
||||
|
||||
expect(event.input).toBe('/')
|
||||
expect(event.key.ctrl).toBe(false)
|
||||
expect(event.key.meta).toBe(false)
|
||||
expect(event.key.shift).toBe(false)
|
||||
expect(event.key.super).toBe(false)
|
||||
})
|
||||
|
||||
test('preserves printable Unicode CSI-u input', () => {
|
||||
const event = parseInputEvent('\x1b[231u')
|
||||
|
||||
expect(event.input).toBe('ç')
|
||||
expect(event.key.ctrl).toBe(false)
|
||||
expect(event.key.meta).toBe(false)
|
||||
expect(event.key.shift).toBe(false)
|
||||
expect(event.key.super).toBe(false)
|
||||
})
|
||||
|
||||
test('preserves printable Unicode CSI-u input with explicit modifier 0', () => {
|
||||
const event = parseInputEvent('\x1b[231;0u')
|
||||
|
||||
expect(event.input).toBe('ç')
|
||||
expect(event.key.ctrl).toBe(false)
|
||||
expect(event.key.meta).toBe(false)
|
||||
expect(event.key.shift).toBe(false)
|
||||
expect(event.key.super).toBe(false)
|
||||
})
|
||||
@@ -468,7 +468,10 @@ function decodeModifier(modifier: number): {
|
||||
ctrl: boolean
|
||||
super: boolean
|
||||
} {
|
||||
const m = modifier - 1
|
||||
// Some Windows VT stacks use 0 instead of 1 for an unmodified CSI-u key.
|
||||
// Clamp to the protocol default so plain printable keys don't look like
|
||||
// ctrl+meta+shift+super all at once.
|
||||
const m = Math.max(modifier, 1) - 1
|
||||
return {
|
||||
shift: !!(m & 1),
|
||||
meta: !!(m & 2),
|
||||
@@ -477,6 +480,14 @@ function decodeModifier(modifier: number): {
|
||||
}
|
||||
}
|
||||
|
||||
function isPrivateUseCodepoint(codepoint: number): boolean {
|
||||
return (
|
||||
(codepoint >= 0xe000 && codepoint <= 0xf8ff) ||
|
||||
(codepoint >= 0xf0000 && codepoint <= 0xffffd) ||
|
||||
(codepoint >= 0x100000 && codepoint <= 0x10fffd)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Map keycode to key name for modifyOtherKeys/CSI u sequences.
|
||||
* Handles both ASCII keycodes and Kitty keyboard protocol functional keys.
|
||||
@@ -536,6 +547,21 @@ function keycodeToName(keycode: number): string | undefined {
|
||||
if (keycode >= 32 && keycode <= 126) {
|
||||
return String.fromCharCode(keycode).toLowerCase()
|
||||
}
|
||||
|
||||
// CSI-u can carry printable Unicode codepoints directly on some
|
||||
// Windows terminals and keyboard layouts. Keep kitty's private-use
|
||||
// functional key range excluded so special keys still stay non-text.
|
||||
if (
|
||||
keycode > 0x1f &&
|
||||
keycode !== 0x7f &&
|
||||
(keycode < 0x80 || keycode > 0x9f) &&
|
||||
keycode <= 0x10ffff &&
|
||||
(keycode < 0xd800 || keycode > 0xdfff) &&
|
||||
!isPrivateUseCodepoint(keycode)
|
||||
) {
|
||||
return String.fromCodePoint(keycode)
|
||||
}
|
||||
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user