authorgravatar for technocratix902@gmail.comKriday Dave <technocratix902@gmail.com> 2026-07-18 01:17:35+05:30
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-07-17 21:47:35+02:00
log7dc75127c2320a64d8148ad7a09fd30db892d4af
treee12d808d7242bed97ece33e75ac2f49a21710414
parente057e2e98583c53946c64e401441777664840987
signature Signed by PGP key B5690EEEBB952194

Fix duplicate keybinding rule when replacing with an existing rule (#3969)

Co-authored-by: Julius Marminge <julius0216@outlook.com>

2 files changed, 25 insertions(+), 1 deletions(-)

apps/server/src/keybindings.test.ts+22
......@@ -411,6 +411,28 @@ it.layer(NodeServices.layer)("keybindings", (it) => {
411411 }).pipe(Effect.provide(makeKeybindingsLayer())),
412412 );
413413
414 it.effect("replacing with a rule that already exists elsewhere does not duplicate it", () =>
415 Effect.gen(function* () {
416 const { keybindingsConfigPath } = yield* ServerConfig.ServerConfig;
417 yield* writeKeybindingsConfig(keybindingsConfigPath, [
418 { key: "mod+r", command: "script.run-tests.run" },
419 { key: "mod+alt+r", command: "script.run-tests.run" },
420 ]);
421 yield* Effect.gen(function* () {
422 const keybindings = yield* Keybindings.Keybindings;
423 return yield* keybindings.upsertKeybindingRule({
424 key: "mod+alt+r",
425 command: "script.run-tests.run",
426 replace: { key: "mod+r", command: "script.run-tests.run" },
427 });
428 });
429
430 const persisted = yield* readKeybindingsConfig(keybindingsConfigPath);
431 const persistedView = persisted.map(({ key, command }) => ({ key, command }));
432 assert.deepEqual(persistedView, [{ key: "mod+alt+r", command: "script.run-tests.run" }]);
433 }).pipe(Effect.provide(makeKeybindingsLayer())),
434 );
435
414436 it.effect("removes only the targeted custom keybinding", () =>
415437 Effect.gen(function* () {
416438 const { keybindingsConfigPath } = yield* ServerConfig.ServerConfig;
apps/server/src/keybindings.ts+3-1
......@@ -644,7 +644,9 @@ const make = Effect.gen(function* () {
644644 const nextConfig = [
645645 ...customConfig.filter((entry) => {
646646 if (replaceTarget) {
647 return !isSameKeybindingRule(entry, replaceTarget);
647 return (
648 !isSameKeybindingRule(entry, replaceTarget) && !isSameKeybindingRule(entry, rule)
649 );
648650 }
649651 return !isSameKeybindingRule(entry, rule);
650652 }),