Skip to content

Commit 8b5368e

Browse files
committed
Fixes microsoft#141638: -command rules should only remove default rules
1 parent 048c70d commit 8b5368e

File tree

2 files changed

+21
-12
lines changed

2 files changed

+21
-12
lines changed

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

+7-12
Original file line numberDiff line numberDiff line change
@@ -87,15 +87,15 @@ export class KeybindingResolver {
8787
*/
8888
public static handleRemovals(rules: ResolvedKeybindingItem[]): ResolvedKeybindingItem[] {
8989
// Do a first pass and construct a hash-map for removals
90-
const removals = new Map<string, { maxIndex: number; rule: ResolvedKeybindingItem; }[]>();
90+
const removals = new Map<string, ResolvedKeybindingItem[]>();
9191
for (let i = 0, len = rules.length; i < len; i++) {
9292
const rule = rules[i];
9393
if (rule.command && rule.command.charAt(0) === '-') {
9494
const command = rule.command.substring(1);
9595
if (!removals.has(command)) {
96-
removals.set(command, [{ maxIndex: i, rule }]);
96+
removals.set(command, [rule]);
9797
} else {
98-
removals.get(command)!.push({ maxIndex: i, rule });
98+
removals.get(command)!.push(rule);
9999
}
100100
}
101101
}
@@ -118,21 +118,16 @@ export class KeybindingResolver {
118118
continue;
119119
}
120120
const commandRemovals = removals.get(rule.command);
121-
if (!commandRemovals) {
121+
if (!commandRemovals || !rule.isDefault) {
122122
result.push(rule);
123123
continue;
124124
}
125125
let isRemoved = false;
126126
for (const commandRemoval of commandRemovals) {
127-
if (i > commandRemoval.maxIndex) {
128-
// this command removal is above this rule, so it cannot influence it
129-
continue;
130-
}
131-
const removalRule = commandRemoval.rule;
132127
// TODO@chords
133-
const keypressFirstPart = removalRule.keypressParts[0];
134-
const keypressChordPart = removalRule.keypressParts[1];
135-
const when = removalRule.when;
128+
const keypressFirstPart = commandRemoval.keypressParts[0];
129+
const keypressChordPart = commandRemoval.keypressParts[1];
130+
const when = commandRemoval.when;
136131
if (this._isTargetedForRemoval(rule, keypressFirstPart, keypressChordPart, when)) {
137132
isRemoved = true;
138133
break;

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

+14
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,20 @@ suite('KeybindingResolver', () => {
221221
]);
222222
});
223223

224+
test('issue #141638: Keyboard Shortcuts: Change When Expression might actually remove keybinding in Insiders', () => {
225+
const defaults = [
226+
kbItem(KeyCode.KeyA, 'command1', null, undefined, true),
227+
];
228+
const overrides = [
229+
kbItem(KeyCode.KeyA, 'command1', null, ContextKeyExpr.equals('a', '1'), false),
230+
kbItem(KeyCode.KeyA, '-command1', null, undefined, false),
231+
];
232+
const actual = KeybindingResolver.handleRemovals([...defaults, ...overrides]);
233+
assert.deepStrictEqual(actual, [
234+
kbItem(KeyCode.KeyA, 'command1', null, ContextKeyExpr.equals('a', '1'), false)
235+
]);
236+
});
237+
224238
test('contextIsEntirelyIncluded', () => {
225239
const toContextKeyExpression = (expr: ContextKeyExpression | string | null) => {
226240
if (typeof expr === 'string' || !expr) {

0 commit comments

Comments
 (0)