Merge vscode source through 1.62 release (#19981)

* Build breaks 1

* Build breaks

* Build breaks

* Build breaks

* More build breaks

* Build breaks (#2512)

* Runtime breaks

* Build breaks

* Fix dialog location break

* Update typescript

* Fix ASAR break issue

* Unit test breaks

* Update distro

* Fix breaks in ADO builds (#2513)

* Bump to node 16

* Fix hygiene errors

* Bump distro

* Remove reference to node type

* Delete vscode specific extension

* Bump to node 16 in CI yaml

* Skip integration tests in CI builds (while fixing)

* yarn.lock update

* Bump moment dependency in remote yarn

* Fix drop-down chevron style

* Bump to node 16

* Remove playwrite from ci.yaml

* Skip building build scripts in hygine check
This commit is contained in:
Karl Burtram
2022-07-11 14:09:32 -07:00
committed by GitHub
parent fa0fcef303
commit 26455e9113
1876 changed files with 72050 additions and 37997 deletions

View File

@@ -7,7 +7,8 @@ import { WorkbenchActionExecutedClassification, WorkbenchActionExecutedEvent } f
import * as arrays from 'vs/base/common/arrays';
import { IntervalTimer, TimeoutTimer } from 'vs/base/common/async';
import { Emitter, Event } from 'vs/base/common/event';
import { Keybinding, KeyCode, ResolvedKeybinding } from 'vs/base/common/keyCodes';
import { KeyCode } from 'vs/base/common/keyCodes';
import { Keybinding, KeybindingModifier, ResolvedKeybinding, ResolvedKeybindingPart } from 'vs/base/common/keybindings';
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
import * as nls from 'vs/nls';
import { ICommandService } from 'vs/platform/commands/common/commands';
@@ -24,6 +25,8 @@ interface CurrentChord {
label: string | null;
}
const HIGH_FREQ_COMMANDS = /^(cursor|delete)/;
export abstract class AbstractKeybindingService extends Disposable implements IKeybindingService {
public _serviceBrand: undefined;
@@ -35,7 +38,8 @@ export abstract class AbstractKeybindingService extends Disposable implements IK
private _currentChord: CurrentChord | null;
private _currentChordChecker: IntervalTimer;
private _currentChordStatusMessage: IDisposable | null;
private _currentSingleModifier: null | string;
private _ignoreSingleModifiers: KeybindingModifierSet;
private _currentSingleModifier: KeybindingModifier | null;
private _currentSingleModifierClearTimeout: TimeoutTimer;
protected _logging: boolean;
@@ -56,6 +60,7 @@ export abstract class AbstractKeybindingService extends Disposable implements IK
this._currentChord = null;
this._currentChordChecker = new IntervalTimer();
this._currentChordStatusMessage = null;
this._ignoreSingleModifiers = KeybindingModifierSet.EMPTY;
this._currentSingleModifier = null;
this._currentSingleModifierClearTimeout = new TimeoutTimer();
this._logging = false;
@@ -169,8 +174,11 @@ export abstract class AbstractKeybindingService extends Disposable implements IK
}
public dispatchByUserSettingsLabel(userSettingsLabel: string, target: IContextKeyServiceTarget): void {
this._log(`/ Dispatching keybinding triggered via menu entry accelerator - ${userSettingsLabel}`);
const keybindings = this.resolveUserBinding(userSettingsLabel);
if (keybindings.length >= 1) {
if (keybindings.length === 0) {
this._log(`\\ Could not resolve - ${userSettingsLabel}`);
} else {
this._doDispatch(keybindings[0], target, /*isSingleModiferChord*/false);
}
}
@@ -183,25 +191,51 @@ export abstract class AbstractKeybindingService extends Disposable implements IK
const keybinding = this.resolveKeyboardEvent(e);
const [singleModifier,] = keybinding.getSingleModifierDispatchParts();
if (singleModifier !== null && this._currentSingleModifier === null) {
// we have a valid `singleModifier`, store it for the next keyup, but clear it in 300ms
this._log(`+ Storing single modifier for possible chord ${singleModifier}.`);
this._currentSingleModifier = singleModifier;
this._currentSingleModifierClearTimeout.cancelAndSet(() => {
this._log(`+ Clearing single modifier due to 300ms elapsed.`);
if (singleModifier) {
if (this._ignoreSingleModifiers.has(singleModifier)) {
this._log(`+ Ignoring single modifier ${singleModifier} due to it being pressed together with other keys.`);
this._ignoreSingleModifiers = KeybindingModifierSet.EMPTY;
this._currentSingleModifierClearTimeout.cancel();
this._currentSingleModifier = null;
}, 300);
return false;
}
this._ignoreSingleModifiers = KeybindingModifierSet.EMPTY;
if (this._currentSingleModifier === null) {
// we have a valid `singleModifier`, store it for the next keyup, but clear it in 300ms
this._log(`+ Storing single modifier for possible chord ${singleModifier}.`);
this._currentSingleModifier = singleModifier;
this._currentSingleModifierClearTimeout.cancelAndSet(() => {
this._log(`+ Clearing single modifier due to 300ms elapsed.`);
this._currentSingleModifier = null;
}, 300);
return false;
}
if (singleModifier === this._currentSingleModifier) {
// bingo!
this._log(`/ Dispatching single modifier chord ${singleModifier} ${singleModifier}`);
this._currentSingleModifierClearTimeout.cancel();
this._currentSingleModifier = null;
return this._doDispatch(keybinding, target, /*isSingleModiferChord*/true);
}
this._log(`+ Clearing single modifier due to modifier mismatch: ${this._currentSingleModifier} ${singleModifier}`);
this._currentSingleModifierClearTimeout.cancel();
this._currentSingleModifier = null;
return false;
}
if (singleModifier !== null && singleModifier === this._currentSingleModifier) {
// bingo!
this._log(`/ Dispatching single modifier chord ${singleModifier} ${singleModifier}`);
this._currentSingleModifierClearTimeout.cancel();
this._currentSingleModifier = null;
return this._doDispatch(keybinding, target, /*isSingleModiferChord*/true);
}
// When pressing a modifier and holding it pressed with any other modifier or key combination,
// the pressed modifiers should no longer be considered for single modifier dispatch.
const [firstPart,] = keybinding.getParts();
this._ignoreSingleModifiers = new KeybindingModifierSet(firstPart);
if (this._currentSingleModifier !== null) {
this._log(`+ Clearing single modifier due to other key up.`);
}
this._currentSingleModifierClearTimeout.cancel();
this._currentSingleModifier = null;
return false;
@@ -263,7 +297,9 @@ export abstract class AbstractKeybindingService extends Disposable implements IK
} else {
this._commandService.executeCommand(resolveResult.commandId, resolveResult.commandArgs).then(undefined, err => this._notificationService.warn(err));
}
this._telemetryService.publicLog2<WorkbenchActionExecutedEvent, WorkbenchActionExecutedClassification>('workbenchActionExecuted', { id: resolveResult.commandId, from: 'keybinding' });
if (!HIGH_FREQ_COMMANDS.test(resolveResult.commandId)) {
this._telemetryService.publicLog2<WorkbenchActionExecutedEvent, WorkbenchActionExecutedClassification>('workbenchActionExecuted', { id: resolveResult.commandId, from: 'keybinding' });
}
}
return shouldPreventDefault;
@@ -276,10 +312,36 @@ export abstract class AbstractKeybindingService extends Disposable implements IK
}
// weak check for certain ranges. this is properly implemented in a subclass
// with access to the KeyboardMapperFactory.
if ((event.keyCode >= KeyCode.KEY_A && event.keyCode <= KeyCode.KEY_Z)
|| (event.keyCode >= KeyCode.KEY_0 && event.keyCode <= KeyCode.KEY_9)) {
if ((event.keyCode >= KeyCode.KeyA && event.keyCode <= KeyCode.KeyZ)
|| (event.keyCode >= KeyCode.Digit0 && event.keyCode <= KeyCode.Digit9)) {
return true;
}
return false;
}
}
class KeybindingModifierSet {
public static EMPTY = new KeybindingModifierSet(null);
private readonly _ctrlKey: boolean;
private readonly _shiftKey: boolean;
private readonly _altKey: boolean;
private readonly _metaKey: boolean;
constructor(source: ResolvedKeybindingPart | null) {
this._ctrlKey = source ? source.ctrlKey : false;
this._shiftKey = source ? source.shiftKey : false;
this._altKey = source ? source.altKey : false;
this._metaKey = source ? source.metaKey : false;
}
has(modifier: KeybindingModifier) {
switch (modifier) {
case 'ctrl': return this._ctrlKey;
case 'shift': return this._shiftKey;
case 'alt': return this._altKey;
case 'meta': return this._metaKey;
}
}
}

View File

@@ -4,11 +4,11 @@
*--------------------------------------------------------------------------------------------*/
import { illegalArgument } from 'vs/base/common/errors';
import { AriaLabelProvider, ElectronAcceleratorLabelProvider, Modifiers, UILabelProvider, UserSettingsLabelProvider } from 'vs/base/common/keybindingLabels';
import { ResolvedKeybinding, ResolvedKeybindingPart } from 'vs/base/common/keyCodes';
import { AriaLabelProvider, ElectronAcceleratorLabelProvider, UILabelProvider, UserSettingsLabelProvider } from 'vs/base/common/keybindingLabels';
import { IBaseKeybinding, KeybindingModifier, ResolvedKeybinding, ResolvedKeybindingPart } from 'vs/base/common/keybindings';
import { OperatingSystem } from 'vs/base/common/platform';
export abstract class BaseResolvedKeybinding<T extends Modifiers> extends ResolvedKeybinding {
export abstract class BaseResolvedKeybinding<T extends IBaseKeybinding> extends ResolvedKeybinding {
protected readonly _os: OperatingSystem;
protected readonly _parts: T[];
@@ -32,7 +32,12 @@ export abstract class BaseResolvedKeybinding<T extends Modifiers> extends Resolv
public getElectronAccelerator(): string | null {
if (this._parts.length > 1) {
// Electron cannot handle chords
// [Electron Accelerators] Electron cannot handle chords
return null;
}
if (this._parts[0].isDuplicateModifierCase()) {
// [Electron Accelerators] Electron cannot handle modifier only keybindings
// e.g. "shift shift"
return null;
}
return ElectronAcceleratorLabelProvider.toLabel(this._os, this._parts, (keybinding) => this._getElectronAccelerator(keybinding));
@@ -69,7 +74,7 @@ export abstract class BaseResolvedKeybinding<T extends Modifiers> extends Resolv
return this._parts.map((keybinding) => this._getDispatchPart(keybinding));
}
public getSingleModifierDispatchParts(): (string | null)[] {
public getSingleModifierDispatchParts(): (KeybindingModifier | null)[] {
return this._parts.map((keybinding) => this._getSingleModifierDispatchPart(keybinding));
}
@@ -79,5 +84,5 @@ export abstract class BaseResolvedKeybinding<T extends Modifiers> extends Resolv
protected abstract _getUserSettingsLabel(keybinding: T): string | null;
protected abstract _isWYSIWYG(keybinding: T): boolean;
protected abstract _getDispatchPart(keybinding: T): string | null;
protected abstract _getSingleModifierDispatchPart(keybinding: T): string | null;
protected abstract _getSingleModifierDispatchPart(keybinding: T): KeybindingModifier | null;
}

View File

@@ -5,7 +5,8 @@
import { Event } from 'vs/base/common/event';
import { IJSONSchema } from 'vs/base/common/jsonSchema';
import { Keybinding, KeyCode, ResolvedKeybinding } from 'vs/base/common/keyCodes';
import { KeyCode } from 'vs/base/common/keyCodes';
import { Keybinding, ResolvedKeybinding } from 'vs/base/common/keybindings';
import { IContextKeyService, IContextKeyServiceTarget } from 'vs/platform/contextkey/common/contextkey';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IResolveResult } from 'vs/platform/keybinding/common/keybindingResolver';

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ContextKeyExpression, ContextKeyExprType, IContext, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { implies, ContextKeyExpression, ContextKeyExprType, IContext, IContextKeyService, expressionsAreEqualWithConstantSubstitution } from 'vs/platform/contextkey/common/contextkey';
import { ResolvedKeybindingItem } from 'vs/platform/keybinding/common/resolvedKeybindingItem';
export interface IResolveResult {
@@ -77,7 +77,7 @@ export class KeybindingResolver {
if (!defaultKb.when) {
return false;
}
if (!when.equals(defaultKb.when)) {
if (!expressionsAreEqualWithConstantSubstitution(when, defaultKb.when)) {
return false;
}
}
@@ -190,35 +190,7 @@ export class KeybindingResolver {
return false;
}
return this._implies(a, b);
}
/**
* Returns true if it is provable `p` implies `q`.
*/
private static _implies(p: ContextKeyExpression, q: ContextKeyExpression): boolean {
const notP = p.negate();
const terminals = (node: ContextKeyExpression) => {
if (node.type === ContextKeyExprType.Or) {
return node.expr;
}
return [node];
};
let expr = terminals(notP).concat(terminals(q));
for (let i = 0; i < expr.length; i++) {
const a = expr[i];
const notA = a.negate();
for (let j = i + 1; j < expr.length; j++) {
const b = expr[j];
if (notA.equals(b)) {
return true;
}
}
}
return false;
return implies(a, b);
}
public getDefaultBoundCommands(): Map<string, boolean> {

View File

@@ -3,14 +3,15 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { createKeybinding, Keybinding, KeyCode, SimpleKeybinding } from 'vs/base/common/keyCodes';
import { KeyCode } from 'vs/base/common/keyCodes';
import { createKeybinding, Keybinding, SimpleKeybinding, ScanCodeBinding } from 'vs/base/common/keybindings';
import { OperatingSystem, OS } from 'vs/base/common/platform';
import { CommandsRegistry, ICommandHandler, ICommandHandlerDescription } from 'vs/platform/commands/common/commands';
import { ContextKeyExpression } from 'vs/platform/contextkey/common/contextkey';
import { Registry } from 'vs/platform/registry/common/platform';
export interface IKeybindingItem {
keybinding: Keybinding;
keybinding: (SimpleKeybinding | ScanCodeBinding)[];
command: string;
commandArgs?: any;
when: ContextKeyExpression | null | undefined;
@@ -44,11 +45,8 @@ export interface IKeybindingRule extends IKeybindings {
when?: ContextKeyExpression | null | undefined;
}
export interface IKeybindingRule2 {
primary: Keybinding | null;
win?: { primary: Keybinding | null; } | null;
linux?: { primary: Keybinding | null; } | null;
mac?: { primary: Keybinding | null; } | null;
export interface IExtensionKeybindingRule {
keybinding: (SimpleKeybinding | ScanCodeBinding)[];
id: string;
args?: any;
weight: number;
@@ -72,7 +70,7 @@ export interface ICommandAndKeybindingRule extends IKeybindingRule {
export interface IKeybindingsRegistry {
registerKeybindingRule(rule: IKeybindingRule): void;
setExtensionKeybindings(rules: IKeybindingRule2[]): void;
setExtensionKeybindings(rules: IExtensionKeybindingRule[]): void;
registerCommandAndKeybindingRule(desc: ICommandAndKeybindingRule): void;
getDefaultKeybindings(): IKeybindingItem[];
}
@@ -110,27 +108,6 @@ class KeybindingsRegistryImpl implements IKeybindingsRegistry {
return kb;
}
/**
* Take current platform into account and reduce to primary & secondary.
*/
private static bindToCurrentPlatform2(kb: IKeybindingRule2): { primary?: Keybinding | null; } {
if (OS === OperatingSystem.Windows) {
if (kb && kb.win) {
return kb.win;
}
} else if (OS === OperatingSystem.Macintosh) {
if (kb && kb.mac) {
return kb.mac;
}
} else {
if (kb && kb.linux) {
return kb.linux;
}
}
return kb;
}
public registerKeybindingRule(rule: IKeybindingRule): void {
const actualKb = KeybindingsRegistryImpl.bindToCurrentPlatform(rule);
@@ -152,15 +129,12 @@ class KeybindingsRegistryImpl implements IKeybindingsRegistry {
}
}
public setExtensionKeybindings(rules: IKeybindingRule2[]): void {
public setExtensionKeybindings(rules: IExtensionKeybindingRule[]): void {
let result: IKeybindingItem[] = [], keybindingsLen = 0;
for (let i = 0, len = rules.length; i < len; i++) {
const rule = rules[i];
let actualKb = KeybindingsRegistryImpl.bindToCurrentPlatform2(rule);
if (actualKb && actualKb.primary) {
for (const rule of rules) {
if (rule.keybinding.length > 0) {
result[keybindingsLen++] = {
keybinding: actualKb.primary,
keybinding: rule.keybinding,
command: rule.id,
commandArgs: rule.args,
when: rule.when,
@@ -182,28 +156,28 @@ class KeybindingsRegistryImpl implements IKeybindingsRegistry {
}
private static _mightProduceChar(keyCode: KeyCode): boolean {
if (keyCode >= KeyCode.KEY_0 && keyCode <= KeyCode.KEY_9) {
if (keyCode >= KeyCode.Digit0 && keyCode <= KeyCode.Digit9) {
return true;
}
if (keyCode >= KeyCode.KEY_A && keyCode <= KeyCode.KEY_Z) {
if (keyCode >= KeyCode.KeyA && keyCode <= KeyCode.KeyZ) {
return true;
}
return (
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.Semicolon
|| keyCode === KeyCode.Equal
|| keyCode === KeyCode.Comma
|| keyCode === KeyCode.Minus
|| keyCode === KeyCode.Period
|| keyCode === KeyCode.Slash
|| keyCode === KeyCode.Backquote
|| keyCode === KeyCode.ABNT_C1
|| keyCode === KeyCode.ABNT_C2
|| keyCode === KeyCode.US_OPEN_SQUARE_BRACKET
|| keyCode === KeyCode.US_BACKSLASH
|| keyCode === KeyCode.US_CLOSE_SQUARE_BRACKET
|| keyCode === KeyCode.US_QUOTE
|| keyCode === KeyCode.BracketLeft
|| keyCode === KeyCode.Backslash
|| keyCode === KeyCode.BracketRight
|| keyCode === KeyCode.Quote
|| keyCode === KeyCode.OEM_8
|| keyCode === KeyCode.OEM_102
|| keyCode === KeyCode.IntlBackslash
);
}
@@ -220,7 +194,7 @@ class KeybindingsRegistryImpl implements IKeybindingsRegistry {
this._assertNoCtrlAlt(keybinding.parts[0], commandId);
}
this._coreKeybindings.push({
keybinding: keybinding,
keybinding: keybinding.parts,
command: commandId,
commandArgs: commandArgs,
when: when,

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { CharCode } from 'vs/base/common/charCode';
import { ResolvedKeybinding } from 'vs/base/common/keyCodes';
import { ResolvedKeybinding } from 'vs/base/common/keybindings';
import { ContextKeyExpression } from 'vs/platform/contextkey/common/contextkey';
export class ResolvedKeybindingItem {

View File

@@ -3,9 +3,11 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Keybinding, KeyCode, KeyCodeUtils, SimpleKeybinding } from 'vs/base/common/keyCodes';
import { KeyCode, KeyCodeUtils, IMMUTABLE_CODE_TO_KEY_CODE, ScanCode } from 'vs/base/common/keyCodes';
import { ChordKeybinding, Keybinding, KeybindingModifier, SimpleKeybinding, ScanCodeBinding } from 'vs/base/common/keybindings';
import { OperatingSystem } from 'vs/base/common/platform';
import { BaseResolvedKeybinding } from 'vs/platform/keybinding/common/baseResolvedKeybinding';
import { removeElementsAfterNulls } from 'vs/platform/keybinding/common/resolvedKeybindingItem';
/**
* Do not instantiate. Use KeybindingService to get a ResolvedKeybinding seeded with information about the current kb layout.
@@ -46,31 +48,8 @@ export class USLayoutResolvedKeybinding extends BaseResolvedKeybinding<SimpleKey
return KeyCodeUtils.toString(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';
}
return KeyCodeUtils.toString(keyCode);
}
protected _getElectronAccelerator(keybinding: SimpleKeybinding): string | null {
if (keybinding.isDuplicateModifierCase()) {
return null;
}
return this._keyCodeToElectronAccelerator(keybinding.keyCode);
return KeyCodeUtils.toElectronAccelerator(keybinding.keyCode);
}
protected _getUserSettingsLabel(keybinding: SimpleKeybinding): string | null {
@@ -112,7 +91,7 @@ export class USLayoutResolvedKeybinding extends BaseResolvedKeybinding<SimpleKey
return result;
}
protected _getSingleModifierDispatchPart(keybinding: SimpleKeybinding): string | null {
protected _getSingleModifierDispatchPart(keybinding: SimpleKeybinding): KeybindingModifier | null {
if (keybinding.keyCode === KeyCode.Ctrl && !keybinding.shiftKey && !keybinding.altKey && !keybinding.metaKey) {
return 'ctrl';
}
@@ -127,4 +106,89 @@ export class USLayoutResolvedKeybinding extends BaseResolvedKeybinding<SimpleKey
}
return null;
}
/**
* *NOTE*: Check return value for `KeyCode.Unknown`.
*/
private static _scanCodeToKeyCode(scanCode: ScanCode): KeyCode {
const immutableKeyCode = IMMUTABLE_CODE_TO_KEY_CODE[scanCode];
if (immutableKeyCode !== KeyCode.DependsOnKbLayout) {
return immutableKeyCode;
}
switch (scanCode) {
case ScanCode.KeyA: return KeyCode.KeyA;
case ScanCode.KeyB: return KeyCode.KeyB;
case ScanCode.KeyC: return KeyCode.KeyC;
case ScanCode.KeyD: return KeyCode.KeyD;
case ScanCode.KeyE: return KeyCode.KeyE;
case ScanCode.KeyF: return KeyCode.KeyF;
case ScanCode.KeyG: return KeyCode.KeyG;
case ScanCode.KeyH: return KeyCode.KeyH;
case ScanCode.KeyI: return KeyCode.KeyI;
case ScanCode.KeyJ: return KeyCode.KeyJ;
case ScanCode.KeyK: return KeyCode.KeyK;
case ScanCode.KeyL: return KeyCode.KeyL;
case ScanCode.KeyM: return KeyCode.KeyM;
case ScanCode.KeyN: return KeyCode.KeyN;
case ScanCode.KeyO: return KeyCode.KeyO;
case ScanCode.KeyP: return KeyCode.KeyP;
case ScanCode.KeyQ: return KeyCode.KeyQ;
case ScanCode.KeyR: return KeyCode.KeyR;
case ScanCode.KeyS: return KeyCode.KeyS;
case ScanCode.KeyT: return KeyCode.KeyT;
case ScanCode.KeyU: return KeyCode.KeyU;
case ScanCode.KeyV: return KeyCode.KeyV;
case ScanCode.KeyW: return KeyCode.KeyW;
case ScanCode.KeyX: return KeyCode.KeyX;
case ScanCode.KeyY: return KeyCode.KeyY;
case ScanCode.KeyZ: return KeyCode.KeyZ;
case ScanCode.Digit1: return KeyCode.Digit1;
case ScanCode.Digit2: return KeyCode.Digit2;
case ScanCode.Digit3: return KeyCode.Digit3;
case ScanCode.Digit4: return KeyCode.Digit4;
case ScanCode.Digit5: return KeyCode.Digit5;
case ScanCode.Digit6: return KeyCode.Digit6;
case ScanCode.Digit7: return KeyCode.Digit7;
case ScanCode.Digit8: return KeyCode.Digit8;
case ScanCode.Digit9: return KeyCode.Digit9;
case ScanCode.Digit0: return KeyCode.Digit0;
case ScanCode.Minus: return KeyCode.Minus;
case ScanCode.Equal: return KeyCode.Equal;
case ScanCode.BracketLeft: return KeyCode.BracketLeft;
case ScanCode.BracketRight: return KeyCode.BracketRight;
case ScanCode.Backslash: return KeyCode.Backslash;
case ScanCode.IntlHash: return KeyCode.Unknown; // missing
case ScanCode.Semicolon: return KeyCode.Semicolon;
case ScanCode.Quote: return KeyCode.Quote;
case ScanCode.Backquote: return KeyCode.Backquote;
case ScanCode.Comma: return KeyCode.Comma;
case ScanCode.Period: return KeyCode.Period;
case ScanCode.Slash: return KeyCode.Slash;
case ScanCode.IntlBackslash: return KeyCode.IntlBackslash;
}
return KeyCode.Unknown;
}
private static _resolveSimpleUserBinding(binding: SimpleKeybinding | ScanCodeBinding | null): SimpleKeybinding | null {
if (!binding) {
return null;
}
if (binding instanceof SimpleKeybinding) {
return binding;
}
const keyCode = this._scanCodeToKeyCode(binding.scanCode);
if (keyCode === KeyCode.Unknown) {
return null;
}
return new SimpleKeybinding(binding.ctrlKey, binding.shiftKey, binding.altKey, binding.metaKey, keyCode);
}
public static resolveUserBinding(input: (SimpleKeybinding | ScanCodeBinding)[], os: OperatingSystem): USLayoutResolvedKeybinding[] {
const parts: SimpleKeybinding[] = removeElementsAfterNulls(input.map(keybinding => this._resolveSimpleUserBinding(keybinding)));
if (parts.length > 0) {
return [new USLayoutResolvedKeybinding(new ChordKeybinding(parts), os)];
}
return [];
}
}

View File

@@ -3,7 +3,8 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { createKeybinding, createSimpleKeybinding, Keybinding, KeyChord, KeyCode, KeyMod, ResolvedKeybinding, SimpleKeybinding } from 'vs/base/common/keyCodes';
import { KeyChord, KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import { createKeybinding, createSimpleKeybinding, Keybinding, ResolvedKeybinding, SimpleKeybinding } from 'vs/base/common/keybindings';
import { Disposable } from 'vs/base/common/lifecycle';
import { OS } from 'vs/base/common/platform';
import Severity from 'vs/base/common/severity';
@@ -208,17 +209,17 @@ suite('AbstractKeybindingService', () => {
test('issue #16498: chord mode is quit for invalid chords', () => {
let kbService = createTestKeybindingService([
kbItem(KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_X), 'chordCommand'),
kbItem(KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.KeyX), 'chordCommand'),
kbItem(KeyCode.Backspace, 'simpleCommand'),
]);
// send Ctrl/Cmd + K
let shouldPreventDefault = kbService.testDispatch(KeyMod.CtrlCmd | KeyCode.KEY_K);
let shouldPreventDefault = kbService.testDispatch(KeyMod.CtrlCmd | KeyCode.KeyK);
assert.strictEqual(shouldPreventDefault, true);
assert.deepStrictEqual(executeCommandCalls, []);
assert.deepStrictEqual(showMessageCalls, []);
assert.deepStrictEqual(statusMessageCalls, [
`(${toUsLabel(KeyMod.CtrlCmd | KeyCode.KEY_K)}) was pressed. Waiting for second key of chord...`
`(${toUsLabel(KeyMod.CtrlCmd | KeyCode.KeyK)}) was pressed. Waiting for second key of chord...`
]);
assert.deepStrictEqual(statusMessageCallsDisposed, []);
executeCommandCalls = [];
@@ -232,10 +233,10 @@ suite('AbstractKeybindingService', () => {
assert.deepStrictEqual(executeCommandCalls, []);
assert.deepStrictEqual(showMessageCalls, []);
assert.deepStrictEqual(statusMessageCalls, [
`The key combination (${toUsLabel(KeyMod.CtrlCmd | KeyCode.KEY_K)}, ${toUsLabel(KeyCode.Backspace)}) is not a command.`
`The key combination (${toUsLabel(KeyMod.CtrlCmd | KeyCode.KeyK)}, ${toUsLabel(KeyCode.Backspace)}) is not a command.`
]);
assert.deepStrictEqual(statusMessageCallsDisposed, [
`(${toUsLabel(KeyMod.CtrlCmd | KeyCode.KEY_K)}) was pressed. Waiting for second key of chord...`
`(${toUsLabel(KeyMod.CtrlCmd | KeyCode.KeyK)}) was pressed. Waiting for second key of chord...`
]);
executeCommandCalls = [];
showMessageCalls = [];
@@ -303,8 +304,8 @@ suite('AbstractKeybindingService', () => {
test('can trigger command that is sharing keybinding with chord', () => {
let kbService = createTestKeybindingService([
kbItem(KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_X), 'chordCommand'),
kbItem(KeyMod.CtrlCmd | KeyCode.KEY_K, 'simpleCommand', ContextKeyExpr.has('key1')),
kbItem(KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.KeyX), 'chordCommand'),
kbItem(KeyMod.CtrlCmd | KeyCode.KeyK, 'simpleCommand', ContextKeyExpr.has('key1')),
]);
@@ -312,7 +313,7 @@ suite('AbstractKeybindingService', () => {
currentContextValue = createContext({
key1: true
});
let shouldPreventDefault = kbService.testDispatch(KeyMod.CtrlCmd | KeyCode.KEY_K);
let shouldPreventDefault = kbService.testDispatch(KeyMod.CtrlCmd | KeyCode.KeyK);
assert.strictEqual(shouldPreventDefault, true);
assert.deepStrictEqual(executeCommandCalls, [{
commandId: 'simpleCommand',
@@ -328,12 +329,12 @@ suite('AbstractKeybindingService', () => {
// send Ctrl/Cmd + K
currentContextValue = createContext({});
shouldPreventDefault = kbService.testDispatch(KeyMod.CtrlCmd | KeyCode.KEY_K);
shouldPreventDefault = kbService.testDispatch(KeyMod.CtrlCmd | KeyCode.KeyK);
assert.strictEqual(shouldPreventDefault, true);
assert.deepStrictEqual(executeCommandCalls, []);
assert.deepStrictEqual(showMessageCalls, []);
assert.deepStrictEqual(statusMessageCalls, [
`(${toUsLabel(KeyMod.CtrlCmd | KeyCode.KEY_K)}) was pressed. Waiting for second key of chord...`
`(${toUsLabel(KeyMod.CtrlCmd | KeyCode.KeyK)}) was pressed. Waiting for second key of chord...`
]);
assert.deepStrictEqual(statusMessageCallsDisposed, []);
executeCommandCalls = [];
@@ -343,7 +344,7 @@ suite('AbstractKeybindingService', () => {
// send Ctrl/Cmd + X
currentContextValue = createContext({});
shouldPreventDefault = kbService.testDispatch(KeyMod.CtrlCmd | KeyCode.KEY_X);
shouldPreventDefault = kbService.testDispatch(KeyMod.CtrlCmd | KeyCode.KeyX);
assert.strictEqual(shouldPreventDefault, true);
assert.deepStrictEqual(executeCommandCalls, [{
commandId: 'chordCommand',
@@ -352,7 +353,7 @@ suite('AbstractKeybindingService', () => {
assert.deepStrictEqual(showMessageCalls, []);
assert.deepStrictEqual(statusMessageCalls, []);
assert.deepStrictEqual(statusMessageCallsDisposed, [
`(${toUsLabel(KeyMod.CtrlCmd | KeyCode.KEY_K)}) was pressed. Waiting for second key of chord...`
`(${toUsLabel(KeyMod.CtrlCmd | KeyCode.KeyK)}) was pressed. Waiting for second key of chord...`
]);
executeCommandCalls = [];
showMessageCalls = [];
@@ -365,14 +366,14 @@ suite('AbstractKeybindingService', () => {
test('cannot trigger chord if command is overwriting', () => {
let kbService = createTestKeybindingService([
kbItem(KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_X), 'chordCommand', ContextKeyExpr.has('key1')),
kbItem(KeyMod.CtrlCmd | KeyCode.KEY_K, 'simpleCommand'),
kbItem(KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.KeyX), 'chordCommand', ContextKeyExpr.has('key1')),
kbItem(KeyMod.CtrlCmd | KeyCode.KeyK, 'simpleCommand'),
]);
// send Ctrl/Cmd + K
currentContextValue = createContext({});
let shouldPreventDefault = kbService.testDispatch(KeyMod.CtrlCmd | KeyCode.KEY_K);
let shouldPreventDefault = kbService.testDispatch(KeyMod.CtrlCmd | KeyCode.KeyK);
assert.strictEqual(shouldPreventDefault, true);
assert.deepStrictEqual(executeCommandCalls, [{
commandId: 'simpleCommand',
@@ -390,7 +391,7 @@ suite('AbstractKeybindingService', () => {
currentContextValue = createContext({
key1: true
});
shouldPreventDefault = kbService.testDispatch(KeyMod.CtrlCmd | KeyCode.KEY_K);
shouldPreventDefault = kbService.testDispatch(KeyMod.CtrlCmd | KeyCode.KeyK);
assert.strictEqual(shouldPreventDefault, true);
assert.deepStrictEqual(executeCommandCalls, [{
commandId: 'simpleCommand',
@@ -408,7 +409,7 @@ suite('AbstractKeybindingService', () => {
currentContextValue = createContext({
key1: true
});
shouldPreventDefault = kbService.testDispatch(KeyMod.CtrlCmd | KeyCode.KEY_X);
shouldPreventDefault = kbService.testDispatch(KeyMod.CtrlCmd | KeyCode.KeyX);
assert.strictEqual(shouldPreventDefault, false);
assert.deepStrictEqual(executeCommandCalls, []);
assert.deepStrictEqual(showMessageCalls, []);
@@ -425,12 +426,12 @@ suite('AbstractKeybindingService', () => {
test('can have spying command', () => {
let kbService = createTestKeybindingService([
kbItem(KeyMod.CtrlCmd | KeyCode.KEY_K, '^simpleCommand'),
kbItem(KeyMod.CtrlCmd | KeyCode.KeyK, '^simpleCommand'),
]);
// send Ctrl/Cmd + K
currentContextValue = createContext({});
let shouldPreventDefault = kbService.testDispatch(KeyMod.CtrlCmd | KeyCode.KEY_K);
let shouldPreventDefault = kbService.testDispatch(KeyMod.CtrlCmd | KeyCode.KeyK);
assert.strictEqual(shouldPreventDefault, false);
assert.deepStrictEqual(executeCommandCalls, [{
commandId: 'simpleCommand',

View File

@@ -3,7 +3,8 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { createKeybinding, KeyChord, KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import { KeyChord, KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import { createKeybinding } from 'vs/base/common/keybindings';
import { OperatingSystem } from 'vs/base/common/platform';
import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/usLayoutResolvedKeybinding';
@@ -16,95 +17,95 @@ suite('KeybindingLabels', () => {
test('Windows US label', () => {
// no modifier
assertUSLabel(OperatingSystem.Windows, KeyCode.KEY_A, 'A');
assertUSLabel(OperatingSystem.Windows, KeyCode.KeyA, 'A');
// one modifier
assertUSLabel(OperatingSystem.Windows, KeyMod.CtrlCmd | KeyCode.KEY_A, 'Ctrl+A');
assertUSLabel(OperatingSystem.Windows, KeyMod.Shift | KeyCode.KEY_A, 'Shift+A');
assertUSLabel(OperatingSystem.Windows, KeyMod.Alt | KeyCode.KEY_A, 'Alt+A');
assertUSLabel(OperatingSystem.Windows, KeyMod.WinCtrl | KeyCode.KEY_A, 'Windows+A');
assertUSLabel(OperatingSystem.Windows, KeyMod.CtrlCmd | KeyCode.KeyA, 'Ctrl+A');
assertUSLabel(OperatingSystem.Windows, KeyMod.Shift | KeyCode.KeyA, 'Shift+A');
assertUSLabel(OperatingSystem.Windows, KeyMod.Alt | KeyCode.KeyA, 'Alt+A');
assertUSLabel(OperatingSystem.Windows, KeyMod.WinCtrl | KeyCode.KeyA, 'Windows+A');
// two modifiers
assertUSLabel(OperatingSystem.Windows, KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_A, 'Ctrl+Shift+A');
assertUSLabel(OperatingSystem.Windows, KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_A, 'Ctrl+Alt+A');
assertUSLabel(OperatingSystem.Windows, KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.KEY_A, 'Ctrl+Windows+A');
assertUSLabel(OperatingSystem.Windows, KeyMod.Shift | KeyMod.Alt | KeyCode.KEY_A, 'Shift+Alt+A');
assertUSLabel(OperatingSystem.Windows, KeyMod.Shift | KeyMod.WinCtrl | KeyCode.KEY_A, 'Shift+Windows+A');
assertUSLabel(OperatingSystem.Windows, KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Alt+Windows+A');
assertUSLabel(OperatingSystem.Windows, KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyA, 'Ctrl+Shift+A');
assertUSLabel(OperatingSystem.Windows, KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KeyA, 'Ctrl+Alt+A');
assertUSLabel(OperatingSystem.Windows, KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.KeyA, 'Ctrl+Windows+A');
assertUSLabel(OperatingSystem.Windows, KeyMod.Shift | KeyMod.Alt | KeyCode.KeyA, 'Shift+Alt+A');
assertUSLabel(OperatingSystem.Windows, KeyMod.Shift | KeyMod.WinCtrl | KeyCode.KeyA, 'Shift+Windows+A');
assertUSLabel(OperatingSystem.Windows, KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KeyA, 'Alt+Windows+A');
// three modifiers
assertUSLabel(OperatingSystem.Windows, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyCode.KEY_A, 'Ctrl+Shift+Alt+A');
assertUSLabel(OperatingSystem.Windows, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.WinCtrl | KeyCode.KEY_A, 'Ctrl+Shift+Windows+A');
assertUSLabel(OperatingSystem.Windows, KeyMod.CtrlCmd | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Ctrl+Alt+Windows+A');
assertUSLabel(OperatingSystem.Windows, KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Shift+Alt+Windows+A');
assertUSLabel(OperatingSystem.Windows, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyCode.KeyA, 'Ctrl+Shift+Alt+A');
assertUSLabel(OperatingSystem.Windows, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.WinCtrl | KeyCode.KeyA, 'Ctrl+Shift+Windows+A');
assertUSLabel(OperatingSystem.Windows, KeyMod.CtrlCmd | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KeyA, 'Ctrl+Alt+Windows+A');
assertUSLabel(OperatingSystem.Windows, KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KeyA, 'Shift+Alt+Windows+A');
// four modifiers
assertUSLabel(OperatingSystem.Windows, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Ctrl+Shift+Alt+Windows+A');
assertUSLabel(OperatingSystem.Windows, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KeyA, 'Ctrl+Shift+Alt+Windows+A');
// chord
assertUSLabel(OperatingSystem.Windows, KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_A, KeyMod.CtrlCmd | KeyCode.KEY_B), 'Ctrl+A Ctrl+B');
assertUSLabel(OperatingSystem.Windows, KeyChord(KeyMod.CtrlCmd | KeyCode.KeyA, KeyMod.CtrlCmd | KeyCode.KeyB), 'Ctrl+A Ctrl+B');
});
test('Linux US label', () => {
// no modifier
assertUSLabel(OperatingSystem.Linux, KeyCode.KEY_A, 'A');
assertUSLabel(OperatingSystem.Linux, KeyCode.KeyA, 'A');
// one modifier
assertUSLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyCode.KEY_A, 'Ctrl+A');
assertUSLabel(OperatingSystem.Linux, KeyMod.Shift | KeyCode.KEY_A, 'Shift+A');
assertUSLabel(OperatingSystem.Linux, KeyMod.Alt | KeyCode.KEY_A, 'Alt+A');
assertUSLabel(OperatingSystem.Linux, KeyMod.WinCtrl | KeyCode.KEY_A, 'Super+A');
assertUSLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyCode.KeyA, 'Ctrl+A');
assertUSLabel(OperatingSystem.Linux, KeyMod.Shift | KeyCode.KeyA, 'Shift+A');
assertUSLabel(OperatingSystem.Linux, KeyMod.Alt | KeyCode.KeyA, 'Alt+A');
assertUSLabel(OperatingSystem.Linux, KeyMod.WinCtrl | KeyCode.KeyA, 'Super+A');
// two modifiers
assertUSLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_A, 'Ctrl+Shift+A');
assertUSLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_A, 'Ctrl+Alt+A');
assertUSLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.KEY_A, 'Ctrl+Super+A');
assertUSLabel(OperatingSystem.Linux, KeyMod.Shift | KeyMod.Alt | KeyCode.KEY_A, 'Shift+Alt+A');
assertUSLabel(OperatingSystem.Linux, KeyMod.Shift | KeyMod.WinCtrl | KeyCode.KEY_A, 'Shift+Super+A');
assertUSLabel(OperatingSystem.Linux, KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Alt+Super+A');
assertUSLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyA, 'Ctrl+Shift+A');
assertUSLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KeyA, 'Ctrl+Alt+A');
assertUSLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.KeyA, 'Ctrl+Super+A');
assertUSLabel(OperatingSystem.Linux, KeyMod.Shift | KeyMod.Alt | KeyCode.KeyA, 'Shift+Alt+A');
assertUSLabel(OperatingSystem.Linux, KeyMod.Shift | KeyMod.WinCtrl | KeyCode.KeyA, 'Shift+Super+A');
assertUSLabel(OperatingSystem.Linux, KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KeyA, 'Alt+Super+A');
// three modifiers
assertUSLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyCode.KEY_A, 'Ctrl+Shift+Alt+A');
assertUSLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.WinCtrl | KeyCode.KEY_A, 'Ctrl+Shift+Super+A');
assertUSLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Ctrl+Alt+Super+A');
assertUSLabel(OperatingSystem.Linux, KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Shift+Alt+Super+A');
assertUSLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyCode.KeyA, 'Ctrl+Shift+Alt+A');
assertUSLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.WinCtrl | KeyCode.KeyA, 'Ctrl+Shift+Super+A');
assertUSLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KeyA, 'Ctrl+Alt+Super+A');
assertUSLabel(OperatingSystem.Linux, KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KeyA, 'Shift+Alt+Super+A');
// four modifiers
assertUSLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Ctrl+Shift+Alt+Super+A');
assertUSLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KeyA, 'Ctrl+Shift+Alt+Super+A');
// chord
assertUSLabel(OperatingSystem.Linux, KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_A, KeyMod.CtrlCmd | KeyCode.KEY_B), 'Ctrl+A Ctrl+B');
assertUSLabel(OperatingSystem.Linux, KeyChord(KeyMod.CtrlCmd | KeyCode.KeyA, KeyMod.CtrlCmd | KeyCode.KeyB), 'Ctrl+A Ctrl+B');
});
test('Mac US label', () => {
// no modifier
assertUSLabel(OperatingSystem.Macintosh, KeyCode.KEY_A, 'A');
assertUSLabel(OperatingSystem.Macintosh, KeyCode.KeyA, 'A');
// one modifier
assertUSLabel(OperatingSystem.Macintosh, KeyMod.CtrlCmd | KeyCode.KEY_A, '⌘A');
assertUSLabel(OperatingSystem.Macintosh, KeyMod.Shift | KeyCode.KEY_A, '⇧A');
assertUSLabel(OperatingSystem.Macintosh, KeyMod.Alt | KeyCode.KEY_A, '⌥A');
assertUSLabel(OperatingSystem.Macintosh, KeyMod.WinCtrl | KeyCode.KEY_A, '⌃A');
assertUSLabel(OperatingSystem.Macintosh, KeyMod.CtrlCmd | KeyCode.KeyA, '⌘A');
assertUSLabel(OperatingSystem.Macintosh, KeyMod.Shift | KeyCode.KeyA, '⇧A');
assertUSLabel(OperatingSystem.Macintosh, KeyMod.Alt | KeyCode.KeyA, '⌥A');
assertUSLabel(OperatingSystem.Macintosh, KeyMod.WinCtrl | KeyCode.KeyA, '⌃A');
// two modifiers
assertUSLabel(OperatingSystem.Macintosh, KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_A, '⇧⌘A');
assertUSLabel(OperatingSystem.Macintosh, KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_A, '⌥⌘A');
assertUSLabel(OperatingSystem.Macintosh, KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.KEY_A, '⌃⌘A');
assertUSLabel(OperatingSystem.Macintosh, KeyMod.Shift | KeyMod.Alt | KeyCode.KEY_A, '⇧⌥A');
assertUSLabel(OperatingSystem.Macintosh, KeyMod.Shift | KeyMod.WinCtrl | KeyCode.KEY_A, '⌃⇧A');
assertUSLabel(OperatingSystem.Macintosh, KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, '⌃⌥A');
assertUSLabel(OperatingSystem.Macintosh, KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyA, '⇧⌘A');
assertUSLabel(OperatingSystem.Macintosh, KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KeyA, '⌥⌘A');
assertUSLabel(OperatingSystem.Macintosh, KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.KeyA, '⌃⌘A');
assertUSLabel(OperatingSystem.Macintosh, KeyMod.Shift | KeyMod.Alt | KeyCode.KeyA, '⇧⌥A');
assertUSLabel(OperatingSystem.Macintosh, KeyMod.Shift | KeyMod.WinCtrl | KeyCode.KeyA, '⌃⇧A');
assertUSLabel(OperatingSystem.Macintosh, KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KeyA, '⌃⌥A');
// three modifiers
assertUSLabel(OperatingSystem.Macintosh, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyCode.KEY_A, '⇧⌥⌘A');
assertUSLabel(OperatingSystem.Macintosh, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.WinCtrl | KeyCode.KEY_A, '⌃⇧⌘A');
assertUSLabel(OperatingSystem.Macintosh, KeyMod.CtrlCmd | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, '⌃⌥⌘A');
assertUSLabel(OperatingSystem.Macintosh, KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, '⌃⇧⌥A');
assertUSLabel(OperatingSystem.Macintosh, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyCode.KeyA, '⇧⌥⌘A');
assertUSLabel(OperatingSystem.Macintosh, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.WinCtrl | KeyCode.KeyA, '⌃⇧⌘A');
assertUSLabel(OperatingSystem.Macintosh, KeyMod.CtrlCmd | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KeyA, '⌃⌥⌘A');
assertUSLabel(OperatingSystem.Macintosh, KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KeyA, '⌃⇧⌥A');
// four modifiers
assertUSLabel(OperatingSystem.Macintosh, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, '⌃⇧⌥⌘A');
assertUSLabel(OperatingSystem.Macintosh, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KeyA, '⌃⇧⌥⌘A');
// chord
assertUSLabel(OperatingSystem.Macintosh, KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_A, KeyMod.CtrlCmd | KeyCode.KEY_B), '⌘A ⌘B');
assertUSLabel(OperatingSystem.Macintosh, KeyChord(KeyMod.CtrlCmd | KeyCode.KeyA, KeyMod.CtrlCmd | KeyCode.KeyB), '⌘A ⌘B');
// special keys
assertUSLabel(OperatingSystem.Macintosh, KeyCode.LeftArrow, '←');
@@ -119,9 +120,9 @@ suite('KeybindingLabels', () => {
assert.strictEqual(usResolvedKeybinding.getAriaLabel(), expected);
}
assertAriaLabel(OperatingSystem.Windows, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Control+Shift+Alt+Windows+A');
assertAriaLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Control+Shift+Alt+Super+A');
assertAriaLabel(OperatingSystem.Macintosh, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Control+Shift+Alt+Command+A');
assertAriaLabel(OperatingSystem.Windows, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KeyA, 'Control+Shift+Alt+Windows+A');
assertAriaLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KeyA, 'Control+Shift+Alt+Super+A');
assertAriaLabel(OperatingSystem.Macintosh, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KeyA, 'Control+Shift+Alt+Command+A');
});
test('Electron Accelerator label', () => {
@@ -130,19 +131,19 @@ suite('KeybindingLabels', () => {
assert.strictEqual(usResolvedKeybinding.getElectronAccelerator(), expected);
}
assertElectronAcceleratorLabel(OperatingSystem.Windows, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Ctrl+Shift+Alt+Super+A');
assertElectronAcceleratorLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Ctrl+Shift+Alt+Super+A');
assertElectronAcceleratorLabel(OperatingSystem.Macintosh, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Ctrl+Shift+Alt+Cmd+A');
assertElectronAcceleratorLabel(OperatingSystem.Windows, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KeyA, 'Ctrl+Shift+Alt+Super+A');
assertElectronAcceleratorLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KeyA, 'Ctrl+Shift+Alt+Super+A');
assertElectronAcceleratorLabel(OperatingSystem.Macintosh, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KeyA, 'Ctrl+Shift+Alt+Cmd+A');
// electron cannot handle chords
assertElectronAcceleratorLabel(OperatingSystem.Windows, KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_A, KeyMod.CtrlCmd | KeyCode.KEY_B), null);
assertElectronAcceleratorLabel(OperatingSystem.Linux, KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_A, KeyMod.CtrlCmd | KeyCode.KEY_B), null);
assertElectronAcceleratorLabel(OperatingSystem.Macintosh, KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_A, KeyMod.CtrlCmd | KeyCode.KEY_B), null);
assertElectronAcceleratorLabel(OperatingSystem.Windows, KeyChord(KeyMod.CtrlCmd | KeyCode.KeyA, KeyMod.CtrlCmd | KeyCode.KeyB), null);
assertElectronAcceleratorLabel(OperatingSystem.Linux, KeyChord(KeyMod.CtrlCmd | KeyCode.KeyA, KeyMod.CtrlCmd | KeyCode.KeyB), null);
assertElectronAcceleratorLabel(OperatingSystem.Macintosh, KeyChord(KeyMod.CtrlCmd | KeyCode.KeyA, KeyMod.CtrlCmd | KeyCode.KeyB), null);
// electron cannot handle numpad keys
assertElectronAcceleratorLabel(OperatingSystem.Windows, KeyCode.NUMPAD_1, null);
assertElectronAcceleratorLabel(OperatingSystem.Linux, KeyCode.NUMPAD_1, null);
assertElectronAcceleratorLabel(OperatingSystem.Macintosh, KeyCode.NUMPAD_1, null);
assertElectronAcceleratorLabel(OperatingSystem.Windows, KeyCode.Numpad1, null);
assertElectronAcceleratorLabel(OperatingSystem.Linux, KeyCode.Numpad1, null);
assertElectronAcceleratorLabel(OperatingSystem.Macintosh, KeyCode.Numpad1, null);
// special
assertElectronAcceleratorLabel(OperatingSystem.Macintosh, KeyCode.LeftArrow, 'Left');
@@ -157,14 +158,14 @@ suite('KeybindingLabels', () => {
assert.strictEqual(usResolvedKeybinding.getUserSettingsLabel(), expected);
}
assertElectronAcceleratorLabel(OperatingSystem.Windows, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'ctrl+shift+alt+win+a');
assertElectronAcceleratorLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'ctrl+shift+alt+meta+a');
assertElectronAcceleratorLabel(OperatingSystem.Macintosh, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'ctrl+shift+alt+cmd+a');
assertElectronAcceleratorLabel(OperatingSystem.Windows, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KeyA, 'ctrl+shift+alt+win+a');
assertElectronAcceleratorLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KeyA, 'ctrl+shift+alt+meta+a');
assertElectronAcceleratorLabel(OperatingSystem.Macintosh, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KeyA, 'ctrl+shift+alt+cmd+a');
// electron cannot handle chords
assertElectronAcceleratorLabel(OperatingSystem.Windows, KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_A, KeyMod.CtrlCmd | KeyCode.KEY_B), 'ctrl+a ctrl+b');
assertElectronAcceleratorLabel(OperatingSystem.Linux, KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_A, KeyMod.CtrlCmd | KeyCode.KEY_B), 'ctrl+a ctrl+b');
assertElectronAcceleratorLabel(OperatingSystem.Macintosh, KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_A, KeyMod.CtrlCmd | KeyCode.KEY_B), 'cmd+a cmd+b');
assertElectronAcceleratorLabel(OperatingSystem.Windows, KeyChord(KeyMod.CtrlCmd | KeyCode.KeyA, KeyMod.CtrlCmd | KeyCode.KeyB), 'ctrl+a ctrl+b');
assertElectronAcceleratorLabel(OperatingSystem.Linux, KeyChord(KeyMod.CtrlCmd | KeyCode.KeyA, KeyMod.CtrlCmd | KeyCode.KeyB), 'ctrl+a ctrl+b');
assertElectronAcceleratorLabel(OperatingSystem.Macintosh, KeyChord(KeyMod.CtrlCmd | KeyCode.KeyA, KeyMod.CtrlCmd | KeyCode.KeyB), 'cmd+a cmd+b');
});
test('issue #91235: Do not end with a +', () => {

View File

@@ -3,7 +3,8 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { createKeybinding, createSimpleKeybinding, KeyChord, KeyCode, KeyMod, SimpleKeybinding } from 'vs/base/common/keyCodes';
import { KeyChord, KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import { createKeybinding, createSimpleKeybinding, SimpleKeybinding } from 'vs/base/common/keybindings';
import { OS } from 'vs/base/common/platform';
import { ContextKeyExpr, ContextKeyExpression, IContext } from 'vs/platform/contextkey/common/contextkey';
import { KeybindingResolver } from 'vs/platform/keybinding/common/keybindingResolver';
@@ -38,7 +39,7 @@ suite('KeybindingResolver', () => {
}
test('resolve key', function () {
let keybinding = KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_Z;
let keybinding = KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyZ;
let runtimeKeybinding = createSimpleKeybinding(keybinding, OS);
let contextRules = ContextKeyExpr.equals('bar', 'baz');
let keybindingItem = kbItem(keybinding, 'yes', null, contextRules, true);
@@ -53,7 +54,7 @@ suite('KeybindingResolver', () => {
test('resolve key with arguments', function () {
let commandArgs = { text: 'no' };
let keybinding = KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_Z;
let keybinding = KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyZ;
let runtimeKeybinding = createSimpleKeybinding(keybinding, OS);
let contextRules = ContextKeyExpr.equals('bar', 'baz');
let keybindingItem = kbItem(keybinding, 'yes', commandArgs, contextRules, true);
@@ -64,131 +65,131 @@ suite('KeybindingResolver', () => {
test('KeybindingResolver.combine simple 1', function () {
let defaults = [
kbItem(KeyCode.KEY_A, 'yes1', null, ContextKeyExpr.equals('1', 'a'), true)
kbItem(KeyCode.KeyA, 'yes1', null, ContextKeyExpr.equals('1', 'a'), true)
];
let overrides = [
kbItem(KeyCode.KEY_B, 'yes2', null, ContextKeyExpr.equals('2', 'b'), false)
kbItem(KeyCode.KeyB, 'yes2', null, ContextKeyExpr.equals('2', 'b'), false)
];
let actual = KeybindingResolver.combine(defaults, overrides);
assert.deepStrictEqual(actual, [
kbItem(KeyCode.KEY_A, 'yes1', null, ContextKeyExpr.equals('1', 'a'), true),
kbItem(KeyCode.KEY_B, 'yes2', null, ContextKeyExpr.equals('2', 'b'), false),
kbItem(KeyCode.KeyA, 'yes1', null, ContextKeyExpr.equals('1', 'a'), true),
kbItem(KeyCode.KeyB, 'yes2', null, ContextKeyExpr.equals('2', 'b'), false),
]);
});
test('KeybindingResolver.combine simple 2', function () {
let defaults = [
kbItem(KeyCode.KEY_A, 'yes1', null, ContextKeyExpr.equals('1', 'a'), true),
kbItem(KeyCode.KEY_B, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true)
kbItem(KeyCode.KeyA, 'yes1', null, ContextKeyExpr.equals('1', 'a'), true),
kbItem(KeyCode.KeyB, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true)
];
let overrides = [
kbItem(KeyCode.KEY_C, 'yes3', null, ContextKeyExpr.equals('3', 'c'), false)
kbItem(KeyCode.KeyC, 'yes3', null, ContextKeyExpr.equals('3', 'c'), false)
];
let actual = KeybindingResolver.combine(defaults, overrides);
assert.deepStrictEqual(actual, [
kbItem(KeyCode.KEY_A, 'yes1', null, ContextKeyExpr.equals('1', 'a'), true),
kbItem(KeyCode.KEY_B, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true),
kbItem(KeyCode.KEY_C, 'yes3', null, ContextKeyExpr.equals('3', 'c'), false),
kbItem(KeyCode.KeyA, 'yes1', null, ContextKeyExpr.equals('1', 'a'), true),
kbItem(KeyCode.KeyB, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true),
kbItem(KeyCode.KeyC, 'yes3', null, ContextKeyExpr.equals('3', 'c'), false),
]);
});
test('KeybindingResolver.combine removal with not matching when', function () {
let defaults = [
kbItem(KeyCode.KEY_A, 'yes1', null, ContextKeyExpr.equals('1', 'a'), true),
kbItem(KeyCode.KEY_B, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true)
kbItem(KeyCode.KeyA, 'yes1', null, ContextKeyExpr.equals('1', 'a'), true),
kbItem(KeyCode.KeyB, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true)
];
let overrides = [
kbItem(KeyCode.KEY_A, '-yes1', null, ContextKeyExpr.equals('1', 'b'), false)
kbItem(KeyCode.KeyA, '-yes1', null, ContextKeyExpr.equals('1', 'b'), false)
];
let actual = KeybindingResolver.combine(defaults, overrides);
assert.deepStrictEqual(actual, [
kbItem(KeyCode.KEY_A, 'yes1', null, ContextKeyExpr.equals('1', 'a'), true),
kbItem(KeyCode.KEY_B, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true)
kbItem(KeyCode.KeyA, 'yes1', null, ContextKeyExpr.equals('1', 'a'), true),
kbItem(KeyCode.KeyB, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true)
]);
});
test('KeybindingResolver.combine removal with not matching keybinding', function () {
let defaults = [
kbItem(KeyCode.KEY_A, 'yes1', null, ContextKeyExpr.equals('1', 'a'), true),
kbItem(KeyCode.KEY_B, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true)
kbItem(KeyCode.KeyA, 'yes1', null, ContextKeyExpr.equals('1', 'a'), true),
kbItem(KeyCode.KeyB, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true)
];
let overrides = [
kbItem(KeyCode.KEY_B, '-yes1', null, ContextKeyExpr.equals('1', 'a'), false)
kbItem(KeyCode.KeyB, '-yes1', null, ContextKeyExpr.equals('1', 'a'), false)
];
let actual = KeybindingResolver.combine(defaults, overrides);
assert.deepStrictEqual(actual, [
kbItem(KeyCode.KEY_A, 'yes1', null, ContextKeyExpr.equals('1', 'a'), true),
kbItem(KeyCode.KEY_B, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true)
kbItem(KeyCode.KeyA, 'yes1', null, ContextKeyExpr.equals('1', 'a'), true),
kbItem(KeyCode.KeyB, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true)
]);
});
test('KeybindingResolver.combine removal with matching keybinding and when', function () {
let defaults = [
kbItem(KeyCode.KEY_A, 'yes1', null, ContextKeyExpr.equals('1', 'a'), true),
kbItem(KeyCode.KEY_B, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true)
kbItem(KeyCode.KeyA, 'yes1', null, ContextKeyExpr.equals('1', 'a'), true),
kbItem(KeyCode.KeyB, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true)
];
let overrides = [
kbItem(KeyCode.KEY_A, '-yes1', null, ContextKeyExpr.equals('1', 'a'), false)
kbItem(KeyCode.KeyA, '-yes1', null, ContextKeyExpr.equals('1', 'a'), false)
];
let actual = KeybindingResolver.combine(defaults, overrides);
assert.deepStrictEqual(actual, [
kbItem(KeyCode.KEY_B, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true)
kbItem(KeyCode.KeyB, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true)
]);
});
test('KeybindingResolver.combine removal with unspecified keybinding', function () {
let defaults = [
kbItem(KeyCode.KEY_A, 'yes1', null, ContextKeyExpr.equals('1', 'a'), true),
kbItem(KeyCode.KEY_B, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true)
kbItem(KeyCode.KeyA, 'yes1', null, ContextKeyExpr.equals('1', 'a'), true),
kbItem(KeyCode.KeyB, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true)
];
let overrides = [
kbItem(0, '-yes1', null, ContextKeyExpr.equals('1', 'a'), false)
];
let actual = KeybindingResolver.combine(defaults, overrides);
assert.deepStrictEqual(actual, [
kbItem(KeyCode.KEY_B, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true)
kbItem(KeyCode.KeyB, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true)
]);
});
test('KeybindingResolver.combine removal with unspecified when', function () {
let defaults = [
kbItem(KeyCode.KEY_A, 'yes1', null, ContextKeyExpr.equals('1', 'a'), true),
kbItem(KeyCode.KEY_B, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true)
kbItem(KeyCode.KeyA, 'yes1', null, ContextKeyExpr.equals('1', 'a'), true),
kbItem(KeyCode.KeyB, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true)
];
let overrides = [
kbItem(KeyCode.KEY_A, '-yes1', null, null!, false)
kbItem(KeyCode.KeyA, '-yes1', null, null!, false)
];
let actual = KeybindingResolver.combine(defaults, overrides);
assert.deepStrictEqual(actual, [
kbItem(KeyCode.KEY_B, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true)
kbItem(KeyCode.KeyB, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true)
]);
});
test('KeybindingResolver.combine removal with unspecified when and unspecified keybinding', function () {
let defaults = [
kbItem(KeyCode.KEY_A, 'yes1', null, ContextKeyExpr.equals('1', 'a'), true),
kbItem(KeyCode.KEY_B, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true)
kbItem(KeyCode.KeyA, 'yes1', null, ContextKeyExpr.equals('1', 'a'), true),
kbItem(KeyCode.KeyB, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true)
];
let overrides = [
kbItem(0, '-yes1', null, null!, false)
];
let actual = KeybindingResolver.combine(defaults, overrides);
assert.deepStrictEqual(actual, [
kbItem(KeyCode.KEY_B, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true)
kbItem(KeyCode.KeyB, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true)
]);
});
test('issue #612#issuecomment-222109084 cannot remove keybindings for commands with ^', function () {
let defaults = [
kbItem(KeyCode.KEY_A, '^yes1', null, ContextKeyExpr.equals('1', 'a'), true),
kbItem(KeyCode.KEY_B, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true)
kbItem(KeyCode.KeyA, '^yes1', null, ContextKeyExpr.equals('1', 'a'), true),
kbItem(KeyCode.KeyB, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true)
];
let overrides = [
kbItem(KeyCode.KEY_A, '-yes1', null, null!, false)
kbItem(KeyCode.KeyA, '-yes1', null, null!, false)
];
let actual = KeybindingResolver.combine(defaults, overrides);
assert.deepStrictEqual(actual, [
kbItem(KeyCode.KEY_B, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true)
kbItem(KeyCode.KeyB, 'yes2', null, ContextKeyExpr.equals('2', 'b'), true)
]);
});
@@ -245,7 +246,7 @@ suite('KeybindingResolver', () => {
let items = [
// This one will never match because its "when" is always overwritten by another one
_kbItem(
KeyCode.KEY_X,
KeyCode.KeyX,
'first',
ContextKeyExpr.and(
ContextKeyExpr.equals('key1', true),
@@ -254,31 +255,31 @@ suite('KeybindingResolver', () => {
),
// This one always overwrites first
_kbItem(
KeyCode.KEY_X,
KeyCode.KeyX,
'second',
ContextKeyExpr.equals('key2', true)
),
// This one is a secondary mapping for `second`
_kbItem(
KeyCode.KEY_Z,
KeyCode.KeyZ,
'second',
null!
),
// This one sometimes overwrites first
_kbItem(
KeyCode.KEY_X,
KeyCode.KeyX,
'third',
ContextKeyExpr.equals('key3', true)
),
// This one is always overwritten by another one
_kbItem(
KeyMod.CtrlCmd | KeyCode.KEY_Y,
KeyMod.CtrlCmd | KeyCode.KeyY,
'fourth',
ContextKeyExpr.equals('key4', true)
),
// This one overwrites with a chord the previous one
_kbItem(
KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_Y, KeyCode.KEY_Z),
KeyChord(KeyMod.CtrlCmd | KeyCode.KeyY, KeyCode.KeyZ),
'fifth',
null!
),
@@ -289,32 +290,32 @@ suite('KeybindingResolver', () => {
null!
),
_kbItem(
KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_U),
KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.KeyU),
'seventh',
null!
),
_kbItem(
KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_K),
KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.KeyK),
'seventh',
null!
),
_kbItem(
KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_U),
KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.KeyU),
'uncomment lines',
null!
),
_kbItem(
KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_C),
KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.KeyC),
'comment lines',
null!
),
_kbItem(
KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_G, KeyMod.CtrlCmd | KeyCode.KEY_C),
KeyChord(KeyMod.CtrlCmd | KeyCode.KeyG, KeyMod.CtrlCmd | KeyCode.KeyC),
'unreachablechord',
null!
),
_kbItem(
KeyMod.CtrlCmd | KeyCode.KEY_G,
KeyMod.CtrlCmd | KeyCode.KeyG,
'eleven',
null!
)
@@ -325,7 +326,7 @@ suite('KeybindingResolver', () => {
let testKey = (commandId: string, expectedKeys: number[]) => {
// Test lookup
let lookupResult = resolver.lookupKeybindings(commandId);
assert.strictEqual(lookupResult.length, expectedKeys.length, 'Length mismatch @ commandId ' + commandId + '; GOT: ' + JSON.stringify(lookupResult, null, '\t'));
assert.strictEqual(lookupResult.length, expectedKeys.length, 'Length mismatch @ commandId ' + commandId);
for (let i = 0, len = lookupResult.length; i < len; i++) {
const expected = new USLayoutResolvedKeybinding(createKeybinding(expectedKeys[i], OS)!, OS);
@@ -359,31 +360,31 @@ suite('KeybindingResolver', () => {
testKey('first', []);
testKey('second', [KeyCode.KEY_Z, KeyCode.KEY_X]);
testResolve(createContext({ key2: true }), KeyCode.KEY_X, 'second');
testResolve(createContext({}), KeyCode.KEY_Z, 'second');
testKey('second', [KeyCode.KeyZ, KeyCode.KeyX]);
testResolve(createContext({ key2: true }), KeyCode.KeyX, 'second');
testResolve(createContext({}), KeyCode.KeyZ, 'second');
testKey('third', [KeyCode.KEY_X]);
testResolve(createContext({ key3: true }), KeyCode.KEY_X, 'third');
testKey('third', [KeyCode.KeyX]);
testResolve(createContext({ key3: true }), KeyCode.KeyX, 'third');
testKey('fourth', []);
testKey('fifth', [KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_Y, KeyCode.KEY_Z)]);
testResolve(createContext({}), KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_Y, KeyCode.KEY_Z), 'fifth');
testKey('fifth', [KeyChord(KeyMod.CtrlCmd | KeyCode.KeyY, KeyCode.KeyZ)]);
testResolve(createContext({}), KeyChord(KeyMod.CtrlCmd | KeyCode.KeyY, KeyCode.KeyZ), 'fifth');
testKey('seventh', [KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_K)]);
testResolve(createContext({}), KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_K), 'seventh');
testKey('seventh', [KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.KeyK)]);
testResolve(createContext({}), KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.KeyK), 'seventh');
testKey('uncomment lines', [KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_U)]);
testResolve(createContext({}), KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_U), 'uncomment lines');
testKey('uncomment lines', [KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.KeyU)]);
testResolve(createContext({}), KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.KeyU), 'uncomment lines');
testKey('comment lines', [KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_C)]);
testResolve(createContext({}), KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_C), 'comment lines');
testKey('comment lines', [KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.KeyC)]);
testResolve(createContext({}), KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyCode.KeyC), 'comment lines');
testKey('unreachablechord', []);
testKey('eleven', [KeyMod.CtrlCmd | KeyCode.KEY_G]);
testResolve(createContext({}), KeyMod.CtrlCmd | KeyCode.KEY_G, 'eleven');
testKey('eleven', [KeyMod.CtrlCmd | KeyCode.KeyG]);
testResolve(createContext({}), KeyMod.CtrlCmd | KeyCode.KeyG, 'eleven');
testKey('sixth', []);
});

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { Event } from 'vs/base/common/event';
import { Keybinding, ResolvedKeybinding, SimpleKeybinding } from 'vs/base/common/keyCodes';
import { Keybinding, ResolvedKeybinding, SimpleKeybinding } from 'vs/base/common/keybindings';
import { OS } from 'vs/base/common/platform';
import { ContextKeyExpression, IContextKey, IContextKeyChangeEvent, IContextKeyService, IContextKeyServiceTarget } from 'vs/platform/contextkey/common/contextkey';
import { IKeybindingEvent, IKeybindingService, IKeyboardEvent } from 'vs/platform/keybinding/common/keybinding';