Skip to content

Commit

Permalink
fix: Vim keybindings taking precedence over text area keybindings (#3220
Browse files Browse the repository at this point in the history
)

Fixes #3200
  • Loading branch information
mscolnick authored Dec 18, 2024
1 parent 9cb69b5 commit d8563ff
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 11 deletions.
11 changes: 9 additions & 2 deletions frontend/src/components/editor/Cell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import { getCurrentLanguageAdapter } from "@/core/codemirror/language/commands";
import { HideCodeButton } from "./code/readonly-python-code";
import { useResizeObserver } from "@/hooks/useResizeObserver";
import type { LanguageAdapterType } from "@/core/codemirror/language/types";
import { Events } from "@/utils/events";

/**
* Imperative interface of the cell.
Expand Down Expand Up @@ -495,11 +496,17 @@ const CellComponent = (
// interfere with editing
...(userConfig.keymap.preset === "vim" && !isCellCodeShown
? {
j: () => {
j: (evt) => {
if (evt && Events.fromInput(evt)) {
return false;
}
moveToNextCell({ cellId, before: false, noCreate: true });
return true;
},
k: () => {
k: (evt) => {
if (evt && Events.fromInput(evt)) {
return false;
}
moveToNextCell({ cellId, before: true, noCreate: true });
return true;
},
Expand Down
8 changes: 5 additions & 3 deletions frontend/src/core/hotkeys/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@ export function useRegisteredActions() {
export function useSetRegisteredAction() {
const set = useSetAtom(registeredActionsAtom);
return {
registerAction: useEvent((shortcut: HotkeyAction, callback: () => void) => {
set((actions) => ({ ...actions, [shortcut]: callback }));
}),
registerAction: useEvent(
(shortcut: HotkeyAction, callback: (evt?: KeyboardEvent) => void) => {
set((actions) => ({ ...actions, [shortcut]: callback }));
},
),
unregisterAction: useEvent((shortcut: HotkeyAction) => {
set((actions) => {
const { [shortcut]: unused, ...rest } = actions;
Expand Down
14 changes: 8 additions & 6 deletions frontend/src/hooks/useHotkey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ import { Functions } from "@/utils/functions";
import { hotkeysAtom } from "@/core/config/config";
import { useAtomValue } from "jotai";

// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
type HotkeyHandler = () => boolean | void | undefined | Promise<void>;
type HotkeyHandler = (
evt?: KeyboardEvent,
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
) => boolean | void | undefined | Promise<void>;

/**
* Registers a hotkey listener for the given shortcut.
Expand All @@ -26,12 +28,12 @@ export function useHotkey(shortcut: HotkeyAction, callback: HotkeyHandler) {
const hotkeys = useAtomValue(hotkeysAtom);

const isNOOP = callback === Functions.NOOP;
const memoizeCallback = useEvent(() => callback());
const memoizeCallback = useEvent((evt?: KeyboardEvent) => callback(evt));

const listener = useEvent((e: KeyboardEvent) => {
const key = hotkeys.getHotkey(shortcut).key;
if (parseShortcut(key)(e)) {
const response = callback();
const response = callback(e);
// Prevent default if the callback does not return false
if (response !== false) {
e.preventDefault();
Expand Down Expand Up @@ -65,7 +67,7 @@ export function useHotkeysOnElement<T extends HotkeyAction>(
const key = hotkeys.getHotkey(shortcut).key;
if (parseShortcut(key)(e)) {
Logger.debug("Satisfied", key, e);
const response = callback();
const response = callback(e);
// Prevent default if the callback does not return false
if (response !== false) {
e.preventDefault();
Expand All @@ -87,7 +89,7 @@ export function useKeydownOnElement(
for (const [key, callback] of Objects.entries(handlers)) {
if (parseShortcut(key)(e)) {
Logger.debug("Satisfied", key, e);
const response = callback();
const response = callback(e);
// Prevent default if the callback does not return false
if (response !== false) {
e.preventDefault();
Expand Down
12 changes: 12 additions & 0 deletions frontend/src/utils/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,16 @@ export const Events = {
// Prevent focus moving to the button on click
e.preventDefault();
},

/**
* Returns true if the event is coming from a text input
*/
fromInput: (e: KeyboardEvent) => {
const target = e.target as HTMLElement;
return (
target.tagName === "INPUT" ||
target.tagName === "TEXTAREA" ||
target.tagName.startsWith("MARIMO")
);
},
};

0 comments on commit d8563ff

Please sign in to comment.