Skip to content

Commit 7bdfa6a

Browse files
committed
Fix keybinding source/default matching for commands with multiple bindings and remove unused parameter from buildWhenVariableOptions
- sourceForBinding now matches by command, shortcut, and when clause instead of only command, preventing false 'Custom' labels on secondary default bindings - defaultBindingForBinding finds the exact matching default entry with cascading fallback (exact match > same when > same command) - buildWhenVariableOptions no longer accepts an unused _keybindings parameter; callers updated to pass no args with an empty useMemo dependency array
1 parent 2824030 commit 7bdfa6a

3 files changed

Lines changed: 32 additions & 35 deletions

File tree

apps/web/src/components/settings/KeybindingsSettings.logic.test.ts

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -124,24 +124,7 @@ describe("KeybindingsSettings.logic", () => {
124124
});
125125

126126
it("builds known when variable options from defaults without frontend labels", () => {
127-
const options = buildWhenVariableOptions([
128-
{
129-
command: "terminal.toggle",
130-
shortcut: {
131-
key: "j",
132-
modKey: true,
133-
metaKey: false,
134-
ctrlKey: false,
135-
altKey: false,
136-
shiftKey: false,
137-
},
138-
whenAst: {
139-
type: "and",
140-
left: { type: "identifier", name: "terminalOpen" },
141-
right: { type: "identifier", name: "customModeActive" },
142-
},
143-
},
144-
] satisfies ResolvedKeybindingsConfig);
127+
const options = buildWhenVariableOptions();
145128

146129
expect(options).toEqual(
147130
expect.arrayContaining(["terminalFocus", "terminalOpen", "modelPickerOpen", "true", "false"]),

apps/web/src/components/settings/KeybindingsSettings.logic.ts

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -91,22 +91,38 @@ function sourceForBinding(binding: ResolvedKeybindingRule): KeybindingSource {
9191
return "Project";
9292
}
9393

94-
const defaultBinding = DEFAULT_RESOLVED_KEYBINDINGS.find(
95-
(entry) => entry.command === binding.command,
94+
const bindingKey = shortcutToKeybindingInput(binding.shortcut);
95+
const bindingWhen = whenAstToExpression(binding.whenAst);
96+
97+
const isDefault = DEFAULT_RESOLVED_KEYBINDINGS.some(
98+
(entry) =>
99+
entry.command === binding.command &&
100+
shortcutToKeybindingInput(entry.shortcut) === bindingKey &&
101+
whenAstToExpression(entry.whenAst) === bindingWhen,
96102
);
97-
if (!defaultBinding) {
98-
return "Custom";
99-
}
100103

101-
return shortcutToKeybindingInput(defaultBinding.shortcut) ===
102-
shortcutToKeybindingInput(binding.shortcut) &&
103-
whenAstToExpression(defaultBinding.whenAst) === whenAstToExpression(binding.whenAst)
104-
? "Default"
105-
: "Custom";
104+
return isDefault ? "Default" : "Custom";
106105
}
107106

108-
function defaultBindingForCommand(command: KeybindingCommand): ResolvedKeybindingRule | undefined {
109-
return DEFAULT_RESOLVED_KEYBINDINGS.find((entry) => entry.command === command);
107+
function defaultBindingForBinding(
108+
binding: ResolvedKeybindingRule,
109+
): ResolvedKeybindingRule | undefined {
110+
const bindingKey = shortcutToKeybindingInput(binding.shortcut);
111+
const bindingWhen = whenAstToExpression(binding.whenAst);
112+
113+
return (
114+
DEFAULT_RESOLVED_KEYBINDINGS.find(
115+
(entry) =>
116+
entry.command === binding.command &&
117+
shortcutToKeybindingInput(entry.shortcut) === bindingKey &&
118+
whenAstToExpression(entry.whenAst) === bindingWhen,
119+
) ??
120+
DEFAULT_RESOLVED_KEYBINDINGS.find(
121+
(entry) =>
122+
entry.command === binding.command && whenAstToExpression(entry.whenAst) === bindingWhen,
123+
) ??
124+
DEFAULT_RESOLVED_KEYBINDINGS.find((entry) => entry.command === binding.command)
125+
);
110126
}
111127

112128
export function buildKeybindingRows(
@@ -115,7 +131,7 @@ export function buildKeybindingRows(
115131
): ReadonlyArray<KeybindingRow> {
116132
const normalizedQuery = query.trim().toLowerCase();
117133
const rows = keybindings.map((binding) => {
118-
const defaultBinding = defaultBindingForCommand(binding.command);
134+
const defaultBinding = defaultBindingForBinding(binding);
119135
const key = shortcutToKeybindingInput(binding.shortcut);
120136
const when = whenAstToExpression(binding.whenAst);
121137
return {
@@ -179,9 +195,7 @@ export function unknownWhenVariables(node: KeybindingWhenNode | undefined): Read
179195
return [...identifiers].filter((identifier) => !isKnownWhenVariable(identifier)).toSorted();
180196
}
181197

182-
export function buildWhenVariableOptions(
183-
_keybindings: ResolvedKeybindingsConfig,
184-
): ReadonlyArray<WhenVariableOption> {
198+
export function buildWhenVariableOptions(): ReadonlyArray<WhenVariableOption> {
185199
return [...KNOWN_WHEN_VARIABLES].toSorted((left, right) => {
186200
const leftCoreIndex = CORE_WHEN_VARIABLES.indexOf(left as (typeof CORE_WHEN_VARIABLES)[number]);
187201
const rightCoreIndex = CORE_WHEN_VARIABLES.indexOf(

apps/web/src/components/settings/KeybindingsSettings.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -852,7 +852,7 @@ export function KeybindingsSettingsPanel() {
852852
const searchInputRef = useRef<HTMLInputElement>(null);
853853
const [savingCommand, setSavingCommand] = useState<KeybindingCommand | null>(null);
854854
const rows = useMemo(() => buildKeybindingRows(keybindings, query), [keybindings, query]);
855-
const whenVariables = useMemo(() => buildWhenVariableOptions(keybindings), [keybindings]);
855+
const whenVariables = useMemo(() => buildWhenVariableOptions(), []);
856856

857857
useEffect(() => {
858858
const handleKeyDown = (event: globalThis.KeyboardEvent) => {

0 commit comments

Comments
 (0)