提交 a01e4685 编写于 作者: A Alex Dima

Eliminate KeybindingLabels

上级 e5aa64c5
......@@ -571,9 +571,25 @@ export type Keybinding = SimpleKeybinding | ChordKeybinding;
* A resolved keybinding.
*/
export abstract class ResolvedKeybinding {
/**
* This prints the binding in a format suitable for displaying in the UI.
*/
public abstract getLabel(): string;
/**
* This prints the binding in a format suitable for ARIA.
*/
public abstract getAriaLabel(): string;
/**
* This prints the binding in a format suitable for displaying in the UI.
*/
public abstract getHTMLLabel(): IHTMLContentElement[];
/**
* This prints the binding in a format suitable for electron's accelerators.
* See https://github.com/electron/electron/blob/master/docs/api/accelerator.md
*/
public abstract getElectronAccelerator(): string;
/**
* This prints the binding in a format suitable for user settings.
*/
public abstract getUserSettingsLabel(): string;
}
......@@ -137,4 +137,11 @@ export const setTimeout = _globals.setTimeout.bind(_globals);
export const clearTimeout = _globals.clearTimeout.bind(_globals);
export const setInterval = _globals.setInterval.bind(_globals);
export const clearInterval = _globals.clearInterval.bind(_globals);
\ No newline at end of file
export const clearInterval = _globals.clearInterval.bind(_globals);
export const enum OperatingSystem {
Windows = 1,
Macintosh = 2,
Linux = 3
}
export const OS = (_isMacintosh ? OperatingSystem.Macintosh : (_isWindows ? OperatingSystem.Windows : OperatingSystem.Linux));
......@@ -11,7 +11,7 @@ import { TPromise } from 'vs/base/common/winjs.base';
import { IConfigurationService, IConfigurationServiceEvent, IConfigurationValue, getConfigurationValue, IConfigurationKeys } from 'vs/platform/configuration/common/configuration';
import { IEditor, IEditorInput, IEditorOptions, IEditorService, IResourceInput, Position } from 'vs/platform/editor/common/editor';
import { ICommandService, ICommand, ICommandEvent, ICommandHandler, CommandsRegistry } from 'vs/platform/commands/common/commands';
import { SimpleResolvedKeybinding, AbstractKeybindingService } from 'vs/platform/keybinding/common/abstractKeybindingService';
import { USLayoutResolvedKeybinding, AbstractKeybindingService } from 'vs/platform/keybinding/common/abstractKeybindingService';
import { KeybindingResolver } from 'vs/platform/keybinding/common/keybindingResolver';
import { IKeybindingEvent, IKeybindingItem, KeybindingSource } from 'vs/platform/keybinding/common/keybinding';
import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
......@@ -33,6 +33,7 @@ import { Menu } from 'vs/platform/actions/common/menu';
import { ITelemetryService, ITelemetryExperiments, ITelemetryInfo } from 'vs/platform/telemetry/common/telemetry';
import { ResolvedKeybinding, Keybinding } from 'vs/base/common/keyCodes';
import { NormalizedKeybindingItem } from 'vs/platform/keybinding/common/normalizedKeybindingItem';
import { OS } from 'vs/base/common/platform';
export class SimpleEditor implements IEditor {
......@@ -380,7 +381,7 @@ export class StandaloneKeybindingService extends AbstractKeybindingService {
}
protected _createResolvedKeybinding(kb: Keybinding): ResolvedKeybinding {
return new SimpleResolvedKeybinding(kb);
return new USLayoutResolvedKeybinding(kb, OS);
}
}
......
......@@ -10,7 +10,6 @@ import * as nls from 'vs/nls';
import { RunOnceScheduler } from 'vs/base/common/async';
import { MarkedString } from 'vs/base/common/htmlContent';
import { ResolvedKeybinding, createKeybinding, KeyCode, KeyMod, KeyChord } from 'vs/base/common/keyCodes';
import { KeybindingLabels } from 'vs/platform/keybinding/common/keybindingLabels';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import * as dom from 'vs/base/browser/dom';
import { renderHtml } from 'vs/base/browser/htmlContentRenderer';
......@@ -27,6 +26,8 @@ import { editorContribution } from 'vs/editor/browser/editorBrowserExtensions';
import { CodeSnippet } from 'vs/editor/contrib/snippet/common/snippet';
import { SnippetController } from 'vs/editor/contrib/snippet/common/snippetController';
import { SmartSnippetInserter } from 'vs/editor/contrib/defineKeybinding/common/smartSnippetInserter';
import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/abstractKeybindingService';
import { OS } from 'vs/base/common/platform';
import EditorContextKeys = editorCommon.EditorContextKeys;
......@@ -153,7 +154,7 @@ export class DefineKeybindingController implements editorCommon.IEditorContribut
private _dec: string[] = [];
private _updateDecorationsNow(): void {
let model = this._editor.getModel();
let regex = KeybindingLabels.getUserSettingsKeybindingRegex();
let regex = KeybindingIO.getUserSettingsKeybindingRegex();
var m = model.findMatches(regex, false, true, false, false, false).map(m => m.range);
......@@ -163,15 +164,16 @@ export class DefineKeybindingController implements editorCommon.IEditorContribut
let strKeybinding = text.substring(1, text.length - 1);
strKeybinding = strKeybinding.replace(/\\\\/g, '\\');
let numKeybinding = KeybindingIO.readKeybinding(strKeybinding);
let numKeybinding = KeybindingIO.readKeybinding(strKeybinding, OS);
let keybinding = createKeybinding(numKeybinding);
let resolvedKeybinding = this._keybindingService.resolveKeybinding(keybinding);
const usResolvedKeybinding = new USLayoutResolvedKeybinding(keybinding, OS);
return {
strKeybinding: strKeybinding,
keybinding: keybinding,
usLabel: KeybindingLabels._toUSLabel(keybinding),
usLabel: usResolvedKeybinding.getLabel(),
label: resolvedKeybinding.getLabel(),
range: range
};
......
......@@ -7,8 +7,9 @@
import * as assert from 'assert';
import { KeyCode as StandaloneKeyCode, Severity as StandaloneSeverity } from 'vs/editor/common/standalone/standaloneBase';
import { createKeybinding, KeyCode as RuntimeKeyCode } from 'vs/base/common/keyCodes';
import { KeybindingLabels } from 'vs/platform/keybinding/common/keybindingLabels';
import RuntimeSeverity from 'vs/base/common/severity';
import { KeybindingIO } from 'vs/platform/keybinding/common/keybindingIO';
import { OS } from 'vs/base/common/platform';
suite('StandaloneBase', () => {
test('exports enums correctly', () => {
......@@ -139,7 +140,7 @@ suite('KeyCode', () => {
});
test('getUserSettingsKeybindingRegex', () => {
let regex = new RegExp(KeybindingLabels.getUserSettingsKeybindingRegex());
let regex = new RegExp(KeybindingIO.getUserSettingsKeybindingRegex());
function testIsGood(userSettingsLabel: string, message: string = userSettingsLabel): void {
let userSettings = '"' + userSettingsLabel.replace(/\\/g, '\\\\') + '"';
......@@ -157,7 +158,7 @@ suite('KeyCode', () => {
if (ignore[keyCode]) {
continue;
}
let userSettings = KeybindingLabels.toUserSettingsLabel(createKeybinding(keyCode));
let userSettings = KeybindingIO.writeKeybinding(createKeybinding(keyCode), OS);
testIsGood(userSettings, keyCode + ' - ' + StandaloneKeyCode[keyCode] + ' - ' + userSettings);
}
......
......@@ -6,8 +6,8 @@
import * as nls from 'vs/nls';
import { IHTMLContentElement } from 'vs/base/common/htmlContent';
import { ResolvedKeybinding, SimpleKeybinding, Keybinding } from 'vs/base/common/keyCodes';
import { KeybindingLabels } from 'vs/platform/keybinding/common/keybindingLabels';
import { ResolvedKeybinding, SimpleKeybinding, Keybinding, KeyCode, KeyCodeUtils } from 'vs/base/common/keyCodes';
import { PrintableKeypress, UILabelProvider, AriaLabelProvider, ElectronAcceleratorLabelProvider } from 'vs/platform/keybinding/common/keybindingLabels';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import Severity from 'vs/base/common/severity';
import { isFalsyOrEmpty } from 'vs/base/common/arrays';
......@@ -20,34 +20,90 @@ import { IMessageService } from 'vs/platform/message/common/message';
import Event, { Emitter } from 'vs/base/common/event';
import { KeybindingIO, OutputBuilder } from 'vs/platform/keybinding/common/keybindingIO';
import { NormalizedKeybindingItem } from 'vs/platform/keybinding/common/normalizedKeybindingItem';
import { OS, OperatingSystem } from 'vs/base/common/platform';
export class SimpleResolvedKeybinding extends ResolvedKeybinding {
/**
* Do not instantiate. Use KeybindingService to get a ResolvedKeybinding.
*/
export class USLayoutResolvedKeybinding extends ResolvedKeybinding {
private readonly _actual: Keybinding;
private readonly _os: OperatingSystem;
constructor(actual: Keybinding) {
constructor(actual: Keybinding, os: OperatingSystem) {
super();
this._actual = actual;
this._os = os;
}
private static _usKeyCodeToUILabel(keyCode: KeyCode, OS: OperatingSystem): string {
if (OS === OperatingSystem.Macintosh) {
switch (keyCode) {
case KeyCode.LeftArrow:
return '';
case KeyCode.UpArrow:
return '';
case KeyCode.RightArrow:
return '';
case KeyCode.DownArrow:
return '';
}
}
return KeyCodeUtils.toString(keyCode);
}
private static _usKeyCodeToAriaLabel(keyCode: KeyCode, OS: OperatingSystem): string {
return KeyCodeUtils.toString(keyCode);
}
public getLabel(): string {
return KeybindingLabels._toUSLabel(this._actual);
const [firstPart, chordPart] = PrintableKeypress.fromKeybinding2(this._actual, USLayoutResolvedKeybinding._usKeyCodeToUILabel, this._os);
return UILabelProvider.toLabel2(firstPart, chordPart, this._os);
}
public getAriaLabel(): string {
return KeybindingLabels._toUSAriaLabel(this._actual);
const [firstPart, chordPart] = PrintableKeypress.fromKeybinding2(this._actual, USLayoutResolvedKeybinding._usKeyCodeToAriaLabel, this._os);
return AriaLabelProvider.toLabel2(firstPart, chordPart, this._os);
}
public getHTMLLabel(): IHTMLContentElement[] {
return KeybindingLabels._toUSHTMLLabel(this._actual);
const [firstPart, chordPart] = PrintableKeypress.fromKeybinding2(this._actual, USLayoutResolvedKeybinding._usKeyCodeToUILabel, this._os);
return UILabelProvider.toHTMLLabel2(firstPart, chordPart, this._os);
}
private static _usKeyCodeToElectronAccelerator(keyCode: KeyCode, OS: OperatingSystem): string {
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);
}
public getElectronAccelerator(): string {
return KeybindingLabels._toElectronAccelerator(this._actual);
if (this._actual.isChord()) {
// Electron cannot handle chords
return null;
}
let keyCode = this._actual.getKeyCode();
if (keyCode >= KeyCode.NUMPAD_0 && keyCode <= KeyCode.NUMPAD_DIVIDE) {
// Electron cannot handle numpad keys
return null;
}
const [firstPart, chordPart] = PrintableKeypress.fromKeybinding2(this._actual, USLayoutResolvedKeybinding._usKeyCodeToElectronAccelerator, this._os);
return ElectronAcceleratorLabelProvider.toLabel2(firstPart, chordPart, this._os);
}
public getUserSettingsLabel(): string {
return KeybindingLabels.toUserSettingsLabel(this._actual);
return KeybindingIO.writeKeybinding(this._actual, this._os);
}
}
......@@ -119,7 +175,7 @@ export abstract class AbstractKeybindingService implements IKeybindingService {
let lastIndex = defaultKeybindings.length - 1;
defaultKeybindings.forEach((k, index) => {
KeybindingIO.writeKeybindingItem(out, k);
KeybindingIO.writeKeybindingItem(out, k, OS);
if (index !== lastIndex) {
out.writeLine(',');
} else {
......
......@@ -4,17 +4,17 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import { Keybinding, KeyMod, KeyChord, USER_SETTINGS } from 'vs/base/common/keyCodes';
import { ISimplifiedPlatform, KeybindingLabels } from 'vs/platform/keybinding/common/keybindingLabels';
import * as platform from 'vs/base/common/platform';
import { Keybinding, KeyMod, KeyChord, USER_SETTINGS, KeyCode } from 'vs/base/common/keyCodes';
import { PrintableKeypress, UserSettingsLabelProvider } from 'vs/platform/keybinding/common/keybindingLabels';
import { OperatingSystem } from 'vs/base/common/platform';
import { IKeybindingItem, IUserFriendlyKeybinding } from 'vs/platform/keybinding/common/keybinding';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { NormalizedKeybindingItem } from 'vs/platform/keybinding/common/normalizedKeybindingItem';
export class KeybindingIO {
public static writeKeybindingItem(out: OutputBuilder, item: NormalizedKeybindingItem): void {
let quotedSerializedKeybinding = JSON.stringify(KeybindingIO.writeKeybinding(item.keybinding));
public static writeKeybindingItem(out: OutputBuilder, item: NormalizedKeybindingItem, OS: OperatingSystem): void {
let quotedSerializedKeybinding = JSON.stringify(KeybindingIO.writeKeybinding(item.keybinding, OS));
out.write(`{ "key": ${rightPaddedString(quotedSerializedKeybinding + ',', 25)} "command": `);
let serializedWhen = item.when ? item.when.serialize() : '';
......@@ -30,10 +30,10 @@ export class KeybindingIO {
out.write('}');
}
public static readKeybindingItem(input: IUserFriendlyKeybinding, index: number): IKeybindingItem {
public static readKeybindingItem(input: IUserFriendlyKeybinding, index: number, OS: OperatingSystem): IKeybindingItem {
let key: number = 0;
if (typeof input.key === 'string') {
key = KeybindingIO.readKeybinding(input.key);
key = KeybindingIO.readKeybinding(input.key, OS);
}
let when: ContextKeyExpr = null;
......@@ -61,11 +61,38 @@ export class KeybindingIO {
};
}
public static writeKeybinding(keybinding: Keybinding, Platform: ISimplifiedPlatform = platform): string {
return KeybindingLabels.toUserSettingsLabel(keybinding, Platform);
private static _cachedKeybindingRegex: string = null;
/**
* @internal
*/
public static getUserSettingsKeybindingRegex(): string {
if (!this._cachedKeybindingRegex) {
let numpadKey = 'numpad(0|1|2|3|4|5|6|7|8|9|_multiply|_add|_subtract|_decimal|_divide|_separator)';
let oemKey = '`|\\-|=|\\[|\\]|\\\\\\\\|;|\'|,|\\.|\\/|oem_8|oem_102';
let specialKey = 'left|up|right|down|pageup|pagedown|end|home|tab|enter|escape|space|backspace|delete|pausebreak|capslock|insert|contextmenu|numlock|scrolllock';
let casualKey = '[a-z]|[0-9]|f(1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19)';
let key = '((' + [numpadKey, oemKey, specialKey, casualKey].join(')|(') + '))';
let mod = '((ctrl|shift|alt|cmd|win|meta)\\+)*';
let keybinding = '(' + mod + key + ')';
this._cachedKeybindingRegex = '"\\s*(' + keybinding + '(\\s+' + keybinding + ')?' + ')\\s*"';
}
return this._cachedKeybindingRegex;
}
private static _keyCodeToStr(keyCode: KeyCode, OS: OperatingSystem): string {
return USER_SETTINGS.fromKeyCode(keyCode);
}
public static writeKeybinding(keybinding: Keybinding, OS: OperatingSystem): string {
const [firstPart, chordPart] = PrintableKeypress.fromKeybinding2(keybinding, this._keyCodeToStr, OS);
let result = UserSettingsLabelProvider.toLabel2(firstPart, chordPart, OS);
return result.toLowerCase();
}
public static readKeybinding(input: string, Platform: ISimplifiedPlatform = platform): number {
public static readKeybinding(input: string, OS: OperatingSystem): number {
if (!input) {
return null;
}
......@@ -79,7 +106,7 @@ export class KeybindingIO {
while (/^(ctrl|shift|alt|meta|win|cmd)(\+|\-)/.test(input)) {
if (/^ctrl(\+|\-)/.test(input)) {
if (Platform.isMacintosh) {
if (OS === OperatingSystem.Macintosh) {
winCtrl = true;
} else {
ctrlCmd = true;
......@@ -95,7 +122,7 @@ export class KeybindingIO {
input = input.substr('alt-'.length);
}
if (/^meta(\+|\-)/.test(input)) {
if (Platform.isMacintosh) {
if (OS === OperatingSystem.Macintosh) {
ctrlCmd = true;
} else {
winCtrl = true;
......@@ -103,7 +130,7 @@ export class KeybindingIO {
input = input.substr('meta-'.length);
}
if (/^win(\+|\-)/.test(input)) {
if (Platform.isMacintosh) {
if (OS === OperatingSystem.Macintosh) {
ctrlCmd = true;
} else {
winCtrl = true;
......@@ -111,7 +138,7 @@ export class KeybindingIO {
input = input.substr('win-'.length);
}
if (/^cmd(\+|\-)/.test(input)) {
if (Platform.isMacintosh) {
if (OS === OperatingSystem.Macintosh) {
ctrlCmd = true;
} else {
winCtrl = true;
......@@ -125,7 +152,7 @@ export class KeybindingIO {
let firstSpaceIdx = input.indexOf(' ');
if (firstSpaceIdx > 0) {
key = input.substring(0, firstSpaceIdx);
chord = KeybindingIO.readKeybinding(input.substring(firstSpaceIdx), Platform);
chord = KeybindingIO.readKeybinding(input.substring(firstSpaceIdx), OS);
} else {
key = input;
}
......
......@@ -6,119 +6,57 @@
'use strict';
import * as nls from 'vs/nls';
import * as defaultPlatform from 'vs/base/common/platform';
import { OperatingSystem } from 'vs/base/common/platform';
import { IHTMLContentElement } from 'vs/base/common/htmlContent';
import { Keybinding, SimpleKeybinding, KeyCode, KeyCodeUtils, USER_SETTINGS } from 'vs/base/common/keyCodes';
import { Keybinding, SimpleKeybinding, KeyCode } from 'vs/base/common/keyCodes';
export interface ISimplifiedPlatform {
isMacintosh: boolean;
isWindows: boolean;
export interface IKeyCodeLabelProvider2 {
(keyCode: KeyCode, OS: OperatingSystem): string;
}
export class KeybindingLabels {
private static _cachedKeybindingRegex: string = null;
/**
* @internal
*/
public static getUserSettingsKeybindingRegex(): string {
if (!this._cachedKeybindingRegex) {
let numpadKey = 'numpad(0|1|2|3|4|5|6|7|8|9|_multiply|_add|_subtract|_decimal|_divide|_separator)';
let oemKey = '`|\\-|=|\\[|\\]|\\\\\\\\|;|\'|,|\\.|\\/|oem_8|oem_102';
let specialKey = 'left|up|right|down|pageup|pagedown|end|home|tab|enter|escape|space|backspace|delete|pausebreak|capslock|insert|contextmenu|numlock|scrolllock';
let casualKey = '[a-z]|[0-9]|f(1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19)';
let key = '((' + [numpadKey, oemKey, specialKey, casualKey].join(')|(') + '))';
let mod = '((ctrl|shift|alt|cmd|win|meta)\\+)*';
let keybinding = '(' + mod + key + ')';
this._cachedKeybindingRegex = '"\\s*(' + keybinding + '(\\s+' + keybinding + ')?' + ')\\s*"';
}
return this._cachedKeybindingRegex;
}
/**
* Format the binding to a format appropiate for the user settings file.
* @internal
*/
public static toUserSettingsLabel(keybinding: Keybinding, Platform: ISimplifiedPlatform = defaultPlatform): string {
let result: string;
if (Platform.isMacintosh) {
result = MacUserSettingsLabelProvider._toUSLabel(keybinding);
} else {
result = ClassicUserSettingsLabelProvider._toUSLabel(keybinding);
}
export class PrintableKeypress {
result = result.toLowerCase();
public static fromSimpleKeybinding2(keybinding: SimpleKeybinding, labelProvider: IKeyCodeLabelProvider2, OS: OperatingSystem): PrintableKeypress {
const ctrlCmd = keybinding.hasCtrlCmd();
const winCtrl = keybinding.hasWinCtrl();
if (Platform.isMacintosh) {
result = result.replace(/meta/g, 'cmd');
} else if (Platform.isWindows) {
result = result.replace(/meta/g, 'win');
}
const ctrlKey = (OS === OperatingSystem.Macintosh ? winCtrl : ctrlCmd);
const metaKey = (OS === OperatingSystem.Macintosh ? ctrlCmd : winCtrl);
const shiftKey = keybinding.hasShift();
const altKey = keybinding.hasAlt();
return result;
}
const keyCode = keybinding.getKeyCode();
const keyLabel = labelProvider(keyCode, OS) || '';
/**
* Format the binding to a format appropiate for rendering in the UI
* @internal
*/
public static _toUSLabel(keybinding: Keybinding, Platform: ISimplifiedPlatform = defaultPlatform): string {
if (Platform.isMacintosh) {
return MacUILabelProvider._toUSLabel(keybinding);
}
return ClassicUILabelProvider._toUSLabel(keybinding);
return new PrintableKeypress(ctrlKey, shiftKey, altKey, metaKey, keyLabel);
}
/**
* Format the binding to a format appropiate for placing in an aria-label.
* @internal
*/
public static _toUSAriaLabel(keybinding: Keybinding, Platform: ISimplifiedPlatform = defaultPlatform): string {
if (Platform.isMacintosh) {
return MacAriaLabelProvider._toUSLabel(keybinding);
public static fromKeybinding2(keybinding: Keybinding, labelProvider: IKeyCodeLabelProvider2, OS: OperatingSystem): [PrintableKeypress, PrintableKeypress] {
if (keybinding.isChord()) {
const firstPart = PrintableKeypress.fromSimpleKeybinding2(keybinding.extractFirstPart(), labelProvider, OS);
const chordPart = PrintableKeypress.fromSimpleKeybinding2(keybinding.extractChordPart(), labelProvider, OS);
return [firstPart, chordPart];
} else {
const printableKeypress = PrintableKeypress.fromSimpleKeybinding2(keybinding, labelProvider, OS);
return [printableKeypress, null];
}
return ClassicAriaLabelProvider._toUSLabel(keybinding);
}
/**
* Format the binding to a format appropiate for rendering in the UI
* @internal
*/
public static _toUSHTMLLabel(keybinding: Keybinding, Platform: ISimplifiedPlatform = defaultPlatform): IHTMLContentElement[] {
if (Platform.isMacintosh) {
return MacUILabelProvider._toUSHTMLLabel(keybinding);
}
return ClassicUILabelProvider._toUSHTMLLabel(keybinding);
}
readonly ctrlKey: boolean;
readonly shiftKey: boolean;
readonly altKey: boolean;
readonly metaKey: boolean;
readonly key: string;
/**
* This prints the binding in a format suitable for electron's accelerators.
* See https://github.com/electron/electron/blob/master/docs/api/accelerator.md
* @internal
*/
public static _toElectronAccelerator(keybinding: Keybinding, Platform: ISimplifiedPlatform = defaultPlatform): string {
if (keybinding.isChord()) {
// Electron cannot handle chords
return null;
}
let keyCode = keybinding.getKeyCode();
if (keyCode >= KeyCode.NUMPAD_0 && keyCode <= KeyCode.NUMPAD_DIVIDE) {
// Electron cannot handle numpad keys
return null;
}
if (Platform.isMacintosh) {
return MacElectronAcceleratorLabelProvider._toUSLabel(keybinding);
}
return ClassicElectronAcceleratorLabelProvider._toUSLabel(keybinding);
constructor(ctrlKey: boolean, shiftKey: boolean, altKey: boolean, metaKey: boolean, key: string) {
this.ctrlKey = ctrlKey;
this.shiftKey = shiftKey;
this.altKey = altKey;
this.metaKey = metaKey;
this.key = key;
}
}
export interface IKeyCodeLabelProvider {
(keyCode: KeyCode): string;
}
export interface ModifierLabels {
readonly ctrlKey: string;
readonly shiftKey: string;
......@@ -127,39 +65,30 @@ export interface ModifierLabels {
readonly separator: string;
}
export class LabelProvider {
private readonly _isMacintosh: boolean;
private readonly _modifierLabels: ModifierLabels;
private readonly _keyCodeLabel: (keyCode: KeyCode) => string;
constructor(isMacintosh: boolean, modifierLabels: ModifierLabels, keyCodeLabel: (keyCode: KeyCode) => string) {
this._isMacintosh = isMacintosh;
this._modifierLabels = modifierLabels;
this._keyCodeLabel = keyCodeLabel;
}
export class ModifierLabelProvider {
public _toUSLabel(keybinding: Keybinding): string {
const [firstPart, chordPart] = PrintableKeypress.fromKeybinding(keybinding, this._keyCodeLabel, this._isMacintosh);
return this.toLabel(firstPart, chordPart);
}
private readonly _labels: ModifierLabels[];
public toLabel(firstPart: PrintableKeypress, chordPart: PrintableKeypress): string {
return _asString(firstPart, chordPart, this._modifierLabels);
constructor(mac: ModifierLabels, windows: ModifierLabels, linux: ModifierLabels = windows) {
this._labels = [null];
this._labels[OperatingSystem.Macintosh] = mac;
this._labels[OperatingSystem.Windows] = windows;
this._labels[OperatingSystem.Linux] = linux;
}
public _toUSHTMLLabel(keybinding: Keybinding): IHTMLContentElement[] {
const [firstPart, chordPart] = PrintableKeypress.fromKeybinding(keybinding, this._keyCodeLabel, this._isMacintosh);
return this.toHTMLLabel(firstPart, chordPart);
public toLabel2(firstPart: PrintableKeypress, chordPart: PrintableKeypress, OS: OperatingSystem): string {
return _asString(firstPart, chordPart, this._labels[OS]);
}
public toHTMLLabel(firstPart: PrintableKeypress, chordPart: PrintableKeypress): IHTMLContentElement[] {
return _asHTML(firstPart, chordPart, this._modifierLabels);
public toHTMLLabel2(firstPart: PrintableKeypress, chordPart: PrintableKeypress, OS: OperatingSystem): IHTMLContentElement[] {
return _asHTML(firstPart, chordPart, this._labels[OS]);
}
}
export const MacUILabelProvider: LabelProvider = new LabelProvider(
true,
/**
* A label provider that prints modifiers in a suitable format for displaying in the UI.
*/
export const UILabelProvider = new ModifierLabelProvider(
{
ctrlKey: '',
shiftKey: '',
......@@ -167,34 +96,19 @@ export const MacUILabelProvider: LabelProvider = new LabelProvider(
metaKey: '',
separator: '',
},
(keyCode: KeyCode): string => {
switch (keyCode) {
case KeyCode.LeftArrow:
return '';
case KeyCode.UpArrow:
return '';
case KeyCode.RightArrow:
return '';
case KeyCode.DownArrow:
return '';
}
return KeyCodeUtils.toString(keyCode);
}
);
export const ClassicUILabelProvider: LabelProvider = new LabelProvider(
false,
{
ctrlKey: nls.localize('ctrlKey', "Ctrl"),
shiftKey: nls.localize('shiftKey', "Shift"),
altKey: nls.localize('altKey', "Alt"),
metaKey: nls.localize('windowsKey', "Windows"),
separator: '+',
},
(keyCode: KeyCode) => KeyCodeUtils.toString(keyCode)
}
);
export const MacAriaLabelProvider: LabelProvider = new LabelProvider(
true,
/**
* A label provider that prints modifiers in a suitable format for ARIA.
*/
export const AriaLabelProvider = new ModifierLabelProvider(
{
ctrlKey: nls.localize('ctrlKey.long', "Control"),
shiftKey: nls.localize('shiftKey.long', "Shift"),
......@@ -202,54 +116,27 @@ export const MacAriaLabelProvider: LabelProvider = new LabelProvider(
metaKey: nls.localize('cmdKey.long', "Command"),
separator: '+',
},
(keyCode: KeyCode) => KeyCodeUtils.toString(keyCode)
);
export const ClassicAriaLabelProvider: LabelProvider = new LabelProvider(
false,
{
ctrlKey: nls.localize('ctrlKey.long', "Control"),
shiftKey: nls.localize('shiftKey.long', "Shift"),
altKey: nls.localize('altKey.long', "Alt"),
metaKey: nls.localize('windowsKey.long', "Windows"),
separator: '+',
},
(keyCode: KeyCode) => KeyCodeUtils.toString(keyCode)
}
);
class AcceleratorLabelProvider extends LabelProvider {
constructor(isMacintosh: boolean, modifierLabels: ModifierLabels) {
super(
isMacintosh,
modifierLabels,
(keyCode: KeyCode) => {
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);
}
);
}
}
const MacElectronAcceleratorLabelProvider = new AcceleratorLabelProvider(
true,
/**
* A label provider that prints modifiers in a suitable format for Electron Accelerators.
* See https://github.com/electron/electron/blob/master/docs/api/accelerator.md
*/
export const ElectronAcceleratorLabelProvider = new ModifierLabelProvider(
{
ctrlKey: 'Ctrl',
shiftKey: 'Shift',
altKey: 'Alt',
metaKey: 'Cmd',
separator: '+',
}
);
const ClassicElectronAcceleratorLabelProvider = new AcceleratorLabelProvider(
false,
},
{
ctrlKey: 'Ctrl',
shiftKey: 'Shift',
......@@ -259,66 +146,32 @@ const ClassicElectronAcceleratorLabelProvider = new AcceleratorLabelProvider(
}
);
class UserSettingsLabelProvider extends LabelProvider {
constructor(isMacintosh: boolean) {
super(
isMacintosh,
{
ctrlKey: 'Ctrl',
shiftKey: 'Shift',
altKey: 'Alt',
metaKey: 'Meta',
separator: '+',
},
(keyCode: KeyCode) => USER_SETTINGS.fromKeyCode(keyCode)
);
}
}
const MacUserSettingsLabelProvider = new UserSettingsLabelProvider(true);
const ClassicUserSettingsLabelProvider = new UserSettingsLabelProvider(false);
export class PrintableKeypress {
public static fromSimpleKeybinding(keybinding: SimpleKeybinding, labelProvider: IKeyCodeLabelProvider, isMacintosh: boolean): PrintableKeypress {
const ctrlCmd = keybinding.hasCtrlCmd();
const winCtrl = keybinding.hasWinCtrl();
const ctrlKey = isMacintosh ? winCtrl : ctrlCmd;
const metaKey = isMacintosh ? ctrlCmd : winCtrl;
const shiftKey = keybinding.hasShift();
const altKey = keybinding.hasAlt();
const keyCode = keybinding.getKeyCode();
const keyLabel = labelProvider(keyCode) || '';
return new PrintableKeypress(ctrlKey, shiftKey, altKey, metaKey, keyLabel);
}
public static fromKeybinding(keybinding: Keybinding, labelProvider: IKeyCodeLabelProvider, isMacintosh: boolean): [PrintableKeypress, PrintableKeypress] {
if (keybinding.isChord()) {
const firstPart = PrintableKeypress.fromSimpleKeybinding(keybinding.extractFirstPart(), labelProvider, isMacintosh);
const chordPart = PrintableKeypress.fromSimpleKeybinding(keybinding.extractChordPart(), labelProvider, isMacintosh);
return [firstPart, chordPart];
} else {
const printableKeypress = PrintableKeypress.fromSimpleKeybinding(keybinding, labelProvider, isMacintosh);
return [printableKeypress, null];
}
}
readonly ctrlKey: boolean;
readonly shiftKey: boolean;
readonly altKey: boolean;
readonly metaKey: boolean;
readonly key: string;
constructor(ctrlKey: boolean, shiftKey: boolean, altKey: boolean, metaKey: boolean, key: string) {
this.ctrlKey = ctrlKey;
this.shiftKey = shiftKey;
this.altKey = altKey;
this.metaKey = metaKey;
this.key = key;
/**
* A label provider that prints modifiers in a suitable format for user settings.
*/
export const UserSettingsLabelProvider = new ModifierLabelProvider(
{
ctrlKey: 'Ctrl',
shiftKey: 'Shift',
altKey: 'Alt',
metaKey: 'Cmd',
separator: '+',
},
{
ctrlKey: 'Ctrl',
shiftKey: 'Shift',
altKey: 'Alt',
metaKey: 'Win',
separator: '+',
},
{
ctrlKey: 'Ctrl',
shiftKey: 'Shift',
altKey: 'Alt',
metaKey: 'Meta',
separator: '+',
}
}
);
function _simpleAsString(keypress: PrintableKeypress, labels: ModifierLabels): string {
if (!keypress.key) {
......
......@@ -228,7 +228,6 @@ export class KeybindingResolver {
}
public resolve(context: any, currentChord: string, keypress: string): IResolveResult {
// console.log('resolve: ' + Keybinding.toUserSettingsLabel(keypress));
let lookupMap: NormalizedKeybindingItem[] = null;
if (currentChord !== null) {
......
......@@ -7,7 +7,7 @@
import { createKeybinding, Keybinding } from 'vs/base/common/keyCodes';
import { IKeybindingItem } from 'vs/platform/keybinding/common/keybinding';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { CharCode } from "vs/base/common/charCode";
import { CharCode } from 'vs/base/common/charCode';
export class NormalizedKeybindingItem {
_normalizedKeybindingItemBrand: void;
......
......@@ -6,8 +6,7 @@
import * as assert from 'assert';
import { ResolvedKeybinding, Keybinding, SimpleKeybinding, createKeybinding, KeyCode, KeyMod, KeyChord } from 'vs/base/common/keyCodes';
import { SimpleResolvedKeybinding, AbstractKeybindingService } from 'vs/platform/keybinding/common/abstractKeybindingService';
import { KeybindingLabels } from 'vs/platform/keybinding/common/keybindingLabels';
import { USLayoutResolvedKeybinding, AbstractKeybindingService } from 'vs/platform/keybinding/common/abstractKeybindingService';
import { IDisposable } from 'vs/base/common/lifecycle';
import Severity from 'vs/base/common/severity';
import { ICommandService } from 'vs/platform/commands/common/commands';
......@@ -17,6 +16,7 @@ import { IStatusbarService } from 'vs/platform/statusbar/common/statusbar';
import { IMessageService } from 'vs/platform/message/common/message';
import { TPromise } from 'vs/base/common/winjs.base';
import { NormalizedKeybindingItem } from 'vs/platform/keybinding/common/normalizedKeybindingItem';
import { OS } from 'vs/base/common/platform';
suite('AbstractKeybindingService', () => {
......@@ -39,7 +39,7 @@ suite('AbstractKeybindingService', () => {
}
protected _createResolvedKeybinding(kb: Keybinding): ResolvedKeybinding {
return new SimpleResolvedKeybinding(kb);
return new USLayoutResolvedKeybinding(kb, OS);
}
public dispatch(keybinding: SimpleKeybinding): boolean {
......@@ -133,6 +133,11 @@ suite('AbstractKeybindingService', () => {
return new NormalizedKeybindingItem(kb, command, null, when, true);
}
function toUsLabel(keybinding: number): string {
const usResolvedKeybinding = new USLayoutResolvedKeybinding(createKeybinding(keybinding), OS);
return usResolvedKeybinding.getLabel();
}
test('issue #16498: chord mode is quit for invalid chords', () => {
let kbService = createTestKeybindingService([
......@@ -146,7 +151,7 @@ suite('AbstractKeybindingService', () => {
assert.deepEqual(executeCommandCalls, []);
assert.deepEqual(showMessageCalls, []);
assert.deepEqual(statusMessageCalls, [
`(${KeybindingLabels._toUSLabel(createKeybinding(KeyMod.CtrlCmd | KeyCode.KEY_K))}) was pressed. Waiting for second key of chord...`
`(${toUsLabel(KeyMod.CtrlCmd | KeyCode.KEY_K)}) was pressed. Waiting for second key of chord...`
]);
assert.deepEqual(statusMessageCallsDisposed, []);
executeCommandCalls = [];
......@@ -160,10 +165,10 @@ suite('AbstractKeybindingService', () => {
assert.deepEqual(executeCommandCalls, []);
assert.deepEqual(showMessageCalls, []);
assert.deepEqual(statusMessageCalls, [
`The key combination (${KeybindingLabels._toUSLabel(createKeybinding(KeyMod.CtrlCmd | KeyCode.KEY_K))}, ${KeybindingLabels._toUSLabel(createKeybinding(KeyCode.Backspace))}) is not a command.`
`The key combination (${toUsLabel(KeyMod.CtrlCmd | KeyCode.KEY_K)}, ${toUsLabel(KeyCode.Backspace)}) is not a command.`
]);
assert.deepEqual(statusMessageCallsDisposed, [
`(${KeybindingLabels._toUSLabel(createKeybinding(KeyMod.CtrlCmd | KeyCode.KEY_K))}) was pressed. Waiting for second key of chord...`
`(${toUsLabel(KeyMod.CtrlCmd | KeyCode.KEY_K)}) was pressed. Waiting for second key of chord...`
]);
executeCommandCalls = [];
showMessageCalls = [];
......@@ -261,7 +266,7 @@ suite('AbstractKeybindingService', () => {
assert.deepEqual(executeCommandCalls, []);
assert.deepEqual(showMessageCalls, []);
assert.deepEqual(statusMessageCalls, [
`(${KeybindingLabels._toUSLabel(createKeybinding(KeyMod.CtrlCmd | KeyCode.KEY_K))}) was pressed. Waiting for second key of chord...`
`(${toUsLabel(KeyMod.CtrlCmd | KeyCode.KEY_K)}) was pressed. Waiting for second key of chord...`
]);
assert.deepEqual(statusMessageCallsDisposed, []);
executeCommandCalls = [];
......@@ -280,7 +285,7 @@ suite('AbstractKeybindingService', () => {
assert.deepEqual(showMessageCalls, []);
assert.deepEqual(statusMessageCalls, []);
assert.deepEqual(statusMessageCallsDisposed, [
`(${KeybindingLabels._toUSLabel(createKeybinding(KeyMod.CtrlCmd | KeyCode.KEY_K))}) was pressed. Waiting for second key of chord...`
`(${toUsLabel(KeyMod.CtrlCmd | KeyCode.KEY_K)}) was pressed. Waiting for second key of chord...`
]);
executeCommandCalls = [];
showMessageCalls = [];
......
......@@ -7,35 +7,32 @@
import * as assert from 'assert';
import { createKeybinding, KeyCode, KeyMod, KeyChord } from 'vs/base/common/keyCodes';
import { IUserFriendlyKeybinding } from 'vs/platform/keybinding/common/keybinding';
import { ISimplifiedPlatform } from 'vs/platform/keybinding/common/keybindingLabels';
import { NormalizedKeybindingItem } from 'vs/platform/keybinding/common/normalizedKeybindingItem';
import { KeybindingIO } from 'vs/platform/keybinding/common/keybindingIO';
import { OS, OperatingSystem } from 'vs/base/common/platform';
suite('Keybinding IO', () => {
test('serialize/deserialize', function () {
const WINDOWS = { isMacintosh: false, isWindows: true };
const MACINTOSH = { isMacintosh: true, isWindows: false };
const LINUX = { isMacintosh: false, isWindows: false };
function testOneSerialization(keybinding: number, expected: string, msg: string, Platform: ISimplifiedPlatform): void {
let actualSerialized = KeybindingIO.writeKeybinding(createKeybinding(keybinding), Platform);
function testOneSerialization(keybinding: number, expected: string, msg: string, OS: OperatingSystem): void {
let actualSerialized = KeybindingIO.writeKeybinding(createKeybinding(keybinding), OS);
assert.equal(actualSerialized, expected, expected + ' - ' + msg);
}
function testSerialization(keybinding: number, expectedWin: string, expectedMac: string, expectedLinux: string): void {
testOneSerialization(keybinding, expectedWin, 'win', WINDOWS);
testOneSerialization(keybinding, expectedMac, 'mac', MACINTOSH);
testOneSerialization(keybinding, expectedLinux, 'linux', LINUX);
testOneSerialization(keybinding, expectedWin, 'win', OperatingSystem.Windows);
testOneSerialization(keybinding, expectedMac, 'mac', OperatingSystem.Macintosh);
testOneSerialization(keybinding, expectedLinux, 'linux', OperatingSystem.Linux);
}
function testOneDeserialization(keybinding: string, expected: number, msg: string, Platform: ISimplifiedPlatform): void {
let actualDeserialized = KeybindingIO.readKeybinding(keybinding, Platform);
function testOneDeserialization(keybinding: string, expected: number, msg: string, OS: OperatingSystem): void {
let actualDeserialized = KeybindingIO.readKeybinding(keybinding, OS);
assert.equal(actualDeserialized, expected, keybinding + ' - ' + msg);
}
function testDeserialization(inWin: string, inMac: string, inLinux: string, expected: number): void {
testOneDeserialization(inWin, expected, 'win', WINDOWS);
testOneDeserialization(inMac, expected, 'mac', MACINTOSH);
testOneDeserialization(inLinux, expected, 'linux', LINUX);
testOneDeserialization(inWin, expected, 'win', OperatingSystem.Windows);
testOneDeserialization(inMac, expected, 'mac', OperatingSystem.Macintosh);
testOneDeserialization(inLinux, expected, 'linux', OperatingSystem.Linux);
}
function testRoundtrip(keybinding: number, expectedWin: string, expectedMac: string, expectedLinux: string): void {
......@@ -117,7 +114,7 @@ suite('Keybinding IO', () => {
test('issue #10452 - invalid command', () => {
let strJSON = `[{ "key": "ctrl+k ctrl+f", "command": ["firstcommand", "seccondcommand"] }]`;
let userKeybinding = <IUserFriendlyKeybinding>JSON.parse(strJSON)[0];
let keybindingItem = KeybindingIO.readKeybindingItem(userKeybinding, 0);
let keybindingItem = KeybindingIO.readKeybindingItem(userKeybinding, 0, OS);
let normalizedKeybindingItem = NormalizedKeybindingItem.fromKeybindingItem(keybindingItem, false);
assert.equal(normalizedKeybindingItem.command, null);
});
......@@ -125,7 +122,7 @@ suite('Keybinding IO', () => {
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.readKeybindingItem(userKeybinding, 0);
let keybindingItem = KeybindingIO.readKeybindingItem(userKeybinding, 0, OS);
let normalizedKeybindingItem = NormalizedKeybindingItem.fromKeybindingItem(keybindingItem, false);
assert.equal(normalizedKeybindingItem.when, null);
});
......@@ -133,7 +130,7 @@ suite('Keybinding IO', () => {
test('issue #10452 - invalid key', () => {
let strJSON = `[{ "key": [], "command": "firstcommand" }]`;
let userKeybinding = <IUserFriendlyKeybinding>JSON.parse(strJSON)[0];
let keybindingItem = KeybindingIO.readKeybindingItem(userKeybinding, 0);
let keybindingItem = KeybindingIO.readKeybindingItem(userKeybinding, 0, OS);
let normalizedKeybindingItem = NormalizedKeybindingItem.fromKeybindingItem(keybindingItem, false);
assert.equal(normalizedKeybindingItem.keybinding, null);
});
......@@ -141,7 +138,7 @@ suite('Keybinding IO', () => {
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.readKeybindingItem(userKeybinding, 0);
let keybindingItem = KeybindingIO.readKeybindingItem(userKeybinding, 0, OS);
let normalizedKeybindingItem = NormalizedKeybindingItem.fromKeybindingItem(keybindingItem, false);
assert.equal(normalizedKeybindingItem.commandArgs.text, 'theText');
});
......
......@@ -6,175 +6,177 @@
import * as assert from 'assert';
import { createKeybinding, KeyCode, KeyMod, KeyChord } from 'vs/base/common/keyCodes';
import { ISimplifiedPlatform, KeybindingLabels } from 'vs/platform/keybinding/common/keybindingLabels';
import { IHTMLContentElement } from 'vs/base/common/htmlContent';
import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/abstractKeybindingService';
import { OperatingSystem } from 'vs/base/common/platform';
suite('KeybindingLabels', () => {
const WINDOWS: ISimplifiedPlatform = { isMacintosh: false, isWindows: true };
const LINUX: ISimplifiedPlatform = { isMacintosh: false, isWindows: false };
const MAC: ISimplifiedPlatform = { isMacintosh: true, isWindows: false };
function assertUSLabel(Platform: ISimplifiedPlatform, keybinding: number, expected: string): void {
assert.equal(KeybindingLabels._toUSLabel(createKeybinding(keybinding), Platform), expected);
function assertUSLabel(OS: OperatingSystem, keybinding: number, expected: string): void {
const usResolvedKeybinding = new USLayoutResolvedKeybinding(createKeybinding(keybinding), OS);
assert.equal(usResolvedKeybinding.getLabel(), expected);
}
test('Windows US label', () => {
// no modifier
assertUSLabel(WINDOWS, KeyCode.KEY_A, 'A');
assertUSLabel(OperatingSystem.Windows, KeyCode.KEY_A, 'A');
// one modifier
assertUSLabel(WINDOWS, KeyMod.CtrlCmd | KeyCode.KEY_A, 'Ctrl+A');
assertUSLabel(WINDOWS, KeyMod.Shift | KeyCode.KEY_A, 'Shift+A');
assertUSLabel(WINDOWS, KeyMod.Alt | KeyCode.KEY_A, 'Alt+A');
assertUSLabel(WINDOWS, KeyMod.WinCtrl | KeyCode.KEY_A, 'Windows+A');
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');
// two modifiers
assertUSLabel(WINDOWS, KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_A, 'Ctrl+Shift+A');
assertUSLabel(WINDOWS, KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_A, 'Ctrl+Alt+A');
assertUSLabel(WINDOWS, KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.KEY_A, 'Ctrl+Windows+A');
assertUSLabel(WINDOWS, KeyMod.Shift | KeyMod.Alt | KeyCode.KEY_A, 'Shift+Alt+A');
assertUSLabel(WINDOWS, KeyMod.Shift | KeyMod.WinCtrl | KeyCode.KEY_A, 'Shift+Windows+A');
assertUSLabel(WINDOWS, KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Alt+Windows+A');
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');
// three modifiers
assertUSLabel(WINDOWS, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyCode.KEY_A, 'Ctrl+Shift+Alt+A');
assertUSLabel(WINDOWS, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.WinCtrl | KeyCode.KEY_A, 'Ctrl+Shift+Windows+A');
assertUSLabel(WINDOWS, KeyMod.CtrlCmd | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Ctrl+Alt+Windows+A');
assertUSLabel(WINDOWS, KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Shift+Alt+Windows+A');
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');
// four modifiers
assertUSLabel(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.KEY_A, 'Ctrl+Shift+Alt+Windows+A');
// chord
assertUSLabel(WINDOWS, KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_A, KeyMod.CtrlCmd | KeyCode.KEY_B), 'Ctrl+A Ctrl+B');
assertUSLabel(OperatingSystem.Windows, KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_A, KeyMod.CtrlCmd | KeyCode.KEY_B), 'Ctrl+A Ctrl+B');
});
test('Linux US label', () => {
// no modifier
assertUSLabel(LINUX, KeyCode.KEY_A, 'A');
assertUSLabel(OperatingSystem.Linux, KeyCode.KEY_A, 'A');
// one modifier
assertUSLabel(LINUX, KeyMod.CtrlCmd | KeyCode.KEY_A, 'Ctrl+A');
assertUSLabel(LINUX, KeyMod.Shift | KeyCode.KEY_A, 'Shift+A');
assertUSLabel(LINUX, KeyMod.Alt | KeyCode.KEY_A, 'Alt+A');
assertUSLabel(LINUX, KeyMod.WinCtrl | KeyCode.KEY_A, 'Windows+A');
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, 'Windows+A');
// two modifiers
assertUSLabel(LINUX, KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_A, 'Ctrl+Shift+A');
assertUSLabel(LINUX, KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_A, 'Ctrl+Alt+A');
assertUSLabel(LINUX, KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.KEY_A, 'Ctrl+Windows+A');
assertUSLabel(LINUX, KeyMod.Shift | KeyMod.Alt | KeyCode.KEY_A, 'Shift+Alt+A');
assertUSLabel(LINUX, KeyMod.Shift | KeyMod.WinCtrl | KeyCode.KEY_A, 'Shift+Windows+A');
assertUSLabel(LINUX, KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Alt+Windows+A');
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+Windows+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+Windows+A');
assertUSLabel(OperatingSystem.Linux, KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Alt+Windows+A');
// three modifiers
assertUSLabel(LINUX, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyCode.KEY_A, 'Ctrl+Shift+Alt+A');
assertUSLabel(LINUX, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.WinCtrl | KeyCode.KEY_A, 'Ctrl+Shift+Windows+A');
assertUSLabel(LINUX, KeyMod.CtrlCmd | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Ctrl+Alt+Windows+A');
assertUSLabel(LINUX, KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Shift+Alt+Windows+A');
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+Windows+A');
assertUSLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Ctrl+Alt+Windows+A');
assertUSLabel(OperatingSystem.Linux, KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Shift+Alt+Windows+A');
// four modifiers
assertUSLabel(LINUX, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Ctrl+Shift+Alt+Windows+A');
assertUSLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Ctrl+Shift+Alt+Windows+A');
// chord
assertUSLabel(LINUX, KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_A, KeyMod.CtrlCmd | KeyCode.KEY_B), 'Ctrl+A Ctrl+B');
assertUSLabel(OperatingSystem.Linux, KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_A, KeyMod.CtrlCmd | KeyCode.KEY_B), 'Ctrl+A Ctrl+B');
});
test('Mac US label', () => {
// no modifier
assertUSLabel(MAC, KeyCode.KEY_A, 'A');
assertUSLabel(OperatingSystem.Macintosh, KeyCode.KEY_A, 'A');
// one modifier
assertUSLabel(MAC, KeyMod.CtrlCmd | KeyCode.KEY_A, '⌘A');
assertUSLabel(MAC, KeyMod.Shift | KeyCode.KEY_A, '⇧A');
assertUSLabel(MAC, KeyMod.Alt | KeyCode.KEY_A, '⌥A');
assertUSLabel(MAC, KeyMod.WinCtrl | KeyCode.KEY_A, '⌃A');
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');
// two modifiers
assertUSLabel(MAC, KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_A, '⇧⌘A');
assertUSLabel(MAC, KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_A, '⌥⌘A');
assertUSLabel(MAC, KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.KEY_A, '⌃⌘A');
assertUSLabel(MAC, KeyMod.Shift | KeyMod.Alt | KeyCode.KEY_A, '⇧⌥A');
assertUSLabel(MAC, KeyMod.Shift | KeyMod.WinCtrl | KeyCode.KEY_A, '⌃⇧A');
assertUSLabel(MAC, KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, '⌃⌥A');
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');
// three modifiers
assertUSLabel(MAC, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyCode.KEY_A, '⇧⌥⌘A');
assertUSLabel(MAC, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.WinCtrl | KeyCode.KEY_A, '⌃⇧⌘A');
assertUSLabel(MAC, KeyMod.CtrlCmd | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, '⌃⌥⌘A');
assertUSLabel(MAC, KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, '⌃⇧⌥A');
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');
// four modifiers
assertUSLabel(MAC, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, '⌃⇧⌥⌘A');
assertUSLabel(OperatingSystem.Macintosh, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, '⌃⇧⌥⌘A');
// chord
assertUSLabel(MAC, KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_A, KeyMod.CtrlCmd | KeyCode.KEY_B), '⌘A ⌘B');
assertUSLabel(OperatingSystem.Macintosh, KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_A, KeyMod.CtrlCmd | KeyCode.KEY_B), '⌘A ⌘B');
// special keys
assertUSLabel(MAC, KeyCode.LeftArrow, '');
assertUSLabel(MAC, KeyCode.UpArrow, '');
assertUSLabel(MAC, KeyCode.RightArrow, '');
assertUSLabel(MAC, KeyCode.DownArrow, '');
assertUSLabel(OperatingSystem.Macintosh, KeyCode.LeftArrow, '');
assertUSLabel(OperatingSystem.Macintosh, KeyCode.UpArrow, '');
assertUSLabel(OperatingSystem.Macintosh, KeyCode.RightArrow, '');
assertUSLabel(OperatingSystem.Macintosh, KeyCode.DownArrow, '');
});
test('Aria label', () => {
function assertAriaLabel(Platform: ISimplifiedPlatform, keybinding: number, expected: string): void {
assert.equal(KeybindingLabels._toUSAriaLabel(createKeybinding(keybinding), Platform), expected);
function assertAriaLabel(OS: OperatingSystem, keybinding: number, expected: string): void {
const usResolvedKeybinding = new USLayoutResolvedKeybinding(createKeybinding(keybinding), OS);
assert.equal(usResolvedKeybinding.getAriaLabel(), expected);
}
assertAriaLabel(WINDOWS, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Control+Shift+Alt+Windows+A');
assertAriaLabel(LINUX, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Control+Shift+Alt+Windows+A');
assertAriaLabel(MAC, 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.KEY_A, 'Control+Shift+Alt+Windows+A');
assertAriaLabel(OperatingSystem.Linux, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Control+Shift+Alt+Windows+A');
assertAriaLabel(OperatingSystem.Macintosh, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Control+Shift+Alt+Command+A');
});
test('Electron Accelerator label', () => {
function assertElectronAcceleratorLabel(Platform: ISimplifiedPlatform, keybinding: number, expected: string): void {
assert.equal(KeybindingLabels._toElectronAccelerator(createKeybinding(keybinding), Platform), expected);
function assertElectronAcceleratorLabel(OS: OperatingSystem, keybinding: number, expected: string): void {
const usResolvedKeybinding = new USLayoutResolvedKeybinding(createKeybinding(keybinding), OS);
assert.equal(usResolvedKeybinding.getElectronAccelerator(), expected);
}
assertElectronAcceleratorLabel(WINDOWS, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Ctrl+Shift+Alt+Super+A');
assertElectronAcceleratorLabel(LINUX, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'Ctrl+Shift+Alt+Super+A');
assertElectronAcceleratorLabel(MAC, 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.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');
// electron cannot handle chords
assertElectronAcceleratorLabel(WINDOWS, KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_A, KeyMod.CtrlCmd | KeyCode.KEY_B), null);
assertElectronAcceleratorLabel(LINUX, KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_A, KeyMod.CtrlCmd | KeyCode.KEY_B), null);
assertElectronAcceleratorLabel(MAC, KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_A, KeyMod.CtrlCmd | KeyCode.KEY_B), null);
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);
// electron cannot handle numpad keys
assertElectronAcceleratorLabel(WINDOWS, KeyCode.NUMPAD_1, null);
assertElectronAcceleratorLabel(LINUX, KeyCode.NUMPAD_1, null);
assertElectronAcceleratorLabel(MAC, KeyCode.NUMPAD_1, null);
assertElectronAcceleratorLabel(OperatingSystem.Windows, KeyCode.NUMPAD_1, null);
assertElectronAcceleratorLabel(OperatingSystem.Linux, KeyCode.NUMPAD_1, null);
assertElectronAcceleratorLabel(OperatingSystem.Macintosh, KeyCode.NUMPAD_1, null);
// special
assertElectronAcceleratorLabel(MAC, KeyCode.LeftArrow, 'Left');
assertElectronAcceleratorLabel(MAC, KeyCode.UpArrow, 'Up');
assertElectronAcceleratorLabel(MAC, KeyCode.RightArrow, 'Right');
assertElectronAcceleratorLabel(MAC, KeyCode.DownArrow, 'Down');
assertElectronAcceleratorLabel(OperatingSystem.Macintosh, KeyCode.LeftArrow, 'Left');
assertElectronAcceleratorLabel(OperatingSystem.Macintosh, KeyCode.UpArrow, 'Up');
assertElectronAcceleratorLabel(OperatingSystem.Macintosh, KeyCode.RightArrow, 'Right');
assertElectronAcceleratorLabel(OperatingSystem.Macintosh, KeyCode.DownArrow, 'Down');
});
test('User Settings label', () => {
function assertElectronAcceleratorLabel(Platform: ISimplifiedPlatform, keybinding: number, expected: string): void {
assert.equal(KeybindingLabels.toUserSettingsLabel(createKeybinding(keybinding), Platform), expected);
function assertElectronAcceleratorLabel(OS: OperatingSystem, keybinding: number, expected: string): void {
const usResolvedKeybinding = new USLayoutResolvedKeybinding(createKeybinding(keybinding), OS);
assert.equal(usResolvedKeybinding.getUserSettingsLabel(), expected);
}
assertElectronAcceleratorLabel(WINDOWS, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'ctrl+shift+alt+win+a');
assertElectronAcceleratorLabel(LINUX, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, 'ctrl+shift+alt+meta+a');
assertElectronAcceleratorLabel(MAC, 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.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');
// electron cannot handle chords
assertElectronAcceleratorLabel(WINDOWS, KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_A, KeyMod.CtrlCmd | KeyCode.KEY_B), 'ctrl+a ctrl+b');
assertElectronAcceleratorLabel(LINUX, KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_A, KeyMod.CtrlCmd | KeyCode.KEY_B), 'ctrl+a ctrl+b');
assertElectronAcceleratorLabel(MAC, KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_A, KeyMod.CtrlCmd | KeyCode.KEY_B), 'cmd+a cmd+b');
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');
});
test('US HTML label', () => {
function assertHTMLLabel(Platform: ISimplifiedPlatform, keybinding: number, expected: IHTMLContentElement[]): void {
assert.deepEqual(KeybindingLabels._toUSHTMLLabel(createKeybinding(keybinding), Platform), expected);
function assertHTMLLabel(OS: OperatingSystem, keybinding: number, expected: IHTMLContentElement[]): void {
const usResolvedKeybinding = new USLayoutResolvedKeybinding(createKeybinding(keybinding), OS);
assert.deepEqual(usResolvedKeybinding.getHTMLLabel(), expected);
}
assertHTMLLabel(WINDOWS, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, [{
assertHTMLLabel(OperatingSystem.Windows, KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, [{
tagName: 'span',
className: 'monaco-kb',
children: [
......@@ -190,7 +192,7 @@ suite('KeybindingLabels', () => {
]
}]);
assertHTMLLabel(WINDOWS, KeyChord(KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, KeyCode.KEY_B), [{
assertHTMLLabel(OperatingSystem.Windows, KeyChord(KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_A, KeyCode.KEY_B), [{
tagName: 'span',
className: 'monaco-kb',
children: [
......
......@@ -9,7 +9,8 @@ import Event from 'vs/base/common/event';
import { IKeybindingService, IKeybindingEvent } from 'vs/platform/keybinding/common/keybinding';
import { IContextKey, IContextKeyService, IContextKeyServiceTarget, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { IResolveResult } from 'vs/platform/keybinding/common/keybindingResolver';
import { SimpleResolvedKeybinding } from 'vs/platform/keybinding/common/abstractKeybindingService';
import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/abstractKeybindingService';
import { OS } from 'vs/base/common/platform';
class MockKeybindingContextKey<T> implements IContextKey<T> {
private _key: string;
......@@ -72,7 +73,7 @@ export class MockKeybindingService2 implements IKeybindingService {
}
public resolveKeybinding(keybinding: Keybinding): ResolvedKeybinding {
return new SimpleResolvedKeybinding(keybinding);
return new USLayoutResolvedKeybinding(keybinding, OS);
}
public lookupKeybindings(commandId: string): Keybinding[] {
......
......@@ -45,6 +45,7 @@ import { IOpenerService } from 'vs/platform/opener/common/opener';
import { Tree } from 'vs/base/parts/tree/browser/treeImpl';
import { Position } from 'vs/platform/editor/common/editor';
import { IListService } from 'vs/platform/list/browser/listService';
import { OS } from 'vs/base/common/platform';
function renderBody(body: string): string {
const nonce = new Date().getTime() + '' + new Date().getMilliseconds();
......@@ -669,7 +670,7 @@ export class ExtensionEditor extends BaseEditor {
case 'darwin': key = rawKeyBinding.mac; break;
}
const keyBinding = createKeybinding(KeybindingIO.readKeybinding(key || rawKeyBinding.key));
const keyBinding = createKeybinding(KeybindingIO.readKeybinding(key || rawKeyBinding.key, OS));
const resolvedKeybinding = this.keybindingService.resolveKeybinding(keyBinding);
const result = resolvedKeybinding.getLabel();
return result === 'unknown' ? null : result;
......
......@@ -17,7 +17,8 @@ import { ModelServiceImpl } from 'vs/editor/common/services/modelServiceImpl';
import { IModelService } from 'vs/editor/common/services/modelService';
import { Tree } from 'vs/base/parts/tree/browser/treeImpl';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { SimpleResolvedKeybinding } from 'vs/platform/keybinding/common/abstractKeybindingService';
import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/abstractKeybindingService';
import { OS } from 'vs/base/common/platform';
suite('Search Actions', () => {
......@@ -28,7 +29,7 @@ suite('Search Actions', () => {
instantiationService = new TestInstantiationService();
instantiationService.stub(IModelService, stubModelService(instantiationService));
instantiationService.stub(IKeybindingService, {});
instantiationService.stub(IKeybindingService, 'resolveKeybinding', (keybinding) => new SimpleResolvedKeybinding(keybinding));
instantiationService.stub(IKeybindingService, 'resolveKeybinding', (keybinding) => new USLayoutResolvedKeybinding(keybinding, OS));
counter = 0;
});
......
......@@ -26,6 +26,7 @@ import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { IUpdateService } from 'vs/platform/update/common/update';
import * as semver from 'semver';
import { OS } from 'vs/base/common/platform';
class ApplyUpdateAction extends Action {
constructor( @IUpdateService private updateService: IUpdateService) {
......@@ -73,7 +74,7 @@ export function loadReleaseNotes(accessor: ServicesAccessor, version: string): T
};
const kbstyle = (match: string, kb: string) => {
const code = KeybindingIO.readKeybinding(kb);
const code = KeybindingIO.readKeybinding(kb, OS);
if (!code) {
return unassigned;
......
......@@ -8,12 +8,12 @@ import * as nls from 'vs/nls';
import { IHTMLContentElement } from 'vs/base/common/htmlContent';
import { IJSONSchema } from 'vs/base/common/jsonSchema';
import { ResolvedKeybinding, Keybinding } from 'vs/base/common/keyCodes';
import { KeybindingLabels, PrintableKeypress, MacUILabelProvider, ClassicUILabelProvider, MacAriaLabelProvider, ClassicAriaLabelProvider } from 'vs/platform/keybinding/common/keybindingLabels';
import * as platform from 'vs/base/common/platform';
import { PrintableKeypress, UILabelProvider, AriaLabelProvider } from 'vs/platform/keybinding/common/keybindingLabels';
import { OS, OperatingSystem } from 'vs/base/common/platform';
import { toDisposable } from 'vs/base/common/lifecycle';
import { ExtensionMessageCollector, ExtensionsRegistry } from 'vs/platform/extensions/common/extensionsRegistry';
import { Extensions, IJSONContributionRegistry } from 'vs/platform/jsonschemas/common/jsonContributionRegistry';
import { AbstractKeybindingService } from 'vs/platform/keybinding/common/abstractKeybindingService';
import { AbstractKeybindingService, USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/abstractKeybindingService';
import { IStatusbarService } from 'vs/platform/statusbar/common/statusbar';
import { KeybindingResolver } from 'vs/platform/keybinding/common/keybindingResolver';
import { ICommandService } from 'vs/platform/commands/common/commands';
......@@ -130,41 +130,34 @@ export class FancyResolvedKeybinding extends ResolvedKeybinding {
public getLabel(): string {
const keyCodeLabelProvider = getNativeUIKeyCodeLabelProvider();
const [firstPart, chordPart] = PrintableKeypress.fromKeybinding(this._actual, keyCodeLabelProvider, platform.isMacintosh);
const [firstPart, chordPart] = PrintableKeypress.fromKeybinding2(this._actual, keyCodeLabelProvider, OS);
if (platform.isMacintosh) {
return MacUILabelProvider.toLabel(firstPart, chordPart);
}
return ClassicUILabelProvider.toLabel(firstPart, chordPart);
return UILabelProvider.toLabel2(firstPart, chordPart, OS);
}
public getAriaLabel(): string {
const keyCodeLabelProvider = getNativeAriaKeyCodeLabelProvider();
const [firstPart, chordPart] = PrintableKeypress.fromKeybinding(this._actual, keyCodeLabelProvider, platform.isMacintosh);
const [firstPart, chordPart] = PrintableKeypress.fromKeybinding2(this._actual, keyCodeLabelProvider, OS);
if (platform.isMacintosh) {
return MacAriaLabelProvider.toLabel(firstPart, chordPart);
}
return ClassicAriaLabelProvider.toLabel(firstPart, chordPart);
return AriaLabelProvider.toLabel2(firstPart, chordPart, OS);
}
public getHTMLLabel(): IHTMLContentElement[] {
const keyCodeLabelProvider = getNativeUIKeyCodeLabelProvider();
const [firstPart, chordPart] = PrintableKeypress.fromKeybinding(this._actual, keyCodeLabelProvider, platform.isMacintosh);
const [firstPart, chordPart] = PrintableKeypress.fromKeybinding2(this._actual, keyCodeLabelProvider, OS);
if (platform.isMacintosh) {
return MacUILabelProvider.toHTMLLabel(firstPart, chordPart);
}
return ClassicUILabelProvider.toHTMLLabel(firstPart, chordPart);
return UILabelProvider.toHTMLLabel2(firstPart, chordPart, OS);
}
public getElectronAccelerator(): string {
if (platform.isWindows) {
const usResolvedKeybinding = new USLayoutResolvedKeybinding(this._actual, OS);
if (OS === OperatingSystem.Windows) {
// electron menus always do the correct rendering on Windows
return KeybindingLabels._toElectronAccelerator(this._actual);
return usResolvedKeybinding.getElectronAccelerator();
}
let usLabel = KeybindingLabels._toUSLabel(this._actual);
let usLabel = usResolvedKeybinding.getLabel();
let label = this.getLabel();
if (usLabel !== label) {
// electron menus are incorrect in rendering (linux) and in rendering and interpreting (mac)
......@@ -172,11 +165,11 @@ export class FancyResolvedKeybinding extends ResolvedKeybinding {
return null;
}
return KeybindingLabels._toElectronAccelerator(this._actual);
return usResolvedKeybinding.getElectronAccelerator();
}
public getUserSettingsLabel(): string {
return KeybindingLabels.toUserSettingsLabel(this._actual);
return KeybindingIO.writeKeybinding(this._actual, OS);
}
}
......@@ -274,7 +267,7 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService {
});
}
return extraUserKeybindings.map((k, i) => KeybindingIO.readKeybindingItem(k, i));
return extraUserKeybindings.map((k, i) => KeybindingIO.readKeybindingItem(k, i, OS));
}
protected _createResolvedKeybinding(kb: Keybinding): ResolvedKeybinding {
......@@ -333,10 +326,10 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService {
id: command,
when: ContextKeyExpr.deserialize(when),
weight: weight,
primary: KeybindingIO.readKeybinding(key),
mac: mac && { primary: KeybindingIO.readKeybinding(mac) },
linux: linux && { primary: KeybindingIO.readKeybinding(linux) },
win: win && { primary: KeybindingIO.readKeybinding(win) }
primary: KeybindingIO.readKeybinding(key, OS),
mac: mac && { primary: KeybindingIO.readKeybinding(mac, OS) },
linux: linux && { primary: KeybindingIO.readKeybinding(linux, OS) },
win: win && { primary: KeybindingIO.readKeybinding(win, OS) }
};
if (!desc.primary && !desc.mac && !desc.linux && !desc.win) {
......
......@@ -7,7 +7,7 @@
import * as nativeKeymap from 'native-keymap';
import { KeyCode, KeyCodeUtils } from 'vs/base/common/keyCodes';
import { CharCode } from 'vs/base/common/charCode';
import { IKeyCodeLabelProvider } from 'vs/platform/keybinding/common/keybindingLabels';
import { IKeyCodeLabelProvider2 } from 'vs/platform/keybinding/common/keybindingLabels';
import { lookupKeyCode, setExtractKeyCode } from 'vs/base/browser/keyboardEvent';
import Platform = require('vs/base/common/platform');
......@@ -332,16 +332,16 @@ setExtractKeyCode((e: KeyboardEvent) => {
return lookupKeyCode(e);
});
let nativeUIKeyCodeLabelProvider: IKeyCodeLabelProvider = null;
export function getNativeUIKeyCodeLabelProvider(): IKeyCodeLabelProvider {
let nativeUIKeyCodeLabelProvider: IKeyCodeLabelProvider2 = null;
export function getNativeUIKeyCodeLabelProvider(): IKeyCodeLabelProvider2 {
if (!nativeUIKeyCodeLabelProvider) {
let remaps = getNativeLabelProviderRemaps();
nativeUIKeyCodeLabelProvider = (keyCode: KeyCode): string => {
nativeUIKeyCodeLabelProvider = (keyCode: KeyCode, OS: Platform.OperatingSystem): string => {
if (remaps[keyCode] !== null) {
return remaps[keyCode].render();
}
if (Platform.isMacintosh) {
if (OS === Platform.OperatingSystem.Macintosh) {
switch (keyCode) {
case KeyCode.LeftArrow:
return '';
......@@ -360,11 +360,11 @@ export function getNativeUIKeyCodeLabelProvider(): IKeyCodeLabelProvider {
return nativeUIKeyCodeLabelProvider;
}
let nativeAriaKeyCodeLabelProvider: IKeyCodeLabelProvider = null;
export function getNativeAriaKeyCodeLabelProvider(): IKeyCodeLabelProvider {
let nativeAriaKeyCodeLabelProvider: IKeyCodeLabelProvider2 = null;
export function getNativeAriaKeyCodeLabelProvider(): IKeyCodeLabelProvider2 {
if (!nativeAriaKeyCodeLabelProvider) {
let remaps = getNativeLabelProviderRemaps();
nativeAriaKeyCodeLabelProvider = (keyCode: KeyCode): string => {
nativeAriaKeyCodeLabelProvider = (keyCode: KeyCode, OS: Platform.OperatingSystem): string => {
if (remaps[keyCode] !== null) {
return remaps[keyCode].render();
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册