未验证 提交 871a6fef 编写于 作者: A Alexandru Dima 提交者: GitHub

Merge pull request #65826 from toumorokoshi/feature/keychords

Modifying ChordKeybinding to support multiple chords
......@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { OperatingSystem } from 'vs/base/common/platform';
import { illegalArgument } from 'vs/base/common/errors';
/**
* Virtual Key Codes, the value does not hold any inherent meaning.
......@@ -417,12 +418,12 @@ export function createKeybinding(keybinding: number, OS: OperatingSystem): Keybi
const firstPart = (keybinding & 0x0000FFFF) >>> 0;
const chordPart = (keybinding & 0xFFFF0000) >>> 16;
if (chordPart !== 0) {
return new ChordKeybinding(
return new ChordKeybinding([
createSimpleKeybinding(firstPart, OS),
createSimpleKeybinding(chordPart, OS),
);
createSimpleKeybinding(chordPart, OS)
]);
}
return createSimpleKeybinding(firstPart, OS);
return new ChordKeybinding([createSimpleKeybinding(firstPart, OS)]);
}
export function createSimpleKeybinding(keybinding: number, OS: OperatingSystem): SimpleKeybinding {
......@@ -439,14 +440,7 @@ export function createSimpleKeybinding(keybinding: number, OS: OperatingSystem):
return new SimpleKeybinding(ctrlKey, shiftKey, altKey, metaKey, keyCode);
}
export const enum KeybindingType {
Simple = 1,
Chord = 2
}
export class SimpleKeybinding {
public readonly type = KeybindingType.Simple;
public readonly ctrlKey: boolean;
public readonly shiftKey: boolean;
public readonly altKey: boolean;
......@@ -461,10 +455,7 @@ export class SimpleKeybinding {
this.keyCode = keyCode;
}
public equals(other: Keybinding): boolean {
if (other.type !== KeybindingType.Simple) {
return false;
}
public equals(other: SimpleKeybinding): boolean {
return (
this.ctrlKey === other.ctrlKey
&& this.shiftKey === other.shiftKey
......@@ -492,6 +483,10 @@ export class SimpleKeybinding {
);
}
public toChord(): ChordKeybinding {
return new ChordKeybinding([this]);
}
/**
* Does this keybinding refer to the key code of a modifier and it also has the modifier flag?
*/
......@@ -506,22 +501,43 @@ export class SimpleKeybinding {
}
export class ChordKeybinding {
public readonly type = KeybindingType.Chord;
public readonly firstPart: SimpleKeybinding;
public readonly chordPart: SimpleKeybinding;
public readonly parts: SimpleKeybinding[];
constructor(firstPart: SimpleKeybinding, chordPart: SimpleKeybinding) {
this.firstPart = firstPart;
this.chordPart = chordPart;
constructor(parts: SimpleKeybinding[]) {
if (parts.length === 0) {
throw illegalArgument(`parts`);
}
this.parts = parts;
}
public getHashCode(): string {
return `${this.firstPart.getHashCode()};${this.chordPart.getHashCode()}`;
let result = '';
for (let i = 0, len = this.parts.length; i < len; i++) {
if (i !== 0) {
result += ';';
}
result += this.parts[i].getHashCode();
}
return result;
}
public equals(other: ChordKeybinding | null): boolean {
if (other === null) {
return false;
}
if (this.parts.length !== other.parts.length) {
return false;
}
for (let i = 0; i < this.parts.length; i++) {
if (!this.parts[i].equals(other.parts[i])) {
return false;
}
}
return true;
}
}
export type Keybinding = SimpleKeybinding | ChordKeybinding;
export type Keybinding = ChordKeybinding;
export class ResolvedKeybindingPart {
readonly ctrlKey: boolean;
......@@ -574,12 +590,12 @@ export abstract class ResolvedKeybinding {
public abstract isChord(): boolean;
/**
* Returns the firstPart, chordPart that should be used for dispatching.
* Returns the parts that should be used for dispatching.
*/
public abstract getDispatchParts(): [string | null, string | null];
public abstract getDispatchParts(): (string | null)[];
/**
* Returns the firstPart, chordPart of the keybinding.
* For simple keybindings, the second element will be null.
* Returns the parts that comprise of the keybinding.
* Simple keybindings return one element.
*/
public abstract getParts(): [ResolvedKeybindingPart, ResolvedKeybindingPart | null];
public abstract getParts(): ResolvedKeybindingPart[];
}
......@@ -21,6 +21,10 @@ export interface Modifiers {
readonly metaKey: boolean;
}
export interface KeyLabelProvider<T extends Modifiers> {
(keybinding: T): string | null;
}
export class ModifierLabelProvider {
public readonly modifierLabels: ModifierLabels[];
......@@ -32,11 +36,22 @@ export class ModifierLabelProvider {
this.modifierLabels[OperatingSystem.Linux] = linux;
}
public toLabel(firstPartMod: Modifiers | null, firstPartKey: string | null, chordPartMod: Modifiers | null, chordPartKey: string | null, OS: OperatingSystem): string | null {
if (firstPartMod === null || firstPartKey === null) {
public toLabel<T extends Modifiers>(OS: OperatingSystem, parts: T[], keyLabelProvider: KeyLabelProvider<T>): string | null {
if (parts.length === 0) {
return null;
}
return _asString(firstPartMod, firstPartKey, chordPartMod, chordPartKey, this.modifierLabels[OS]);
let result: string[] = [];
for (let i = 0, len = parts.length; i < len; i++) {
const part = parts[i];
const keyLabel = keyLabelProvider(part);
if (keyLabel === null) {
// this keybinding cannot be expressed...
return null;
}
result[i] = _simpleAsString(part, keyLabel, this.modifierLabels[OS]);
}
return result.join(' ');
}
}
......@@ -171,14 +186,3 @@ function _simpleAsString(modifiers: Modifiers, key: string, labels: ModifierLabe
return result.join(labels.separator);
}
function _asString(firstPartMod: Modifiers, firstPartKey: string, chordPartMod: Modifiers | null, chordPartKey: string | null, labels: ModifierLabels): string {
let result = _simpleAsString(firstPartMod, firstPartKey, labels);
if (chordPartMod !== null && chordPartKey !== null) {
result += ' ';
result += _simpleAsString(chordPartMod, chordPartKey, labels);
}
return result;
}
\ No newline at end of file
......@@ -85,16 +85,14 @@ export class KeybindingParser {
return null;
}
let [firstPart, remains] = this.parseSimpleKeybinding(input);
let chordPart: SimpleKeybinding | null = null;
if (remains.length > 0) {
[chordPart] = this.parseSimpleKeybinding(remains);
}
let parts: SimpleKeybinding[] = [];
let part: SimpleKeybinding;
if (chordPart) {
return new ChordKeybinding(firstPart, chordPart);
}
return firstPart;
do {
[part, input] = this.parseSimpleKeybinding(input);
parts.push(part);
} while (input.length > 0);
return new ChordKeybinding(parts);
}
private static parseSimpleUserBinding(input: string): [SimpleKeybinding | ScanCodeBinding, string] {
......@@ -110,6 +108,7 @@ export class KeybindingParser {
}
static parseUserBinding(input: string): [SimpleKeybinding | ScanCodeBinding | null, SimpleKeybinding | ScanCodeBinding | null] {
// TODO@chords: allow users to define N chords
if (!input) {
return [null, null];
}
......
......@@ -13,7 +13,7 @@ import * as mouse from 'vs/base/browser/mouseEvent';
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import * as _ from 'vs/base/parts/tree/browser/tree';
import { IDragAndDropData } from 'vs/base/browser/dnd';
import { KeyCode, KeyMod, Keybinding, SimpleKeybinding, createSimpleKeybinding } from 'vs/base/common/keyCodes';
import { KeyCode, KeyMod, Keybinding, SimpleKeybinding, createKeybinding } from 'vs/base/common/keyCodes';
export interface IKeyBindingCallback {
(tree: _.ITree, event: IKeyboardEvent): void;
......@@ -49,7 +49,7 @@ export interface IControllerOptions {
}
interface IKeybindingDispatcherItem {
keybinding: Keybinding;
keybinding: Keybinding | null;
callback: IKeyBindingCallback;
}
......@@ -62,10 +62,12 @@ export class KeybindingDispatcher {
}
public has(keybinding: KeyCode): boolean {
let target = createSimpleKeybinding(keybinding, platform.OS);
for (const a of this._arr) {
if (target.equals(a.keybinding)) {
return true;
let target = createKeybinding(keybinding, platform.OS);
if (target !== null) {
for (const a of this._arr) {
if (target.equals(a.keybinding)) {
return true;
}
}
}
return false;
......@@ -73,7 +75,7 @@ export class KeybindingDispatcher {
public set(keybinding: number, callback: IKeyBindingCallback) {
this._arr.push({
keybinding: createSimpleKeybinding(keybinding, platform.OS),
keybinding: createKeybinding(keybinding, platform.OS),
callback: callback
});
}
......@@ -82,7 +84,7 @@ export class KeybindingDispatcher {
// Loop from the last to the first to handle overwrites
for (let i = this._arr.length - 1; i >= 0; i--) {
let item = this._arr[i];
if (keybinding.equals(item.keybinding)) {
if (keybinding.toChord().equals(item.keybinding)) {
return item.callback;
}
}
......
......@@ -20,35 +20,35 @@ suite('keyCodes', () => {
}
test(null, 0);
test(new SimpleKeybinding(false, false, false, false, KeyCode.Enter), KeyCode.Enter);
test(new SimpleKeybinding(true, false, false, false, KeyCode.Enter), KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(false, false, true, false, KeyCode.Enter), KeyMod.Alt | KeyCode.Enter);
test(new SimpleKeybinding(true, false, true, false, KeyCode.Enter), KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(false, true, false, false, KeyCode.Enter), KeyMod.Shift | KeyCode.Enter);
test(new SimpleKeybinding(true, true, false, false, KeyCode.Enter), KeyMod.Shift | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(false, true, true, false, KeyCode.Enter), KeyMod.Shift | KeyMod.Alt | KeyCode.Enter);
test(new SimpleKeybinding(true, true, true, false, KeyCode.Enter), KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(false, false, false, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyCode.Enter);
test(new SimpleKeybinding(true, false, false, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(false, false, true, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.Enter);
test(new SimpleKeybinding(true, false, true, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(false, true, false, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Enter);
test(new SimpleKeybinding(true, true, false, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(false, true, true, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyCode.Enter);
test(new SimpleKeybinding(true, true, true, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(false, false, false, false, KeyCode.Enter).toChord(), KeyCode.Enter);
test(new SimpleKeybinding(true, false, false, false, KeyCode.Enter).toChord(), KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(false, false, true, false, KeyCode.Enter).toChord(), KeyMod.Alt | KeyCode.Enter);
test(new SimpleKeybinding(true, false, true, false, KeyCode.Enter).toChord(), KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(false, true, false, false, KeyCode.Enter).toChord(), KeyMod.Shift | KeyCode.Enter);
test(new SimpleKeybinding(true, true, false, false, KeyCode.Enter).toChord(), KeyMod.Shift | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(false, true, true, false, KeyCode.Enter).toChord(), KeyMod.Shift | KeyMod.Alt | KeyCode.Enter);
test(new SimpleKeybinding(true, true, true, false, KeyCode.Enter).toChord(), KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(false, false, false, true, KeyCode.Enter).toChord(), KeyMod.CtrlCmd | KeyCode.Enter);
test(new SimpleKeybinding(true, false, false, true, KeyCode.Enter).toChord(), KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(false, false, true, true, KeyCode.Enter).toChord(), KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.Enter);
test(new SimpleKeybinding(true, false, true, true, KeyCode.Enter).toChord(), KeyMod.CtrlCmd | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(false, true, false, true, KeyCode.Enter).toChord(), KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Enter);
test(new SimpleKeybinding(true, true, false, true, KeyCode.Enter).toChord(), KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(false, true, true, true, KeyCode.Enter).toChord(), KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyCode.Enter);
test(new SimpleKeybinding(true, true, true, true, KeyCode.Enter).toChord(), KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
test(
new ChordKeybinding(
new ChordKeybinding([
new SimpleKeybinding(false, false, false, false, KeyCode.Enter),
new SimpleKeybinding(false, false, false, false, KeyCode.Tab)
),
]),
KeyChord(KeyCode.Enter, KeyCode.Tab)
);
test(
new ChordKeybinding(
new ChordKeybinding([
new SimpleKeybinding(false, false, false, true, KeyCode.KEY_Y),
new SimpleKeybinding(false, false, false, false, KeyCode.KEY_Z)
),
]),
KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_Y, KeyCode.KEY_Z)
);
});
......@@ -62,35 +62,35 @@ suite('keyCodes', () => {
}
test(null, 0);
test(new SimpleKeybinding(false, false, false, false, KeyCode.Enter), KeyCode.Enter);
test(new SimpleKeybinding(false, false, false, true, KeyCode.Enter), KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(false, false, true, false, KeyCode.Enter), KeyMod.Alt | KeyCode.Enter);
test(new SimpleKeybinding(false, false, true, true, KeyCode.Enter), KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(false, true, false, false, KeyCode.Enter), KeyMod.Shift | KeyCode.Enter);
test(new SimpleKeybinding(false, true, false, true, KeyCode.Enter), KeyMod.Shift | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(false, true, true, false, KeyCode.Enter), KeyMod.Shift | KeyMod.Alt | KeyCode.Enter);
test(new SimpleKeybinding(false, true, true, true, KeyCode.Enter), KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(true, false, false, false, KeyCode.Enter), KeyMod.CtrlCmd | KeyCode.Enter);
test(new SimpleKeybinding(true, false, false, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(true, false, true, false, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.Enter);
test(new SimpleKeybinding(true, false, true, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(true, true, false, false, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Enter);
test(new SimpleKeybinding(true, true, false, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(true, true, true, false, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyCode.Enter);
test(new SimpleKeybinding(true, true, true, true, KeyCode.Enter), KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(false, false, false, false, KeyCode.Enter).toChord(), KeyCode.Enter);
test(new SimpleKeybinding(false, false, false, true, KeyCode.Enter).toChord(), KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(false, false, true, false, KeyCode.Enter).toChord(), KeyMod.Alt | KeyCode.Enter);
test(new SimpleKeybinding(false, false, true, true, KeyCode.Enter).toChord(), KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(false, true, false, false, KeyCode.Enter).toChord(), KeyMod.Shift | KeyCode.Enter);
test(new SimpleKeybinding(false, true, false, true, KeyCode.Enter).toChord(), KeyMod.Shift | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(false, true, true, false, KeyCode.Enter).toChord(), KeyMod.Shift | KeyMod.Alt | KeyCode.Enter);
test(new SimpleKeybinding(false, true, true, true, KeyCode.Enter).toChord(), KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(true, false, false, false, KeyCode.Enter).toChord(), KeyMod.CtrlCmd | KeyCode.Enter);
test(new SimpleKeybinding(true, false, false, true, KeyCode.Enter).toChord(), KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(true, false, true, false, KeyCode.Enter).toChord(), KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.Enter);
test(new SimpleKeybinding(true, false, true, true, KeyCode.Enter).toChord(), KeyMod.CtrlCmd | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(true, true, false, false, KeyCode.Enter).toChord(), KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Enter);
test(new SimpleKeybinding(true, true, false, true, KeyCode.Enter).toChord(), KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.WinCtrl | KeyCode.Enter);
test(new SimpleKeybinding(true, true, true, false, KeyCode.Enter).toChord(), KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyCode.Enter);
test(new SimpleKeybinding(true, true, true, true, KeyCode.Enter).toChord(), KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.Enter);
test(
new ChordKeybinding(
new ChordKeybinding([
new SimpleKeybinding(false, false, false, false, KeyCode.Enter),
new SimpleKeybinding(false, false, false, false, KeyCode.Tab)
),
]),
KeyChord(KeyCode.Enter, KeyCode.Tab)
);
test(
new ChordKeybinding(
new ChordKeybinding([
new SimpleKeybinding(true, false, false, false, KeyCode.KEY_Y),
new SimpleKeybinding(false, false, false, false, KeyCode.KEY_Z)
),
]),
KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_Y, KeyCode.KEY_Z)
);
......
......@@ -369,7 +369,7 @@ export class StandaloneKeybindingService extends AbstractKeybindingService {
keyboardEvent.altKey,
keyboardEvent.metaKey,
keyboardEvent.keyCode
);
).toChord();
return new USLayoutResolvedKeybinding(keybinding, OS);
}
......
......@@ -107,7 +107,7 @@ export class Driver implements IDriver, IWindowDriverRegistry {
}
const webContents = window.win.webContents;
const noModifiedKeybinding = new SimpleKeybinding(false, false, false, false, keybinding.keyCode);
const resolvedKeybinding = new USLayoutResolvedKeybinding(noModifiedKeybinding, OS);
const resolvedKeybinding = new USLayoutResolvedKeybinding(noModifiedKeybinding.toChord(), OS);
const keyCode = resolvedKeybinding.getElectronAccelerator();
const modifiers: string[] = [];
......
......@@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { KeyCode, Keybinding, KeybindingType, SimpleKeybinding, createKeybinding } from 'vs/base/common/keyCodes';
import { KeyCode, Keybinding, SimpleKeybinding, createKeybinding } from 'vs/base/common/keyCodes';
import { OS, OperatingSystem } from 'vs/base/common/platform';
import { CommandsRegistry, ICommandHandler, ICommandHandlerDescription } from 'vs/platform/commands/common/commands';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
......@@ -210,11 +210,7 @@ class KeybindingsRegistryImpl implements IKeybindingsRegistry {
private _registerDefaultKeybinding(keybinding: Keybinding, commandId: string, commandArgs: any, weight1: number, weight2: number, when: ContextKeyExpr | null | undefined): void {
if (OS === OperatingSystem.Windows) {
if (keybinding.type === KeybindingType.Chord) {
this._assertNoCtrlAlt(keybinding.firstPart, commandId);
} else {
this._assertNoCtrlAlt(keybinding, commandId);
}
this._assertNoCtrlAlt(keybinding.parts[0], commandId);
}
this._coreKeybindings.push({
keybinding: keybinding,
......
......@@ -22,9 +22,18 @@ export class ResolvedKeybindingItem {
constructor(resolvedKeybinding: ResolvedKeybinding | null, command: string | null, commandArgs: any, when: ContextKeyExpr | null, isDefault: boolean) {
this.resolvedKeybinding = resolvedKeybinding;
if (resolvedKeybinding) {
let [keypressFirstPart, keypressChordPart] = resolvedKeybinding.getDispatchParts();
this.keypressFirstPart = keypressFirstPart;
this.keypressChordPart = keypressChordPart;
const dispatchParts = resolvedKeybinding.getDispatchParts();
// TODO@chords: add support for dispatching N chords here
if (dispatchParts.length >= 2) {
this.keypressFirstPart = dispatchParts[0];
this.keypressChordPart = dispatchParts[1];
} else if (dispatchParts.length === 1) {
this.keypressFirstPart = dispatchParts[0];
this.keypressChordPart = null;
} else {
this.keypressFirstPart = null;
this.keypressChordPart = null;
}
} else {
this.keypressFirstPart = null;
this.keypressChordPart = null;
......
......@@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { KeyCode, KeyCodeUtils, Keybinding, KeybindingType, ResolvedKeybinding, ResolvedKeybindingPart, SimpleKeybinding } from 'vs/base/common/keyCodes';
import { KeyCode, KeyCodeUtils, Keybinding, ResolvedKeybinding, ResolvedKeybindingPart, SimpleKeybinding } from 'vs/base/common/keyCodes';
import { AriaLabelProvider, ElectronAcceleratorLabelProvider, UILabelProvider, UserSettingsLabelProvider } from 'vs/base/common/keybindingLabels';
import { OperatingSystem } from 'vs/base/common/platform';
......@@ -13,20 +13,15 @@ import { OperatingSystem } from 'vs/base/common/platform';
export class USLayoutResolvedKeybinding extends ResolvedKeybinding {
private readonly _os: OperatingSystem;
private readonly _firstPart: SimpleKeybinding;
private readonly _chordPart: SimpleKeybinding | null;
private readonly _parts: SimpleKeybinding[];
constructor(actual: Keybinding, OS: OperatingSystem) {
super();
this._os = OS;
if (!actual) {
throw new Error(`Invalid USLayoutResolvedKeybinding`);
} else if (actual.type === KeybindingType.Chord) {
this._firstPart = actual.firstPart;
this._chordPart = actual.chordPart;
} else {
this._firstPart = actual;
this._chordPart = null;
this._parts = actual.parts;
}
}
......@@ -57,9 +52,7 @@ export class USLayoutResolvedKeybinding extends ResolvedKeybinding {
}
public getLabel(): string | null {
let firstPart = this._getUILabelForKeybinding(this._firstPart);
let chordPart = this._getUILabelForKeybinding(this._chordPart);
return UILabelProvider.toLabel(this._firstPart, firstPart, this._chordPart, chordPart, this._os);
return UILabelProvider.toLabel(this._os, this._parts, (keybinding) => this._getUILabelForKeybinding(keybinding));
}
private _getAriaLabelForKeybinding(keybinding: SimpleKeybinding | null): string | null {
......@@ -73,9 +66,7 @@ export class USLayoutResolvedKeybinding extends ResolvedKeybinding {
}
public getAriaLabel(): string | null {
let firstPart = this._getAriaLabelForKeybinding(this._firstPart);
let chordPart = this._getAriaLabelForKeybinding(this._chordPart);
return AriaLabelProvider.toLabel(this._firstPart, firstPart, this._chordPart, chordPart, this._os);
return AriaLabelProvider.toLabel(this._os, this._parts, (keybinding) => this._getAriaLabelForKeybinding(keybinding));
}
private _keyCodeToElectronAccelerator(keyCode: KeyCode): string | null {
......@@ -109,13 +100,12 @@ export class USLayoutResolvedKeybinding extends ResolvedKeybinding {
}
public getElectronAccelerator(): string | null {
if (this._chordPart !== null) {
if (this._parts.length > 1) {
// Electron cannot handle chords
return null;
}
let firstPart = this._getElectronAcceleratorLabelForKeybinding(this._firstPart);
return ElectronAcceleratorLabelProvider.toLabel(this._firstPart, firstPart, null, null, this._os);
return ElectronAcceleratorLabelProvider.toLabel(this._os, this._parts, (keybinding) => this._getElectronAcceleratorLabelForKeybinding(keybinding));
}
private _getUserSettingsLabelForKeybinding(keybinding: SimpleKeybinding | null): string | null {
......@@ -129,9 +119,7 @@ export class USLayoutResolvedKeybinding extends ResolvedKeybinding {
}
public getUserSettingsLabel(): string | null {
let firstPart = this._getUserSettingsLabelForKeybinding(this._firstPart);
let chordPart = this._getUserSettingsLabelForKeybinding(this._chordPart);
let result = UserSettingsLabelProvider.toLabel(this._firstPart, firstPart, this._chordPart, chordPart, this._os);
const result = UserSettingsLabelProvider.toLabel(this._os, this._parts, (keybinding) => this._getUserSettingsLabelForKeybinding(keybinding));
return (result ? result.toLowerCase() : result);
}
......@@ -140,14 +128,11 @@ export class USLayoutResolvedKeybinding extends ResolvedKeybinding {
}
public isChord(): boolean {
return (this._chordPart ? true : false);
return (this._parts.length > 1);
}
public getParts(): [ResolvedKeybindingPart, ResolvedKeybindingPart | null] {
return [
this._toResolvedKeybindingPart(this._firstPart),
this._chordPart ? this._toResolvedKeybindingPart(this._chordPart) : null
];
public getParts(): ResolvedKeybindingPart[] {
return this._parts.map((keybinding) => this._toResolvedKeybindingPart(keybinding));
}
private _toResolvedKeybindingPart(keybinding: SimpleKeybinding): ResolvedKeybindingPart {
......@@ -161,10 +146,8 @@ export class USLayoutResolvedKeybinding extends ResolvedKeybinding {
);
}
public getDispatchParts(): [string | null, string | null] {
let firstPart = this._firstPart ? USLayoutResolvedKeybinding.getDispatchStr(this._firstPart) : null;
let chordPart = this._chordPart ? USLayoutResolvedKeybinding.getDispatchStr(this._chordPart) : null;
return [firstPart, chordPart];
public getDispatchParts(): (string | null)[] {
return this._parts.map((keybinding) => USLayoutResolvedKeybinding.getDispatchStr(keybinding));
}
public static getDispatchStr(keybinding: SimpleKeybinding): string | null {
......
......@@ -61,7 +61,7 @@ suite('AbstractKeybindingService', () => {
keyboardEvent.altKey,
keyboardEvent.metaKey,
keyboardEvent.keyCode
);
).toChord();
return this.resolveKeybinding(keybinding)[0];
}
......
......@@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { KeyChord, KeyCode, KeyMod, KeybindingType, SimpleKeybinding, createKeybinding } from 'vs/base/common/keyCodes';
import { KeyChord, KeyCode, KeyMod, SimpleKeybinding, createKeybinding, createSimpleKeybinding } from 'vs/base/common/keyCodes';
import { OS } from 'vs/base/common/platform';
import { ContextKeyAndExpr, ContextKeyExpr, IContext } from 'vs/platform/contextkey/common/contextkey';
import { KeybindingResolver } from 'vs/platform/keybinding/common/keybindingResolver';
......@@ -37,7 +37,7 @@ suite('KeybindingResolver', () => {
test('resolve key', function () {
let keybinding = KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_Z;
let runtimeKeybinding = createKeybinding(keybinding, OS);
let runtimeKeybinding = createSimpleKeybinding(keybinding, OS);
let contextRules = ContextKeyExpr.equals('bar', 'baz');
let keybindingItem = kbItem(keybinding, 'yes', null, contextRules, true);
......@@ -45,19 +45,19 @@ suite('KeybindingResolver', () => {
assert.equal(KeybindingResolver.contextMatchesRules(createContext({ bar: 'bz' }), contextRules), false);
let resolver = new KeybindingResolver([keybindingItem], []);
assert.equal(resolver.resolve(createContext({ bar: 'baz' }), null, getDispatchStr(<SimpleKeybinding>runtimeKeybinding))!.commandId, 'yes');
assert.equal(resolver.resolve(createContext({ bar: 'bz' }), null, getDispatchStr(<SimpleKeybinding>runtimeKeybinding)), null);
assert.equal(resolver.resolve(createContext({ bar: 'baz' }), null, getDispatchStr(runtimeKeybinding))!.commandId, 'yes');
assert.equal(resolver.resolve(createContext({ bar: 'bz' }), null, getDispatchStr(runtimeKeybinding)), null);
});
test('resolve key with arguments', function () {
let commandArgs = { text: 'no' };
let keybinding = KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_Z;
let runtimeKeybinding = createKeybinding(keybinding, OS);
let runtimeKeybinding = createSimpleKeybinding(keybinding, OS);
let contextRules = ContextKeyExpr.equals('bar', 'baz');
let keybindingItem = kbItem(keybinding, 'yes', commandArgs, contextRules, true);
let resolver = new KeybindingResolver([keybindingItem], []);
assert.equal(resolver.resolve(createContext({ bar: 'baz' }), null, getDispatchStr(<SimpleKeybinding>runtimeKeybinding))!.commandArgs, commandArgs);
assert.equal(resolver.resolve(createContext({ bar: 'baz' }), null, getDispatchStr(runtimeKeybinding))!.commandArgs, commandArgs);
});
test('KeybindingResolver.combine simple 1', function () {
......@@ -346,24 +346,24 @@ suite('KeybindingResolver', () => {
let testResolve = (ctx: IContext, _expectedKey: number, commandId: string) => {
const expectedKey = createKeybinding(_expectedKey, OS)!;
if (expectedKey.type === KeybindingType.Chord) {
let firstPart = getDispatchStr(expectedKey.firstPart);
let chordPart = getDispatchStr(expectedKey.chordPart);
let result = resolver.resolve(ctx, null, firstPart)!;
assert.ok(result !== null, 'Enters chord for ' + commandId);
assert.equal(result.commandId, null, 'Enters chord for ' + commandId);
assert.equal(result.enterChord, true, 'Enters chord for ' + commandId);
result = resolver.resolve(ctx, firstPart, chordPart)!;
assert.ok(result !== null, 'Enters chord for ' + commandId);
assert.equal(result.commandId, commandId, 'Finds chorded command ' + commandId);
assert.equal(result.enterChord, false, 'Finds chorded command ' + commandId);
} else {
let result = resolver.resolve(ctx, null, getDispatchStr(expectedKey))!;
assert.ok(result !== null, 'Finds command ' + commandId);
assert.equal(result.commandId, commandId, 'Finds command ' + commandId);
assert.equal(result.enterChord, false, 'Finds command ' + commandId);
let previousPart: (string | null) = null;
for (let i = 0, len = expectedKey.parts.length; i < len; i++) {
let part = getDispatchStr(expectedKey.parts[i]);
let result = resolver.resolve(ctx, previousPart, part);
if (i === len - 1) {
// if it's the final part, then we should find a valid command,
// and there should not be a chord.
assert.ok(result !== null, `Enters chord for ${commandId} at part ${i}`);
assert.equal(result!.commandId, commandId, `Enters chord for ${commandId} at part ${i}`);
assert.equal(result!.enterChord, false, `Enters chord for ${commandId} at part ${i}`);
} else {
// if it's not the final part, then we should not find a valid command,
// and there should be a chord.
assert.ok(result !== null, `Enters chord for ${commandId} at part ${i}`);
assert.equal(result!.commandId, null, `Enters chord for ${commandId} at part ${i}`);
assert.equal(result!.enterChord, true, `Enters chord for ${commandId} at part ${i}`);
}
previousPart = part;
}
};
......
......@@ -98,7 +98,7 @@ export class MockKeybindingService implements IKeybindingService {
keyboardEvent.metaKey,
keyboardEvent.keyCode
);
return this.resolveKeybinding(keybinding)[0];
return this.resolveKeybinding(keybinding.toChord())[0];
}
public resolveUserBinding(userBinding: string): ResolvedKeybinding[] {
......
......@@ -40,7 +40,7 @@ export class MacLinuxFallbackKeyboardMapper implements IKeyboardMapper {
keyboardEvent.metaKey,
keyboardEvent.keyCode
);
return new USLayoutResolvedKeybinding(keybinding, this._OS);
return new USLayoutResolvedKeybinding(keybinding.toChord(), this._OS);
}
private _scanCodeToKeyCode(scanCode: ScanCode): KeyCode {
......@@ -120,11 +120,15 @@ export class MacLinuxFallbackKeyboardMapper implements IKeyboardMapper {
public resolveUserBinding(firstPart: SimpleKeybinding | ScanCodeBinding | null, chordPart: SimpleKeybinding | ScanCodeBinding | null): ResolvedKeybinding[] {
const _firstPart = this._resolveSimpleUserBinding(firstPart);
const _chordPart = this._resolveSimpleUserBinding(chordPart);
if (_firstPart && _chordPart) {
return [new USLayoutResolvedKeybinding(new ChordKeybinding(_firstPart, _chordPart), this._OS)];
}
let parts: SimpleKeybinding[] = [];
if (_firstPart) {
return [new USLayoutResolvedKeybinding(_firstPart, this._OS)];
parts.push(_firstPart);
}
if (_chordPart) {
parts.push(_chordPart);
}
if (parts.length > 0) {
return [new USLayoutResolvedKeybinding(new ChordKeybinding(parts), this._OS)];
}
return [];
}
......
......@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { CharCode } from 'vs/base/common/charCode';
import { KeyCode, KeyCodeUtils, Keybinding, KeybindingType, ResolvedKeybinding, ResolvedKeybindingPart, SimpleKeybinding } from 'vs/base/common/keyCodes';
import { KeyCode, KeyCodeUtils, Keybinding, ResolvedKeybinding, ResolvedKeybindingPart, SimpleKeybinding } from 'vs/base/common/keyCodes';
import { AriaLabelProvider, ElectronAcceleratorLabelProvider, UILabelProvider, UserSettingsLabelProvider } from 'vs/base/common/keybindingLabels';
import { OperatingSystem } from 'vs/base/common/platform';
import { IMMUTABLE_CODE_TO_KEY_CODE, IMMUTABLE_KEY_CODE_TO_CODE, ScanCode, ScanCodeBinding, ScanCodeUtils } from 'vs/base/common/scanCode';
......@@ -67,46 +67,37 @@ export class NativeResolvedKeybinding extends ResolvedKeybinding {
private readonly _mapper: MacLinuxKeyboardMapper;
private readonly _OS: OperatingSystem;
private readonly _firstPart: ScanCodeBinding;
private readonly _chordPart: ScanCodeBinding | null;
private readonly _parts: ScanCodeBinding[];
constructor(mapper: MacLinuxKeyboardMapper, OS: OperatingSystem, firstPart: ScanCodeBinding, chordPart: ScanCodeBinding | null) {
constructor(mapper: MacLinuxKeyboardMapper, OS: OperatingSystem, parts: ScanCodeBinding[]) {
super();
if (!firstPart) {
throw new Error(`Invalid USLayoutResolvedKeybinding`);
if (parts.length === 0) {
throw new Error(`Invalid NativeResolvedKeybinding`);
}
this._mapper = mapper;
this._OS = OS;
this._firstPart = firstPart;
this._chordPart = chordPart;
this._parts = parts;
}
public getLabel(): string | null {
let firstPart = this._mapper.getUILabelForScanCodeBinding(this._firstPart);
let chordPart = this._mapper.getUILabelForScanCodeBinding(this._chordPart);
return UILabelProvider.toLabel(this._firstPart, firstPart, this._chordPart, chordPart, this._OS);
return UILabelProvider.toLabel(this._OS, this._parts, (keybinding) => this._mapper.getUILabelForScanCodeBinding(keybinding));
}
public getAriaLabel(): string | null {
let firstPart = this._mapper.getAriaLabelForScanCodeBinding(this._firstPart);
let chordPart = this._mapper.getAriaLabelForScanCodeBinding(this._chordPart);
return AriaLabelProvider.toLabel(this._firstPart, firstPart, this._chordPart, chordPart, this._OS);
return AriaLabelProvider.toLabel(this._OS, this._parts, (keybinding) => this._mapper.getAriaLabelForScanCodeBinding(keybinding));
}
public getElectronAccelerator(): string | null {
if (this._chordPart !== null) {
if (this._parts.length > 1) {
// Electron cannot handle chords
return null;
}
let firstPart = this._mapper.getElectronAcceleratorLabelForScanCodeBinding(this._firstPart);
return ElectronAcceleratorLabelProvider.toLabel(this._firstPart, firstPart, null, null, this._OS);
return ElectronAcceleratorLabelProvider.toLabel(this._OS, this._parts, (keybinding) => this._mapper.getElectronAcceleratorLabelForScanCodeBinding(keybinding));
}
public getUserSettingsLabel(): string | null {
let firstPart = this._mapper.getUserSettingsLabelForScanCodeBinding(this._firstPart);
let chordPart = this._mapper.getUserSettingsLabelForScanCodeBinding(this._chordPart);
return UserSettingsLabelProvider.toLabel(this._firstPart, firstPart, this._chordPart, chordPart, this._OS);
return UserSettingsLabelProvider.toLabel(this._OS, this._parts, (keybinding) => this._mapper.getUserSettingsLabelForScanCodeBinding(keybinding));
}
private _isWYSIWYG(binding: ScanCodeBinding | null): boolean {
......@@ -129,18 +120,15 @@ export class NativeResolvedKeybinding extends ResolvedKeybinding {
}
public isWYSIWYG(): boolean {
return (this._isWYSIWYG(this._firstPart) && this._isWYSIWYG(this._chordPart));
return this._parts.every((keybinding) => this._isWYSIWYG(keybinding));
}
public isChord(): boolean {
return (this._chordPart ? true : false);
return (this._parts.length > 1);
}
public getParts(): [ResolvedKeybindingPart, ResolvedKeybindingPart | null] {
return [
this._toResolvedKeybindingPart(this._firstPart),
this._chordPart ? this._toResolvedKeybindingPart(this._chordPart) : null
];
public getParts(): ResolvedKeybindingPart[] {
return this._parts.map((keybinding) => this._toResolvedKeybindingPart(keybinding));
}
private _toResolvedKeybindingPart(binding: ScanCodeBinding): ResolvedKeybindingPart {
......@@ -154,10 +142,8 @@ export class NativeResolvedKeybinding extends ResolvedKeybinding {
);
}
public getDispatchParts(): [string | null, string | null] {
let firstPart = this._firstPart ? this._mapper.getDispatchStrForScanCodeBinding(this._firstPart) : null;
let chordPart = this._chordPart ? this._mapper.getDispatchStrForScanCodeBinding(this._chordPart) : null;
return [firstPart, chordPart];
public getDispatchParts(): (string | null)[] {
return this._parts.map((keybinding) => this._mapper.getDispatchStrForScanCodeBinding(keybinding));
}
}
......@@ -1012,31 +998,26 @@ export class MacLinuxKeyboardMapper implements IKeyboardMapper {
}
public resolveKeybinding(keybinding: Keybinding): NativeResolvedKeybinding[] {
let result: NativeResolvedKeybinding[] = [], resultLen = 0;
if (keybinding.type === KeybindingType.Chord) {
const firstParts = this.simpleKeybindingToScanCodeBinding(keybinding.firstPart);
const chordParts = this.simpleKeybindingToScanCodeBinding(keybinding.chordPart);
for (let i = 0, len = firstParts.length; i < len; i++) {
const firstPart = firstParts[i];
for (let j = 0, lenJ = chordParts.length; j < lenJ; j++) {
const chordPart = chordParts[j];
result[resultLen++] = new NativeResolvedKeybinding(this, this._OS, firstPart, chordPart);
}
}
} else {
const firstParts = this.simpleKeybindingToScanCodeBinding(keybinding);
for (let i = 0, len = firstParts.length; i < len; i++) {
const firstPart = firstParts[i];
let chordParts: ScanCodeBinding[][] = [];
for (let part of keybinding.parts) {
chordParts.push(this.simpleKeybindingToScanCodeBinding(part));
}
let result: NativeResolvedKeybinding[] = [];
this._generateResolvedKeybindings(chordParts, 0, [], result);
return result;
}
result[resultLen++] = new NativeResolvedKeybinding(this, this._OS, firstPart, null);
private _generateResolvedKeybindings(chordParts: ScanCodeBinding[][], currentIndex: number, previousParts: ScanCodeBinding[], result: NativeResolvedKeybinding[]) {
const chordPart = chordParts[currentIndex];
const isFinalIndex = currentIndex === chordParts.length - 1;
for (let i = 0, len = chordPart.length; i < len; i++) {
let chords = [...previousParts, chordPart[i]];
if (isFinalIndex) {
result.push(new NativeResolvedKeybinding(this, this._OS, chords));
} else {
this._generateResolvedKeybindings(chordParts, currentIndex + 1, chords, result);
}
}
return result;
}
public resolveKeyboardEvent(keyboardEvent: IKeyboardEvent): NativeResolvedKeybinding {
......@@ -1094,7 +1075,7 @@ export class MacLinuxKeyboardMapper implements IKeyboardMapper {
}
const keypress = new ScanCodeBinding(keyboardEvent.ctrlKey, keyboardEvent.shiftKey, keyboardEvent.altKey, keyboardEvent.metaKey, code);
return new NativeResolvedKeybinding(this, this._OS, keypress, null);
return new NativeResolvedKeybinding(this, this._OS, [keypress]);
}
private _resolveSimpleUserBinding(binding: SimpleKeybinding | ScanCodeBinding | null): ScanCodeBinding[] {
......@@ -1108,22 +1089,15 @@ export class MacLinuxKeyboardMapper implements IKeyboardMapper {
}
public resolveUserBinding(_firstPart: SimpleKeybinding | ScanCodeBinding | null, _chordPart: SimpleKeybinding | ScanCodeBinding | null): ResolvedKeybinding[] {
const firstParts = this._resolveSimpleUserBinding(_firstPart);
const chordParts = this._resolveSimpleUserBinding(_chordPart);
let result: NativeResolvedKeybinding[] = [], resultLen = 0;
for (let i = 0, len = firstParts.length; i < len; i++) {
const firstPart = firstParts[i];
if (_chordPart) {
for (let j = 0, lenJ = chordParts.length; j < lenJ; j++) {
const chordPart = chordParts[j];
result[resultLen++] = new NativeResolvedKeybinding(this, this._OS, firstPart, chordPart);
}
} else {
result[resultLen++] = new NativeResolvedKeybinding(this, this._OS, firstPart, null);
}
let parts: ScanCodeBinding[][] = [];
if (_firstPart) {
parts.push(this._resolveSimpleUserBinding(_firstPart));
}
if (_chordPart) {
parts.push(this._resolveSimpleUserBinding(_chordPart));
}
let result: NativeResolvedKeybinding[] = [];
this._generateResolvedKeybindings(parts, 0, [], result);
return result;
}
......
......@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { CharCode } from 'vs/base/common/charCode';
import { KeyCode, KeyCodeUtils, Keybinding, KeybindingType, ResolvedKeybinding, ResolvedKeybindingPart, SimpleKeybinding } from 'vs/base/common/keyCodes';
import { KeyCode, KeyCodeUtils, Keybinding, ResolvedKeybinding, ResolvedKeybindingPart, SimpleKeybinding } from 'vs/base/common/keyCodes';
import { AriaLabelProvider, ElectronAcceleratorLabelProvider, UILabelProvider, UserSettingsLabelProvider } from 'vs/base/common/keybindingLabels';
import { OperatingSystem } from 'vs/base/common/platform';
import { IMMUTABLE_CODE_TO_KEY_CODE, ScanCode, ScanCodeBinding, ScanCodeUtils } from 'vs/base/common/scanCode';
......@@ -79,17 +79,15 @@ export interface IScanCodeMapping {
export class WindowsNativeResolvedKeybinding extends ResolvedKeybinding {
private readonly _mapper: WindowsKeyboardMapper;
private readonly _firstPart: SimpleKeybinding;
private readonly _chordPart: SimpleKeybinding | null;
private readonly _parts: SimpleKeybinding[];
constructor(mapper: WindowsKeyboardMapper, firstPart: SimpleKeybinding, chordPart: SimpleKeybinding | null) {
constructor(mapper: WindowsKeyboardMapper, parts: SimpleKeybinding[]) {
super();
if (!firstPart) {
throw new Error(`Invalid WindowsNativeResolvedKeybinding firstPart`);
if (parts.length === 0) {
throw new Error(`Invalid WindowsNativeResolvedKeybinding`);
}
this._mapper = mapper;
this._firstPart = firstPart;
this._chordPart = chordPart;
this._parts = parts;
}
private _getUILabelForKeybinding(keybinding: SimpleKeybinding | null): string | null {
......@@ -103,9 +101,7 @@ export class WindowsNativeResolvedKeybinding extends ResolvedKeybinding {
}
public getLabel(): string | null {
let firstPart = this._getUILabelForKeybinding(this._firstPart);
let chordPart = this._getUILabelForKeybinding(this._chordPart);
return UILabelProvider.toLabel(this._firstPart, firstPart, this._chordPart, chordPart, OperatingSystem.Windows);
return UILabelProvider.toLabel(OperatingSystem.Windows, this._parts, (keybinding) => this._getUILabelForKeybinding(keybinding));
}
private _getUSLabelForKeybinding(keybinding: SimpleKeybinding | null): string | null {
......@@ -119,9 +115,7 @@ export class WindowsNativeResolvedKeybinding extends ResolvedKeybinding {
}
public getUSLabel(): string | null {
let firstPart = this._getUSLabelForKeybinding(this._firstPart);
let chordPart = this._getUSLabelForKeybinding(this._chordPart);
return UILabelProvider.toLabel(this._firstPart, firstPart, this._chordPart, chordPart, OperatingSystem.Windows);
return UILabelProvider.toLabel(OperatingSystem.Windows, this._parts, (keybinding) => this._getUSLabelForKeybinding(keybinding));
}
private _getAriaLabelForKeybinding(keybinding: SimpleKeybinding | null): string | null {
......@@ -135,9 +129,7 @@ export class WindowsNativeResolvedKeybinding extends ResolvedKeybinding {
}
public getAriaLabel(): string | null {
let firstPart = this._getAriaLabelForKeybinding(this._firstPart);
let chordPart = this._getAriaLabelForKeybinding(this._chordPart);
return AriaLabelProvider.toLabel(this._firstPart, firstPart, this._chordPart, chordPart, OperatingSystem.Windows);
return AriaLabelProvider.toLabel(OperatingSystem.Windows, this._parts, (keybinding) => this._getAriaLabelForKeybinding(keybinding));
}
private _keyCodeToElectronAccelerator(keyCode: KeyCode): string | null {
......@@ -172,13 +164,12 @@ export class WindowsNativeResolvedKeybinding extends ResolvedKeybinding {
}
public getElectronAccelerator(): string | null {
if (this._chordPart !== null) {
if (this._parts.length > 1) {
// Electron cannot handle chords
return null;
}
let firstPart = this._getElectronAcceleratorLabelForKeybinding(this._firstPart);
return ElectronAcceleratorLabelProvider.toLabel(this._firstPart, firstPart, null, null, OperatingSystem.Windows);
return ElectronAcceleratorLabelProvider.toLabel(OperatingSystem.Windows, this._parts, (keybinding) => this._getElectronAcceleratorLabelForKeybinding(keybinding));
}
private _getUserSettingsLabelForKeybinding(keybinding: SimpleKeybinding | null): string | null {
......@@ -192,20 +183,12 @@ export class WindowsNativeResolvedKeybinding extends ResolvedKeybinding {
}
public getUserSettingsLabel(): string | null {
let firstPart = this._getUserSettingsLabelForKeybinding(this._firstPart);
let chordPart = this._getUserSettingsLabelForKeybinding(this._chordPart);
let result = UserSettingsLabelProvider.toLabel(this._firstPart, firstPart, this._chordPart, chordPart, OperatingSystem.Windows);
const result = UserSettingsLabelProvider.toLabel(OperatingSystem.Windows, this._parts, (keybinding) => this._getUserSettingsLabelForKeybinding(keybinding));
return (result ? result.toLowerCase() : result);
}
public isWYSIWYG(): boolean {
if (this._firstPart && !this._isWYSIWYG(this._firstPart.keyCode)) {
return false;
}
if (this._chordPart && !this._isWYSIWYG(this._chordPart.keyCode)) {
return false;
}
return true;
return this._parts.every((keybinding) => this._isWYSIWYG(keybinding.keyCode));
}
private _isWYSIWYG(keyCode: KeyCode): boolean {
......@@ -223,14 +206,11 @@ export class WindowsNativeResolvedKeybinding extends ResolvedKeybinding {
}
public isChord(): boolean {
return (this._chordPart ? true : false);
return (this._parts.length > 1);
}
public getParts(): [ResolvedKeybindingPart, ResolvedKeybindingPart | null] {
return [
this._toResolvedKeybindingPart(this._firstPart),
this._chordPart ? this._toResolvedKeybindingPart(this._chordPart) : null
];
public getParts(): ResolvedKeybindingPart[] {
return this._parts.map((keybinding) => this._toResolvedKeybindingPart(keybinding));
}
private _toResolvedKeybindingPart(keybinding: SimpleKeybinding): ResolvedKeybindingPart {
......@@ -244,10 +224,8 @@ export class WindowsNativeResolvedKeybinding extends ResolvedKeybinding {
);
}
public getDispatchParts(): [string | null, string | null] {
let firstPart = this._firstPart ? this._getDispatchStr(this._firstPart) : null;
let chordPart = this._chordPart ? this._getDispatchStr(this._chordPart) : null;
return [firstPart, chordPart];
public getDispatchParts(): (string | null)[] {
return this._parts.map((keybinding) => this._getDispatchStr(keybinding));
}
private _getDispatchStr(keybinding: SimpleKeybinding): string | null {
......@@ -468,7 +446,7 @@ export class WindowsKeyboardMapper implements IKeyboardMapper {
const scanCodeBinding = new ScanCodeBinding(ctrlKey, shiftKey, altKey, false, scanCode);
const kb = this._resolveSimpleUserBinding(scanCodeBinding);
const strKeyCode = (kb ? KeyCodeUtils.toString(kb.keyCode) : null);
const resolvedKb = (kb ? new WindowsNativeResolvedKeybinding(this, kb, null) : null);
const resolvedKb = (kb ? new WindowsNativeResolvedKeybinding(this, [kb]) : null);
const outScanCode = `${ctrlKey ? 'Ctrl+' : ''}${shiftKey ? 'Shift+' : ''}${altKey ? 'Alt+' : ''}${strCode}`;
const ariaLabel = (resolvedKb ? resolvedKb.getAriaLabel() : null);
......@@ -517,24 +495,19 @@ export class WindowsKeyboardMapper implements IKeyboardMapper {
}
public resolveKeybinding(keybinding: Keybinding): WindowsNativeResolvedKeybinding[] {
if (keybinding.type === KeybindingType.Chord) {
const firstPartKeyCode = keybinding.firstPart.keyCode;
const chordPartKeyCode = keybinding.chordPart.keyCode;
if (!this._keyCodeExists[firstPartKeyCode] || !this._keyCodeExists[chordPartKeyCode]) {
const parts = keybinding.parts;
for (let i = 0, len = parts.length; i < len; i++) {
const part = parts[i];
if (!this._keyCodeExists[part.keyCode]) {
return [];
}
return [new WindowsNativeResolvedKeybinding(this, keybinding.firstPart, keybinding.chordPart)];
} else {
if (!this._keyCodeExists[keybinding.keyCode]) {
return [];
}
return [new WindowsNativeResolvedKeybinding(this, keybinding, null)];
}
return [new WindowsNativeResolvedKeybinding(this, parts)];
}
public resolveKeyboardEvent(keyboardEvent: IKeyboardEvent): WindowsNativeResolvedKeybinding {
const keybinding = new SimpleKeybinding(keyboardEvent.ctrlKey, keyboardEvent.shiftKey, keyboardEvent.altKey, keyboardEvent.metaKey, keyboardEvent.keyCode);
return new WindowsNativeResolvedKeybinding(this, keybinding, null);
return new WindowsNativeResolvedKeybinding(this, [keybinding]);
}
private _resolveSimpleUserBinding(binding: SimpleKeybinding | ScanCodeBinding | null): SimpleKeybinding | null {
......@@ -557,11 +530,15 @@ export class WindowsKeyboardMapper implements IKeyboardMapper {
public resolveUserBinding(firstPart: SimpleKeybinding | ScanCodeBinding | null, chordPart: SimpleKeybinding | ScanCodeBinding | null): ResolvedKeybinding[] {
const _firstPart = this._resolveSimpleUserBinding(firstPart);
const _chordPart = this._resolveSimpleUserBinding(chordPart);
if (_firstPart && _chordPart) {
return [new WindowsNativeResolvedKeybinding(this, _firstPart, _chordPart)];
}
let parts: SimpleKeybinding[] = [];
if (_firstPart) {
return [new WindowsNativeResolvedKeybinding(this, _firstPart, null)];
parts.push(_firstPart);
}
if (_chordPart) {
parts.push(_chordPart);
}
if (parts.length > 0) {
return [new WindowsNativeResolvedKeybinding(this, parts)];
}
return [];
}
......
......@@ -270,8 +270,15 @@ suite('KeybindingsEditing', () => {
const { ctrlKey, shiftKey, altKey, metaKey } = part.modifiers || { ctrlKey: false, shiftKey: false, altKey: false, metaKey: false };
return new SimpleKeybinding(ctrlKey!, shiftKey!, altKey!, metaKey!, part.keyCode);
};
const keybinding = firstPart ? chordPart ? new ChordKeybinding(aSimpleKeybinding(firstPart), aSimpleKeybinding(chordPart)) : aSimpleKeybinding(firstPart) : null;
return new ResolvedKeybindingItem(keybinding ? new USLayoutResolvedKeybinding(keybinding, OS) : null, command || 'some command', null, when ? ContextKeyExpr.deserialize(when) : null, isDefault === undefined ? true : isDefault);
let parts: SimpleKeybinding[] = [];
if (firstPart) {
parts.push(aSimpleKeybinding(firstPart));
if (chordPart) {
parts.push(aSimpleKeybinding(chordPart));
}
}
let keybinding = parts.length > 0 ? new USLayoutResolvedKeybinding(new ChordKeybinding(parts), OS) : null;
return new ResolvedKeybindingItem(keybinding, command || 'some command', null, when ? ContextKeyExpr.deserialize(when) : null, isDefault === undefined ? true : isDefault);
}
});
......@@ -19,7 +19,7 @@ export interface IResolvedKeybinding {
userSettingsLabel: string | null;
isWYSIWYG: boolean;
isChord: boolean;
dispatchParts: [string | null, string | null];
dispatchParts: (string | null)[];
}
function toIResolvedKeybinding(kb: ResolvedKeybinding): IResolvedKeybinding {
......
......@@ -27,7 +27,7 @@ suite('keyboardMapper - MAC fallback', () => {
userSettingsLabel: 'cmd+z',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['meta+Z', null],
dispatchParts: ['meta+Z'],
}]
);
});
......@@ -65,7 +65,7 @@ suite('keyboardMapper - MAC fallback', () => {
userSettingsLabel: 'cmd+z',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['meta+Z', null],
dispatchParts: ['meta+Z'],
}
);
});
......@@ -105,7 +105,7 @@ suite('keyboardMapper - MAC fallback', () => {
userSettingsLabel: 'cmd+',
isWYSIWYG: true,
isChord: false,
dispatchParts: [null, null],
dispatchParts: [null],
}
);
});
......@@ -129,7 +129,7 @@ suite('keyboardMapper - LINUX fallback', () => {
userSettingsLabel: 'ctrl+z',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+Z', null],
dispatchParts: ['ctrl+Z'],
}]
);
});
......@@ -167,7 +167,7 @@ suite('keyboardMapper - LINUX fallback', () => {
userSettingsLabel: 'ctrl+z',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+Z', null],
dispatchParts: ['ctrl+Z'],
}
);
});
......@@ -201,7 +201,7 @@ suite('keyboardMapper - LINUX fallback', () => {
userSettingsLabel: 'ctrl+,',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+,', null],
dispatchParts: ['ctrl+,'],
}]
);
});
......@@ -224,7 +224,7 @@ suite('keyboardMapper - LINUX fallback', () => {
userSettingsLabel: 'ctrl+',
isWYSIWYG: true,
isChord: false,
dispatchParts: [null, null],
dispatchParts: [null],
}
);
});
......
......@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { KeyChord, KeyCode, KeyMod, SimpleKeybinding, createKeybinding } from 'vs/base/common/keyCodes';
import { KeyChord, KeyCode, KeyMod, SimpleKeybinding, createKeybinding, createSimpleKeybinding } from 'vs/base/common/keyCodes';
import { UserSettingsLabelProvider } from 'vs/base/common/keybindingLabels';
import { OperatingSystem } from 'vs/base/common/platform';
import { ScanCode, ScanCodeBinding, ScanCodeUtils } from 'vs/base/common/scanCode';
......@@ -65,7 +65,7 @@ suite('keyboardMapper - MAC de_ch', () => {
userSettingsLabel: 'cmd+a',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['meta+[KeyA]', null],
dispatchParts: ['meta+[KeyA]'],
}]
);
});
......@@ -80,7 +80,7 @@ suite('keyboardMapper - MAC de_ch', () => {
userSettingsLabel: 'cmd+b',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['meta+[KeyB]', null],
dispatchParts: ['meta+[KeyB]'],
}]
);
});
......@@ -95,7 +95,7 @@ suite('keyboardMapper - MAC de_ch', () => {
userSettingsLabel: 'cmd+z',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['meta+[KeyY]', null],
dispatchParts: ['meta+[KeyY]'],
}]
);
});
......@@ -118,7 +118,7 @@ suite('keyboardMapper - MAC de_ch', () => {
userSettingsLabel: 'cmd+z',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['meta+[KeyY]', null],
dispatchParts: ['meta+[KeyY]'],
}
);
});
......@@ -133,7 +133,7 @@ suite('keyboardMapper - MAC de_ch', () => {
userSettingsLabel: 'ctrl+alt+cmd+6',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+alt+meta+[Digit6]', null],
dispatchParts: ['ctrl+alt+meta+[Digit6]'],
}]
);
});
......@@ -156,7 +156,7 @@ suite('keyboardMapper - MAC de_ch', () => {
userSettingsLabel: 'cmd+[BracketRight]',
isWYSIWYG: false,
isChord: false,
dispatchParts: ['meta+[BracketRight]', null],
dispatchParts: ['meta+[BracketRight]'],
}
);
});
......@@ -171,7 +171,7 @@ suite('keyboardMapper - MAC de_ch', () => {
userSettingsLabel: 'ctrl+alt+9',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+alt+[Digit9]', null],
dispatchParts: ['ctrl+alt+[Digit9]'],
}]
);
});
......@@ -186,7 +186,7 @@ suite('keyboardMapper - MAC de_ch', () => {
userSettingsLabel: 'shift+cmd+7',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['shift+meta+[Digit7]', null],
dispatchParts: ['shift+meta+[Digit7]'],
}]
);
});
......@@ -201,7 +201,7 @@ suite('keyboardMapper - MAC de_ch', () => {
userSettingsLabel: 'shift+cmd+[Minus]',
isWYSIWYG: false,
isChord: false,
dispatchParts: ['shift+meta+[Minus]', null],
dispatchParts: ['shift+meta+[Minus]'],
}]
);
});
......@@ -246,7 +246,7 @@ suite('keyboardMapper - MAC de_ch', () => {
userSettingsLabel: 'cmd+down',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['meta+[ArrowDown]', null],
dispatchParts: ['meta+[ArrowDown]'],
}]
);
});
......@@ -261,7 +261,7 @@ suite('keyboardMapper - MAC de_ch', () => {
userSettingsLabel: 'cmd+numpad0',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['meta+[Numpad0]', null],
dispatchParts: ['meta+[Numpad0]'],
}]
);
});
......@@ -276,7 +276,7 @@ suite('keyboardMapper - MAC de_ch', () => {
userSettingsLabel: 'cmd+home',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['meta+[Home]', null],
dispatchParts: ['meta+[Home]'],
}]
);
});
......@@ -299,7 +299,7 @@ suite('keyboardMapper - MAC de_ch', () => {
userSettingsLabel: 'cmd+home',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['meta+[Home]', null],
dispatchParts: ['meta+[Home]'],
}
);
});
......@@ -339,7 +339,7 @@ suite('keyboardMapper - MAC de_ch', () => {
userSettingsLabel: 'cmd+',
isWYSIWYG: true,
isChord: false,
dispatchParts: [null, null],
dispatchParts: [null],
}
);
});
......@@ -362,7 +362,7 @@ suite('keyboardMapper - MAC de_ch', () => {
userSettingsLabel: 'cmd+',
isWYSIWYG: true,
isChord: false,
dispatchParts: [null, null],
dispatchParts: [null],
}
);
});
......@@ -416,7 +416,7 @@ suite('keyboardMapper - MAC en_us', () => {
userSettingsLabel: 'cmd+',
isWYSIWYG: true,
isChord: false,
dispatchParts: [null, null],
dispatchParts: [null],
}
);
});
......@@ -439,7 +439,7 @@ suite('keyboardMapper - MAC en_us', () => {
userSettingsLabel: 'cmd+',
isWYSIWYG: true,
isChord: false,
dispatchParts: [null, null],
dispatchParts: [null],
}
);
});
......@@ -491,7 +491,7 @@ suite('keyboardMapper - LINUX de_ch', () => {
userSettingsLabel: 'ctrl+a',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[KeyA]', null],
dispatchParts: ['ctrl+[KeyA]'],
}]
);
});
......@@ -506,7 +506,7 @@ suite('keyboardMapper - LINUX de_ch', () => {
userSettingsLabel: 'ctrl+z',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[KeyY]', null],
dispatchParts: ['ctrl+[KeyY]'],
}]
);
});
......@@ -529,7 +529,7 @@ suite('keyboardMapper - LINUX de_ch', () => {
userSettingsLabel: 'ctrl+z',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[KeyY]', null],
dispatchParts: ['ctrl+[KeyY]'],
}
);
});
......@@ -559,7 +559,7 @@ suite('keyboardMapper - LINUX de_ch', () => {
userSettingsLabel: 'ctrl+[BracketRight]',
isWYSIWYG: false,
isChord: false,
dispatchParts: ['ctrl+[BracketRight]', null],
dispatchParts: ['ctrl+[BracketRight]'],
}
);
});
......@@ -574,7 +574,7 @@ suite('keyboardMapper - LINUX de_ch', () => {
userSettingsLabel: 'ctrl+alt+0',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+alt+[Digit0]', null],
dispatchParts: ['ctrl+alt+[Digit0]'],
}, {
label: 'Ctrl+Alt+$',
ariaLabel: 'Control+Alt+$',
......@@ -582,7 +582,7 @@ suite('keyboardMapper - LINUX de_ch', () => {
userSettingsLabel: 'ctrl+alt+[Backslash]',
isWYSIWYG: false,
isChord: false,
dispatchParts: ['ctrl+alt+[Backslash]', null],
dispatchParts: ['ctrl+alt+[Backslash]'],
}]
);
});
......@@ -597,7 +597,7 @@ suite('keyboardMapper - LINUX de_ch', () => {
userSettingsLabel: 'ctrl+shift+7',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+shift+[Digit7]', null],
dispatchParts: ['ctrl+shift+[Digit7]'],
}]
);
});
......@@ -612,7 +612,7 @@ suite('keyboardMapper - LINUX de_ch', () => {
userSettingsLabel: 'ctrl+shift+[Minus]',
isWYSIWYG: false,
isChord: false,
dispatchParts: ['ctrl+shift+[Minus]', null],
dispatchParts: ['ctrl+shift+[Minus]'],
}]
);
});
......@@ -649,7 +649,7 @@ suite('keyboardMapper - LINUX de_ch', () => {
userSettingsLabel: 'ctrl+down',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[ArrowDown]', null],
dispatchParts: ['ctrl+[ArrowDown]'],
}]
);
});
......@@ -664,7 +664,7 @@ suite('keyboardMapper - LINUX de_ch', () => {
userSettingsLabel: 'ctrl+numpad0',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[Numpad0]', null],
dispatchParts: ['ctrl+[Numpad0]'],
}]
);
});
......@@ -679,7 +679,7 @@ suite('keyboardMapper - LINUX de_ch', () => {
userSettingsLabel: 'ctrl+home',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[Home]', null],
dispatchParts: ['ctrl+[Home]'],
}]
);
});
......@@ -702,7 +702,7 @@ suite('keyboardMapper - LINUX de_ch', () => {
userSettingsLabel: 'ctrl+home',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[Home]', null],
dispatchParts: ['ctrl+[Home]'],
}
);
});
......@@ -725,7 +725,7 @@ suite('keyboardMapper - LINUX de_ch', () => {
userSettingsLabel: 'ctrl+x',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[KeyX]', null],
dispatchParts: ['ctrl+[KeyX]'],
}
);
});
......@@ -765,7 +765,7 @@ suite('keyboardMapper - LINUX de_ch', () => {
userSettingsLabel: 'ctrl+',
isWYSIWYG: true,
isChord: false,
dispatchParts: [null, null],
dispatchParts: [null],
}
);
});
......@@ -788,7 +788,7 @@ suite('keyboardMapper - LINUX de_ch', () => {
userSettingsLabel: 'ctrl+',
isWYSIWYG: true,
isChord: false,
dispatchParts: [null, null],
dispatchParts: [null],
}
);
});
......@@ -821,7 +821,7 @@ suite('keyboardMapper - LINUX en_us', () => {
userSettingsLabel: 'ctrl+a',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[KeyA]', null],
dispatchParts: ['ctrl+[KeyA]'],
}]
);
});
......@@ -836,7 +836,7 @@ suite('keyboardMapper - LINUX en_us', () => {
userSettingsLabel: 'ctrl+z',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[KeyZ]', null],
dispatchParts: ['ctrl+[KeyZ]'],
}]
);
});
......@@ -859,7 +859,7 @@ suite('keyboardMapper - LINUX en_us', () => {
userSettingsLabel: 'ctrl+z',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[KeyZ]', null],
dispatchParts: ['ctrl+[KeyZ]'],
}
);
});
......@@ -874,7 +874,7 @@ suite('keyboardMapper - LINUX en_us', () => {
userSettingsLabel: 'ctrl+]',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[BracketRight]', null],
dispatchParts: ['ctrl+[BracketRight]'],
}]
);
});
......@@ -897,7 +897,7 @@ suite('keyboardMapper - LINUX en_us', () => {
userSettingsLabel: 'ctrl+]',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[BracketRight]', null],
dispatchParts: ['ctrl+[BracketRight]'],
}
);
});
......@@ -912,7 +912,7 @@ suite('keyboardMapper - LINUX en_us', () => {
userSettingsLabel: 'shift+]',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['shift+[BracketRight]', null],
dispatchParts: ['shift+[BracketRight]'],
}]
);
});
......@@ -927,7 +927,7 @@ suite('keyboardMapper - LINUX en_us', () => {
userSettingsLabel: 'ctrl+/',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[Slash]', null],
dispatchParts: ['ctrl+[Slash]'],
}]
);
});
......@@ -942,7 +942,7 @@ suite('keyboardMapper - LINUX en_us', () => {
userSettingsLabel: 'ctrl+shift+/',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+shift+[Slash]', null],
dispatchParts: ['ctrl+shift+[Slash]'],
}]
);
});
......@@ -987,7 +987,7 @@ suite('keyboardMapper - LINUX en_us', () => {
userSettingsLabel: 'ctrl+down',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[ArrowDown]', null],
dispatchParts: ['ctrl+[ArrowDown]'],
}]
);
});
......@@ -1002,7 +1002,7 @@ suite('keyboardMapper - LINUX en_us', () => {
userSettingsLabel: 'ctrl+numpad0',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[Numpad0]', null],
dispatchParts: ['ctrl+[Numpad0]'],
}]
);
});
......@@ -1017,7 +1017,7 @@ suite('keyboardMapper - LINUX en_us', () => {
userSettingsLabel: 'ctrl+home',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[Home]', null],
dispatchParts: ['ctrl+[Home]'],
}]
);
});
......@@ -1040,7 +1040,7 @@ suite('keyboardMapper - LINUX en_us', () => {
userSettingsLabel: 'ctrl+home',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[Home]', null],
dispatchParts: ['ctrl+[Home]'],
}
);
});
......@@ -1055,7 +1055,7 @@ suite('keyboardMapper - LINUX en_us', () => {
userSettingsLabel: 'ctrl+shift+,',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+shift+[Comma]', null],
dispatchParts: ['ctrl+shift+[Comma]'],
}, {
label: 'Ctrl+<',
ariaLabel: 'Control+<',
......@@ -1063,7 +1063,7 @@ suite('keyboardMapper - LINUX en_us', () => {
userSettingsLabel: 'ctrl+[IntlBackslash]',
isWYSIWYG: false,
isChord: false,
dispatchParts: ['ctrl+[IntlBackslash]', null],
dispatchParts: ['ctrl+[IntlBackslash]'],
}]
);
});
......@@ -1078,7 +1078,7 @@ suite('keyboardMapper - LINUX en_us', () => {
userSettingsLabel: 'ctrl+enter',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[Enter]', null],
dispatchParts: ['ctrl+[Enter]'],
}]
);
});
......@@ -1101,7 +1101,7 @@ suite('keyboardMapper - LINUX en_us', () => {
userSettingsLabel: 'ctrl+enter',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[Enter]', null],
dispatchParts: ['ctrl+[Enter]'],
}
);
});
......@@ -1135,7 +1135,7 @@ suite('keyboardMapper - LINUX en_us', () => {
userSettingsLabel: 'ctrl+,',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[Comma]', null],
dispatchParts: ['ctrl+[Comma]'],
}]
);
});
......@@ -1158,7 +1158,7 @@ suite('keyboardMapper - LINUX en_us', () => {
userSettingsLabel: 'ctrl+',
isWYSIWYG: true,
isChord: false,
dispatchParts: [null, null],
dispatchParts: [null],
}
);
});
......@@ -1181,7 +1181,7 @@ suite('keyboardMapper - LINUX en_us', () => {
userSettingsLabel: 'ctrl+',
isWYSIWYG: true,
isChord: false,
dispatchParts: [null, null],
dispatchParts: [null],
}
);
});
......@@ -1216,7 +1216,7 @@ suite('keyboardMapper', () => {
userSettingsLabel: 'ctrl+`',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[Backquote]', null],
dispatchParts: ['ctrl+[Backquote]'],
}
);
});
......@@ -1242,7 +1242,7 @@ suite('keyboardMapper', () => {
userSettingsLabel: userSettingsLabel,
isWYSIWYG: true,
isChord: false,
dispatchParts: [dispatch, null],
dispatchParts: [dispatch],
}
);
}
......@@ -1281,7 +1281,7 @@ suite('keyboardMapper', () => {
userSettingsLabel: userSettingsLabel,
isWYSIWYG: true,
isChord: false,
dispatchParts: [dispatch, null],
dispatchParts: [dispatch],
}
);
}
......@@ -1339,7 +1339,7 @@ suite('keyboardMapper - LINUX ru', () => {
userSettingsLabel: 'ctrl+s',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+[KeyS]', null],
dispatchParts: ['ctrl+[KeyS]'],
}]
);
});
......@@ -1376,7 +1376,7 @@ suite('keyboardMapper - LINUX en_uk', () => {
userSettingsLabel: 'ctrl+alt+[Minus]',
isWYSIWYG: false,
isChord: false,
dispatchParts: ['ctrl+alt+[Minus]', null],
dispatchParts: ['ctrl+alt+[Minus]'],
}
);
});
......@@ -1409,7 +1409,7 @@ suite('keyboardMapper - MAC zh_hant', () => {
userSettingsLabel: 'cmd+c',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['meta+[KeyC]', null],
dispatchParts: ['meta+[KeyC]'],
}]
);
});
......@@ -1425,17 +1425,17 @@ function _assertKeybindingTranslation(mapper: MacLinuxKeyboardMapper, OS: Operat
expected = [];
}
const runtimeKeybinding = createKeybinding(kb, OS);
const runtimeKeybinding = createSimpleKeybinding(kb, OS);
const keybindingLabel = new USLayoutResolvedKeybinding(runtimeKeybinding!, OS).getUserSettingsLabel();
const keybindingLabel = new USLayoutResolvedKeybinding(runtimeKeybinding.toChord(), OS).getUserSettingsLabel();
const actualHardwareKeypresses = mapper.simpleKeybindingToScanCodeBinding(<SimpleKeybinding>runtimeKeybinding);
const actualHardwareKeypresses = mapper.simpleKeybindingToScanCodeBinding(runtimeKeybinding);
if (actualHardwareKeypresses.length === 0) {
assert.deepEqual([], expected, `simpleKeybindingToHardwareKeypress -- "${keybindingLabel}" -- actual: "[]" -- expected: "${expected}"`);
return;
}
const actual = actualHardwareKeypresses
.map(k => UserSettingsLabelProvider.toLabel(k, ScanCodeUtils.toString(k.scanCode), null, null, OS));
.map(k => UserSettingsLabelProvider.toLabel(OS, [k], (keybinding) => ScanCodeUtils.toString(keybinding.scanCode)));
assert.deepEqual(actual, expected, `simpleKeybindingToHardwareKeypress -- "${keybindingLabel}" -- actual: "${actual}" -- expected: "${expected}"`);
}
......@@ -44,7 +44,7 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
userSettingsLabel: 'ctrl+a',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+A', null],
dispatchParts: ['ctrl+A'],
}]
);
});
......@@ -60,7 +60,7 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
userSettingsLabel: 'ctrl+z',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+Z', null],
dispatchParts: ['ctrl+Z'],
}]
);
});
......@@ -83,7 +83,7 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
userSettingsLabel: 'ctrl+z',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+Z', null],
dispatchParts: ['ctrl+Z'],
}
);
});
......@@ -99,7 +99,7 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
userSettingsLabel: 'ctrl+oem_6',
isWYSIWYG: false,
isChord: false,
dispatchParts: ['ctrl+]', null],
dispatchParts: ['ctrl+]'],
}]
);
});
......@@ -122,7 +122,7 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
userSettingsLabel: 'ctrl+oem_6',
isWYSIWYG: false,
isChord: false,
dispatchParts: ['ctrl+]', null],
dispatchParts: ['ctrl+]'],
}
);
});
......@@ -138,7 +138,7 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
userSettingsLabel: 'shift+oem_6',
isWYSIWYG: false,
isChord: false,
dispatchParts: ['shift+]', null],
dispatchParts: ['shift+]'],
}]
);
});
......@@ -154,7 +154,7 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
userSettingsLabel: 'ctrl+oem_2',
isWYSIWYG: false,
isChord: false,
dispatchParts: ['ctrl+/', null],
dispatchParts: ['ctrl+/'],
}]
);
});
......@@ -170,7 +170,7 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
userSettingsLabel: 'ctrl+shift+oem_2',
isWYSIWYG: false,
isChord: false,
dispatchParts: ['ctrl+shift+/', null],
dispatchParts: ['ctrl+shift+/'],
}]
);
});
......@@ -210,7 +210,7 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
userSettingsLabel: 'ctrl+down',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+DownArrow', null],
dispatchParts: ['ctrl+DownArrow'],
}]
);
});
......@@ -226,7 +226,7 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
userSettingsLabel: 'ctrl+numpad0',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+NumPad0', null],
dispatchParts: ['ctrl+NumPad0'],
}]
);
});
......@@ -242,7 +242,7 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
userSettingsLabel: 'ctrl+home',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+Home', null],
dispatchParts: ['ctrl+Home'],
}]
);
});
......@@ -265,7 +265,7 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
userSettingsLabel: 'ctrl+home',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+Home', null],
dispatchParts: ['ctrl+Home'],
}
);
});
......@@ -305,7 +305,7 @@ suite('keyboardMapper - WINDOWS de_ch', () => {
userSettingsLabel: 'ctrl+',
isWYSIWYG: true,
isChord: false,
dispatchParts: [null, null],
dispatchParts: [null],
}
);
});
......@@ -368,7 +368,7 @@ suite('keyboardMapper - WINDOWS en_us', () => {
userSettingsLabel: 'ctrl+,',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+,', null],
dispatchParts: ['ctrl+,'],
}]
);
});
......@@ -391,7 +391,7 @@ suite('keyboardMapper - WINDOWS en_us', () => {
userSettingsLabel: 'ctrl+',
isWYSIWYG: true,
isChord: false,
dispatchParts: [null, null],
dispatchParts: [null],
}
);
});
......@@ -427,7 +427,7 @@ suite('keyboardMapper - WINDOWS por_ptb', () => {
userSettingsLabel: 'ctrl+abnt_c1',
isWYSIWYG: false,
isChord: false,
dispatchParts: ['ctrl+ABNT_C1', null],
dispatchParts: ['ctrl+ABNT_C1'],
}
);
});
......@@ -450,7 +450,7 @@ suite('keyboardMapper - WINDOWS por_ptb', () => {
userSettingsLabel: 'ctrl+abnt_c2',
isWYSIWYG: false,
isChord: false,
dispatchParts: ['ctrl+ABNT_C2', null],
dispatchParts: ['ctrl+ABNT_C2'],
}
);
});
......@@ -514,7 +514,7 @@ suite('keyboardMapper - misc', () => {
userSettingsLabel: 'ctrl+b',
isWYSIWYG: true,
isChord: false,
dispatchParts: ['ctrl+B', null],
dispatchParts: ['ctrl+B'],
}]
);
});
......
......@@ -610,8 +610,15 @@ suite('KeybindingsEditorModel test', () => {
const { ctrlKey, shiftKey, altKey, metaKey } = part.modifiers || { ctrlKey: false, shiftKey: false, altKey: false, metaKey: false };
return new SimpleKeybinding(ctrlKey!, shiftKey!, altKey!, metaKey!, part.keyCode);
};
const keybinding = firstPart ? chordPart ? new ChordKeybinding(aSimpleKeybinding(firstPart), aSimpleKeybinding(chordPart)) : aSimpleKeybinding(firstPart) : null;
return new ResolvedKeybindingItem(keybinding ? new USLayoutResolvedKeybinding(keybinding, OS) : null, command || 'some command', null, when ? ContextKeyExpr.deserialize(when) : null, isDefault === undefined ? true : isDefault);
let parts: SimpleKeybinding[] = [];
if (firstPart) {
parts.push(aSimpleKeybinding(firstPart));
if (chordPart) {
parts.push(aSimpleKeybinding(chordPart));
}
}
let keybinding = parts.length > 0 ? new USLayoutResolvedKeybinding(new ChordKeybinding(parts), OS) : null;
return new ResolvedKeybindingItem(keybinding, command || 'some command', null, when ? ContextKeyExpr.deserialize(when) : null, isDefault === undefined ? true : isDefault);
}
function asResolvedKeybindingItems(keybindingEntries: IKeybindingItemEntry[], keepUnassigned: boolean = false): ResolvedKeybindingItem[] {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册