Merge from vscode bead496a613e475819f89f08e9e882b841bc1fe8 (#14883)

* Merge from vscode bead496a613e475819f89f08e9e882b841bc1fe8

* Bump distro

* Upgrade GCC to 4.9 due to yarn install errors

* Update build image

* Fix bootstrap base url

* Bump distro

* Fix build errors

* Update source map file

* Disable checkbox for blocking migration issues (#15131)

* disable checkbox for blocking issues

* wip

* disable checkbox fixes

* fix strings

* Remove duplicate tsec command

* Default to off for tab color if settings not present

* re-skip failing tests

* Fix mocha error

* Bump sqlite version & fix notebooks search view

* Turn off esbuild warnings

* Update esbuild log level

* Fix overflowactionbar tests

* Fix ts-ignore in dropdown tests

* cleanup/fixes

* Fix hygiene

* Bundle in entire zone.js module

* Remove extra constructor param

* bump distro for web compile break

* bump distro for web compile break v2

* Undo log level change

* New distro

* Fix integration test scripts

* remove the "no yarn.lock changes" workflow

* fix scripts v2

* Update unit test scripts

* Ensure ads-kerberos2 updates in .vscodeignore

* Try fix unit tests

* Upload crash reports

* remove nogpu

* always upload crashes

* Use bash script

* Consolidate data/ext dir names

* Create in tmp directory

Co-authored-by: chlafreniere <hichise@gmail.com>
Co-authored-by: Christopher Suh <chsuh@microsoft.com>
Co-authored-by: chgagnon <chgagnon@microsoft.com>
This commit is contained in:
Karl Burtram
2021-04-27 14:01:59 -07:00
committed by GitHub
parent 7e1c0076ba
commit 867a963882
1817 changed files with 81812 additions and 50843 deletions

View File

@@ -50,6 +50,7 @@ import { BrowserFeatures, KeyboardSupport } from 'vs/base/browser/canIUse';
import { ILogService } from 'vs/platform/log/common/log';
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
import { dirname } from 'vs/base/common/resources';
import { getAllUnboundCommands } from 'vs/workbench/services/keybinding/browser/unboundCommands';
interface ContributedKeyBinding {
command: string;
@@ -250,6 +251,7 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService {
this.updateSchema();
this._register(extensionService.onDidRegisterExtensions(() => this.updateSchema()));
// for standard keybindings
this._register(dom.addDisposableListener(window, dom.EventType.KEY_DOWN, (e: KeyboardEvent) => {
this.isComposingGlobalContextKey.set(e.isComposing);
const keyEvent = new StandardKeyboardEvent(e);
@@ -262,6 +264,17 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService {
this.isComposingGlobalContextKey.set(false);
}));
// for single modifier chord keybindings (e.g. shift shift)
this._register(dom.addDisposableListener(window, dom.EventType.KEY_UP, (e: KeyboardEvent) => {
this.isComposingGlobalContextKey.set(e.isComposing);
const keyEvent = new StandardKeyboardEvent(e);
const shouldPreventDefault = this._singleModifierDispatch(keyEvent, keyEvent.target);
if (shouldPreventDefault) {
keyEvent.preventDefault();
}
this.isComposingGlobalContextKey.set(false);
}));
let data = this.keyboardLayoutService.getCurrentKeyboardLayout();
/* __GDPR__FRAGMENT__
"IKeyboardLayoutInfo" : {
@@ -594,7 +607,7 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService {
}
private static _getAllCommandsAsComment(boundCommands: Map<string, boolean>): string {
const unboundCommands = KeybindingResolver.getAllUnboundCommands(boundCommands);
const unboundCommands = getAllUnboundCommands(boundCommands);
let pretty = unboundCommands.sort().join('\n// - ');
return '// ' + nls.localize('unboundCommands', "Here are other available commands: ") + '\n// - ' + pretty;
}

View File

@@ -0,0 +1,52 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { CommandsRegistry, ICommandHandlerDescription } from 'vs/platform/commands/common/commands';
import { isNonEmptyArray } from 'vs/base/common/arrays';
import { EditorExtensionsRegistry } from 'vs/editor/browser/editorExtensions';
import { MenuRegistry, MenuId, isIMenuItem } from 'vs/platform/actions/common/actions';
export function getAllUnboundCommands(boundCommands: Map<string, boolean>): string[] {
const unboundCommands: string[] = [];
const seenMap: Map<string, boolean> = new Map<string, boolean>();
const addCommand = (id: string, includeCommandWithArgs: boolean) => {
if (seenMap.has(id)) {
return;
}
seenMap.set(id, true);
if (id[0] === '_' || id.indexOf('vscode.') === 0) { // private command
return;
}
if (boundCommands.get(id) === true) {
return;
}
if (!includeCommandWithArgs) {
const command = CommandsRegistry.getCommand(id);
if (command && typeof command.description === 'object'
&& isNonEmptyArray((<ICommandHandlerDescription>command.description).args)) { // command with args
return;
}
}
unboundCommands.push(id);
};
// Add all commands from Command Palette
for (const menuItem of MenuRegistry.getMenuItems(MenuId.CommandPalette)) {
if (isIMenuItem(menuItem)) {
addCommand(menuItem.command.id, true);
}
}
// Add all editor actions
for (const editorAction of EditorExtensionsRegistry.getEditorActions()) {
addCommand(editorAction.id, true);
}
for (const id of CommandsRegistry.getCommands().keys()) {
addCommand(id, false);
}
return unboundCommands;
}

View File

@@ -67,6 +67,22 @@ export class NativeResolvedKeybinding extends BaseResolvedKeybinding<ScanCodeBin
protected _getDispatchPart(keybinding: ScanCodeBinding): string | null {
return this._mapper.getDispatchStrForScanCodeBinding(keybinding);
}
protected _getSingleModifierDispatchPart(keybinding: ScanCodeBinding): string | null {
if ((keybinding.scanCode === ScanCode.ControlLeft || keybinding.scanCode === ScanCode.ControlRight) && !keybinding.shiftKey && !keybinding.altKey && !keybinding.metaKey) {
return 'ctrl';
}
if ((keybinding.scanCode === ScanCode.AltLeft || keybinding.scanCode === ScanCode.AltRight) && !keybinding.ctrlKey && !keybinding.shiftKey && !keybinding.metaKey) {
return 'alt';
}
if ((keybinding.scanCode === ScanCode.ShiftLeft || keybinding.scanCode === ScanCode.ShiftRight) && !keybinding.ctrlKey && !keybinding.altKey && !keybinding.metaKey) {
return 'shift';
}
if ((keybinding.scanCode === ScanCode.MetaLeft || keybinding.scanCode === ScanCode.MetaRight) && !keybinding.ctrlKey && !keybinding.shiftKey && !keybinding.altKey) {
return 'meta';
}
return null;
}
}
interface IScanCodeMapping {

View File

@@ -66,32 +66,11 @@ export class WindowsNativeResolvedKeybinding extends BaseResolvedKeybinding<Simp
return this._mapper.getAriaLabelForKeyCode(keybinding.keyCode);
}
private _keyCodeToElectronAccelerator(keyCode: KeyCode): string | null {
if (keyCode >= KeyCode.NUMPAD_0 && keyCode <= KeyCode.NUMPAD_DIVIDE) {
// Electron cannot handle numpad keys
return null;
}
switch (keyCode) {
case KeyCode.UpArrow:
return 'Up';
case KeyCode.DownArrow:
return 'Down';
case KeyCode.LeftArrow:
return 'Left';
case KeyCode.RightArrow:
return 'Right';
}
// electron menus always do the correct rendering on Windows
return KeyCodeUtils.toString(keyCode);
}
protected _getElectronAccelerator(keybinding: SimpleKeybinding): string | null {
if (keybinding.isDuplicateModifierCase()) {
return null;
}
return this._keyCodeToElectronAccelerator(keybinding.keyCode);
return this._mapper.getElectronAcceleratorForKeyBinding(keybinding);
}
protected _getUserSettingsLabel(keybinding: SimpleKeybinding): string | null {
@@ -143,6 +122,22 @@ export class WindowsNativeResolvedKeybinding extends BaseResolvedKeybinding<Simp
return result;
}
protected _getSingleModifierDispatchPart(keybinding: SimpleKeybinding): string | null {
if (keybinding.keyCode === KeyCode.Ctrl && !keybinding.shiftKey && !keybinding.altKey && !keybinding.metaKey) {
return 'ctrl';
}
if (keybinding.keyCode === KeyCode.Shift && !keybinding.ctrlKey && !keybinding.altKey && !keybinding.metaKey) {
return 'shift';
}
if (keybinding.keyCode === KeyCode.Alt && !keybinding.ctrlKey && !keybinding.shiftKey && !keybinding.metaKey) {
return 'alt';
}
if (keybinding.keyCode === KeyCode.Meta && !keybinding.ctrlKey && !keybinding.shiftKey && !keybinding.altKey) {
return 'meta';
}
return null;
}
private static getProducedCharCode(kb: ScanCodeBinding, mapping: IScanCodeMapping): string | null {
if (!mapping) {
return null;
@@ -409,6 +404,53 @@ export class WindowsKeyboardMapper implements IKeyboardMapper {
return KeyCodeUtils.toUserSettingsGeneral(keyCode);
}
public getElectronAcceleratorForKeyBinding(keybinding: SimpleKeybinding): string | null {
if (!this.isUSStandard) {
// See https://github.com/electron/electron/issues/26888
// Electron does not render accelerators respecting the current keyboard layout since 3.x
const keyCode = keybinding.keyCode;
const isOEMKey = (
keyCode === KeyCode.US_SEMICOLON
|| keyCode === KeyCode.US_EQUAL
|| keyCode === KeyCode.US_COMMA
|| keyCode === KeyCode.US_MINUS
|| keyCode === KeyCode.US_DOT
|| keyCode === KeyCode.US_SLASH
|| keyCode === KeyCode.US_BACKTICK
|| keyCode === KeyCode.US_OPEN_SQUARE_BRACKET
|| keyCode === KeyCode.US_BACKSLASH
|| keyCode === KeyCode.US_CLOSE_SQUARE_BRACKET
|| keyCode === KeyCode.OEM_8
|| keyCode === KeyCode.OEM_102
);
if (isOEMKey) {
return null;
}
}
return this._keyCodeToElectronAccelerator(keybinding.keyCode);
}
private _keyCodeToElectronAccelerator(keyCode: KeyCode): string | null {
if (keyCode >= KeyCode.NUMPAD_0 && keyCode <= KeyCode.NUMPAD_DIVIDE) {
// Electron cannot handle numpad keys
return null;
}
switch (keyCode) {
case KeyCode.UpArrow:
return 'Up';
case KeyCode.DownArrow:
return 'Down';
case KeyCode.LeftArrow:
return 'Left';
case KeyCode.RightArrow:
return 'Right';
}
// electron menus always do the correct rendering on Windows
return KeyCodeUtils.toString(keyCode);
}
private _getLabelForKeyCode(keyCode: KeyCode): string {
return this._keyCodeToLabel[keyCode] || KeyCodeUtils.toString(KeyCode.Unknown);
}

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import 'vs/workbench/services/keybinding/browser/keyboardLayouts/en.darwin'; // 15%
import 'vs/workbench/services/keybinding/browser/keyboardLayouts/en.darwin';
import 'vs/workbench/services/keybinding/browser/keyboardLayouts/de.darwin';
import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution';
import { BrowserKeyboardMapperFactoryBase } from 'vs/workbench/services/keybinding/browser/keyboardLayoutService';
@@ -41,12 +41,12 @@ suite('keyboard layout loader', () => {
let instance = new TestKeyboardMapperFactory(notitifcationService, storageService, commandService);
test('load default US keyboard layout', () => {
assert.notEqual(instance.activeKeyboardLayout, null);
assert.notStrictEqual(instance.activeKeyboardLayout, null);
});
test('isKeyMappingActive', () => {
instance.setUSKeyboardLayout();
assert.equal(instance.isKeyMappingActive({
assert.strictEqual(instance.isKeyMappingActive({
KeyA: {
value: 'a',
valueIsDeadKey: false,
@@ -59,7 +59,7 @@ suite('keyboard layout loader', () => {
}
}), true);
assert.equal(instance.isKeyMappingActive({
assert.strictEqual(instance.isKeyMappingActive({
KeyA: {
value: 'a',
valueIsDeadKey: false,
@@ -82,7 +82,7 @@ suite('keyboard layout loader', () => {
}
}), true);
assert.equal(instance.isKeyMappingActive({
assert.strictEqual(instance.isKeyMappingActive({
KeyZ: {
value: 'y',
valueIsDeadKey: false,
@@ -110,8 +110,8 @@ suite('keyboard layout loader', () => {
withShiftAltGrIsDeadKey: false
}
});
assert.equal(!!instance.activeKeyboardLayout!.isUSStandard, false);
assert.equal(instance.isKeyMappingActive({
assert.strictEqual(!!instance.activeKeyboardLayout!.isUSStandard, false);
assert.strictEqual(instance.isKeyMappingActive({
KeyZ: {
value: 'y',
valueIsDeadKey: false,
@@ -125,13 +125,13 @@ suite('keyboard layout loader', () => {
}), true);
instance.setUSKeyboardLayout();
assert.equal(instance.activeKeyboardLayout!.isUSStandard, true);
assert.strictEqual(instance.activeKeyboardLayout!.isUSStandard, true);
});
test('Switch keyboard layout info', () => {
instance.setKeyboardLayout('com.apple.keylayout.German');
assert.equal(!!instance.activeKeyboardLayout!.isUSStandard, false);
assert.equal(instance.isKeyMappingActive({
assert.strictEqual(!!instance.activeKeyboardLayout!.isUSStandard, false);
assert.strictEqual(instance.isKeyMappingActive({
KeyZ: {
value: 'y',
valueIsDeadKey: false,
@@ -145,6 +145,6 @@ suite('keyboard layout loader', () => {
}), true);
instance.setUSKeyboardLayout();
assert.equal(instance.activeKeyboardLayout!.isUSStandard, true);
assert.strictEqual(instance.activeKeyboardLayout!.isUSStandard, true);
});
});

View File

@@ -0,0 +1,315 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import * as json from 'vs/base/common/json';
import { ChordKeybinding, KeyCode, SimpleKeybinding } from 'vs/base/common/keyCodes';
import { OS } from 'vs/base/common/platform';
import { IModeService } from 'vs/editor/common/services/modeService';
import { ModeServiceImpl } from 'vs/editor/common/services/modeServiceImpl';
import { IModelService } from 'vs/editor/common/services/modelService';
import { ModelServiceImpl } from 'vs/editor/common/services/modelServiceImpl';
import { ITextModelService } from 'vs/editor/common/services/resolverService';
import { ITextResourcePropertiesService } from 'vs/editor/common/services/textResourceConfigurationService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IFileService } from 'vs/platform/files/common/files';
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
import { IUserFriendlyKeybinding } from 'vs/platform/keybinding/common/keybinding';
import { ResolvedKeybindingItem } from 'vs/platform/keybinding/common/resolvedKeybindingItem';
import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/usLayoutResolvedKeybinding';
import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService';
import { ILifecycleService } from 'vs/workbench/services/lifecycle/common/lifecycle';
import { ILogService, NullLogService } from 'vs/platform/log/common/log';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IBackupFileService } from 'vs/workbench/services/backup/common/backup';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { KeybindingsEditingService } from 'vs/workbench/services/keybinding/common/keybindingEditing';
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
import { TextModelResolverService } from 'vs/workbench/services/textmodelResolver/common/textModelResolverService';
import { TestBackupFileService, TestEditorGroupsService, TestEditorService, TestEnvironmentService, TestLifecycleService, TestPathService, TestTextFileService } from 'vs/workbench/test/browser/workbenchTestServices';
import { FileService } from 'vs/platform/files/common/fileService';
import { Schemas } from 'vs/base/common/network';
import { URI } from 'vs/base/common/uri';
import { FileUserDataProvider } from 'vs/workbench/services/userData/common/fileUserDataProvider';
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService';
import { ILabelService } from 'vs/platform/label/common/label';
import { LabelService } from 'vs/workbench/services/label/common/labelService';
import { IFilesConfigurationService, FilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService';
import { WorkingCopyFileService, IWorkingCopyFileService } from 'vs/workbench/services/workingCopy/common/workingCopyFileService';
import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo';
import { UndoRedoService } from 'vs/platform/undoRedo/common/undoRedoService';
import { TestTextResourcePropertiesService, TestContextService, TestWorkingCopyService } from 'vs/workbench/test/common/workbenchTestServices';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService';
import { IPathService } from 'vs/workbench/services/path/common/pathService';
import { IUriIdentityService } from 'vs/workbench/services/uriIdentity/common/uriIdentity';
import { UriIdentityService } from 'vs/workbench/services/uriIdentity/common/uriIdentityService';
import { joinPath } from 'vs/base/common/resources';
import { InMemoryFileSystemProvider } from 'vs/platform/files/common/inMemoryFilesystemProvider';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { VSBuffer } from 'vs/base/common/buffer';
interface Modifiers {
metaKey?: boolean;
ctrlKey?: boolean;
altKey?: boolean;
shiftKey?: boolean;
}
const ROOT = URI.file('tests').with({ scheme: 'vscode-tests' });
suite('KeybindingsEditing', () => {
const disposables = new DisposableStore();
let instantiationService: TestInstantiationService, fileService: IFileService, environmentService: IEnvironmentService;
let testObject: KeybindingsEditingService;
setup(async () => {
const logService = new NullLogService();
fileService = disposables.add(new FileService(logService));
const fileSystemProvider = disposables.add(new InMemoryFileSystemProvider());
disposables.add(fileService.registerProvider(ROOT.scheme, fileSystemProvider));
const userFolder = joinPath(ROOT, 'User');
await fileService.createFolder(userFolder);
environmentService = TestEnvironmentService;
instantiationService = new TestInstantiationService();
const configService = new TestConfigurationService();
configService.setUserConfiguration('files', { 'eol': '\n' });
instantiationService.stub(IEnvironmentService, environmentService);
instantiationService.stub(IPathService, new TestPathService());
instantiationService.stub(IConfigurationService, configService);
instantiationService.stub(IWorkspaceContextService, new TestContextService());
const lifecycleService = new TestLifecycleService();
instantiationService.stub(ILifecycleService, lifecycleService);
instantiationService.stub(IContextKeyService, <IContextKeyService>instantiationService.createInstance(MockContextKeyService));
instantiationService.stub(IEditorGroupsService, new TestEditorGroupsService());
instantiationService.stub(IEditorService, new TestEditorService());
instantiationService.stub(IWorkingCopyService, new TestWorkingCopyService());
instantiationService.stub(ITelemetryService, NullTelemetryService);
instantiationService.stub(IModeService, ModeServiceImpl);
instantiationService.stub(ILogService, new NullLogService());
instantiationService.stub(ILabelService, disposables.add(instantiationService.createInstance(LabelService)));
instantiationService.stub(IFilesConfigurationService, disposables.add(instantiationService.createInstance(FilesConfigurationService)));
instantiationService.stub(ITextResourcePropertiesService, new TestTextResourcePropertiesService(instantiationService.get(IConfigurationService)));
instantiationService.stub(IUndoRedoService, instantiationService.createInstance(UndoRedoService));
instantiationService.stub(IThemeService, new TestThemeService());
instantiationService.stub(IModelService, disposables.add(instantiationService.createInstance(ModelServiceImpl)));
fileService.registerProvider(Schemas.userData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.userData, new NullLogService())));
instantiationService.stub(IFileService, fileService);
instantiationService.stub(IUriIdentityService, new UriIdentityService(fileService));
instantiationService.stub(IWorkingCopyService, disposables.add(new TestWorkingCopyService()));
instantiationService.stub(IWorkingCopyFileService, disposables.add(instantiationService.createInstance(WorkingCopyFileService)));
instantiationService.stub(ITextFileService, disposables.add(instantiationService.createInstance(TestTextFileService)));
instantiationService.stub(ITextModelService, disposables.add(instantiationService.createInstance(TextModelResolverService)));
instantiationService.stub(IBackupFileService, new TestBackupFileService());
testObject = disposables.add(instantiationService.createInstance(KeybindingsEditingService));
});
teardown(() => disposables.clear());
test('errors cases - parse errors', async () => {
await fileService.writeFile(environmentService.keybindingsResource, VSBuffer.fromString(',,,,,,,,,,,,,,'));
try {
await testObject.editKeybinding(aResolvedKeybindingItem({ firstPart: { keyCode: KeyCode.Escape } }), 'alt+c', undefined);
assert.fail('Should fail with parse errors');
} catch (error) {
assert.equal(error.message, 'Unable to write to the keybindings configuration file. Please open it to correct errors/warnings in the file and try again.');
}
});
test('errors cases - parse errors 2', async () => {
await fileService.writeFile(environmentService.keybindingsResource, VSBuffer.fromString('[{"key": }]'));
try {
await testObject.editKeybinding(aResolvedKeybindingItem({ firstPart: { keyCode: KeyCode.Escape } }), 'alt+c', undefined);
assert.fail('Should fail with parse errors');
} catch (error) {
assert.equal(error.message, 'Unable to write to the keybindings configuration file. Please open it to correct errors/warnings in the file and try again.');
}
});
test('errors cases - dirty', () => {
instantiationService.stub(ITextFileService, 'isDirty', true);
return testObject.editKeybinding(aResolvedKeybindingItem({ firstPart: { keyCode: KeyCode.Escape } }), 'alt+c', undefined)
.then(() => assert.fail('Should fail with dirty error'),
error => assert.equal(error.message, 'Unable to write because the keybindings configuration file is dirty. Please save it first and then try again.'));
});
test('errors cases - did not find an array', async () => {
await fileService.writeFile(environmentService.keybindingsResource, VSBuffer.fromString('{"key": "alt+c", "command": "hello"}'));
try {
await testObject.editKeybinding(aResolvedKeybindingItem({ firstPart: { keyCode: KeyCode.Escape } }), 'alt+c', undefined);
assert.fail('Should fail');
} catch (error) {
assert.equal(error.message, 'Unable to write to the keybindings configuration file. It has an object which is not of type Array. Please open the file to clean up and try again.');
}
});
test('edit a default keybinding to an empty file', async () => {
await fileService.writeFile(environmentService.keybindingsResource, VSBuffer.fromString(''));
const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: 'a' }, { key: 'escape', command: '-a' }];
await testObject.editKeybinding(aResolvedKeybindingItem({ firstPart: { keyCode: KeyCode.Escape }, command: 'a' }), 'alt+c', undefined);
assert.deepEqual(await getUserKeybindings(), expected);
});
test('edit a default keybinding to an empty array', async () => {
await writeToKeybindingsFile();
const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: 'a' }, { key: 'escape', command: '-a' }];
await testObject.editKeybinding(aResolvedKeybindingItem({ firstPart: { keyCode: KeyCode.Escape }, command: 'a' }), 'alt+c', undefined);
return assert.deepEqual(await getUserKeybindings(), expected);
});
test('edit a default keybinding in an existing array', async () => {
await writeToKeybindingsFile({ command: 'b', key: 'shift+c' });
const expected: IUserFriendlyKeybinding[] = [{ key: 'shift+c', command: 'b' }, { key: 'alt+c', command: 'a' }, { key: 'escape', command: '-a' }];
await testObject.editKeybinding(aResolvedKeybindingItem({ firstPart: { keyCode: KeyCode.Escape }, command: 'a' }), 'alt+c', undefined);
return assert.deepEqual(await getUserKeybindings(), expected);
});
test('add another keybinding', async () => {
const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: 'a' }];
await testObject.addKeybinding(aResolvedKeybindingItem({ firstPart: { keyCode: KeyCode.Escape }, command: 'a' }), 'alt+c', undefined);
return assert.deepEqual(await getUserKeybindings(), expected);
});
test('add a new default keybinding', async () => {
const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: 'a' }];
await testObject.addKeybinding(aResolvedKeybindingItem({ command: 'a' }), 'alt+c', undefined);
return assert.deepEqual(await getUserKeybindings(), expected);
});
test('add a new default keybinding using edit', async () => {
const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: 'a' }];
await testObject.editKeybinding(aResolvedKeybindingItem({ command: 'a' }), 'alt+c', undefined);
assert.deepEqual(await getUserKeybindings(), expected);
});
test('edit an user keybinding', async () => {
await writeToKeybindingsFile({ key: 'escape', command: 'b' });
const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: 'b' }];
await testObject.editKeybinding(aResolvedKeybindingItem({ firstPart: { keyCode: KeyCode.Escape }, command: 'b', isDefault: false }), 'alt+c', undefined);
assert.deepEqual(await getUserKeybindings(), expected);
});
test('edit an user keybinding with more than one element', async () => {
await writeToKeybindingsFile({ key: 'escape', command: 'b' }, { key: 'alt+shift+g', command: 'c' });
const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: 'b' }, { key: 'alt+shift+g', command: 'c' }];
await testObject.editKeybinding(aResolvedKeybindingItem({ firstPart: { keyCode: KeyCode.Escape }, command: 'b', isDefault: false }), 'alt+c', undefined);
assert.deepEqual(await getUserKeybindings(), expected);
});
test('remove a default keybinding', async () => {
const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: '-a' }];
await testObject.removeKeybinding(aResolvedKeybindingItem({ command: 'a', firstPart: { keyCode: KeyCode.KEY_C, modifiers: { altKey: true } } }));
assert.deepEqual(await getUserKeybindings(), expected);
});
test('remove a default keybinding should not ad duplicate entries', async () => {
const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: '-a' }];
await testObject.removeKeybinding(aResolvedKeybindingItem({ command: 'a', firstPart: { keyCode: KeyCode.KEY_C, modifiers: { altKey: true } } }));
await testObject.removeKeybinding(aResolvedKeybindingItem({ command: 'a', firstPart: { keyCode: KeyCode.KEY_C, modifiers: { altKey: true } } }));
await testObject.removeKeybinding(aResolvedKeybindingItem({ command: 'a', firstPart: { keyCode: KeyCode.KEY_C, modifiers: { altKey: true } } }));
await testObject.removeKeybinding(aResolvedKeybindingItem({ command: 'a', firstPart: { keyCode: KeyCode.KEY_C, modifiers: { altKey: true } } }));
await testObject.removeKeybinding(aResolvedKeybindingItem({ command: 'a', firstPart: { keyCode: KeyCode.KEY_C, modifiers: { altKey: true } } }));
assert.deepEqual(await getUserKeybindings(), expected);
});
test('remove a user keybinding', async () => {
await writeToKeybindingsFile({ key: 'alt+c', command: 'b' });
await testObject.removeKeybinding(aResolvedKeybindingItem({ command: 'b', firstPart: { keyCode: KeyCode.KEY_C, modifiers: { altKey: true } }, isDefault: false }));
assert.deepEqual(await getUserKeybindings(), []);
});
test('reset an edited keybinding', async () => {
await writeToKeybindingsFile({ key: 'alt+c', command: 'b' });
await testObject.resetKeybinding(aResolvedKeybindingItem({ command: 'b', firstPart: { keyCode: KeyCode.KEY_C, modifiers: { altKey: true } }, isDefault: false }));
assert.deepEqual(await getUserKeybindings(), []);
});
test('reset a removed keybinding', async () => {
await writeToKeybindingsFile({ key: 'alt+c', command: '-b' });
await testObject.resetKeybinding(aResolvedKeybindingItem({ command: 'b', isDefault: false }));
assert.deepEqual(await getUserKeybindings(), []);
});
test('reset multiple removed keybindings', async () => {
await writeToKeybindingsFile({ key: 'alt+c', command: '-b' });
await writeToKeybindingsFile({ key: 'alt+shift+c', command: '-b' });
await writeToKeybindingsFile({ key: 'escape', command: '-b' });
await testObject.resetKeybinding(aResolvedKeybindingItem({ command: 'b', isDefault: false }));
assert.deepEqual(await getUserKeybindings(), []);
});
test('add a new keybinding to unassigned keybinding', async () => {
await writeToKeybindingsFile({ key: 'alt+c', command: '-a' });
const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: '-a' }, { key: 'shift+alt+c', command: 'a' }];
await testObject.editKeybinding(aResolvedKeybindingItem({ command: 'a', isDefault: false }), 'shift+alt+c', undefined);
assert.deepEqual(await getUserKeybindings(), expected);
});
test('add when expression', async () => {
await writeToKeybindingsFile({ key: 'alt+c', command: '-a' });
const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: '-a' }, { key: 'shift+alt+c', command: 'a', when: 'editorTextFocus' }];
await testObject.editKeybinding(aResolvedKeybindingItem({ command: 'a', isDefault: false }), 'shift+alt+c', 'editorTextFocus');
assert.deepEqual(await getUserKeybindings(), expected);
});
test('update command and when expression', async () => {
await writeToKeybindingsFile({ key: 'alt+c', command: '-a', when: 'editorTextFocus && !editorReadonly' });
const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: '-a', when: 'editorTextFocus && !editorReadonly' }, { key: 'shift+alt+c', command: 'a', when: 'editorTextFocus' }];
await testObject.editKeybinding(aResolvedKeybindingItem({ command: 'a', isDefault: false }), 'shift+alt+c', 'editorTextFocus');
assert.deepEqual(await getUserKeybindings(), expected);
});
test('update when expression', async () => {
await writeToKeybindingsFile({ key: 'alt+c', command: '-a', when: 'editorTextFocus && !editorReadonly' }, { key: 'shift+alt+c', command: 'a', when: 'editorTextFocus && !editorReadonly' });
const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: '-a', when: 'editorTextFocus && !editorReadonly' }, { key: 'shift+alt+c', command: 'a', when: 'editorTextFocus' }];
await testObject.editKeybinding(aResolvedKeybindingItem({ command: 'a', isDefault: false, when: 'editorTextFocus && !editorReadonly' }), 'shift+alt+c', 'editorTextFocus');
assert.deepEqual(await getUserKeybindings(), expected);
});
test('remove when expression', async () => {
await writeToKeybindingsFile({ key: 'alt+c', command: '-a', when: 'editorTextFocus && !editorReadonly' });
const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: '-a', when: 'editorTextFocus && !editorReadonly' }, { key: 'shift+alt+c', command: 'a' }];
await testObject.editKeybinding(aResolvedKeybindingItem({ command: 'a', isDefault: false }), 'shift+alt+c', undefined);
assert.deepEqual(await getUserKeybindings(), expected);
});
async function writeToKeybindingsFile(...keybindings: IUserFriendlyKeybinding[]): Promise<void> {
await fileService.writeFile(environmentService.keybindingsResource, VSBuffer.fromString(JSON.stringify(keybindings || [])));
}
async function getUserKeybindings(): Promise<IUserFriendlyKeybinding[]> {
return json.parse((await fileService.readFile(environmentService.keybindingsResource)).value.toString());
}
function aResolvedKeybindingItem({ command, when, isDefault, firstPart, chordPart }: { command?: string, when?: string, isDefault?: boolean, firstPart?: { keyCode: KeyCode, modifiers?: Modifiers }, chordPart?: { keyCode: KeyCode, modifiers?: Modifiers } }): ResolvedKeybindingItem {
const aSimpleKeybinding = function (part: { keyCode: KeyCode, modifiers?: Modifiers }): SimpleKeybinding {
const { ctrlKey, shiftKey, altKey, metaKey } = part.modifiers || { ctrlKey: false, shiftKey: false, altKey: false, metaKey: false };
return new SimpleKeybinding(ctrlKey!, shiftKey!, altKey!, metaKey!, part.keyCode);
};
let parts: SimpleKeybinding[] = [];
if (firstPart) {
parts.push(aSimpleKeybinding(firstPart));
if (chordPart) {
parts.push(aSimpleKeybinding(chordPart));
}
}
const keybinding = parts.length > 0 ? new USLayoutResolvedKeybinding(new ChordKeybinding(parts), OS) : undefined;
return new ResolvedKeybindingItem(keybinding, command || 'some command', null, when ? ContextKeyExpr.deserialize(when) : undefined, isDefault === undefined ? true : isDefault, null, false);
}
});

View File

@@ -18,7 +18,7 @@ suite('keybindingIO', () => {
function testOneSerialization(keybinding: number, expected: string, msg: string, OS: OperatingSystem): void {
let usLayoutResolvedKeybinding = new USLayoutResolvedKeybinding(createKeybinding(keybinding, OS)!, OS);
let actualSerialized = usLayoutResolvedKeybinding.getUserSettingsLabel();
assert.equal(actualSerialized, expected, expected + ' - ' + msg);
assert.strictEqual(actualSerialized, expected, expected + ' - ' + msg);
}
function testSerialization(keybinding: number, expectedWin: string, expectedMac: string, expectedLinux: string): void {
testOneSerialization(keybinding, expectedWin, 'win', OperatingSystem.Windows);
@@ -29,7 +29,7 @@ suite('keybindingIO', () => {
function testOneDeserialization(keybinding: string, _expected: number, msg: string, OS: OperatingSystem): void {
let actualDeserialized = KeybindingParser.parseKeybinding(keybinding, OS);
let expected = createKeybinding(_expected, OS);
assert.deepEqual(actualDeserialized, expected, keybinding + ' - ' + msg);
assert.deepStrictEqual(actualDeserialized, expected, keybinding + ' - ' + msg);
}
function testDeserialization(inWin: string, inMac: string, inLinux: string, expected: number): void {
testOneDeserialization(inWin, expected, 'win', OperatingSystem.Windows);
@@ -117,7 +117,7 @@ suite('keybindingIO', () => {
});
test('deserialize scan codes', () => {
assert.deepEqual(
assert.deepStrictEqual(
KeybindingParser.parseUserBinding('ctrl+shift+[comma] ctrl+/'),
[new ScanCodeBinding(true, true, false, false, ScanCode.Comma), new SimpleKeybinding(true, false, false, false, KeyCode.US_SLASH)]
);
@@ -127,34 +127,34 @@ suite('keybindingIO', () => {
let strJSON = `[{ "key": "ctrl+k ctrl+f", "command": ["firstcommand", "seccondcommand"] }]`;
let userKeybinding = <IUserFriendlyKeybinding>JSON.parse(strJSON)[0];
let keybindingItem = KeybindingIO.readUserKeybindingItem(userKeybinding);
assert.equal(keybindingItem.command, null);
assert.strictEqual(keybindingItem.command, null);
});
test('issue #10452 - invalid when', () => {
let strJSON = `[{ "key": "ctrl+k ctrl+f", "command": "firstcommand", "when": [] }]`;
let userKeybinding = <IUserFriendlyKeybinding>JSON.parse(strJSON)[0];
let keybindingItem = KeybindingIO.readUserKeybindingItem(userKeybinding);
assert.equal(keybindingItem.when, null);
assert.strictEqual(keybindingItem.when, undefined);
});
test('issue #10452 - invalid key', () => {
let strJSON = `[{ "key": [], "command": "firstcommand" }]`;
let userKeybinding = <IUserFriendlyKeybinding>JSON.parse(strJSON)[0];
let keybindingItem = KeybindingIO.readUserKeybindingItem(userKeybinding);
assert.deepEqual(keybindingItem.parts, []);
assert.deepStrictEqual(keybindingItem.parts, []);
});
test('issue #10452 - invalid key 2', () => {
let strJSON = `[{ "key": "", "command": "firstcommand" }]`;
let userKeybinding = <IUserFriendlyKeybinding>JSON.parse(strJSON)[0];
let keybindingItem = KeybindingIO.readUserKeybindingItem(userKeybinding);
assert.deepEqual(keybindingItem.parts, []);
assert.deepStrictEqual(keybindingItem.parts, []);
});
test('test commands args', () => {
let strJSON = `[{ "key": "ctrl+k ctrl+f", "command": "firstcommand", "when": [], "args": { "text": "theText" } }]`;
let userKeybinding = <IUserFriendlyKeybinding>JSON.parse(strJSON)[0];
let keybindingItem = KeybindingIO.readUserKeybindingItem(userKeybinding);
assert.equal(keybindingItem.commandArgs.text, 'theText');
assert.strictEqual(keybindingItem.commandArgs.text, 'theText');
});
});

View File

@@ -1,330 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import * as fs from 'fs';
import * as os from 'os';
import * as path from 'vs/base/common/path';
import * as json from 'vs/base/common/json';
import { ChordKeybinding, KeyCode, SimpleKeybinding } from 'vs/base/common/keyCodes';
import { OS } from 'vs/base/common/platform';
import * as uuid from 'vs/base/common/uuid';
import { mkdirp, rimraf, RimRafMode } from 'vs/base/node/pfs';
import { IModeService } from 'vs/editor/common/services/modeService';
import { ModeServiceImpl } from 'vs/editor/common/services/modeServiceImpl';
import { IModelService } from 'vs/editor/common/services/modelService';
import { ModelServiceImpl } from 'vs/editor/common/services/modelServiceImpl';
import { ITextModelService } from 'vs/editor/common/services/resolverService';
import { ITextResourcePropertiesService } from 'vs/editor/common/services/textResourceConfigurationService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IFileService } from 'vs/platform/files/common/files';
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
import { IUserFriendlyKeybinding } from 'vs/platform/keybinding/common/keybinding';
import { ResolvedKeybindingItem } from 'vs/platform/keybinding/common/resolvedKeybindingItem';
import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/usLayoutResolvedKeybinding';
import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService';
import { ILifecycleService } from 'vs/workbench/services/lifecycle/common/lifecycle';
import { ILogService, NullLogService } from 'vs/platform/log/common/log';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IBackupFileService } from 'vs/workbench/services/backup/common/backup';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { KeybindingsEditingService } from 'vs/workbench/services/keybinding/common/keybindingEditing';
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
import { TextModelResolverService } from 'vs/workbench/services/textmodelResolver/common/textModelResolverService';
import { TestBackupFileService, TestEditorGroupsService, TestEditorService, TestLifecycleService, TestPathService, TestProductService } from 'vs/workbench/test/browser/workbenchTestServices';
import { FileService } from 'vs/platform/files/common/fileService';
import { Schemas } from 'vs/base/common/network';
import { DiskFileSystemProvider } from 'vs/platform/files/node/diskFileSystemProvider';
import { URI } from 'vs/base/common/uri';
import { FileUserDataProvider } from 'vs/workbench/services/userData/common/fileUserDataProvider';
import { NativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-browser/environmentService';
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService';
import { TestWorkbenchConfiguration, TestTextFileService } from 'vs/workbench/test/electron-browser/workbenchTestServices';
import { ILabelService } from 'vs/platform/label/common/label';
import { LabelService } from 'vs/workbench/services/label/common/labelService';
import { IFilesConfigurationService, FilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService';
import { WorkingCopyFileService, IWorkingCopyFileService } from 'vs/workbench/services/workingCopy/common/workingCopyFileService';
import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo';
import { UndoRedoService } from 'vs/platform/undoRedo/common/undoRedoService';
import { TestTextResourcePropertiesService, TestContextService, TestWorkingCopyService } from 'vs/workbench/test/common/workbenchTestServices';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService';
import { IPathService } from 'vs/workbench/services/path/common/pathService';
import { IUriIdentityService } from 'vs/workbench/services/uriIdentity/common/uriIdentity';
import { UriIdentityService } from 'vs/workbench/services/uriIdentity/common/uriIdentityService';
class TestWorkbenchEnvironmentService extends NativeWorkbenchEnvironmentService {
constructor(private _appSettingsHome: URI) {
super(TestWorkbenchConfiguration, TestProductService);
}
get appSettingsHome() { return this._appSettingsHome; }
}
interface Modifiers {
metaKey?: boolean;
ctrlKey?: boolean;
altKey?: boolean;
shiftKey?: boolean;
}
suite('KeybindingsEditing', () => {
let instantiationService: TestInstantiationService;
let testObject: KeybindingsEditingService;
let testDir: string;
let keybindingsFile: string;
setup(() => {
return setUpWorkspace().then(() => {
keybindingsFile = path.join(testDir, 'keybindings.json');
instantiationService = new TestInstantiationService();
const environmentService = new TestWorkbenchEnvironmentService(URI.file(testDir));
const configService = new TestConfigurationService();
configService.setUserConfiguration('files', { 'eol': '\n' });
instantiationService.stub(IEnvironmentService, environmentService);
instantiationService.stub(IPathService, new TestPathService());
instantiationService.stub(IConfigurationService, configService);
instantiationService.stub(IWorkspaceContextService, new TestContextService());
const lifecycleService = new TestLifecycleService();
instantiationService.stub(ILifecycleService, lifecycleService);
instantiationService.stub(IContextKeyService, <IContextKeyService>instantiationService.createInstance(MockContextKeyService));
instantiationService.stub(IEditorGroupsService, new TestEditorGroupsService());
instantiationService.stub(IEditorService, new TestEditorService());
instantiationService.stub(IWorkingCopyService, new TestWorkingCopyService());
instantiationService.stub(ITelemetryService, NullTelemetryService);
instantiationService.stub(IModeService, ModeServiceImpl);
instantiationService.stub(ILogService, new NullLogService());
instantiationService.stub(ILabelService, instantiationService.createInstance(LabelService));
instantiationService.stub(IFilesConfigurationService, instantiationService.createInstance(FilesConfigurationService));
instantiationService.stub(ITextResourcePropertiesService, new TestTextResourcePropertiesService(instantiationService.get(IConfigurationService)));
instantiationService.stub(IUndoRedoService, instantiationService.createInstance(UndoRedoService));
instantiationService.stub(IThemeService, new TestThemeService());
instantiationService.stub(IModelService, instantiationService.createInstance(ModelServiceImpl));
const fileService = new FileService(new NullLogService());
const diskFileSystemProvider = new DiskFileSystemProvider(new NullLogService());
fileService.registerProvider(Schemas.file, diskFileSystemProvider);
fileService.registerProvider(Schemas.userData, new FileUserDataProvider(Schemas.file, diskFileSystemProvider, Schemas.userData, new NullLogService()));
instantiationService.stub(IFileService, fileService);
instantiationService.stub(IUriIdentityService, new UriIdentityService(fileService));
instantiationService.stub(IWorkingCopyService, new TestWorkingCopyService());
instantiationService.stub(IWorkingCopyFileService, instantiationService.createInstance(WorkingCopyFileService));
instantiationService.stub(ITextFileService, instantiationService.createInstance(TestTextFileService));
instantiationService.stub(ITextModelService, <ITextModelService>instantiationService.createInstance(TextModelResolverService));
instantiationService.stub(IBackupFileService, new TestBackupFileService());
testObject = instantiationService.createInstance(KeybindingsEditingService);
});
});
async function setUpWorkspace(): Promise<void> {
testDir = path.join(os.tmpdir(), 'vsctests', uuid.generateUuid());
return await mkdirp(testDir, 493);
}
teardown(() => {
return new Promise<void>((c) => {
if (testDir) {
rimraf(testDir, RimRafMode.MOVE).then(c, c);
} else {
c(undefined);
}
}).then(() => testDir = null!);
});
test('errors cases - parse errors', () => {
fs.writeFileSync(keybindingsFile, ',,,,,,,,,,,,,,');
return testObject.editKeybinding(aResolvedKeybindingItem({ firstPart: { keyCode: KeyCode.Escape } }), 'alt+c', undefined)
.then(() => assert.fail('Should fail with parse errors'),
error => assert.equal(error.message, 'Unable to write to the keybindings configuration file. Please open it to correct errors/warnings in the file and try again.'));
});
test('errors cases - parse errors 2', () => {
fs.writeFileSync(keybindingsFile, '[{"key": }]');
return testObject.editKeybinding(aResolvedKeybindingItem({ firstPart: { keyCode: KeyCode.Escape } }), 'alt+c', undefined)
.then(() => assert.fail('Should fail with parse errors'),
error => assert.equal(error.message, 'Unable to write to the keybindings configuration file. Please open it to correct errors/warnings in the file and try again.'));
});
test('errors cases - dirty', () => {
instantiationService.stub(ITextFileService, 'isDirty', true);
return testObject.editKeybinding(aResolvedKeybindingItem({ firstPart: { keyCode: KeyCode.Escape } }), 'alt+c', undefined)
.then(() => assert.fail('Should fail with dirty error'),
error => assert.equal(error.message, 'Unable to write because the keybindings configuration file is dirty. Please save it first and then try again.'));
});
test('errors cases - did not find an array', () => {
fs.writeFileSync(keybindingsFile, '{"key": "alt+c", "command": "hello"}');
return testObject.editKeybinding(aResolvedKeybindingItem({ firstPart: { keyCode: KeyCode.Escape } }), 'alt+c', undefined)
.then(() => assert.fail('Should fail with dirty error'),
error => assert.equal(error.message, 'Unable to write to the keybindings configuration file. It has an object which is not of type Array. Please open the file to clean up and try again.'));
});
test('edit a default keybinding to an empty file', () => {
fs.writeFileSync(keybindingsFile, '');
const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: 'a' }, { key: 'escape', command: '-a' }];
return testObject.editKeybinding(aResolvedKeybindingItem({ firstPart: { keyCode: KeyCode.Escape }, command: 'a' }), 'alt+c', undefined)
.then(() => assert.deepEqual(getUserKeybindings(), expected));
});
test('edit a default keybinding to an empty array', () => {
writeToKeybindingsFile();
const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: 'a' }, { key: 'escape', command: '-a' }];
return testObject.editKeybinding(aResolvedKeybindingItem({ firstPart: { keyCode: KeyCode.Escape }, command: 'a' }), 'alt+c', undefined)
.then(() => assert.deepEqual(getUserKeybindings(), expected));
});
test('edit a default keybinding in an existing array', () => {
writeToKeybindingsFile({ command: 'b', key: 'shift+c' });
const expected: IUserFriendlyKeybinding[] = [{ key: 'shift+c', command: 'b' }, { key: 'alt+c', command: 'a' }, { key: 'escape', command: '-a' }];
return testObject.editKeybinding(aResolvedKeybindingItem({ firstPart: { keyCode: KeyCode.Escape }, command: 'a' }), 'alt+c', undefined)
.then(() => assert.deepEqual(getUserKeybindings(), expected));
});
test('add another keybinding', () => {
const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: 'a' }];
return testObject.addKeybinding(aResolvedKeybindingItem({ firstPart: { keyCode: KeyCode.Escape }, command: 'a' }), 'alt+c', undefined)
.then(() => assert.deepEqual(getUserKeybindings(), expected));
});
test('add a new default keybinding', () => {
const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: 'a' }];
return testObject.addKeybinding(aResolvedKeybindingItem({ command: 'a' }), 'alt+c', undefined)
.then(() => assert.deepEqual(getUserKeybindings(), expected));
});
test('add a new default keybinding using edit', () => {
const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: 'a' }];
return testObject.editKeybinding(aResolvedKeybindingItem({ command: 'a' }), 'alt+c', undefined)
.then(() => assert.deepEqual(getUserKeybindings(), expected));
});
test('edit an user keybinding', () => {
writeToKeybindingsFile({ key: 'escape', command: 'b' });
const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: 'b' }];
return testObject.editKeybinding(aResolvedKeybindingItem({ firstPart: { keyCode: KeyCode.Escape }, command: 'b', isDefault: false }), 'alt+c', undefined)
.then(() => assert.deepEqual(getUserKeybindings(), expected));
});
test('edit an user keybinding with more than one element', () => {
writeToKeybindingsFile({ key: 'escape', command: 'b' }, { key: 'alt+shift+g', command: 'c' });
const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: 'b' }, { key: 'alt+shift+g', command: 'c' }];
return testObject.editKeybinding(aResolvedKeybindingItem({ firstPart: { keyCode: KeyCode.Escape }, command: 'b', isDefault: false }), 'alt+c', undefined)
.then(() => assert.deepEqual(getUserKeybindings(), expected));
});
test('remove a default keybinding', () => {
const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: '-a' }];
return testObject.removeKeybinding(aResolvedKeybindingItem({ command: 'a', firstPart: { keyCode: KeyCode.KEY_C, modifiers: { altKey: true } } }))
.then(() => assert.deepEqual(getUserKeybindings(), expected));
});
test('remove a default keybinding should not ad duplicate entries', async () => {
const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: '-a' }];
await testObject.removeKeybinding(aResolvedKeybindingItem({ command: 'a', firstPart: { keyCode: KeyCode.KEY_C, modifiers: { altKey: true } } }));
await testObject.removeKeybinding(aResolvedKeybindingItem({ command: 'a', firstPart: { keyCode: KeyCode.KEY_C, modifiers: { altKey: true } } }));
await testObject.removeKeybinding(aResolvedKeybindingItem({ command: 'a', firstPart: { keyCode: KeyCode.KEY_C, modifiers: { altKey: true } } }));
await testObject.removeKeybinding(aResolvedKeybindingItem({ command: 'a', firstPart: { keyCode: KeyCode.KEY_C, modifiers: { altKey: true } } }));
await testObject.removeKeybinding(aResolvedKeybindingItem({ command: 'a', firstPart: { keyCode: KeyCode.KEY_C, modifiers: { altKey: true } } }));
assert.deepEqual(getUserKeybindings(), expected);
});
test('remove a user keybinding', () => {
writeToKeybindingsFile({ key: 'alt+c', command: 'b' });
return testObject.removeKeybinding(aResolvedKeybindingItem({ command: 'b', firstPart: { keyCode: KeyCode.KEY_C, modifiers: { altKey: true } }, isDefault: false }))
.then(() => assert.deepEqual(getUserKeybindings(), []));
});
test('reset an edited keybinding', () => {
writeToKeybindingsFile({ key: 'alt+c', command: 'b' });
return testObject.resetKeybinding(aResolvedKeybindingItem({ command: 'b', firstPart: { keyCode: KeyCode.KEY_C, modifiers: { altKey: true } }, isDefault: false }))
.then(() => assert.deepEqual(getUserKeybindings(), []));
});
test('reset a removed keybinding', () => {
writeToKeybindingsFile({ key: 'alt+c', command: '-b' });
return testObject.resetKeybinding(aResolvedKeybindingItem({ command: 'b', isDefault: false }))
.then(() => assert.deepEqual(getUserKeybindings(), []));
});
test('reset multiple removed keybindings', () => {
writeToKeybindingsFile({ key: 'alt+c', command: '-b' });
writeToKeybindingsFile({ key: 'alt+shift+c', command: '-b' });
writeToKeybindingsFile({ key: 'escape', command: '-b' });
return testObject.resetKeybinding(aResolvedKeybindingItem({ command: 'b', isDefault: false }))
.then(() => assert.deepEqual(getUserKeybindings(), []));
});
test('add a new keybinding to unassigned keybinding', () => {
writeToKeybindingsFile({ key: 'alt+c', command: '-a' });
const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: '-a' }, { key: 'shift+alt+c', command: 'a' }];
return testObject.editKeybinding(aResolvedKeybindingItem({ command: 'a', isDefault: false }), 'shift+alt+c', undefined)
.then(() => assert.deepEqual(getUserKeybindings(), expected));
});
test('add when expression', () => {
writeToKeybindingsFile({ key: 'alt+c', command: '-a' });
const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: '-a' }, { key: 'shift+alt+c', command: 'a', when: 'editorTextFocus' }];
return testObject.editKeybinding(aResolvedKeybindingItem({ command: 'a', isDefault: false }), 'shift+alt+c', 'editorTextFocus')
.then(() => assert.deepEqual(getUserKeybindings(), expected));
});
test('update command and when expression', () => {
writeToKeybindingsFile({ key: 'alt+c', command: '-a', when: 'editorTextFocus && !editorReadonly' });
const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: '-a', when: 'editorTextFocus && !editorReadonly' }, { key: 'shift+alt+c', command: 'a', when: 'editorTextFocus' }];
return testObject.editKeybinding(aResolvedKeybindingItem({ command: 'a', isDefault: false }), 'shift+alt+c', 'editorTextFocus')
.then(() => assert.deepEqual(getUserKeybindings(), expected));
});
test('update when expression', () => {
writeToKeybindingsFile({ key: 'alt+c', command: '-a', when: 'editorTextFocus && !editorReadonly' }, { key: 'shift+alt+c', command: 'a', when: 'editorTextFocus && !editorReadonly' });
const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: '-a', when: 'editorTextFocus && !editorReadonly' }, { key: 'shift+alt+c', command: 'a', when: 'editorTextFocus' }];
return testObject.editKeybinding(aResolvedKeybindingItem({ command: 'a', isDefault: false, when: 'editorTextFocus && !editorReadonly' }), 'shift+alt+c', 'editorTextFocus')
.then(() => assert.deepEqual(getUserKeybindings(), expected));
});
test('remove when expression', () => {
writeToKeybindingsFile({ key: 'alt+c', command: '-a', when: 'editorTextFocus && !editorReadonly' });
const expected: IUserFriendlyKeybinding[] = [{ key: 'alt+c', command: '-a', when: 'editorTextFocus && !editorReadonly' }, { key: 'shift+alt+c', command: 'a' }];
return testObject.editKeybinding(aResolvedKeybindingItem({ command: 'a', isDefault: false }), 'shift+alt+c', undefined)
.then(() => assert.deepEqual(getUserKeybindings(), expected));
});
function writeToKeybindingsFile(...keybindings: IUserFriendlyKeybinding[]) {
fs.writeFileSync(keybindingsFile, JSON.stringify(keybindings || []));
}
function getUserKeybindings(): IUserFriendlyKeybinding[] {
return json.parse(fs.readFileSync(keybindingsFile).toString('utf8'));
}
function aResolvedKeybindingItem({ command, when, isDefault, firstPart, chordPart }: { command?: string, when?: string, isDefault?: boolean, firstPart?: { keyCode: KeyCode, modifiers?: Modifiers }, chordPart?: { keyCode: KeyCode, modifiers?: Modifiers } }): ResolvedKeybindingItem {
const aSimpleKeybinding = function (part: { keyCode: KeyCode, modifiers?: Modifiers }): SimpleKeybinding {
const { ctrlKey, shiftKey, altKey, metaKey } = part.modifiers || { ctrlKey: false, shiftKey: false, altKey: false, metaKey: false };
return new SimpleKeybinding(ctrlKey!, shiftKey!, altKey!, metaKey!, part.keyCode);
};
let parts: SimpleKeybinding[] = [];
if (firstPart) {
parts.push(aSimpleKeybinding(firstPart));
if (chordPart) {
parts.push(aSimpleKeybinding(chordPart));
}
}
const keybinding = parts.length > 0 ? new USLayoutResolvedKeybinding(new ChordKeybinding(parts), OS) : undefined;
return new ResolvedKeybindingItem(keybinding, command || 'some command', null, when ? ContextKeyExpr.deserialize(when) : undefined, isDefault === undefined ? true : isDefault, null, false);
}
});

View File

@@ -5,10 +5,11 @@
import * as assert from 'assert';
import * as path from 'vs/base/common/path';
import { promises } from 'fs';
import { getPathFromAmdModule } from 'vs/base/common/amd';
import { Keybinding, ResolvedKeybinding, SimpleKeybinding } from 'vs/base/common/keyCodes';
import { ScanCodeBinding } from 'vs/base/common/scanCode';
import { readFile, writeFile } from 'vs/base/node/pfs';
import { writeFile } from 'vs/base/node/pfs';
import { IKeyboardEvent } from 'vs/platform/keybinding/common/keybinding';
import { IKeyboardMapper } from 'vs/platform/keyboardLayout/common/keyboardMapper';
@@ -20,6 +21,7 @@ export interface IResolvedKeybinding {
isWYSIWYG: boolean;
isChord: boolean;
dispatchParts: (string | null)[];
singleModifierDispatchParts: (string | null)[];
}
function toIResolvedKeybinding(kb: ResolvedKeybinding): IResolvedKeybinding {
@@ -31,6 +33,7 @@ function toIResolvedKeybinding(kb: ResolvedKeybinding): IResolvedKeybinding {
isWYSIWYG: kb.isWYSIWYG(),
isChord: kb.isChord(),
dispatchParts: kb.getDispatchParts(),
singleModifierDispatchParts: kb.getSingleModifierDispatchParts()
};
}
@@ -50,7 +53,7 @@ export function assertResolveUserBinding(mapper: IKeyboardMapper, parts: (Simple
}
export function readRawMapping<T>(file: string): Promise<T> {
return readFile(getPathFromAmdModule(require, `vs/workbench/services/keybinding/test/electron-browser/${file}.js`)).then((buff) => {
return promises.readFile(getPathFromAmdModule(require, `vs/workbench/services/keybinding/test/electron-browser/${file}.js`)).then((buff) => {
let contents = buff.toString();
let func = new Function('define', contents);
let rawMappings: T | null = null;
@@ -64,14 +67,13 @@ export function readRawMapping<T>(file: string): Promise<T> {
export function assertMapping(writeFileIfDifferent: boolean, mapper: IKeyboardMapper, file: string): Promise<void> {
const filePath = path.normalize(getPathFromAmdModule(require, `vs/workbench/services/keybinding/test/electron-browser/${file}`));
return readFile(filePath).then((buff) => {
let expected = buff.toString();
const actual = mapper.dumpDebugInfo();
return promises.readFile(filePath).then((buff) => {
const expected = buff.toString().replace(/\r\n/g, '\n');
const actual = mapper.dumpDebugInfo().replace(/\r\n/g, '\n');
if (actual !== expected && writeFileIfDifferent) {
const destPath = filePath.replace(/vscode[\/\\]out[\/\\]vs/, 'vscode/src/vs');
writeFile(destPath, actual);
}
assert.deepEqual(actual.split(/\r\n|\n/), expected.split(/\r\n|\n/));
assert.deepEqual(actual, expected);
});
}

View File

@@ -28,6 +28,7 @@ suite('keyboardMapper - MAC fallback', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['meta+Z'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -43,6 +44,7 @@ suite('keyboardMapper - MAC fallback', () => {
isWYSIWYG: true,
isChord: true,
dispatchParts: ['meta+K', 'meta+='],
singleModifierDispatchParts: [null, null],
}]
);
});
@@ -67,6 +69,7 @@ suite('keyboardMapper - MAC fallback', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['meta+Z'],
singleModifierDispatchParts: [null],
}
);
});
@@ -89,11 +92,12 @@ suite('keyboardMapper - MAC fallback', () => {
isWYSIWYG: true,
isChord: true,
dispatchParts: ['meta+,', 'meta+/'],
singleModifierDispatchParts: [null, null],
}]
);
});
test('resolveKeyboardEvent Modifier only Meta+', () => {
test('resolveKeyboardEvent Single Modifier Meta+', () => {
assertResolveKeyboardEvent(
mapper,
{
@@ -113,6 +117,107 @@ suite('keyboardMapper - MAC fallback', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: [null],
singleModifierDispatchParts: ['meta'],
}
);
});
test('resolveKeyboardEvent Single Modifier Shift+', () => {
assertResolveKeyboardEvent(
mapper,
{
_standardKeyboardEventBrand: true,
ctrlKey: false,
shiftKey: true,
altKey: false,
metaKey: false,
keyCode: KeyCode.Shift,
code: null!
},
{
label: '⇧',
ariaLabel: 'Shift',
electronAccelerator: null,
userSettingsLabel: 'shift',
isWYSIWYG: true,
isChord: false,
dispatchParts: [null],
singleModifierDispatchParts: ['shift'],
}
);
});
test('resolveKeyboardEvent Single Modifier Alt+', () => {
assertResolveKeyboardEvent(
mapper,
{
_standardKeyboardEventBrand: true,
ctrlKey: false,
shiftKey: false,
altKey: true,
metaKey: false,
keyCode: KeyCode.Alt,
code: null!
},
{
label: '⌥',
ariaLabel: 'Alt',
electronAccelerator: null,
userSettingsLabel: 'alt',
isWYSIWYG: true,
isChord: false,
dispatchParts: [null],
singleModifierDispatchParts: ['alt'],
}
);
});
test('resolveKeyboardEvent Single Modifier Meta+', () => {
assertResolveKeyboardEvent(
mapper,
{
_standardKeyboardEventBrand: true,
ctrlKey: false,
shiftKey: false,
altKey: false,
metaKey: true,
keyCode: KeyCode.Meta,
code: null!
},
{
label: '⌘',
ariaLabel: 'Command',
electronAccelerator: null,
userSettingsLabel: 'cmd',
isWYSIWYG: true,
isChord: false,
dispatchParts: [null],
singleModifierDispatchParts: ['meta'],
}
);
});
test('resolveKeyboardEvent Only Modifiers Ctrl+Shift+', () => {
assertResolveKeyboardEvent(
mapper,
{
_standardKeyboardEventBrand: true,
ctrlKey: true,
shiftKey: true,
altKey: false,
metaKey: false,
keyCode: KeyCode.Shift,
code: null!
},
{
label: '⌃⇧',
ariaLabel: 'Control+Shift',
electronAccelerator: null,
userSettingsLabel: 'ctrl+shift',
isWYSIWYG: true,
isChord: false,
dispatchParts: [null],
singleModifierDispatchParts: [null],
}
);
});
@@ -137,6 +242,7 @@ suite('keyboardMapper - LINUX fallback', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+Z'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -152,6 +258,7 @@ suite('keyboardMapper - LINUX fallback', () => {
isWYSIWYG: true,
isChord: true,
dispatchParts: ['ctrl+K', 'ctrl+='],
singleModifierDispatchParts: [null, null],
}]
);
});
@@ -176,6 +283,7 @@ suite('keyboardMapper - LINUX fallback', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+Z'],
singleModifierDispatchParts: [null],
}
);
});
@@ -194,6 +302,7 @@ suite('keyboardMapper - LINUX fallback', () => {
isWYSIWYG: true,
isChord: true,
dispatchParts: ['ctrl+,', 'ctrl+/'],
singleModifierDispatchParts: [null, null],
}]
);
});
@@ -211,11 +320,12 @@ suite('keyboardMapper - LINUX fallback', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+,'],
singleModifierDispatchParts: [null],
}]
);
});
test('resolveKeyboardEvent Modifier only Ctrl+', () => {
test('resolveKeyboardEvent Single Modifier Ctrl+', () => {
assertResolveKeyboardEvent(
mapper,
{
@@ -235,6 +345,7 @@ suite('keyboardMapper - LINUX fallback', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: [null],
singleModifierDispatchParts: ['ctrl'],
}
);
});

View File

@@ -67,6 +67,7 @@ suite('keyboardMapper - MAC de_ch', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['meta+[KeyA]'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -82,6 +83,7 @@ suite('keyboardMapper - MAC de_ch', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['meta+[KeyB]'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -97,6 +99,7 @@ suite('keyboardMapper - MAC de_ch', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['meta+[KeyY]'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -121,6 +124,7 @@ suite('keyboardMapper - MAC de_ch', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['meta+[KeyY]'],
singleModifierDispatchParts: [null],
}
);
});
@@ -136,6 +140,7 @@ suite('keyboardMapper - MAC de_ch', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+alt+meta+[Digit6]'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -160,6 +165,7 @@ suite('keyboardMapper - MAC de_ch', () => {
isWYSIWYG: false,
isChord: false,
dispatchParts: ['meta+[BracketRight]'],
singleModifierDispatchParts: [null],
}
);
});
@@ -175,6 +181,7 @@ suite('keyboardMapper - MAC de_ch', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+alt+[Digit9]'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -190,6 +197,7 @@ suite('keyboardMapper - MAC de_ch', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['shift+meta+[Digit7]'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -205,6 +213,7 @@ suite('keyboardMapper - MAC de_ch', () => {
isWYSIWYG: false,
isChord: false,
dispatchParts: ['shift+meta+[Minus]'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -220,6 +229,7 @@ suite('keyboardMapper - MAC de_ch', () => {
isWYSIWYG: true,
isChord: true,
dispatchParts: ['meta+[KeyK]', 'ctrl+shift+alt+meta+[Digit7]'],
singleModifierDispatchParts: [null, null],
}]
);
});
@@ -235,6 +245,7 @@ suite('keyboardMapper - MAC de_ch', () => {
isWYSIWYG: true,
isChord: true,
dispatchParts: ['meta+[KeyK]', 'shift+meta+[Digit0]'],
singleModifierDispatchParts: [null, null],
}]
);
});
@@ -250,6 +261,7 @@ suite('keyboardMapper - MAC de_ch', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['meta+[ArrowDown]'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -265,6 +277,7 @@ suite('keyboardMapper - MAC de_ch', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['meta+[Numpad0]'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -280,6 +293,7 @@ suite('keyboardMapper - MAC de_ch', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['meta+[Home]'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -304,6 +318,7 @@ suite('keyboardMapper - MAC de_ch', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['meta+[Home]'],
singleModifierDispatchParts: [null],
}
);
});
@@ -327,11 +342,12 @@ suite('keyboardMapper - MAC de_ch', () => {
isWYSIWYG: false,
isChord: true,
dispatchParts: ['meta+[Comma]', 'shift+meta+[Digit7]'],
singleModifierDispatchParts: [null, null],
}]
);
});
test('resolveKeyboardEvent Modifier only MetaLeft+', () => {
test('resolveKeyboardEvent Single Modifier MetaLeft+', () => {
assertResolveKeyboardEvent(
mapper,
{
@@ -351,11 +367,12 @@ suite('keyboardMapper - MAC de_ch', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: [null],
singleModifierDispatchParts: ['meta'],
}
);
});
test('resolveKeyboardEvent Modifier only MetaRight+', () => {
test('resolveKeyboardEvent Single Modifier MetaRight+', () => {
assertResolveKeyboardEvent(
mapper,
{
@@ -375,6 +392,7 @@ suite('keyboardMapper - MAC de_ch', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: [null],
singleModifierDispatchParts: ['meta'],
}
);
});
@@ -408,11 +426,12 @@ suite('keyboardMapper - MAC en_us', () => {
isWYSIWYG: true,
isChord: true,
dispatchParts: ['meta+[Comma]', 'meta+[Slash]'],
singleModifierDispatchParts: [null, null],
}]
);
});
test('resolveKeyboardEvent Modifier only MetaLeft+', () => {
test('resolveKeyboardEvent Single Modifier MetaLeft+', () => {
assertResolveKeyboardEvent(
mapper,
{
@@ -432,11 +451,12 @@ suite('keyboardMapper - MAC en_us', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: [null],
singleModifierDispatchParts: ['meta'],
}
);
});
test('resolveKeyboardEvent Modifier only MetaRight+', () => {
test('resolveKeyboardEvent Single Modifier MetaRight+', () => {
assertResolveKeyboardEvent(
mapper,
{
@@ -456,6 +476,7 @@ suite('keyboardMapper - MAC en_us', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: [null],
singleModifierDispatchParts: ['meta'],
}
);
});
@@ -508,6 +529,7 @@ suite('keyboardMapper - LINUX de_ch', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[KeyA]'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -523,6 +545,7 @@ suite('keyboardMapper - LINUX de_ch', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[KeyY]'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -547,6 +570,7 @@ suite('keyboardMapper - LINUX de_ch', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[KeyY]'],
singleModifierDispatchParts: [null],
}
);
});
@@ -578,6 +602,7 @@ suite('keyboardMapper - LINUX de_ch', () => {
isWYSIWYG: false,
isChord: false,
dispatchParts: ['ctrl+[BracketRight]'],
singleModifierDispatchParts: [null],
}
);
});
@@ -593,6 +618,7 @@ suite('keyboardMapper - LINUX de_ch', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+alt+[Digit0]'],
singleModifierDispatchParts: [null],
}, {
label: 'Ctrl+Alt+$',
ariaLabel: 'Control+Alt+$',
@@ -601,6 +627,7 @@ suite('keyboardMapper - LINUX de_ch', () => {
isWYSIWYG: false,
isChord: false,
dispatchParts: ['ctrl+alt+[Backslash]'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -616,6 +643,7 @@ suite('keyboardMapper - LINUX de_ch', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+shift+[Digit7]'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -631,6 +659,7 @@ suite('keyboardMapper - LINUX de_ch', () => {
isWYSIWYG: false,
isChord: false,
dispatchParts: ['ctrl+shift+[Minus]'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -653,6 +682,7 @@ suite('keyboardMapper - LINUX de_ch', () => {
isWYSIWYG: true,
isChord: true,
dispatchParts: ['ctrl+[KeyK]', 'ctrl+shift+[Digit0]'],
singleModifierDispatchParts: [null, null],
}]
);
});
@@ -668,6 +698,7 @@ suite('keyboardMapper - LINUX de_ch', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[ArrowDown]'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -683,6 +714,7 @@ suite('keyboardMapper - LINUX de_ch', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[Numpad0]'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -698,6 +730,7 @@ suite('keyboardMapper - LINUX de_ch', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[Home]'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -722,6 +755,7 @@ suite('keyboardMapper - LINUX de_ch', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[Home]'],
singleModifierDispatchParts: [null],
}
);
});
@@ -746,6 +780,7 @@ suite('keyboardMapper - LINUX de_ch', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[KeyX]'],
singleModifierDispatchParts: [null],
}
);
});
@@ -764,11 +799,12 @@ suite('keyboardMapper - LINUX de_ch', () => {
isWYSIWYG: false,
isChord: true,
dispatchParts: ['ctrl+[Comma]', 'ctrl+shift+[Digit7]'],
singleModifierDispatchParts: [null, null],
}]
);
});
test('resolveKeyboardEvent Modifier only ControlLeft+', () => {
test('resolveKeyboardEvent Single Modifier ControlLeft+', () => {
assertResolveKeyboardEvent(
mapper,
{
@@ -788,11 +824,12 @@ suite('keyboardMapper - LINUX de_ch', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: [null],
singleModifierDispatchParts: ['ctrl'],
}
);
});
test('resolveKeyboardEvent Modifier only ControlRight+', () => {
test('resolveKeyboardEvent Single Modifier ControlRight+', () => {
assertResolveKeyboardEvent(
mapper,
{
@@ -812,6 +849,7 @@ suite('keyboardMapper - LINUX de_ch', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: [null],
singleModifierDispatchParts: ['ctrl'],
}
);
});
@@ -845,6 +883,7 @@ suite('keyboardMapper - LINUX en_us', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[KeyA]'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -860,6 +899,7 @@ suite('keyboardMapper - LINUX en_us', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[KeyZ]'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -884,6 +924,7 @@ suite('keyboardMapper - LINUX en_us', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[KeyZ]'],
singleModifierDispatchParts: [null],
}
);
});
@@ -899,6 +940,7 @@ suite('keyboardMapper - LINUX en_us', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[BracketRight]'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -923,6 +965,7 @@ suite('keyboardMapper - LINUX en_us', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[BracketRight]'],
singleModifierDispatchParts: [null],
}
);
});
@@ -938,6 +981,7 @@ suite('keyboardMapper - LINUX en_us', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['shift+[BracketRight]'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -953,6 +997,7 @@ suite('keyboardMapper - LINUX en_us', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[Slash]'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -968,6 +1013,7 @@ suite('keyboardMapper - LINUX en_us', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+shift+[Slash]'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -983,6 +1029,7 @@ suite('keyboardMapper - LINUX en_us', () => {
isWYSIWYG: true,
isChord: true,
dispatchParts: ['ctrl+[KeyK]', 'ctrl+[Backslash]'],
singleModifierDispatchParts: [null, null],
}]
);
});
@@ -998,6 +1045,7 @@ suite('keyboardMapper - LINUX en_us', () => {
isWYSIWYG: true,
isChord: true,
dispatchParts: ['ctrl+[KeyK]', 'ctrl+[Equal]'],
singleModifierDispatchParts: [null, null],
}]
);
});
@@ -1013,6 +1061,7 @@ suite('keyboardMapper - LINUX en_us', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[ArrowDown]'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -1028,6 +1077,7 @@ suite('keyboardMapper - LINUX en_us', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[Numpad0]'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -1043,6 +1093,7 @@ suite('keyboardMapper - LINUX en_us', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[Home]'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -1067,6 +1118,7 @@ suite('keyboardMapper - LINUX en_us', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[Home]'],
singleModifierDispatchParts: [null],
}
);
});
@@ -1082,6 +1134,7 @@ suite('keyboardMapper - LINUX en_us', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+shift+[Comma]'],
singleModifierDispatchParts: [null],
}, {
label: 'Ctrl+<',
ariaLabel: 'Control+<',
@@ -1090,6 +1143,7 @@ suite('keyboardMapper - LINUX en_us', () => {
isWYSIWYG: false,
isChord: false,
dispatchParts: ['ctrl+[IntlBackslash]'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -1105,6 +1159,7 @@ suite('keyboardMapper - LINUX en_us', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[Enter]'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -1129,6 +1184,7 @@ suite('keyboardMapper - LINUX en_us', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[Enter]'],
singleModifierDispatchParts: [null],
}
);
});
@@ -1147,6 +1203,7 @@ suite('keyboardMapper - LINUX en_us', () => {
isWYSIWYG: true,
isChord: true,
dispatchParts: ['ctrl+[Comma]', 'ctrl+[Slash]'],
singleModifierDispatchParts: [null, null],
}]
);
});
@@ -1164,11 +1221,12 @@ suite('keyboardMapper - LINUX en_us', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[Comma]'],
singleModifierDispatchParts: [null],
}]
);
});
test('resolveKeyboardEvent Modifier only ControlLeft+', () => {
test('resolveKeyboardEvent Single Modifier ControlLeft+', () => {
assertResolveKeyboardEvent(
mapper,
{
@@ -1188,11 +1246,12 @@ suite('keyboardMapper - LINUX en_us', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: [null],
singleModifierDispatchParts: ['ctrl'],
}
);
});
test('resolveKeyboardEvent Modifier only ControlRight+', () => {
test('resolveKeyboardEvent Single Modifier ControlRight+', () => {
assertResolveKeyboardEvent(
mapper,
{
@@ -1212,6 +1271,182 @@ suite('keyboardMapper - LINUX en_us', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: [null],
singleModifierDispatchParts: ['ctrl'],
}
);
});
test('resolveKeyboardEvent Single Modifier ShiftLeft+', () => {
assertResolveKeyboardEvent(
mapper,
{
_standardKeyboardEventBrand: true,
ctrlKey: false,
shiftKey: true,
altKey: false,
metaKey: false,
keyCode: -1,
code: 'ShiftLeft'
},
{
label: 'Shift',
ariaLabel: 'Shift',
electronAccelerator: null,
userSettingsLabel: 'shift',
isWYSIWYG: true,
isChord: false,
dispatchParts: [null],
singleModifierDispatchParts: ['shift'],
}
);
});
test('resolveKeyboardEvent Single Modifier ShiftRight+', () => {
assertResolveKeyboardEvent(
mapper,
{
_standardKeyboardEventBrand: true,
ctrlKey: false,
shiftKey: true,
altKey: false,
metaKey: false,
keyCode: -1,
code: 'ShiftRight'
},
{
label: 'Shift',
ariaLabel: 'Shift',
electronAccelerator: null,
userSettingsLabel: 'shift',
isWYSIWYG: true,
isChord: false,
dispatchParts: [null],
singleModifierDispatchParts: ['shift'],
}
);
});
test('resolveKeyboardEvent Single Modifier AltLeft+', () => {
assertResolveKeyboardEvent(
mapper,
{
_standardKeyboardEventBrand: true,
ctrlKey: false,
shiftKey: false,
altKey: true,
metaKey: false,
keyCode: -1,
code: 'AltLeft'
},
{
label: 'Alt',
ariaLabel: 'Alt',
electronAccelerator: null,
userSettingsLabel: 'alt',
isWYSIWYG: true,
isChord: false,
dispatchParts: [null],
singleModifierDispatchParts: ['alt'],
}
);
});
test('resolveKeyboardEvent Single Modifier AltRight+', () => {
assertResolveKeyboardEvent(
mapper,
{
_standardKeyboardEventBrand: true,
ctrlKey: false,
shiftKey: false,
altKey: true,
metaKey: false,
keyCode: -1,
code: 'AltRight'
},
{
label: 'Alt',
ariaLabel: 'Alt',
electronAccelerator: null,
userSettingsLabel: 'alt',
isWYSIWYG: true,
isChord: false,
dispatchParts: [null],
singleModifierDispatchParts: ['alt'],
}
);
});
test('resolveKeyboardEvent Single Modifier MetaLeft+', () => {
assertResolveKeyboardEvent(
mapper,
{
_standardKeyboardEventBrand: true,
ctrlKey: false,
shiftKey: false,
altKey: false,
metaKey: true,
keyCode: -1,
code: 'MetaLeft'
},
{
label: 'Super',
ariaLabel: 'Super',
electronAccelerator: null,
userSettingsLabel: 'meta',
isWYSIWYG: true,
isChord: false,
dispatchParts: [null],
singleModifierDispatchParts: ['meta'],
}
);
});
test('resolveKeyboardEvent Single Modifier MetaRight+', () => {
assertResolveKeyboardEvent(
mapper,
{
_standardKeyboardEventBrand: true,
ctrlKey: false,
shiftKey: false,
altKey: false,
metaKey: true,
keyCode: -1,
code: 'MetaRight'
},
{
label: 'Super',
ariaLabel: 'Super',
electronAccelerator: null,
userSettingsLabel: 'meta',
isWYSIWYG: true,
isChord: false,
dispatchParts: [null],
singleModifierDispatchParts: ['meta'],
}
);
});
test('resolveKeyboardEvent Only Modifiers Ctrl+Shift+', () => {
assertResolveKeyboardEvent(
mapper,
{
_standardKeyboardEventBrand: true,
ctrlKey: true,
shiftKey: true,
altKey: false,
metaKey: false,
keyCode: -1,
code: 'ShiftLeft'
},
{
label: 'Ctrl+Shift',
ariaLabel: 'Control+Shift',
electronAccelerator: null,
userSettingsLabel: 'ctrl+shift',
isWYSIWYG: true,
isChord: false,
dispatchParts: [null],
singleModifierDispatchParts: [null],
}
);
});
@@ -1248,6 +1483,7 @@ suite('keyboardMapper', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[Backquote]'],
singleModifierDispatchParts: [null],
}
);
});
@@ -1275,6 +1511,7 @@ suite('keyboardMapper', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: [dispatch],
singleModifierDispatchParts: [null],
}
);
}
@@ -1315,6 +1552,7 @@ suite('keyboardMapper', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: [dispatch],
singleModifierDispatchParts: [null],
}
);
}
@@ -1373,6 +1611,7 @@ suite('keyboardMapper - LINUX ru', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[KeyS]'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -1411,6 +1650,7 @@ suite('keyboardMapper - LINUX en_uk', () => {
isWYSIWYG: false,
isChord: false,
dispatchParts: ['ctrl+alt+[Minus]'],
singleModifierDispatchParts: [null],
}
);
});
@@ -1444,6 +1684,7 @@ suite('keyboardMapper - MAC zh_hant', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['meta+[KeyC]'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -1465,11 +1706,11 @@ function _assertKeybindingTranslation(mapper: MacLinuxKeyboardMapper, OS: Operat
const actualHardwareKeypresses = mapper.simpleKeybindingToScanCodeBinding(runtimeKeybinding);
if (actualHardwareKeypresses.length === 0) {
assert.deepEqual([], expected, `simpleKeybindingToHardwareKeypress -- "${keybindingLabel}" -- actual: "[]" -- expected: "${expected}"`);
assert.deepStrictEqual([], expected, `simpleKeybindingToHardwareKeypress -- "${keybindingLabel}" -- actual: "[]" -- expected: "${expected}"`);
return;
}
const actual = actualHardwareKeypresses
.map(k => UserSettingsLabelProvider.toLabel(OS, [k], (keybinding) => ScanCodeUtils.toString(keybinding.scanCode)));
assert.deepEqual(actual, expected, `simpleKeybindingToHardwareKeypress -- "${keybindingLabel}" -- actual: "${actual}" -- expected: "${expected}"`);
assert.deepStrictEqual(actual, expected, `simpleKeybindingToHardwareKeypress -- "${keybindingLabel}" -- actual: "${actual}" -- expected: "${expected}"`);
}

View File

@@ -46,6 +46,7 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+A'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -62,6 +63,7 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+Z'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -86,6 +88,7 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+Z'],
singleModifierDispatchParts: [null],
}
);
});
@@ -97,11 +100,12 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
[{
label: 'Ctrl+^',
ariaLabel: 'Control+^',
electronAccelerator: 'Ctrl+]',
electronAccelerator: null,
userSettingsLabel: 'ctrl+oem_6',
isWYSIWYG: false,
isChord: false,
dispatchParts: ['ctrl+]'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -121,11 +125,12 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
{
label: 'Ctrl+^',
ariaLabel: 'Control+^',
electronAccelerator: 'Ctrl+]',
electronAccelerator: null,
userSettingsLabel: 'ctrl+oem_6',
isWYSIWYG: false,
isChord: false,
dispatchParts: ['ctrl+]'],
singleModifierDispatchParts: [null],
}
);
});
@@ -137,11 +142,12 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
[{
label: 'Shift+^',
ariaLabel: 'Shift+^',
electronAccelerator: 'Shift+]',
electronAccelerator: null,
userSettingsLabel: 'shift+oem_6',
isWYSIWYG: false,
isChord: false,
dispatchParts: ['shift+]'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -153,11 +159,12 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
[{
label: 'Ctrl+§',
ariaLabel: 'Control+§',
electronAccelerator: 'Ctrl+/',
electronAccelerator: null,
userSettingsLabel: 'ctrl+oem_2',
isWYSIWYG: false,
isChord: false,
dispatchParts: ['ctrl+/'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -169,11 +176,12 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
[{
label: 'Ctrl+Shift+§',
ariaLabel: 'Control+Shift+§',
electronAccelerator: 'Ctrl+Shift+/',
electronAccelerator: null,
userSettingsLabel: 'ctrl+shift+oem_2',
isWYSIWYG: false,
isChord: false,
dispatchParts: ['ctrl+shift+/'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -190,6 +198,7 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
isWYSIWYG: false,
isChord: true,
dispatchParts: ['ctrl+K', 'ctrl+\\'],
singleModifierDispatchParts: [null, null],
}]
);
});
@@ -214,6 +223,7 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+DownArrow'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -230,6 +240,7 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+NumPad0'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -246,6 +257,7 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+Home'],
singleModifierDispatchParts: [null],
}]
);
});
@@ -270,6 +282,7 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+Home'],
singleModifierDispatchParts: [null],
}
);
});
@@ -292,11 +305,12 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
isWYSIWYG: false,
isChord: true,
dispatchParts: ['ctrl+,', 'ctrl+/'],
singleModifierDispatchParts: [null, null],
}]
);
});
test('resolveKeyboardEvent Modifier only Ctrl+', () => {
test('resolveKeyboardEvent Single Modifier Ctrl+', () => {
assertResolveKeyboardEvent(
mapper,
{
@@ -316,6 +330,7 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: [null],
singleModifierDispatchParts: ['ctrl'],
}
);
});
@@ -345,6 +360,7 @@ suite('keyboardMapper - WINDOWS en_us', () => {
isWYSIWYG: true,
isChord: true,
dispatchParts: ['ctrl+K', 'ctrl+\\'],
singleModifierDispatchParts: [null, null],
}]
);
});
@@ -363,6 +379,7 @@ suite('keyboardMapper - WINDOWS en_us', () => {
isWYSIWYG: true,
isChord: true,
dispatchParts: ['ctrl+,', 'ctrl+/'],
singleModifierDispatchParts: [null, null],
}]
);
});
@@ -380,11 +397,12 @@ suite('keyboardMapper - WINDOWS en_us', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+,'],
singleModifierDispatchParts: [null],
}]
);
});
test('resolveKeyboardEvent Modifier only Ctrl+', () => {
test('resolveKeyboardEvent Single Modifier Ctrl+', () => {
assertResolveKeyboardEvent(
mapper,
{
@@ -404,6 +422,107 @@ suite('keyboardMapper - WINDOWS en_us', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: [null],
singleModifierDispatchParts: ['ctrl'],
}
);
});
test('resolveKeyboardEvent Single Modifier Shift+', () => {
assertResolveKeyboardEvent(
mapper,
{
_standardKeyboardEventBrand: true,
ctrlKey: false,
shiftKey: true,
altKey: false,
metaKey: false,
keyCode: KeyCode.Shift,
code: null!
},
{
label: 'Shift',
ariaLabel: 'Shift',
electronAccelerator: null,
userSettingsLabel: 'shift',
isWYSIWYG: true,
isChord: false,
dispatchParts: [null],
singleModifierDispatchParts: ['shift'],
}
);
});
test('resolveKeyboardEvent Single Modifier Alt+', () => {
assertResolveKeyboardEvent(
mapper,
{
_standardKeyboardEventBrand: true,
ctrlKey: false,
shiftKey: false,
altKey: true,
metaKey: false,
keyCode: KeyCode.Alt,
code: null!
},
{
label: 'Alt',
ariaLabel: 'Alt',
electronAccelerator: null,
userSettingsLabel: 'alt',
isWYSIWYG: true,
isChord: false,
dispatchParts: [null],
singleModifierDispatchParts: ['alt'],
}
);
});
test('resolveKeyboardEvent Single Modifier Meta+', () => {
assertResolveKeyboardEvent(
mapper,
{
_standardKeyboardEventBrand: true,
ctrlKey: false,
shiftKey: false,
altKey: false,
metaKey: true,
keyCode: KeyCode.Meta,
code: null!
},
{
label: 'Windows',
ariaLabel: 'Windows',
electronAccelerator: null,
userSettingsLabel: 'win',
isWYSIWYG: true,
isChord: false,
dispatchParts: [null],
singleModifierDispatchParts: ['meta'],
}
);
});
test('resolveKeyboardEvent Only Modifiers Ctrl+Shift+', () => {
assertResolveKeyboardEvent(
mapper,
{
_standardKeyboardEventBrand: true,
ctrlKey: true,
shiftKey: true,
altKey: false,
metaKey: false,
keyCode: KeyCode.Shift,
code: null!
},
{
label: 'Ctrl+Shift',
ariaLabel: 'Control+Shift',
electronAccelerator: null,
userSettingsLabel: 'ctrl+shift',
isWYSIWYG: true,
isChord: false,
dispatchParts: [null],
singleModifierDispatchParts: [null],
}
);
});
@@ -441,6 +560,7 @@ suite('keyboardMapper - WINDOWS por_ptb', () => {
isWYSIWYG: false,
isChord: false,
dispatchParts: ['ctrl+ABNT_C1'],
singleModifierDispatchParts: [null],
}
);
});
@@ -465,6 +585,7 @@ suite('keyboardMapper - WINDOWS por_ptb', () => {
isWYSIWYG: false,
isChord: false,
dispatchParts: ['ctrl+ABNT_C2'],
singleModifierDispatchParts: [null],
}
);
});
@@ -494,6 +615,7 @@ suite('keyboardMapper - WINDOWS ru', () => {
isWYSIWYG: true,
isChord: true,
dispatchParts: ['ctrl+K', 'ctrl+K'],
singleModifierDispatchParts: [null, null],
}]
);
});
@@ -529,6 +651,7 @@ suite('keyboardMapper - misc', () => {
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+B'],
singleModifierDispatchParts: [null],
}]
);
});