@draht/tui 2026.5.12 → 2026.7.7-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/autocomplete.d.ts +5 -1
- package/dist/autocomplete.d.ts.map +1 -1
- package/dist/autocomplete.js +16 -7
- package/dist/autocomplete.js.map +1 -1
- package/dist/components/box.d.ts +1 -1
- package/dist/components/box.d.ts.map +1 -1
- package/dist/components/box.js.map +1 -1
- package/dist/components/cancellable-loader.d.ts +1 -1
- package/dist/components/cancellable-loader.d.ts.map +1 -1
- package/dist/components/cancellable-loader.js.map +1 -1
- package/dist/components/editor.d.ts +14 -3
- package/dist/components/editor.d.ts.map +1 -1
- package/dist/components/editor.js +234 -175
- package/dist/components/editor.js.map +1 -1
- package/dist/components/image.d.ts +2 -2
- package/dist/components/image.d.ts.map +1 -1
- package/dist/components/image.js +31 -11
- package/dist/components/image.js.map +1 -1
- package/dist/components/input.d.ts +1 -1
- package/dist/components/input.d.ts.map +1 -1
- package/dist/components/input.js +7 -55
- package/dist/components/input.js.map +1 -1
- package/dist/components/loader.d.ts +17 -7
- package/dist/components/loader.d.ts.map +1 -1
- package/dist/components/loader.js +34 -14
- package/dist/components/loader.js.map +1 -1
- package/dist/components/markdown.d.ts +11 -7
- package/dist/components/markdown.d.ts.map +1 -1
- package/dist/components/markdown.js +119 -102
- package/dist/components/markdown.js.map +1 -1
- package/dist/components/select-list.d.ts +1 -1
- package/dist/components/select-list.d.ts.map +1 -1
- package/dist/components/select-list.js.map +1 -1
- package/dist/components/settings-list.d.ts +1 -1
- package/dist/components/settings-list.d.ts.map +1 -1
- package/dist/components/settings-list.js.map +1 -1
- package/dist/components/spacer.d.ts +1 -1
- package/dist/components/spacer.d.ts.map +1 -1
- package/dist/components/spacer.js.map +1 -1
- package/dist/components/text.d.ts +1 -1
- package/dist/components/text.d.ts.map +1 -1
- package/dist/components/text.js.map +1 -1
- package/dist/components/truncated-text.d.ts +1 -1
- package/dist/components/truncated-text.d.ts.map +1 -1
- package/dist/components/truncated-text.js.map +1 -1
- package/dist/editor-component.d.ts +2 -2
- package/dist/editor-component.d.ts.map +1 -1
- package/dist/editor-component.js.map +1 -1
- package/dist/fuzzy.d.ts +1 -1
- package/dist/fuzzy.d.ts.map +1 -1
- package/dist/fuzzy.js +5 -2
- package/dist/fuzzy.js.map +1 -1
- package/dist/index.d.ts +23 -22
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/keybindings.d.ts +2 -2
- package/dist/keybindings.d.ts.map +1 -1
- package/dist/keybindings.js +1 -1
- package/dist/keybindings.js.map +1 -1
- package/dist/keys.d.ts +19 -5
- package/dist/keys.d.ts.map +1 -1
- package/dist/keys.js +82 -33
- package/dist/keys.js.map +1 -1
- package/dist/native-modifiers.d.ts +3 -0
- package/dist/native-modifiers.d.ts.map +1 -0
- package/dist/native-modifiers.js +53 -0
- package/dist/native-modifiers.js.map +1 -0
- package/dist/stdin-buffer.d.ts +2 -0
- package/dist/stdin-buffer.d.ts.map +1 -1
- package/dist/stdin-buffer.js +48 -4
- package/dist/stdin-buffer.js.map +1 -1
- package/dist/terminal-colors.d.ts +10 -0
- package/dist/terminal-colors.d.ts.map +1 -0
- package/dist/terminal-colors.js +59 -0
- package/dist/terminal-colors.js.map +1 -0
- package/dist/terminal-image.d.ts +23 -1
- package/dist/terminal-image.d.ts.map +1 -1
- package/dist/terminal-image.js +98 -16
- package/dist/terminal-image.js.map +1 -1
- package/dist/terminal.d.ts +36 -10
- package/dist/terminal.d.ts.map +1 -1
- package/dist/terminal.js +212 -64
- package/dist/terminal.js.map +1 -1
- package/dist/tui.d.ts +51 -5
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +431 -32
- package/dist/tui.js.map +1 -1
- package/dist/utils.d.ts +8 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +143 -43
- package/dist/utils.js.map +1 -1
- package/dist/word-navigation.d.ts +25 -0
- package/dist/word-navigation.d.ts.map +1 -0
- package/dist/word-navigation.js +96 -0
- package/dist/word-navigation.js.map +1 -0
- package/package.json +1 -1
package/dist/keys.js
CHANGED
|
@@ -40,8 +40,8 @@ export function isKittyProtocolActive() {
|
|
|
40
40
|
* Usage:
|
|
41
41
|
* - Key.escape, Key.enter, Key.tab, etc. for special keys
|
|
42
42
|
* - Key.backtick, Key.comma, Key.period, etc. for symbol keys
|
|
43
|
-
* - Key.ctrl("c"), Key.alt("x") for single
|
|
44
|
-
* - Key.ctrlShift("p"), Key.ctrlAlt("x") for combined modifiers
|
|
43
|
+
* - Key.ctrl("c"), Key.alt("x"), Key.super("k") for single modifiers
|
|
44
|
+
* - Key.ctrlShift("p"), Key.ctrlAlt("x"), Key.ctrlSuper("k") for combined modifiers
|
|
45
45
|
*/
|
|
46
46
|
export const Key = {
|
|
47
47
|
// Special keys
|
|
@@ -111,6 +111,7 @@ export const Key = {
|
|
|
111
111
|
ctrl: (key) => `ctrl+${key}`,
|
|
112
112
|
shift: (key) => `shift+${key}`,
|
|
113
113
|
alt: (key) => `alt+${key}`,
|
|
114
|
+
super: (key) => `super+${key}`,
|
|
114
115
|
// Combined modifiers
|
|
115
116
|
ctrlShift: (key) => `ctrl+shift+${key}`,
|
|
116
117
|
shiftCtrl: (key) => `shift+ctrl+${key}`,
|
|
@@ -118,8 +119,15 @@ export const Key = {
|
|
|
118
119
|
altCtrl: (key) => `alt+ctrl+${key}`,
|
|
119
120
|
shiftAlt: (key) => `shift+alt+${key}`,
|
|
120
121
|
altShift: (key) => `alt+shift+${key}`,
|
|
122
|
+
ctrlSuper: (key) => `ctrl+super+${key}`,
|
|
123
|
+
superCtrl: (key) => `super+ctrl+${key}`,
|
|
124
|
+
shiftSuper: (key) => `shift+super+${key}`,
|
|
125
|
+
superShift: (key) => `super+shift+${key}`,
|
|
126
|
+
altSuper: (key) => `alt+super+${key}`,
|
|
127
|
+
superAlt: (key) => `super+alt+${key}`,
|
|
121
128
|
// Triple modifiers
|
|
122
129
|
ctrlShiftAlt: (key) => `ctrl+shift+alt+${key}`,
|
|
130
|
+
ctrlShiftSuper: (key) => `ctrl+shift+super+${key}`,
|
|
123
131
|
};
|
|
124
132
|
// =============================================================================
|
|
125
133
|
// Constants
|
|
@@ -161,6 +169,7 @@ const MODIFIERS = {
|
|
|
161
169
|
shift: 1,
|
|
162
170
|
alt: 2,
|
|
163
171
|
ctrl: 4,
|
|
172
|
+
super: 8,
|
|
164
173
|
};
|
|
165
174
|
const LOCK_MASK = 64 + 128; // Caps Lock + Num Lock
|
|
166
175
|
const CODEPOINTS = {
|
|
@@ -217,6 +226,13 @@ const KITTY_FUNCTIONAL_KEY_EQUIVALENTS = new Map([
|
|
|
217
226
|
function normalizeKittyFunctionalCodepoint(codepoint) {
|
|
218
227
|
return KITTY_FUNCTIONAL_KEY_EQUIVALENTS.get(codepoint) ?? codepoint;
|
|
219
228
|
}
|
|
229
|
+
function normalizeShiftedLetterIdentityCodepoint(codepoint, modifier) {
|
|
230
|
+
const effectiveModifier = modifier & ~LOCK_MASK;
|
|
231
|
+
if ((effectiveModifier & MODIFIERS.shift) !== 0 && codepoint >= 65 && codepoint <= 90) {
|
|
232
|
+
return codepoint + 32;
|
|
233
|
+
}
|
|
234
|
+
return codepoint;
|
|
235
|
+
}
|
|
220
236
|
const LEGACY_KEY_SEQUENCES = {
|
|
221
237
|
up: ["\x1b[A", "\x1bOA"],
|
|
222
238
|
down: ["\x1b[B", "\x1bOB"],
|
|
@@ -468,8 +484,8 @@ function matchesKittySequence(data, expectedCodepoint, expectedModifier) {
|
|
|
468
484
|
// Check if modifiers match
|
|
469
485
|
if (actualMod !== expectedMod)
|
|
470
486
|
return false;
|
|
471
|
-
const normalizedCodepoint = normalizeKittyFunctionalCodepoint(parsed.codepoint);
|
|
472
|
-
const normalizedExpectedCodepoint = normalizeKittyFunctionalCodepoint(expectedCodepoint);
|
|
487
|
+
const normalizedCodepoint = normalizeShiftedLetterIdentityCodepoint(normalizeKittyFunctionalCodepoint(parsed.codepoint), parsed.modifier);
|
|
488
|
+
const normalizedExpectedCodepoint = normalizeShiftedLetterIdentityCodepoint(normalizeKittyFunctionalCodepoint(expectedCodepoint), expectedModifier);
|
|
473
489
|
// Primary match: codepoint matches directly after normalizing functional keys
|
|
474
490
|
if (normalizedCodepoint === normalizedExpectedCodepoint)
|
|
475
491
|
return true;
|
|
@@ -562,12 +578,16 @@ function isDigitKey(key) {
|
|
|
562
578
|
function matchesPrintableModifyOtherKeys(data, expectedKeycode, expectedModifier) {
|
|
563
579
|
if (expectedModifier === 0)
|
|
564
580
|
return false;
|
|
565
|
-
|
|
581
|
+
const parsed = parseModifyOtherKeysSequence(data);
|
|
582
|
+
if (!parsed || parsed.modifier !== expectedModifier)
|
|
583
|
+
return false;
|
|
584
|
+
return (normalizeShiftedLetterIdentityCodepoint(parsed.codepoint, parsed.modifier) ===
|
|
585
|
+
normalizeShiftedLetterIdentityCodepoint(expectedKeycode, expectedModifier));
|
|
566
586
|
}
|
|
567
587
|
function formatKeyNameWithModifiers(keyName, modifier) {
|
|
568
588
|
const mods = [];
|
|
569
589
|
const effectiveMod = modifier & ~LOCK_MASK;
|
|
570
|
-
const supportedModifierMask = MODIFIERS.shift | MODIFIERS.ctrl | MODIFIERS.alt;
|
|
590
|
+
const supportedModifierMask = MODIFIERS.shift | MODIFIERS.ctrl | MODIFIERS.alt | MODIFIERS.super;
|
|
571
591
|
if ((effectiveMod & ~supportedModifierMask) !== 0)
|
|
572
592
|
return undefined;
|
|
573
593
|
if (effectiveMod & MODIFIERS.shift)
|
|
@@ -576,6 +596,8 @@ function formatKeyNameWithModifiers(keyName, modifier) {
|
|
|
576
596
|
mods.push("ctrl");
|
|
577
597
|
if (effectiveMod & MODIFIERS.alt)
|
|
578
598
|
mods.push("alt");
|
|
599
|
+
if (effectiveMod & MODIFIERS.super)
|
|
600
|
+
mods.push("super");
|
|
579
601
|
return mods.length > 0 ? `${mods.join("+")}+${keyName}` : keyName;
|
|
580
602
|
}
|
|
581
603
|
function parseKeyId(keyId) {
|
|
@@ -588,6 +610,7 @@ function parseKeyId(keyId) {
|
|
|
588
610
|
ctrl: parts.includes("ctrl"),
|
|
589
611
|
shift: parts.includes("shift"),
|
|
590
612
|
alt: parts.includes("alt"),
|
|
613
|
+
super: parts.includes("super"),
|
|
591
614
|
};
|
|
592
615
|
}
|
|
593
616
|
/**
|
|
@@ -599,9 +622,10 @@ function parseKeyId(keyId) {
|
|
|
599
622
|
* - Ctrl combinations: "ctrl+c", "ctrl+z", etc.
|
|
600
623
|
* - Shift combinations: "shift+tab", "shift+enter"
|
|
601
624
|
* - Alt combinations: "alt+enter", "alt+backspace"
|
|
602
|
-
* -
|
|
625
|
+
* - Super combinations: "super+k", "super+enter"
|
|
626
|
+
* - Combined modifiers: "shift+ctrl+p", "ctrl+alt+x", "ctrl+super+k"
|
|
603
627
|
*
|
|
604
|
-
* Use the Key helper for autocomplete: Key.ctrl("c"), Key.escape, Key.ctrlShift("p")
|
|
628
|
+
* Use the Key helper for autocomplete: Key.ctrl("c"), Key.escape, Key.ctrlShift("p"), Key.super("k")
|
|
605
629
|
*
|
|
606
630
|
* @param data - Raw input data from terminal
|
|
607
631
|
* @param keyId - Key identifier (e.g., "ctrl+c", "escape", Key.ctrl("c"))
|
|
@@ -610,7 +634,7 @@ export function matchesKey(data, keyId) {
|
|
|
610
634
|
const parsed = parseKeyId(keyId);
|
|
611
635
|
if (!parsed)
|
|
612
636
|
return false;
|
|
613
|
-
const { key, ctrl, shift, alt } = parsed;
|
|
637
|
+
const { key, ctrl, shift, alt, super: superModifier } = parsed;
|
|
614
638
|
let modifier = 0;
|
|
615
639
|
if (shift)
|
|
616
640
|
modifier |= MODIFIERS.shift;
|
|
@@ -618,6 +642,8 @@ export function matchesKey(data, keyId) {
|
|
|
618
642
|
modifier |= MODIFIERS.alt;
|
|
619
643
|
if (ctrl)
|
|
620
644
|
modifier |= MODIFIERS.ctrl;
|
|
645
|
+
if (superModifier)
|
|
646
|
+
modifier |= MODIFIERS.super;
|
|
621
647
|
switch (key) {
|
|
622
648
|
case "escape":
|
|
623
649
|
case "esc":
|
|
@@ -628,10 +654,10 @@ export function matchesKey(data, keyId) {
|
|
|
628
654
|
matchesModifyOtherKeys(data, CODEPOINTS.escape, 0));
|
|
629
655
|
case "space":
|
|
630
656
|
if (!_kittyProtocolActive) {
|
|
631
|
-
if (
|
|
657
|
+
if (modifier === MODIFIERS.ctrl && data === "\x00") {
|
|
632
658
|
return true;
|
|
633
659
|
}
|
|
634
|
-
if (
|
|
660
|
+
if (modifier === MODIFIERS.alt && data === "\x1b ") {
|
|
635
661
|
return true;
|
|
636
662
|
}
|
|
637
663
|
}
|
|
@@ -643,7 +669,7 @@ export function matchesKey(data, keyId) {
|
|
|
643
669
|
return (matchesKittySequence(data, CODEPOINTS.space, modifier) ||
|
|
644
670
|
matchesModifyOtherKeys(data, CODEPOINTS.space, modifier));
|
|
645
671
|
case "tab":
|
|
646
|
-
if (
|
|
672
|
+
if (modifier === MODIFIERS.shift) {
|
|
647
673
|
return (data === "\x1b[Z" ||
|
|
648
674
|
matchesKittySequence(data, CODEPOINTS.tab, MODIFIERS.shift) ||
|
|
649
675
|
matchesModifyOtherKeys(data, CODEPOINTS.tab, MODIFIERS.shift));
|
|
@@ -655,7 +681,7 @@ export function matchesKey(data, keyId) {
|
|
|
655
681
|
matchesModifyOtherKeys(data, CODEPOINTS.tab, modifier));
|
|
656
682
|
case "enter":
|
|
657
683
|
case "return":
|
|
658
|
-
if (
|
|
684
|
+
if (modifier === MODIFIERS.shift) {
|
|
659
685
|
// CSI u sequences (standard Kitty protocol)
|
|
660
686
|
if (matchesKittySequence(data, CODEPOINTS.enter, MODIFIERS.shift) ||
|
|
661
687
|
matchesKittySequence(data, CODEPOINTS.kpEnter, MODIFIERS.shift)) {
|
|
@@ -673,7 +699,7 @@ export function matchesKey(data, keyId) {
|
|
|
673
699
|
}
|
|
674
700
|
return false;
|
|
675
701
|
}
|
|
676
|
-
if (
|
|
702
|
+
if (modifier === MODIFIERS.alt) {
|
|
677
703
|
// CSI u sequences (standard Kitty protocol)
|
|
678
704
|
if (matchesKittySequence(data, CODEPOINTS.enter, MODIFIERS.alt) ||
|
|
679
705
|
matchesKittySequence(data, CODEPOINTS.kpEnter, MODIFIERS.alt)) {
|
|
@@ -701,14 +727,14 @@ export function matchesKey(data, keyId) {
|
|
|
701
727
|
matchesKittySequence(data, CODEPOINTS.kpEnter, modifier) ||
|
|
702
728
|
matchesModifyOtherKeys(data, CODEPOINTS.enter, modifier));
|
|
703
729
|
case "backspace":
|
|
704
|
-
if (
|
|
730
|
+
if (modifier === MODIFIERS.alt) {
|
|
705
731
|
if (data === "\x1b\x7f" || data === "\x1b\b") {
|
|
706
732
|
return true;
|
|
707
733
|
}
|
|
708
734
|
return (matchesKittySequence(data, CODEPOINTS.backspace, MODIFIERS.alt) ||
|
|
709
735
|
matchesModifyOtherKeys(data, CODEPOINTS.backspace, MODIFIERS.alt));
|
|
710
736
|
}
|
|
711
|
-
if (
|
|
737
|
+
if (modifier === MODIFIERS.ctrl) {
|
|
712
738
|
// Legacy raw 0x08 is ambiguous: it can be Ctrl+Backspace on Windows
|
|
713
739
|
// Terminal or plain Backspace on other terminals, while also
|
|
714
740
|
// overlapping with Ctrl+H.
|
|
@@ -784,7 +810,7 @@ export function matchesKey(data, keyId) {
|
|
|
784
810
|
}
|
|
785
811
|
return matchesKittySequence(data, FUNCTIONAL_CODEPOINTS.pageDown, modifier);
|
|
786
812
|
case "up":
|
|
787
|
-
if (
|
|
813
|
+
if (modifier === MODIFIERS.alt) {
|
|
788
814
|
return data === "\x1bp" || matchesKittySequence(data, ARROW_CODEPOINTS.up, MODIFIERS.alt);
|
|
789
815
|
}
|
|
790
816
|
if (modifier === 0) {
|
|
@@ -796,7 +822,7 @@ export function matchesKey(data, keyId) {
|
|
|
796
822
|
}
|
|
797
823
|
return matchesKittySequence(data, ARROW_CODEPOINTS.up, modifier);
|
|
798
824
|
case "down":
|
|
799
|
-
if (
|
|
825
|
+
if (modifier === MODIFIERS.alt) {
|
|
800
826
|
return data === "\x1bn" || matchesKittySequence(data, ARROW_CODEPOINTS.down, MODIFIERS.alt);
|
|
801
827
|
}
|
|
802
828
|
if (modifier === 0) {
|
|
@@ -808,13 +834,13 @@ export function matchesKey(data, keyId) {
|
|
|
808
834
|
}
|
|
809
835
|
return matchesKittySequence(data, ARROW_CODEPOINTS.down, modifier);
|
|
810
836
|
case "left":
|
|
811
|
-
if (
|
|
837
|
+
if (modifier === MODIFIERS.alt) {
|
|
812
838
|
return (data === "\x1b[1;3D" ||
|
|
813
839
|
(!_kittyProtocolActive && data === "\x1bB") ||
|
|
814
840
|
data === "\x1bb" ||
|
|
815
841
|
matchesKittySequence(data, ARROW_CODEPOINTS.left, MODIFIERS.alt));
|
|
816
842
|
}
|
|
817
|
-
if (
|
|
843
|
+
if (modifier === MODIFIERS.ctrl) {
|
|
818
844
|
return (data === "\x1b[1;5D" ||
|
|
819
845
|
matchesLegacyModifierSequence(data, "left", MODIFIERS.ctrl) ||
|
|
820
846
|
matchesKittySequence(data, ARROW_CODEPOINTS.left, MODIFIERS.ctrl));
|
|
@@ -828,13 +854,13 @@ export function matchesKey(data, keyId) {
|
|
|
828
854
|
}
|
|
829
855
|
return matchesKittySequence(data, ARROW_CODEPOINTS.left, modifier);
|
|
830
856
|
case "right":
|
|
831
|
-
if (
|
|
857
|
+
if (modifier === MODIFIERS.alt) {
|
|
832
858
|
return (data === "\x1b[1;3C" ||
|
|
833
859
|
(!_kittyProtocolActive && data === "\x1bF") ||
|
|
834
860
|
data === "\x1bf" ||
|
|
835
861
|
matchesKittySequence(data, ARROW_CODEPOINTS.right, MODIFIERS.alt));
|
|
836
862
|
}
|
|
837
|
-
if (
|
|
863
|
+
if (modifier === MODIFIERS.ctrl) {
|
|
838
864
|
return (data === "\x1b[1;5C" ||
|
|
839
865
|
matchesLegacyModifierSequence(data, "right", MODIFIERS.ctrl) ||
|
|
840
866
|
matchesKittySequence(data, ARROW_CODEPOINTS.right, MODIFIERS.ctrl));
|
|
@@ -872,27 +898,30 @@ export function matchesKey(data, keyId) {
|
|
|
872
898
|
const rawCtrl = rawCtrlChar(key);
|
|
873
899
|
const isLetter = key >= "a" && key <= "z";
|
|
874
900
|
const isDigit = isDigitKey(key);
|
|
875
|
-
if (ctrl
|
|
876
|
-
// Legacy: ctrl+alt+key is ESC followed by the control character
|
|
877
|
-
|
|
901
|
+
if (modifier === MODIFIERS.ctrl + MODIFIERS.alt && !_kittyProtocolActive && rawCtrl) {
|
|
902
|
+
// Legacy: ctrl+alt+key is ESC followed by the control character.
|
|
903
|
+
// If that legacy form does not match, continue so CSI-u and
|
|
904
|
+
// modifyOtherKeys sequences from tmux can still be recognized.
|
|
905
|
+
if (data === `\x1b${rawCtrl}`)
|
|
906
|
+
return true;
|
|
878
907
|
}
|
|
879
|
-
if (
|
|
908
|
+
if (modifier === MODIFIERS.alt && !_kittyProtocolActive && (isLetter || isDigit)) {
|
|
880
909
|
// Legacy: alt+letter/digit is ESC followed by the key
|
|
881
910
|
if (data === `\x1b${key}`)
|
|
882
911
|
return true;
|
|
883
912
|
}
|
|
884
|
-
if (
|
|
913
|
+
if (modifier === MODIFIERS.ctrl) {
|
|
885
914
|
// Legacy: ctrl+key sends the control character
|
|
886
915
|
if (rawCtrl && data === rawCtrl)
|
|
887
916
|
return true;
|
|
888
917
|
return (matchesKittySequence(data, codepoint, MODIFIERS.ctrl) ||
|
|
889
918
|
matchesPrintableModifyOtherKeys(data, codepoint, MODIFIERS.ctrl));
|
|
890
919
|
}
|
|
891
|
-
if (
|
|
920
|
+
if (modifier === MODIFIERS.shift + MODIFIERS.ctrl) {
|
|
892
921
|
return (matchesKittySequence(data, codepoint, MODIFIERS.shift + MODIFIERS.ctrl) ||
|
|
893
922
|
matchesPrintableModifyOtherKeys(data, codepoint, MODIFIERS.shift + MODIFIERS.ctrl));
|
|
894
923
|
}
|
|
895
|
-
if (
|
|
924
|
+
if (modifier === MODIFIERS.shift) {
|
|
896
925
|
// Legacy: shift+letter produces uppercase
|
|
897
926
|
if (isLetter && data === key.toUpperCase())
|
|
898
927
|
return true;
|
|
@@ -916,15 +945,16 @@ export function matchesKey(data, keyId) {
|
|
|
916
945
|
*/
|
|
917
946
|
function formatParsedKey(codepoint, modifier, baseLayoutKey) {
|
|
918
947
|
const normalizedCodepoint = normalizeKittyFunctionalCodepoint(codepoint);
|
|
948
|
+
const identityCodepoint = normalizeShiftedLetterIdentityCodepoint(normalizedCodepoint, modifier);
|
|
919
949
|
// Use base layout key only when codepoint is not a recognized Latin
|
|
920
950
|
// letter (a-z), digit (0-9), or symbol (/, -, [, ;, etc.). For those,
|
|
921
951
|
// the codepoint is authoritative regardless of physical key position.
|
|
922
952
|
// This prevents remapped layouts (Dvorak, Colemak, xremap, etc.) from
|
|
923
953
|
// reporting the wrong key name based on the QWERTY physical position.
|
|
924
|
-
const isLatinLetter =
|
|
925
|
-
const isDigit =
|
|
926
|
-
const isKnownSymbol = SYMBOL_KEYS.has(String.fromCharCode(
|
|
927
|
-
const effectiveCodepoint = isLatinLetter || isDigit || isKnownSymbol ?
|
|
954
|
+
const isLatinLetter = identityCodepoint >= 97 && identityCodepoint <= 122; // a-z
|
|
955
|
+
const isDigit = identityCodepoint >= 48 && identityCodepoint <= 57; // 0-9
|
|
956
|
+
const isKnownSymbol = SYMBOL_KEYS.has(String.fromCharCode(identityCodepoint));
|
|
957
|
+
const effectiveCodepoint = isLatinLetter || isDigit || isKnownSymbol ? identityCodepoint : (baseLayoutKey ?? identityCodepoint);
|
|
928
958
|
let keyName;
|
|
929
959
|
if (effectiveCodepoint === CODEPOINTS.escape)
|
|
930
960
|
keyName = "escape";
|
|
@@ -1121,4 +1151,23 @@ export function decodeKittyPrintable(data) {
|
|
|
1121
1151
|
return undefined;
|
|
1122
1152
|
}
|
|
1123
1153
|
}
|
|
1154
|
+
function decodeModifyOtherKeysPrintable(data) {
|
|
1155
|
+
const parsed = parseModifyOtherKeysSequence(data);
|
|
1156
|
+
if (!parsed)
|
|
1157
|
+
return undefined;
|
|
1158
|
+
const modifier = parsed.modifier & ~LOCK_MASK;
|
|
1159
|
+
if ((modifier & ~MODIFIERS.shift) !== 0)
|
|
1160
|
+
return undefined;
|
|
1161
|
+
if (!Number.isFinite(parsed.codepoint) || parsed.codepoint < 32)
|
|
1162
|
+
return undefined;
|
|
1163
|
+
try {
|
|
1164
|
+
return String.fromCodePoint(parsed.codepoint);
|
|
1165
|
+
}
|
|
1166
|
+
catch {
|
|
1167
|
+
return undefined;
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
export function decodePrintableKey(data) {
|
|
1171
|
+
return decodeKittyPrintable(data) ?? decodeModifyOtherKeysPrintable(data);
|
|
1172
|
+
}
|
|
1124
1173
|
//# sourceMappingURL=keys.js.map
|