Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 31 additions & 2 deletions frontend/src/core/codemirror/keymaps/__tests__/keymaps.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
/* Copyright 2026 Marimo. All rights reserved. */

import { defaultKeymap as originalDefaultKeymap } from "@codemirror/commands";
import {
copyLineDown,
copyLineUp,
defaultKeymap as originalDefaultKeymap,
} from "@codemirror/commands";
import { describe, expect, it } from "vitest";
import { HotkeyProvider } from "@/core/hotkeys/hotkeys";
import {
HotkeyProvider,
OverridingHotkeyProvider,
} from "@/core/hotkeys/hotkeys";
import { visibleForTesting } from "../keymaps";

const { defaultKeymap, defaultVimKeymap, overrideKeymap, OVERRIDDEN_COMMANDS } =
Expand Down Expand Up @@ -40,4 +47,26 @@ describe("keymaps", () => {
expect(keys.some((k) => k.run === command)).toBe(true);
}
});

it.each([
["cell.copyLineUp", copyLineUp, "Alt-Shift-ArrowUp"],
["cell.copyLineDown", copyLineDown, "Alt-Shift-ArrowDown"],
] as const)(
"%s is bound to the configured hotkey, not CodeMirror's default",
(action, command, defaultKey) => {
// Without an override, the binding matches CodeMirror's default key.
expect(
overrideKeymap(HotkeyProvider.create()).find((k) => k.run === command)
?.key,
).toBe(defaultKey);

// With an override, the binding follows the user's configured key.
// This is what `editable: true` on these hotkeys promises.
expect(
overrideKeymap(
new OverridingHotkeyProvider({ [action]: "Ctrl-d" }),
).find((k) => k.run === command)?.key,
).toBe("Ctrl-d");
},
);
});
12 changes: 12 additions & 0 deletions frontend/src/core/codemirror/keymaps/keymaps.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
/* Copyright 2026 Marimo. All rights reserved. */

import {
copyLineDown,
copyLineUp,
cursorCharLeft,
cursorCharRight,
cursorLineDown,
Expand Down Expand Up @@ -94,6 +96,8 @@ export function keymapBundle(
const OVERRIDDEN_COMMANDS = new Set<Command | undefined>([
toggleComment,
toggleBlockComment,
copyLineUp,
copyLineDown,
]);

const defaultKeymap = once(() => {
Expand All @@ -111,6 +115,14 @@ const overrideKeymap = (keymap: HotkeyProvider): readonly KeyBinding[] => {
key: keymap.getHotkey("cell.toggleBlockComment").key,
run: toggleBlockComment,
},
{
key: keymap.getHotkey("cell.copyLineUp").key,
run: copyLineUp,
},
{
key: keymap.getHotkey("cell.copyLineDown").key,
run: copyLineDown,
},
];
};

Expand Down
2 changes: 0 additions & 2 deletions frontend/src/core/hotkeys/hotkeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,13 +256,11 @@ const DEFAULT_HOT_KEY = {
name: "Copy line(s) up",
group: "Editing",
key: "Alt-Shift-ArrowUp",
editable: false,
},
"cell.copyLineDown": {
name: "Copy line(s) down",
group: "Editing",
key: "Alt-Shift-ArrowDown",
editable: false,
},

// Markdown
Expand Down
Loading