Skip to content

Commit e0ba314

Browse files
committed
Tweaks for microsoft#68863
1 parent 0566e65 commit e0ba314

13 files changed

Lines changed: 58 additions & 59 deletions

File tree

src/vs/base/common/keybindingParser.ts

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -107,24 +107,17 @@ export class KeybindingParser {
107107
return [new SimpleKeybinding(mods.ctrl, mods.shift, mods.alt, mods.meta, keyCode), mods.remains];
108108
}
109109

110-
static parseUserBinding(input: string): Array<SimpleKeybinding | ScanCodeBinding> {
111-
// TODO@chords: allow users to define N chords
110+
static parseUserBinding(input: string): (SimpleKeybinding | ScanCodeBinding)[] {
112111
if (!input) {
113112
return [];
114113
}
115114

116-
let parts = [];
117-
let remains = input;
118-
while (remains.length > 0) {
119-
let [part, nextRemains] = this.parseSimpleUserBinding(remains);
115+
let parts: (SimpleKeybinding | ScanCodeBinding)[] = [];
116+
let part: SimpleKeybinding | ScanCodeBinding;
117+
118+
while (input.length > 0) {
119+
[part, input] = this.parseSimpleUserBinding(input);
120120
parts.push(part);
121-
// check equality to break out of a possible infinite loop.
122-
// if nothing was consumed it implies that an empty keybinding
123-
// was returned.
124-
if (remains === nextRemains) {
125-
break;
126-
}
127-
remains = nextRemains;
128121
}
129122
return parts;
130123
}

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export class KeybindingResolver {
4545
continue;
4646
}
4747

48+
// TODO@chords
4849
this._addKeyPress(k.keypressParts[0], k);
4950
}
5051
}
@@ -53,9 +54,11 @@ export class KeybindingResolver {
5354
if (defaultKb.command !== command) {
5455
return false;
5556
}
57+
// TODO@chords
5658
if (keypressFirstPart && defaultKb.keypressParts[0] !== keypressFirstPart) {
5759
return false;
5860
}
61+
// TODO@chords
5962
if (keypressChordPart && defaultKb.keypressParts[1] !== keypressChordPart) {
6063
return false;
6164
}
@@ -84,6 +87,7 @@ export class KeybindingResolver {
8487
}
8588

8689
const command = override.command.substr(1);
90+
// TODO@chords
8791
const keypressFirstPart = override.keypressParts[0];
8892
const keypressChordPart = override.keypressParts[1];
8993
const when = override.when;
@@ -117,6 +121,7 @@ export class KeybindingResolver {
117121
const conflictIsChord = (conflict.keypressParts.length > 1);
118122
const itemIsChord = (item.keypressParts.length > 1);
119123

124+
// TODO@chords
120125
if (conflictIsChord && itemIsChord && conflict.keypressParts[1] !== item.keypressParts[1]) {
121126
// The conflict only shares the chord start with this command
122127
continue;
@@ -247,6 +252,7 @@ export class KeybindingResolver {
247252
lookupMap = [];
248253
for (let i = 0, len = candidates.length; i < len; i++) {
249254
let candidate = candidates[i];
255+
// TODO@chords
250256
if (candidate.keypressParts[1] === keypress) {
251257
lookupMap.push(candidate);
252258
}
@@ -266,6 +272,7 @@ export class KeybindingResolver {
266272
return null;
267273
}
268274

275+
// TODO@chords
269276
if (currentChord === null && result.keypressParts.length > 1 && result.keypressParts[1] !== null) {
270277
return {
271278
enterChord: true,

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

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
1010
export class ResolvedKeybindingItem {
1111
_resolvedKeybindingItemBrand: void;
1212

13-
public readonly keypressParts: string[];
1413
public readonly resolvedKeybinding: ResolvedKeybinding | null;
14+
public readonly keypressParts: string[];
1515
public readonly bubble: boolean;
1616
public readonly command: string | null;
1717
public readonly commandArgs: any;
@@ -20,15 +20,24 @@ export class ResolvedKeybindingItem {
2020

2121
constructor(resolvedKeybinding: ResolvedKeybinding | null, command: string | null, commandArgs: any, when: ContextKeyExpr | null, isDefault: boolean) {
2222
this.resolvedKeybinding = resolvedKeybinding;
23-
if (resolvedKeybinding) {
24-
this.keypressParts = resolvedKeybinding.getDispatchParts();
25-
} else {
26-
this.keypressParts = [];
27-
}
23+
this.keypressParts = resolvedKeybinding ? removeElementsAfterNulls(resolvedKeybinding.getDispatchParts()) : [];
2824
this.bubble = (command ? command.charCodeAt(0) === CharCode.Caret : false);
2925
this.command = this.bubble ? command!.substr(1) : command;
3026
this.commandArgs = commandArgs;
3127
this.when = when;
3228
this.isDefault = isDefault;
3329
}
3430
}
31+
32+
export function removeElementsAfterNulls<T>(arr: (T | null)[]): T[] {
33+
let result: T[] = [];
34+
for (let i = 0, len = arr.length; i < len; i++) {
35+
const element = arr[i];
36+
if (!element) {
37+
// stop processing at first encountered null
38+
return result;
39+
}
40+
result.push(element);
41+
}
42+
return result;
43+
}

src/vs/workbench/contrib/preferences/browser/keybindingsEditorContribution.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,11 +272,12 @@ export class KeybindingEditorDecorationsRenderer extends Disposable {
272272
return false;
273273
}
274274

275-
for (let i = 0, length = aParts.length; i < length; i++) {
275+
for (let i = 0, len = aParts.length; i < len; i++) {
276276
if (!this._userBindingEquals(aParts[i], bParts[i])) {
277277
return false;
278278
}
279279
}
280+
280281
return true;
281282
}
282283

src/vs/workbench/contrib/preferences/test/browser/keybindingsEditorContribution.test.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ suite('KeybindingsEditorContribution', () => {
1111
function assertUserSettingsFuzzyEquals(a: string, b: string, expected: boolean): void {
1212
const actual = KeybindingEditorDecorationsRenderer._userSettingsFuzzyEquals(a, b);
1313
const message = expected ? `${a} == ${b}` : `${a} != ${b}`;
14-
console.log(a);
15-
console.log(b);
1614
assert.equal(actual, expected, 'fuzzy: ' + message);
1715
}
1816

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

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,21 @@
55

66
import { SimpleKeybinding } from 'vs/base/common/keyCodes';
77
import { KeybindingParser } from 'vs/base/common/keybindingParser';
8-
import { OperatingSystem } from 'vs/base/common/platform';
98
import { ScanCodeBinding } from 'vs/base/common/scanCode';
109
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
1110
import { IUserFriendlyKeybinding } from 'vs/platform/keybinding/common/keybinding';
1211
import { ResolvedKeybindingItem } from 'vs/platform/keybinding/common/resolvedKeybindingItem';
1312

1413
export interface IUserKeybindingItem {
15-
firstPart: SimpleKeybinding | ScanCodeBinding | null;
16-
chordPart: SimpleKeybinding | ScanCodeBinding | null;
14+
parts: (SimpleKeybinding | ScanCodeBinding)[];
1715
command: string | null;
1816
commandArgs?: any;
1917
when: ContextKeyExpr | null;
2018
}
2119

2220
export class KeybindingIO {
2321

24-
public static writeKeybindingItem(out: OutputBuilder, item: ResolvedKeybindingItem, OS: OperatingSystem): void {
22+
public static writeKeybindingItem(out: OutputBuilder, item: ResolvedKeybindingItem): void {
2523
if (!item.resolvedKeybinding) {
2624
return;
2725
}
@@ -41,15 +39,13 @@ export class KeybindingIO {
4139
out.write('}');
4240
}
4341

44-
public static readUserKeybindingItem(input: IUserFriendlyKeybinding, OS: OperatingSystem): IUserKeybindingItem {
45-
// TODO yusuke: replace with keychords.
46-
const [firstPart, chordPart] = (typeof input.key === 'string' ? KeybindingParser.parseUserBinding(input.key) : [null, null]);
42+
public static readUserKeybindingItem(input: IUserFriendlyKeybinding): IUserKeybindingItem {
43+
const parts = (typeof input.key === 'string' ? KeybindingParser.parseUserBinding(input.key) : []);
4744
const when = (typeof input.when === 'string' ? ContextKeyExpr.deserialize(input.when) : null);
4845
const command = (typeof input.command === 'string' ? input.command : null);
4946
const commandArgs = (typeof input.args !== 'undefined' ? input.args : undefined);
5047
return {
51-
firstPart: firstPart,
52-
chordPart: chordPart,
48+
parts: parts,
5349
command: command,
5450
commandArgs: commandArgs,
5551
when: when

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export interface IKeyboardMapper {
1111
dumpDebugInfo(): string;
1212
resolveKeybinding(keybinding: Keybinding): ResolvedKeybinding[];
1313
resolveKeyboardEvent(keyboardEvent: IKeyboardEvent): ResolvedKeybinding;
14-
resolveUserBinding(firstPart: Array<SimpleKeybinding | ScanCodeBinding>): ResolvedKeybinding[];
14+
resolveUserBinding(firstPart: (SimpleKeybinding | ScanCodeBinding)[]): ResolvedKeybinding[];
1515
}
1616

1717
export class CachedKeyboardMapper implements IKeyboardMapper {
@@ -43,7 +43,7 @@ export class CachedKeyboardMapper implements IKeyboardMapper {
4343
return this._actual.resolveKeyboardEvent(keyboardEvent);
4444
}
4545

46-
public resolveUserBinding(parts: Array<SimpleKeybinding | ScanCodeBinding>): ResolvedKeybinding[] {
46+
public resolveUserBinding(parts: (SimpleKeybinding | ScanCodeBinding)[]): ResolvedKeybinding[] {
4747
return this._actual.resolveUserBinding(parts);
4848
}
4949
}

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { IMMUTABLE_CODE_TO_KEY_CODE, ScanCode, ScanCodeBinding } from 'vs/base/c
99
import { IKeyboardEvent } from 'vs/platform/keybinding/common/keybinding';
1010
import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/usLayoutResolvedKeybinding';
1111
import { IKeyboardMapper } from 'vs/workbench/services/keybinding/common/keyboardMapper';
12+
import { removeElementsAfterNulls } from 'vs/platform/keybinding/common/resolvedKeybindingItem';
1213

1314
/**
1415
* A keyboard mapper to be used when reading the keymap from the OS fails.
@@ -117,8 +118,8 @@ export class MacLinuxFallbackKeyboardMapper implements IKeyboardMapper {
117118
return new SimpleKeybinding(binding.ctrlKey, binding.shiftKey, binding.altKey, binding.metaKey, keyCode);
118119
}
119120

120-
public resolveUserBinding(input: Array<SimpleKeybinding | ScanCodeBinding>): ResolvedKeybinding[] {
121-
let parts: SimpleKeybinding[] = input.map(this._resolveSimpleUserBinding.bind(this));
121+
public resolveUserBinding(input: (SimpleKeybinding | ScanCodeBinding)[]): ResolvedKeybinding[] {
122+
const parts: SimpleKeybinding[] = removeElementsAfterNulls(input.map(keybinding => this._resolveSimpleUserBinding(keybinding)));
122123
if (parts.length > 0) {
123124
return [new USLayoutResolvedKeybinding(new ChordKeybinding(parts), this._OS)];
124125
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,8 +1053,8 @@ export class MacLinuxKeyboardMapper implements IKeyboardMapper {
10531053
return this.simpleKeybindingToScanCodeBinding(binding);
10541054
}
10551055

1056-
public resolveUserBinding(input: Array<SimpleKeybinding | ScanCodeBinding>): ResolvedKeybinding[] {
1057-
let parts: ScanCodeBinding[][] = input.map(this._resolveSimpleUserBinding.bind(this));
1056+
public resolveUserBinding(input: (SimpleKeybinding | ScanCodeBinding)[]): ResolvedKeybinding[] {
1057+
const parts: ScanCodeBinding[][] = input.map(keybinding => this._resolveSimpleUserBinding(keybinding));
10581058
let result: NativeResolvedKeybinding[] = [];
10591059
this._generateResolvedKeybindings(parts, 0, [], result);
10601060
return result;

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { IMMUTABLE_CODE_TO_KEY_CODE, ScanCode, ScanCodeBinding, ScanCodeUtils }
1111
import { IKeyboardEvent } from 'vs/platform/keybinding/common/keybinding';
1212
import { IKeyboardMapper } from 'vs/workbench/services/keybinding/common/keyboardMapper';
1313
import { BaseResolvedKeybinding } from 'vs/platform/keybinding/common/baseResolvedKeybinding';
14+
import { removeElementsAfterNulls } from 'vs/platform/keybinding/common/resolvedKeybindingItem';
1415

1516
export interface IWindowsKeyMapping {
1617
vkey: string;
@@ -464,8 +465,8 @@ export class WindowsKeyboardMapper implements IKeyboardMapper {
464465
return new SimpleKeybinding(binding.ctrlKey, binding.shiftKey, binding.altKey, binding.metaKey, keyCode);
465466
}
466467

467-
public resolveUserBinding(input: Array<SimpleKeybinding | ScanCodeBinding>): ResolvedKeybinding[] {
468-
let parts: SimpleKeybinding[] = input.map(this._resolveSimpleUserBinding.bind(this));
468+
public resolveUserBinding(input: (SimpleKeybinding | ScanCodeBinding)[]): ResolvedKeybinding[] {
469+
const parts: SimpleKeybinding[] = removeElementsAfterNulls(input.map(keybinding => this._resolveSimpleUserBinding(keybinding)));
469470
if (parts.length > 0) {
470471
return [new WindowsNativeResolvedKeybinding(this, parts)];
471472
}

0 commit comments

Comments
 (0)