Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/services/keybinding/test/node/windowsKeyboardMapper.test.ts
3296 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { KeyChord, KeyCode, KeyMod, ScanCode } from '../../../../../base/common/keyCodes.js';
7
import { KeyCodeChord, decodeKeybinding, ScanCodeChord, Keybinding } from '../../../../../base/common/keybindings.js';
8
import { OperatingSystem } from '../../../../../base/common/platform.js';
9
import { WindowsKeyboardMapper } from '../../common/windowsKeyboardMapper.js';
10
import { IResolvedKeybinding, assertMapping, assertResolveKeyboardEvent, assertResolveKeybinding, readRawMapping } from './keyboardMapperTestUtils.js';
11
import { IWindowsKeyboardMapping } from '../../../../../platform/keyboardLayout/common/keyboardLayout.js';
12
import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../../base/test/common/utils.js';
13
14
const WRITE_FILE_IF_DIFFERENT = false;
15
16
async function createKeyboardMapper(isUSStandard: boolean, file: string, mapAltGrToCtrlAlt: boolean): Promise<WindowsKeyboardMapper> {
17
const rawMappings = await readRawMapping<IWindowsKeyboardMapping>(file);
18
return new WindowsKeyboardMapper(isUSStandard, rawMappings, mapAltGrToCtrlAlt);
19
}
20
21
function _assertResolveKeybinding(mapper: WindowsKeyboardMapper, k: number, expected: IResolvedKeybinding[]): void {
22
const keyBinding = decodeKeybinding(k, OperatingSystem.Windows);
23
assertResolveKeybinding(mapper, keyBinding!, expected);
24
}
25
26
suite('keyboardMapper - WINDOWS de_ch', () => {
27
28
ensureNoDisposablesAreLeakedInTestSuite();
29
30
let mapper: WindowsKeyboardMapper;
31
32
suiteSetup(async () => {
33
mapper = await createKeyboardMapper(false, 'win_de_ch', false);
34
});
35
36
test('mapping', () => {
37
return assertMapping(WRITE_FILE_IF_DIFFERENT, mapper, 'win_de_ch.txt');
38
});
39
40
test('resolveKeybinding Ctrl+A', () => {
41
_assertResolveKeybinding(
42
mapper,
43
KeyMod.CtrlCmd | KeyCode.KeyA,
44
[{
45
label: 'Ctrl+A',
46
ariaLabel: 'Control+A',
47
electronAccelerator: 'Ctrl+A',
48
userSettingsLabel: 'ctrl+a',
49
isWYSIWYG: true,
50
isMultiChord: false,
51
dispatchParts: ['ctrl+A'],
52
singleModifierDispatchParts: [null],
53
}]
54
);
55
});
56
57
test('resolveKeybinding Ctrl+Z', () => {
58
_assertResolveKeybinding(
59
mapper,
60
KeyMod.CtrlCmd | KeyCode.KeyZ,
61
[{
62
label: 'Ctrl+Z',
63
ariaLabel: 'Control+Z',
64
electronAccelerator: 'Ctrl+Z',
65
userSettingsLabel: 'ctrl+z',
66
isWYSIWYG: true,
67
isMultiChord: false,
68
dispatchParts: ['ctrl+Z'],
69
singleModifierDispatchParts: [null],
70
}]
71
);
72
});
73
74
test('resolveKeyboardEvent Ctrl+Z', () => {
75
assertResolveKeyboardEvent(
76
mapper,
77
{
78
_standardKeyboardEventBrand: true,
79
ctrlKey: true,
80
shiftKey: false,
81
altKey: false,
82
metaKey: false,
83
altGraphKey: false,
84
keyCode: KeyCode.KeyZ,
85
code: null!
86
},
87
{
88
label: 'Ctrl+Z',
89
ariaLabel: 'Control+Z',
90
electronAccelerator: 'Ctrl+Z',
91
userSettingsLabel: 'ctrl+z',
92
isWYSIWYG: true,
93
isMultiChord: false,
94
dispatchParts: ['ctrl+Z'],
95
singleModifierDispatchParts: [null],
96
}
97
);
98
});
99
100
test('resolveKeybinding Ctrl+]', () => {
101
_assertResolveKeybinding(
102
mapper,
103
KeyMod.CtrlCmd | KeyCode.BracketRight,
104
[{
105
label: 'Ctrl+^',
106
ariaLabel: 'Control+^',
107
electronAccelerator: 'Ctrl+]',
108
userSettingsLabel: 'ctrl+oem_6',
109
isWYSIWYG: false,
110
isMultiChord: false,
111
dispatchParts: ['ctrl+]'],
112
singleModifierDispatchParts: [null],
113
}]
114
);
115
});
116
117
test('resolveKeyboardEvent Ctrl+]', () => {
118
assertResolveKeyboardEvent(
119
mapper,
120
{
121
_standardKeyboardEventBrand: true,
122
ctrlKey: true,
123
shiftKey: false,
124
altKey: false,
125
metaKey: false,
126
altGraphKey: false,
127
keyCode: KeyCode.BracketRight,
128
code: null!
129
},
130
{
131
label: 'Ctrl+^',
132
ariaLabel: 'Control+^',
133
electronAccelerator: 'Ctrl+]',
134
userSettingsLabel: 'ctrl+oem_6',
135
isWYSIWYG: false,
136
isMultiChord: false,
137
dispatchParts: ['ctrl+]'],
138
singleModifierDispatchParts: [null],
139
}
140
);
141
});
142
143
test('resolveKeybinding Shift+]', () => {
144
_assertResolveKeybinding(
145
mapper,
146
KeyMod.Shift | KeyCode.BracketRight,
147
[{
148
label: 'Shift+^',
149
ariaLabel: 'Shift+^',
150
electronAccelerator: 'Shift+]',
151
userSettingsLabel: 'shift+oem_6',
152
isWYSIWYG: false,
153
isMultiChord: false,
154
dispatchParts: ['shift+]'],
155
singleModifierDispatchParts: [null],
156
}]
157
);
158
});
159
160
test('resolveKeybinding Ctrl+/', () => {
161
_assertResolveKeybinding(
162
mapper,
163
KeyMod.CtrlCmd | KeyCode.Slash,
164
[{
165
label: 'Ctrl+§',
166
ariaLabel: 'Control+§',
167
electronAccelerator: 'Ctrl+/',
168
userSettingsLabel: 'ctrl+oem_2',
169
isWYSIWYG: false,
170
isMultiChord: false,
171
dispatchParts: ['ctrl+/'],
172
singleModifierDispatchParts: [null],
173
}]
174
);
175
});
176
177
test('resolveKeybinding Ctrl+Shift+/', () => {
178
_assertResolveKeybinding(
179
mapper,
180
KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Slash,
181
[{
182
label: 'Ctrl+Shift+§',
183
ariaLabel: 'Control+Shift+§',
184
electronAccelerator: 'Ctrl+Shift+/',
185
userSettingsLabel: 'ctrl+shift+oem_2',
186
isWYSIWYG: false,
187
isMultiChord: false,
188
dispatchParts: ['ctrl+shift+/'],
189
singleModifierDispatchParts: [null],
190
}]
191
);
192
});
193
194
test('resolveKeybinding Ctrl+K Ctrl+\\', () => {
195
_assertResolveKeybinding(
196
mapper,
197
KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.Backslash),
198
[{
199
label: 'Ctrl+K Ctrl+ä',
200
ariaLabel: 'Control+K Control+ä',
201
electronAccelerator: null,
202
userSettingsLabel: 'ctrl+k ctrl+oem_5',
203
isWYSIWYG: false,
204
isMultiChord: true,
205
dispatchParts: ['ctrl+K', 'ctrl+\\'],
206
singleModifierDispatchParts: [null, null],
207
}]
208
);
209
});
210
211
test('resolveKeybinding Ctrl+K Ctrl+=', () => {
212
_assertResolveKeybinding(
213
mapper,
214
KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.Equal),
215
[]
216
);
217
});
218
219
test('resolveKeybinding Ctrl+DownArrow', () => {
220
_assertResolveKeybinding(
221
mapper,
222
KeyMod.CtrlCmd | KeyCode.DownArrow,
223
[{
224
label: 'Ctrl+DownArrow',
225
ariaLabel: 'Control+DownArrow',
226
electronAccelerator: 'Ctrl+Down',
227
userSettingsLabel: 'ctrl+down',
228
isWYSIWYG: true,
229
isMultiChord: false,
230
dispatchParts: ['ctrl+DownArrow'],
231
singleModifierDispatchParts: [null],
232
}]
233
);
234
});
235
236
test('resolveKeybinding Ctrl+NUMPAD_0', () => {
237
_assertResolveKeybinding(
238
mapper,
239
KeyMod.CtrlCmd | KeyCode.Numpad0,
240
[{
241
label: 'Ctrl+NumPad0',
242
ariaLabel: 'Control+NumPad0',
243
electronAccelerator: null,
244
userSettingsLabel: 'ctrl+numpad0',
245
isWYSIWYG: true,
246
isMultiChord: false,
247
dispatchParts: ['ctrl+NumPad0'],
248
singleModifierDispatchParts: [null],
249
}]
250
);
251
});
252
253
test('resolveKeybinding Ctrl+Home', () => {
254
_assertResolveKeybinding(
255
mapper,
256
KeyMod.CtrlCmd | KeyCode.Home,
257
[{
258
label: 'Ctrl+Home',
259
ariaLabel: 'Control+Home',
260
electronAccelerator: 'Ctrl+Home',
261
userSettingsLabel: 'ctrl+home',
262
isWYSIWYG: true,
263
isMultiChord: false,
264
dispatchParts: ['ctrl+Home'],
265
singleModifierDispatchParts: [null],
266
}]
267
);
268
});
269
270
test('resolveKeyboardEvent Ctrl+Home', () => {
271
assertResolveKeyboardEvent(
272
mapper,
273
{
274
_standardKeyboardEventBrand: true,
275
ctrlKey: true,
276
shiftKey: false,
277
altKey: false,
278
metaKey: false,
279
altGraphKey: false,
280
keyCode: KeyCode.Home,
281
code: null!
282
},
283
{
284
label: 'Ctrl+Home',
285
ariaLabel: 'Control+Home',
286
electronAccelerator: 'Ctrl+Home',
287
userSettingsLabel: 'ctrl+home',
288
isWYSIWYG: true,
289
isMultiChord: false,
290
dispatchParts: ['ctrl+Home'],
291
singleModifierDispatchParts: [null],
292
}
293
);
294
});
295
296
test('resolveUserBinding Ctrl+[Comma] Ctrl+/', () => {
297
assertResolveKeybinding(
298
mapper, new Keybinding([
299
new ScanCodeChord(true, false, false, false, ScanCode.Comma),
300
new KeyCodeChord(true, false, false, false, KeyCode.Slash),
301
]),
302
[{
303
label: 'Ctrl+, Ctrl+§',
304
ariaLabel: 'Control+, Control+§',
305
electronAccelerator: null,
306
userSettingsLabel: 'ctrl+oem_comma ctrl+oem_2',
307
isWYSIWYG: false,
308
isMultiChord: true,
309
dispatchParts: ['ctrl+,', 'ctrl+/'],
310
singleModifierDispatchParts: [null, null],
311
}]
312
);
313
});
314
315
test('resolveKeyboardEvent Single Modifier Ctrl+', () => {
316
assertResolveKeyboardEvent(
317
mapper,
318
{
319
_standardKeyboardEventBrand: true,
320
ctrlKey: true,
321
shiftKey: false,
322
altKey: false,
323
metaKey: false,
324
altGraphKey: false,
325
keyCode: KeyCode.Ctrl,
326
code: null!
327
},
328
{
329
label: 'Ctrl',
330
ariaLabel: 'Control',
331
electronAccelerator: null,
332
userSettingsLabel: 'ctrl',
333
isWYSIWYG: true,
334
isMultiChord: false,
335
dispatchParts: [null],
336
singleModifierDispatchParts: ['ctrl'],
337
}
338
);
339
});
340
});
341
342
suite('keyboardMapper - WINDOWS en_us', () => {
343
344
ensureNoDisposablesAreLeakedInTestSuite();
345
346
let mapper: WindowsKeyboardMapper;
347
348
suiteSetup(async () => {
349
mapper = await createKeyboardMapper(true, 'win_en_us', false);
350
});
351
352
test('mapping', () => {
353
return assertMapping(WRITE_FILE_IF_DIFFERENT, mapper, 'win_en_us.txt');
354
});
355
356
test('resolveKeybinding Ctrl+K Ctrl+\\', () => {
357
_assertResolveKeybinding(
358
mapper,
359
KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.Backslash),
360
[{
361
label: 'Ctrl+K Ctrl+\\',
362
ariaLabel: 'Control+K Control+\\',
363
electronAccelerator: null,
364
userSettingsLabel: 'ctrl+k ctrl+\\',
365
isWYSIWYG: true,
366
isMultiChord: true,
367
dispatchParts: ['ctrl+K', 'ctrl+\\'],
368
singleModifierDispatchParts: [null, null],
369
}]
370
);
371
});
372
373
test('resolveUserBinding Ctrl+[Comma] Ctrl+/', () => {
374
assertResolveKeybinding(
375
mapper, new Keybinding([
376
new ScanCodeChord(true, false, false, false, ScanCode.Comma),
377
new KeyCodeChord(true, false, false, false, KeyCode.Slash),
378
]),
379
[{
380
label: 'Ctrl+, Ctrl+/',
381
ariaLabel: 'Control+, Control+/',
382
electronAccelerator: null,
383
userSettingsLabel: 'ctrl+, ctrl+/',
384
isWYSIWYG: true,
385
isMultiChord: true,
386
dispatchParts: ['ctrl+,', 'ctrl+/'],
387
singleModifierDispatchParts: [null, null],
388
}]
389
);
390
});
391
392
test('resolveUserBinding Ctrl+[Comma]', () => {
393
assertResolveKeybinding(
394
mapper, new Keybinding([
395
new ScanCodeChord(true, false, false, false, ScanCode.Comma),
396
]),
397
[{
398
label: 'Ctrl+,',
399
ariaLabel: 'Control+,',
400
electronAccelerator: 'Ctrl+,',
401
userSettingsLabel: 'ctrl+,',
402
isWYSIWYG: true,
403
isMultiChord: false,
404
dispatchParts: ['ctrl+,'],
405
singleModifierDispatchParts: [null],
406
}]
407
);
408
});
409
410
test('resolveKeyboardEvent Single Modifier Ctrl+', () => {
411
assertResolveKeyboardEvent(
412
mapper,
413
{
414
_standardKeyboardEventBrand: true,
415
ctrlKey: true,
416
shiftKey: false,
417
altKey: false,
418
metaKey: false,
419
altGraphKey: false,
420
keyCode: KeyCode.Ctrl,
421
code: null!
422
},
423
{
424
label: 'Ctrl',
425
ariaLabel: 'Control',
426
electronAccelerator: null,
427
userSettingsLabel: 'ctrl',
428
isWYSIWYG: true,
429
isMultiChord: false,
430
dispatchParts: [null],
431
singleModifierDispatchParts: ['ctrl'],
432
}
433
);
434
});
435
436
test('resolveKeyboardEvent Single Modifier Shift+', () => {
437
assertResolveKeyboardEvent(
438
mapper,
439
{
440
_standardKeyboardEventBrand: true,
441
ctrlKey: false,
442
shiftKey: true,
443
altKey: false,
444
metaKey: false,
445
altGraphKey: false,
446
keyCode: KeyCode.Shift,
447
code: null!
448
},
449
{
450
label: 'Shift',
451
ariaLabel: 'Shift',
452
electronAccelerator: null,
453
userSettingsLabel: 'shift',
454
isWYSIWYG: true,
455
isMultiChord: false,
456
dispatchParts: [null],
457
singleModifierDispatchParts: ['shift'],
458
}
459
);
460
});
461
462
test('resolveKeyboardEvent Single Modifier Alt+', () => {
463
assertResolveKeyboardEvent(
464
mapper,
465
{
466
_standardKeyboardEventBrand: true,
467
ctrlKey: false,
468
shiftKey: false,
469
altKey: true,
470
metaKey: false,
471
altGraphKey: false,
472
keyCode: KeyCode.Alt,
473
code: null!
474
},
475
{
476
label: 'Alt',
477
ariaLabel: 'Alt',
478
electronAccelerator: null,
479
userSettingsLabel: 'alt',
480
isWYSIWYG: true,
481
isMultiChord: false,
482
dispatchParts: [null],
483
singleModifierDispatchParts: ['alt'],
484
}
485
);
486
});
487
488
test('resolveKeyboardEvent Single Modifier Meta+', () => {
489
assertResolveKeyboardEvent(
490
mapper,
491
{
492
_standardKeyboardEventBrand: true,
493
ctrlKey: false,
494
shiftKey: false,
495
altKey: false,
496
metaKey: true,
497
altGraphKey: false,
498
keyCode: KeyCode.Meta,
499
code: null!
500
},
501
{
502
label: 'Windows',
503
ariaLabel: 'Windows',
504
electronAccelerator: null,
505
userSettingsLabel: 'win',
506
isWYSIWYG: true,
507
isMultiChord: false,
508
dispatchParts: [null],
509
singleModifierDispatchParts: ['meta'],
510
}
511
);
512
});
513
514
test('resolveKeyboardEvent Only Modifiers Ctrl+Shift+', () => {
515
assertResolveKeyboardEvent(
516
mapper,
517
{
518
_standardKeyboardEventBrand: true,
519
ctrlKey: true,
520
shiftKey: true,
521
altKey: false,
522
metaKey: false,
523
altGraphKey: false,
524
keyCode: KeyCode.Shift,
525
code: null!
526
},
527
{
528
label: 'Ctrl+Shift',
529
ariaLabel: 'Control+Shift',
530
electronAccelerator: null,
531
userSettingsLabel: 'ctrl+shift',
532
isWYSIWYG: true,
533
isMultiChord: false,
534
dispatchParts: [null],
535
singleModifierDispatchParts: [null],
536
}
537
);
538
});
539
540
test('resolveKeyboardEvent mapAltGrToCtrlAlt AltGr+Z', async () => {
541
const mapper = await createKeyboardMapper(true, 'win_en_us', true);
542
543
assertResolveKeyboardEvent(
544
mapper,
545
{
546
_standardKeyboardEventBrand: true,
547
ctrlKey: false,
548
shiftKey: false,
549
altKey: false,
550
metaKey: false,
551
altGraphKey: true,
552
keyCode: KeyCode.KeyZ,
553
code: null!
554
},
555
{
556
label: 'Ctrl+Alt+Z',
557
ariaLabel: 'Control+Alt+Z',
558
electronAccelerator: 'Ctrl+Alt+Z',
559
userSettingsLabel: 'ctrl+alt+z',
560
isWYSIWYG: true,
561
isMultiChord: false,
562
dispatchParts: ['ctrl+alt+Z'],
563
singleModifierDispatchParts: [null],
564
}
565
);
566
});
567
});
568
569
suite('keyboardMapper - WINDOWS por_ptb', () => {
570
571
ensureNoDisposablesAreLeakedInTestSuite();
572
573
let mapper: WindowsKeyboardMapper;
574
575
suiteSetup(async () => {
576
mapper = await createKeyboardMapper(false, 'win_por_ptb', false);
577
});
578
579
test('mapping', () => {
580
return assertMapping(WRITE_FILE_IF_DIFFERENT, mapper, 'win_por_ptb.txt');
581
});
582
583
test('resolveKeyboardEvent Ctrl+[IntlRo]', () => {
584
assertResolveKeyboardEvent(
585
mapper,
586
{
587
_standardKeyboardEventBrand: true,
588
ctrlKey: true,
589
shiftKey: false,
590
altKey: false,
591
metaKey: false,
592
altGraphKey: false,
593
keyCode: KeyCode.ABNT_C1,
594
code: null!
595
},
596
{
597
label: 'Ctrl+/',
598
ariaLabel: 'Control+/',
599
electronAccelerator: 'Ctrl+ABNT_C1',
600
userSettingsLabel: 'ctrl+abnt_c1',
601
isWYSIWYG: false,
602
isMultiChord: false,
603
dispatchParts: ['ctrl+ABNT_C1'],
604
singleModifierDispatchParts: [null],
605
}
606
);
607
});
608
609
test('resolveKeyboardEvent Ctrl+[NumpadComma]', () => {
610
assertResolveKeyboardEvent(
611
mapper,
612
{
613
_standardKeyboardEventBrand: true,
614
ctrlKey: true,
615
shiftKey: false,
616
altKey: false,
617
metaKey: false,
618
altGraphKey: false,
619
keyCode: KeyCode.ABNT_C2,
620
code: null!
621
},
622
{
623
label: 'Ctrl+.',
624
ariaLabel: 'Control+.',
625
electronAccelerator: 'Ctrl+ABNT_C2',
626
userSettingsLabel: 'ctrl+abnt_c2',
627
isWYSIWYG: false,
628
isMultiChord: false,
629
dispatchParts: ['ctrl+ABNT_C2'],
630
singleModifierDispatchParts: [null],
631
}
632
);
633
});
634
});
635
636
suite('keyboardMapper - WINDOWS ru', () => {
637
638
ensureNoDisposablesAreLeakedInTestSuite();
639
640
let mapper: WindowsKeyboardMapper;
641
642
suiteSetup(async () => {
643
mapper = await createKeyboardMapper(false, 'win_ru', false);
644
});
645
646
test('mapping', () => {
647
return assertMapping(WRITE_FILE_IF_DIFFERENT, mapper, 'win_ru.txt');
648
});
649
650
test('issue ##24361: resolveKeybinding Ctrl+K Ctrl+K', () => {
651
_assertResolveKeybinding(
652
mapper,
653
KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.KeyK),
654
[{
655
label: 'Ctrl+K Ctrl+K',
656
ariaLabel: 'Control+K Control+K',
657
electronAccelerator: null,
658
userSettingsLabel: 'ctrl+k ctrl+k',
659
isWYSIWYG: true,
660
isMultiChord: true,
661
dispatchParts: ['ctrl+K', 'ctrl+K'],
662
singleModifierDispatchParts: [null, null],
663
}]
664
);
665
});
666
});
667
668
suite('keyboardMapper - misc', () => {
669
670
ensureNoDisposablesAreLeakedInTestSuite();
671
672
test('issue #23513: Toggle Sidebar Visibility and Go to Line display same key mapping in Arabic keyboard', () => {
673
const mapper = new WindowsKeyboardMapper(false, {
674
'KeyB': {
675
'vkey': 'VK_B',
676
'value': 'لا',
677
'withShift': 'لآ',
678
'withAltGr': '',
679
'withShiftAltGr': ''
680
},
681
'KeyG': {
682
'vkey': 'VK_G',
683
'value': 'ل',
684
'withShift': 'لأ',
685
'withAltGr': '',
686
'withShiftAltGr': ''
687
}
688
}, false);
689
690
_assertResolveKeybinding(
691
mapper,
692
KeyMod.CtrlCmd | KeyCode.KeyB,
693
[{
694
label: 'Ctrl+B',
695
ariaLabel: 'Control+B',
696
electronAccelerator: 'Ctrl+B',
697
userSettingsLabel: 'ctrl+b',
698
isWYSIWYG: true,
699
isMultiChord: false,
700
dispatchParts: ['ctrl+B'],
701
singleModifierDispatchParts: [null],
702
}]
703
);
704
});
705
});
706
707