提交 48566c7a 编写于 作者: A Alex Dima

NormalizedKeybindingItem uses ResolvedKeybinding

上级 8d6e85ac
......@@ -617,4 +617,9 @@ export abstract class ResolvedKeybinding {
* If it is a chord, it always returns false.
*/
public abstract hasMetaModifier(): boolean;
/**
* Returns the firstPart, chordPart that should be used for dispatching.
*/
public abstract getDispatchParts(): [string, string];
}
......@@ -31,7 +31,7 @@ import { KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRe
import { MenuId, IMenu, IMenuService } from 'vs/platform/actions/common/actions';
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 { ResolvedKeybinding, Keybinding, createKeybinding } from 'vs/base/common/keyCodes';
import { NormalizedKeybindingItem } from 'vs/platform/keybinding/common/normalizedKeybindingItem';
import { OS } from 'vs/base/common/platform';
......@@ -373,13 +373,27 @@ export class StandaloneKeybindingService extends AbstractKeybindingService {
protected _getResolver(): KeybindingResolver {
if (!this._cachedResolver) {
const defaults = KeybindingsRegistry.getDefaultKeybindings().map(k => NormalizedKeybindingItem.fromKeybindingItem(k, true));
const overrides = this._dynamicKeybindings.map(k => NormalizedKeybindingItem.fromKeybindingItem(k, false));
const defaults = this._toNormalizedKeybindingItems(KeybindingsRegistry.getDefaultKeybindings(), true);
const overrides = this._toNormalizedKeybindingItems(this._dynamicKeybindings, false);
this._cachedResolver = new KeybindingResolver(defaults, overrides);
}
return this._cachedResolver;
}
private _toNormalizedKeybindingItems(items: IKeybindingItem[], isDefault: boolean): NormalizedKeybindingItem[] {
let result: NormalizedKeybindingItem[] = [], resultLen = 0;
for (let i = 0, len = items.length; i < len; i++) {
const item = items[i];
const when = (item.when ? item.when.normalize() : null);
const keybinding = (item.keybinding !== 0 ? createKeybinding(item.keybinding) : null);
const resolvedKeybinding = (keybinding !== null ? this._createResolvedKeybinding(keybinding) : null);
result[resultLen++] = new NormalizedKeybindingItem(resolvedKeybinding, item.command, item.commandArgs, when, isDefault);
}
return result;
}
protected _createResolvedKeybinding(kb: Keybinding): ResolvedKeybinding {
return new USLayoutResolvedKeybinding(kb, OS);
}
......
......@@ -149,6 +149,22 @@ export class USLayoutResolvedKeybinding extends ResolvedKeybinding {
return this._actual.hasWinCtrl();
}
}
public getDispatchParts(): [string, string] {
let keypressFirstPart: string;
let keypressChordPart: string;
if (this._actual === null) {
keypressFirstPart = null;
keypressChordPart = null;
} else if (this._actual.isChord()) {
keypressFirstPart = this._actual.extractFirstPart().value.toString();
keypressChordPart = this._actual.extractChordPart().value.toString();
} else {
keypressFirstPart = this._actual.value.toString();
keypressChordPart = null;
}
return [keypressFirstPart, keypressChordPart];
}
}
interface CurrentChord {
......@@ -208,7 +224,7 @@ export abstract class AbstractKeybindingService implements IKeybindingService {
public getKeybindings(): IKeybindingItem2[] {
return this._getResolver().getKeybindings().map(keybinding => ({
keybinding: this.resolveKeybinding(keybinding.keybinding),
keybinding: keybinding.resolvedKeybinding,
command: keybinding.command,
when: keybinding.when,
source: keybinding.isDefault ? KeybindingSource.Default : KeybindingSource.User
......@@ -220,7 +236,7 @@ export abstract class AbstractKeybindingService implements IKeybindingService {
}
public lookupKeybindings(commandId: string): ResolvedKeybinding[] {
return this._getResolver().lookupKeybindings(commandId).map(item => this._createResolvedKeybinding(item.keybinding));
return this._getResolver().lookupKeybindings(commandId).map(item => item.resolvedKeybinding);
}
public lookupKeybinding(commandId: string): ResolvedKeybinding {
......@@ -228,7 +244,7 @@ export abstract class AbstractKeybindingService implements IKeybindingService {
if (!result) {
return null;
}
return this._createResolvedKeybinding(result.keybinding);
return result.resolvedKeybinding;
}
public resolve(keybinding: SimpleKeybinding, target: IContextKeyServiceTarget): IResolveResult {
......
......@@ -4,15 +4,14 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import { createKeybinding, Keybinding } from 'vs/base/common/keyCodes';
import { IKeybindingItem } from 'vs/platform/keybinding/common/keybinding';
import { ResolvedKeybinding } from 'vs/base/common/keyCodes';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { CharCode } from 'vs/base/common/charCode';
export class NormalizedKeybindingItem {
_normalizedKeybindingItemBrand: void;
public readonly keybinding: Keybinding;
public readonly resolvedKeybinding: ResolvedKeybinding;
public readonly keypressFirstPart: string;
public readonly keypressChordPart: string;
public readonly bubble: boolean;
......@@ -21,35 +20,16 @@ export class NormalizedKeybindingItem {
public readonly when: ContextKeyExpr;
public readonly isDefault: boolean;
public static fromKeybindingItem(source: IKeybindingItem, isDefault: boolean): NormalizedKeybindingItem {
let when: ContextKeyExpr = null;
if (source.when) {
when = source.when.normalize();
}
let keybinding: Keybinding = null;
if (source.keybinding !== 0) {
keybinding = createKeybinding(source.keybinding);
}
let keypressFirstPart: string;
let keypressChordPart: string;
if (keybinding === null) {
keypressFirstPart = null;
keypressChordPart = null;
} else if (keybinding.isChord()) {
keypressFirstPart = keybinding.extractFirstPart().value.toString();
keypressChordPart = keybinding.extractChordPart().value.toString();
constructor(resolvedKeybinding: ResolvedKeybinding, command: string, commandArgs: any, when: ContextKeyExpr, isDefault: boolean) {
this.resolvedKeybinding = resolvedKeybinding;
if (resolvedKeybinding) {
let [keypressFirstPart, keypressChordPart] = resolvedKeybinding.getDispatchParts();
this.keypressFirstPart = keypressFirstPart;
this.keypressChordPart = keypressChordPart;
} else {
keypressFirstPart = keybinding.value.toString();
keypressChordPart = null;
this.keypressFirstPart = null;
this.keypressChordPart = null;
}
return new NormalizedKeybindingItem(keybinding, keypressFirstPart, keypressChordPart, source.command, source.commandArgs, when, isDefault);
}
constructor(keybinding: Keybinding, keypressFirstPart: string, keypressChordPart: string, command: string, commandArgs: any, when: ContextKeyExpr, isDefault: boolean) {
this.keybinding = keybinding;
this.keypressFirstPart = keypressFirstPart;
this.keypressChordPart = keypressChordPart;
this.bubble = (command ? command.charCodeAt(0) === CharCode.Caret : false);
this.command = this.bubble ? command.substr(1) : command;
this.commandArgs = commandArgs;
......
......@@ -129,14 +129,14 @@ suite('AbstractKeybindingService', () => {
});
function kbItem(keybinding: number, command: string, when: ContextKeyExpr = null): NormalizedKeybindingItem {
return NormalizedKeybindingItem.fromKeybindingItem({
keybinding: keybinding,
command: command,
commandArgs: null,
when: when,
weight1: 0,
weight2: 0
}, true);
const resolvedKeybinding = (keybinding !== 0 ? new USLayoutResolvedKeybinding(createKeybinding(keybinding), OS) : null);
return new NormalizedKeybindingItem(
resolvedKeybinding,
command,
null,
when,
true
);
}
function toUsLabel(keybinding: number): string {
......
......@@ -9,18 +9,20 @@ import { createKeybinding, SimpleKeybinding, KeyCode, KeyMod, KeyChord } from 'v
import { KeybindingResolver } from 'vs/platform/keybinding/common/keybindingResolver';
import { ContextKeyAndExpr, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { NormalizedKeybindingItem } from 'vs/platform/keybinding/common/normalizedKeybindingItem';
import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/abstractKeybindingService';
import { OS } from 'vs/base/common/platform';
suite('KeybindingResolver', () => {
function kbItem(keybinding: number, command: string, commandArgs: any, when: ContextKeyExpr, isDefault: boolean): NormalizedKeybindingItem {
return NormalizedKeybindingItem.fromKeybindingItem({
keybinding: keybinding,
command: command,
commandArgs: commandArgs,
when: when,
weight1: 0,
weight2: 0
}, isDefault);
const resolvedKeybinding = (keybinding !== 0 ? new USLayoutResolvedKeybinding(createKeybinding(keybinding), OS) : null);
return new NormalizedKeybindingItem(
resolvedKeybinding,
command,
commandArgs,
when,
isDefault
);
}
test('resolve key', function () {
......@@ -319,7 +321,9 @@ suite('KeybindingResolver', () => {
let lookupResult = resolver.lookupKeybindings(commandId);
assert.equal(lookupResult.length, expectedKeys.length, 'Length mismatch @ commandId ' + commandId + '; GOT: ' + JSON.stringify(lookupResult, null, '\t'));
for (let i = 0, len = lookupResult.length; i < len; i++) {
assert.equal(lookupResult[i].keybinding.value, expectedKeys[i], 'value mismatch @ commandId ' + commandId);
const expected = new USLayoutResolvedKeybinding(createKeybinding(expectedKeys[i]), OS);
assert.equal(lookupResult[i].resolvedKeybinding.getUserSettingsLabel(), expected.getUserSettingsLabel(), 'value mismatch @ commandId ' + commandId);
}
};
......
......@@ -4,8 +4,7 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import { Keybinding, KeyMod, KeyChord, USER_SETTINGS, KeyCode } from 'vs/base/common/keyCodes';
import { PrintableKeypress, UserSettingsLabelProvider } from 'vs/platform/keybinding/common/keybindingLabels';
import { KeyMod, KeyChord, USER_SETTINGS } from 'vs/base/common/keyCodes';
import { OperatingSystem } from 'vs/base/common/platform';
import { IKeybindingItem, IUserFriendlyKeybinding } from 'vs/platform/keybinding/common/keybinding';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
......@@ -14,7 +13,7 @@ import { NormalizedKeybindingItem } from 'vs/platform/keybinding/common/normaliz
export class KeybindingIO {
public static writeKeybindingItem(out: OutputBuilder, item: NormalizedKeybindingItem, OS: OperatingSystem): void {
let quotedSerializedKeybinding = JSON.stringify(KeybindingIO.writeKeybinding(item.keybinding, OS));
let quotedSerializedKeybinding = JSON.stringify(item.resolvedKeybinding.getUserSettingsLabel());
out.write(`{ "key": ${rightPaddedString(quotedSerializedKeybinding + ',', 25)} "command": `);
let serializedWhen = item.when ? item.when.serialize() : '';
......@@ -81,17 +80,6 @@ export class KeybindingIO {
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.fromKeybinding(keybinding, this._keyCodeToStr, OS);
let result = UserSettingsLabelProvider.toLabel2(firstPart, chordPart, OS);
return result.toLowerCase();
}
public static readKeybinding(input: string, OS: OperatingSystem): number {
if (!input) {
return 0;
......
......@@ -137,6 +137,10 @@ export class NativeResolvedKeybinding extends ResolvedKeybinding {
public hasMetaModifier(): boolean {
throw new Error('TODO!');
}
public getDispatchParts(): [string, string] {
throw new Error('TODO!');
}
}
interface IHardwareCodeMapping {
......
......@@ -7,8 +7,8 @@
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 { PrintableKeypress, UILabelProvider, AriaLabelProvider } from 'vs/platform/keybinding/common/keybindingLabels';
import { ResolvedKeybinding, Keybinding, createKeybinding, KeyCode, USER_SETTINGS } from 'vs/base/common/keyCodes';
import { PrintableKeypress, UILabelProvider, AriaLabelProvider, UserSettingsLabelProvider } 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';
......@@ -169,8 +169,15 @@ export class FancyResolvedKeybinding extends ResolvedKeybinding {
return usResolvedKeybinding.getElectronAccelerator();
}
private static _usKeyCodeToUserSettings(keyCode: KeyCode, OS: OperatingSystem): string {
return USER_SETTINGS.fromKeyCode(keyCode);
}
public getUserSettingsLabel(): string {
return KeybindingIO.writeKeybinding(this._actual, OS);
const [firstPart, chordPart] = PrintableKeypress.fromKeybinding(this._actual, FancyResolvedKeybinding._usKeyCodeToUserSettings, OS);
let result = UserSettingsLabelProvider.toLabel2(firstPart, chordPart, OS);
return result.toLowerCase();
}
public isChord(): boolean {
......@@ -212,6 +219,22 @@ export class FancyResolvedKeybinding extends ResolvedKeybinding {
return this._actual.hasWinCtrl();
}
}
public getDispatchParts(): [string, string] {
let keypressFirstPart: string;
let keypressChordPart: string;
if (this._actual === null) {
keypressFirstPart = null;
keypressChordPart = null;
} else if (this._actual.isChord()) {
keypressFirstPart = this._actual.extractFirstPart().value.toString();
keypressChordPart = this._actual.extractChordPart().value.toString();
} else {
keypressFirstPart = this._actual.value.toString();
keypressChordPart = null;
}
return [keypressFirstPart, keypressChordPart];
}
}
export class WorkbenchKeybindingService extends AbstractKeybindingService {
......@@ -290,14 +313,28 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService {
protected _getResolver(): KeybindingResolver {
if (!this._cachedResolver) {
const defaults = KeybindingsRegistry.getDefaultKeybindings().map(k => NormalizedKeybindingItem.fromKeybindingItem(k, true));
const overrides = this._getExtraKeybindings(this._firstTimeComputingResolver).map(k => NormalizedKeybindingItem.fromKeybindingItem(k, false));
const defaults = this._toNormalizedKeybindingItems(KeybindingsRegistry.getDefaultKeybindings(), true);
const overrides = this._toNormalizedKeybindingItems(this._getExtraKeybindings(this._firstTimeComputingResolver), false);
this._cachedResolver = new KeybindingResolver(defaults, overrides);
this._firstTimeComputingResolver = false;
}
return this._cachedResolver;
}
private _toNormalizedKeybindingItems(items: IKeybindingItem[], isDefault: boolean): NormalizedKeybindingItem[] {
let result: NormalizedKeybindingItem[] = [], resultLen = 0;
for (let i = 0, len = items.length; i < len; i++) {
const item = items[i];
const when = (item.when ? item.when.normalize() : null);
const keybinding = (item.keybinding !== 0 ? createKeybinding(item.keybinding) : null);
const resolvedKeybinding = (keybinding !== null ? this._createResolvedKeybinding(keybinding) : null);
result[resultLen++] = new NormalizedKeybindingItem(resolvedKeybinding, item.command, item.commandArgs, when, isDefault);
}
return result;
}
private _getExtraKeybindings(isFirstTime: boolean): IKeybindingItem[] {
let extraUserKeybindings: IUserFriendlyKeybinding[] = this._safeGetConfig();
if (!isFirstTime) {
......
......@@ -9,7 +9,7 @@ import { createKeybinding, KeyCode, KeyMod, KeyChord, KeyCodeUtils } from 'vs/ba
import { KeybindingIO } from 'vs/workbench/services/keybinding/common/keybindingIO';
import { OS, OperatingSystem } from 'vs/base/common/platform';
import { IUserFriendlyKeybinding } from 'vs/platform/keybinding/common/keybinding';
import { NormalizedKeybindingItem } from 'vs/platform/keybinding/common/normalizedKeybindingItem';
import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/abstractKeybindingService';
suite('keybindingIO', () => {
test('getUserSettingsKeybindingRegex', () => {
......@@ -31,7 +31,8 @@ suite('keybindingIO', () => {
if (ignore[keyCode]) {
continue;
}
let userSettings = KeybindingIO.writeKeybinding(createKeybinding(keyCode), OS);
let usLayoutResolvedKeybinding = new USLayoutResolvedKeybinding(createKeybinding(keyCode), OS);
let userSettings = usLayoutResolvedKeybinding.getUserSettingsLabel();
testIsGood(userSettings, keyCode + ' - ' + KeyCodeUtils.toString(keyCode) + ' - ' + userSettings);
}
......@@ -56,7 +57,8 @@ suite('keybindingIO', () => {
test('serialize/deserialize', function () {
function testOneSerialization(keybinding: number, expected: string, msg: string, OS: OperatingSystem): void {
let actualSerialized = KeybindingIO.writeKeybinding(createKeybinding(keybinding), OS);
let usLayoutResolvedKeybinding = new USLayoutResolvedKeybinding(createKeybinding(keybinding), OS);
let actualSerialized = usLayoutResolvedKeybinding.getUserSettingsLabel();
assert.equal(actualSerialized, expected, expected + ' - ' + msg);
}
function testSerialization(keybinding: number, expectedWin: string, expectedMac: string, expectedLinux: string): void {
......@@ -154,31 +156,27 @@ suite('keybindingIO', () => {
let strJSON = `[{ "key": "ctrl+k ctrl+f", "command": ["firstcommand", "seccondcommand"] }]`;
let userKeybinding = <IUserFriendlyKeybinding>JSON.parse(strJSON)[0];
let keybindingItem = KeybindingIO.readKeybindingItem(userKeybinding, 0, OS);
let normalizedKeybindingItem = NormalizedKeybindingItem.fromKeybindingItem(keybindingItem, false);
assert.equal(normalizedKeybindingItem.command, null);
assert.equal(keybindingItem.command, null);
});
test('issue #10452 - invalid when', () => {
let strJSON = `[{ "key": "ctrl+k ctrl+f", "command": "firstcommand", "when": [] }]`;
let userKeybinding = <IUserFriendlyKeybinding>JSON.parse(strJSON)[0];
let keybindingItem = KeybindingIO.readKeybindingItem(userKeybinding, 0, OS);
let normalizedKeybindingItem = NormalizedKeybindingItem.fromKeybindingItem(keybindingItem, false);
assert.equal(normalizedKeybindingItem.when, null);
assert.equal(keybindingItem.when, null);
});
test('issue #10452 - invalid key', () => {
let strJSON = `[{ "key": [], "command": "firstcommand" }]`;
let userKeybinding = <IUserFriendlyKeybinding>JSON.parse(strJSON)[0];
let keybindingItem = KeybindingIO.readKeybindingItem(userKeybinding, 0, OS);
let normalizedKeybindingItem = NormalizedKeybindingItem.fromKeybindingItem(keybindingItem, false);
assert.equal(normalizedKeybindingItem.keybinding, null);
assert.equal(keybindingItem.keybinding, 0);
});
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, OS);
let normalizedKeybindingItem = NormalizedKeybindingItem.fromKeybindingItem(keybindingItem, false);
assert.equal(normalizedKeybindingItem.commandArgs.text, 'theText');
assert.equal(keybindingItem.commandArgs.text, 'theText');
});
});
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册