diff --git a/src/vs/workbench/services/preferences/browser/keybindingsEditorModel.ts b/src/vs/workbench/services/preferences/browser/keybindingsEditorModel.ts index 7893ac5b595f0..95e12f6ba5ebc 100644 --- a/src/vs/workbench/services/preferences/browser/keybindingsEditorModel.ts +++ b/src/vs/workbench/services/preferences/browser/keybindingsEditorModel.ts @@ -19,6 +19,7 @@ import { ResolvedKeybindingItem } from 'vs/platform/keybinding/common/resolvedKe import { getAllUnboundCommands } from 'vs/workbench/services/keybinding/browser/unboundCommands'; import { IKeybindingItemEntry, KeybindingMatches, KeybindingMatch, IKeybindingItem } from 'vs/workbench/services/preferences/common/preferences'; import { ICommandAction, ILocalizedString } from 'vs/platform/action/common/action'; +import { isEmptyObject } from 'vs/base/common/types'; export const KEYBINDING_ENTRY_TEMPLATE_ID = 'keybinding.entry.template'; @@ -348,8 +349,13 @@ class KeybindingItemMatches { if (matchedWords.length !== words.length) { return null; } - if (completeMatch && (!this.isCompleteMatch(firstPart, firstPartMatch) || !this.isCompleteMatch(chordPart, chordPartMatch))) { - return null; + if (completeMatch) { + if (!this.isCompleteMatch(firstPart, firstPartMatch)) { + return null; + } + if (!isEmptyObject(chordPartMatch) && !this.isCompleteMatch(chordPart, chordPartMatch)) { + return null; + } } return this.hasAnyMatch(firstPartMatch) || this.hasAnyMatch(chordPartMatch) ? { firstPart: firstPartMatch, chordPart: chordPartMatch } : null; } diff --git a/src/vs/workbench/services/preferences/test/browser/keybindingsEditorModel.test.ts b/src/vs/workbench/services/preferences/test/browser/keybindingsEditorModel.test.ts index b998a95ae9a9e..c3a718fb8dc43 100644 --- a/src/vs/workbench/services/preferences/test/browser/keybindingsEditorModel.test.ts +++ b/src/vs/workbench/services/preferences/test/browser/keybindingsEditorModel.test.ts @@ -620,6 +620,18 @@ suite('KeybindingsEditorModel', () => { assert.deepStrictEqual(actual[0].keybindingMatches!.firstPart, { keyCode: true }); }); + test('filter exact matches also return chords', async () => { + const command = 'a' + uuid.generateUuid(); + const expected = aResolvedKeybindingItem({ command, firstChord: { keyCode: KeyCode.KeyK, modifiers: { ctrlKey: true } }, secondChord: { keyCode: KeyCode.KeyC, modifiers: { ctrlKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false }); + prepareKeybindingService(expected, aResolvedKeybindingItem({ command, firstChord: { keyCode: KeyCode.Escape, modifiers: { shiftKey: true, metaKey: true } }, secondChord: { keyCode: KeyCode.KeyC, modifiers: { ctrlKey: true } }, when: 'whenContext1 && whenContext2', isDefault: false })); + + await testObject.resolve(new Map()); + const actual = testObject.fetch('"control+k"').filter(element => element.keybindingItem.command === command); + assert.strictEqual(1, actual.length); + assert.deepStrictEqual(actual[0].keybindingMatches!.firstPart, { ctrlKey: true, keyCode: true }); + assert.deepStrictEqual(actual[0].keybindingMatches!.chordPart, {}); + }); + test('filter modifiers are not matched when not completely matched (prefix)', async () => { testObject = instantiationService.createInstance(KeybindingsEditorModel, OperatingSystem.Macintosh); const term = `alt.${uuid.generateUuid()}`;