Skip to content

Commit 555739f

Browse files
committed
Tweaks for microsoft#65826
1 parent 861923b commit 555739f

14 files changed

Lines changed: 104 additions & 187 deletions

src/vs/base/common/keyCodes.ts

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { OperatingSystem } from 'vs/base/common/platform';
7+
import { illegalArgument } from 'vs/base/common/errors';
78

89
/**
910
* Virtual Key Codes, the value does not hold any inherent meaning.
@@ -416,11 +417,13 @@ export function createKeybinding(keybinding: number, OS: OperatingSystem): Keybi
416417
}
417418
const firstPart = (keybinding & 0x0000FFFF) >>> 0;
418419
const chordPart = (keybinding & 0xFFFF0000) >>> 16;
419-
let parts = [createSimpleKeybinding(firstPart, OS)];
420420
if (chordPart !== 0) {
421-
parts.push(createSimpleKeybinding(chordPart, OS));
421+
return new ChordKeybinding([
422+
createSimpleKeybinding(firstPart, OS),
423+
createSimpleKeybinding(chordPart, OS)
424+
]);
422425
}
423-
return new ChordKeybinding(parts);
426+
return new ChordKeybinding([createSimpleKeybinding(firstPart, OS)]);
424427
}
425428

426429
export function createSimpleKeybinding(keybinding: number, OS: OperatingSystem): SimpleKeybinding {
@@ -437,14 +440,7 @@ export function createSimpleKeybinding(keybinding: number, OS: OperatingSystem):
437440
return new SimpleKeybinding(ctrlKey, shiftKey, altKey, metaKey, keyCode);
438441
}
439442

440-
export const enum KeybindingType {
441-
Simple = 1,
442-
Chord = 2
443-
}
444-
445443
export class SimpleKeybinding {
446-
public readonly type = KeybindingType.Simple;
447-
448444
public readonly ctrlKey: boolean;
449445
public readonly shiftKey: boolean;
450446
public readonly altKey: boolean;
@@ -505,16 +501,24 @@ export class SimpleKeybinding {
505501
}
506502

507503
export class ChordKeybinding {
508-
public readonly type = KeybindingType.Chord;
509504
public readonly parts: SimpleKeybinding[];
510505

511506
constructor(parts: SimpleKeybinding[]) {
507+
if (parts.length === 0) {
508+
throw illegalArgument(`parts`);
509+
}
512510
this.parts = parts;
513511
}
514512

515513
public getHashCode(): string {
516-
let hashCodes = this.parts.map((p) => p.getHashCode().toString());
517-
return hashCodes.join(';');
514+
let result = '';
515+
for (let i = 0, len = this.parts.length; i < len; i++) {
516+
if (i !== 0) {
517+
result += ';';
518+
}
519+
result += this.parts[i].getHashCode();
520+
}
521+
return result;
518522
}
519523

520524
public equals(other: ChordKeybinding | null): boolean {

src/vs/base/common/keybindingLabels.ts

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ export interface Modifiers {
2121
readonly metaKey: boolean;
2222
}
2323

24+
export interface KeyLabelProvider<T extends Modifiers> {
25+
(keybinding: T): string | null;
26+
}
27+
2428
export class ModifierLabelProvider {
2529

2630
public readonly modifierLabels: ModifierLabels[];
@@ -32,8 +36,22 @@ export class ModifierLabelProvider {
3236
this.modifierLabels[OperatingSystem.Linux] = linux;
3337
}
3438

35-
public toLabel(partModifiers: Modifiers[], partKeys: string[], OS: OperatingSystem): string | null {
36-
return _asString(partModifiers, partKeys, this.modifierLabels[OS]);
39+
public toLabel<T extends Modifiers>(OS: OperatingSystem, parts: T[], keyLabelProvider: KeyLabelProvider<T>): string | null {
40+
if (parts.length === 0) {
41+
return null;
42+
}
43+
44+
let result: string[] = [];
45+
for (let i = 0, len = parts.length; i < len; i++) {
46+
const part = parts[i];
47+
const keyLabel = keyLabelProvider(part);
48+
if (keyLabel === null) {
49+
// this keybinding cannot be expressed...
50+
return null;
51+
}
52+
result[i] = _simpleAsString(part, keyLabel, this.modifierLabels[OS]);
53+
}
54+
return result.join(' ');
3755
}
3856
}
3957

@@ -168,11 +186,3 @@ function _simpleAsString(modifiers: Modifiers, key: string, labels: ModifierLabe
168186

169187
return result.join(labels.separator);
170188
}
171-
172-
function _asString(partModifiers: Modifiers[], partKeys: string[], labels: ModifierLabels): string {
173-
let results: string[] = [];
174-
for (let i = 0; i < partModifiers.length; i++) {
175-
results.push(_simpleAsString(partModifiers[i], partKeys[i], labels));
176-
}
177-
return results.join(' ');
178-
}

src/vs/base/common/keybindingParser.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ export class KeybindingParser {
108108
}
109109

110110
static parseUserBinding(input: string): [SimpleKeybinding | ScanCodeBinding | null, SimpleKeybinding | ScanCodeBinding | null] {
111+
// TODO@chords: allow users to define N chords
111112
if (!input) {
112113
return [null, null];
113114
}

src/vs/base/parts/tree/browser/treeDefaults.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ import * as dom from 'vs/base/browser/dom';
1212
import * as mouse from 'vs/base/browser/mouseEvent';
1313
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
1414
import * as _ from 'vs/base/parts/tree/browser/tree';
15-
import { KeyCode, KeyMod, Keybinding, SimpleKeybinding, createKeybinding } from 'vs/base/common/keyCodes';
1615
import { IDragAndDropData } from 'vs/base/browser/dnd';
16+
import { KeyCode, KeyMod, Keybinding, SimpleKeybinding, createKeybinding } from 'vs/base/common/keyCodes';
1717

1818
export interface IKeyBindingCallback {
1919
(tree: _.ITree, event: IKeyboardEvent): void;

src/vs/platform/keybinding/common/keybindingsRegistry.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
* Copyright (c) Microsoft Corporation. All rights reserved.
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
5+
56
import { KeyCode, Keybinding, SimpleKeybinding, createKeybinding } from 'vs/base/common/keyCodes';
67
import { OS, OperatingSystem } from 'vs/base/common/platform';
78
import { CommandsRegistry, ICommandHandler, ICommandHandlerDescription } from 'vs/platform/commands/common/commands';

src/vs/platform/keybinding/common/resolvedKeybindingItem.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,18 @@ export class ResolvedKeybindingItem {
2222
constructor(resolvedKeybinding: ResolvedKeybinding | null, command: string | null, commandArgs: any, when: ContextKeyExpr | null, isDefault: boolean) {
2323
this.resolvedKeybinding = resolvedKeybinding;
2424
if (resolvedKeybinding) {
25-
let [keypressFirstPart, keypressChordPart] = resolvedKeybinding.getDispatchParts();
26-
this.keypressFirstPart = keypressFirstPart;
27-
if (keypressChordPart === undefined) {
28-
keypressChordPart = null;
25+
const dispatchParts = resolvedKeybinding.getDispatchParts();
26+
// TODO@chords: add support for dispatching N chords here
27+
if (dispatchParts.length >= 2) {
28+
this.keypressFirstPart = dispatchParts[0];
29+
this.keypressChordPart = dispatchParts[1];
30+
} else if (dispatchParts.length === 1) {
31+
this.keypressFirstPart = dispatchParts[0];
32+
this.keypressChordPart = null;
33+
} else {
34+
this.keypressFirstPart = null;
35+
this.keypressChordPart = null;
2936
}
30-
this.keypressChordPart = keypressChordPart;
3137
} else {
3238
this.keypressFirstPart = null;
3339
this.keypressChordPart = null;

src/vs/platform/keybinding/common/usLayoutResolvedKeybinding.ts

Lines changed: 7 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,7 @@ export class USLayoutResolvedKeybinding extends ResolvedKeybinding {
5252
}
5353

5454
public getLabel(): string | null {
55-
let partKeys: string[] = [];
56-
for (let part of this._parts) {
57-
let key = this._getUILabelForKeybinding(part);
58-
if (key === null) {
59-
return null;
60-
}
61-
partKeys.push(key);
62-
}
63-
return UILabelProvider.toLabel(this._parts, partKeys, this._os);
55+
return UILabelProvider.toLabel(this._os, this._parts, (keybinding) => this._getUILabelForKeybinding(keybinding));
6456
}
6557

6658
private _getAriaLabelForKeybinding(keybinding: SimpleKeybinding | null): string | null {
@@ -74,15 +66,7 @@ export class USLayoutResolvedKeybinding extends ResolvedKeybinding {
7466
}
7567

7668
public getAriaLabel(): string | null {
77-
let partKeys: string[] = [];
78-
for (let part of this._parts) {
79-
let key = this._getAriaLabelForKeybinding(part);
80-
if (key === null) {
81-
return null;
82-
}
83-
partKeys.push(key);
84-
}
85-
return AriaLabelProvider.toLabel(this._parts, partKeys, this._os);
69+
return AriaLabelProvider.toLabel(this._os, this._parts, (keybinding) => this._getAriaLabelForKeybinding(keybinding));
8670
}
8771

8872
private _keyCodeToElectronAccelerator(keyCode: KeyCode): string | null {
@@ -121,11 +105,7 @@ export class USLayoutResolvedKeybinding extends ResolvedKeybinding {
121105
return null;
122106
}
123107

124-
let firstPart = this._getElectronAcceleratorLabelForKeybinding(this._parts[0]);
125-
if (firstPart === null) {
126-
return null;
127-
}
128-
return ElectronAcceleratorLabelProvider.toLabel(this._parts, [firstPart], this._os);
108+
return ElectronAcceleratorLabelProvider.toLabel(this._os, this._parts, (keybinding) => this._getElectronAcceleratorLabelForKeybinding(keybinding));
129109
}
130110

131111
private _getUserSettingsLabelForKeybinding(keybinding: SimpleKeybinding | null): string | null {
@@ -139,15 +119,7 @@ export class USLayoutResolvedKeybinding extends ResolvedKeybinding {
139119
}
140120

141121
public getUserSettingsLabel(): string | null {
142-
let partKeys: string[] = [];
143-
for (let part of this._parts) {
144-
let key = this._getUserSettingsLabelForKeybinding(part);
145-
if (key === null) {
146-
return null;
147-
}
148-
partKeys.push(key);
149-
}
150-
let result = UserSettingsLabelProvider.toLabel(this._parts, partKeys, this._os);
122+
const result = UserSettingsLabelProvider.toLabel(this._os, this._parts, (keybinding) => this._getUserSettingsLabelForKeybinding(keybinding));
151123
return (result ? result.toLowerCase() : result);
152124
}
153125

@@ -156,11 +128,11 @@ export class USLayoutResolvedKeybinding extends ResolvedKeybinding {
156128
}
157129

158130
public isChord(): boolean {
159-
return this._parts.length > 1;
131+
return (this._parts.length > 1);
160132
}
161133

162134
public getParts(): ResolvedKeybindingPart[] {
163-
return this._parts.map(this._toResolvedKeybindingPart, this);
135+
return this._parts.map((keybinding) => this._toResolvedKeybindingPart(keybinding));
164136
}
165137

166138
private _toResolvedKeybindingPart(keybinding: SimpleKeybinding): ResolvedKeybindingPart {
@@ -175,7 +147,7 @@ export class USLayoutResolvedKeybinding extends ResolvedKeybinding {
175147
}
176148

177149
public getDispatchParts(): (string | null)[] {
178-
return this._parts.map((chord) => USLayoutResolvedKeybinding.getDispatchStr(chord));
150+
return this._parts.map((keybinding) => USLayoutResolvedKeybinding.getDispatchStr(keybinding));
179151
}
180152

181153
public static getDispatchStr(keybinding: SimpleKeybinding): string | null {

src/vs/workbench/services/keybinding/common/macLinuxFallbackKeyboardMapper.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -120,14 +120,15 @@ export class MacLinuxFallbackKeyboardMapper implements IKeyboardMapper {
120120
public resolveUserBinding(firstPart: SimpleKeybinding | ScanCodeBinding | null, chordPart: SimpleKeybinding | ScanCodeBinding | null): ResolvedKeybinding[] {
121121
const _firstPart = this._resolveSimpleUserBinding(firstPart);
122122
const _chordPart = this._resolveSimpleUserBinding(chordPart);
123+
let parts: SimpleKeybinding[] = [];
123124
if (_firstPart) {
124-
let parts = [_firstPart];
125-
if (_chordPart) {
126-
parts.push(_chordPart);
127-
}
128-
return [new USLayoutResolvedKeybinding(
129-
new ChordKeybinding(parts), this._OS
130-
)];
125+
parts.push(_firstPart);
126+
}
127+
if (_chordPart) {
128+
parts.push(_chordPart);
129+
}
130+
if (parts.length > 0) {
131+
return [new USLayoutResolvedKeybinding(new ChordKeybinding(parts), this._OS)];
131132
}
132133
return [];
133134
}

0 commit comments

Comments
 (0)