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