Skip to content

Commit 7d8b562

Browse files
committed
Fix shortcuts in editor
1 parent fc5c7ff commit 7d8b562

File tree

6 files changed

+60
-6
lines changed

6 files changed

+60
-6
lines changed

src/components/Menu/MenuBar.tsx

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ import ListItem from "@mui/joy/ListItem";
44
import { useCallback, useEffect, useRef, useState } from "react";
55
import MenuBarButton from "./MenuBarButton";
66
import MenuGroup from "./MenuGroup";
7-
import { Shortcut, acceleratorPresssed } from "../../utilities/Shortcut";
7+
import {
8+
Shortcut,
9+
acceleratorPresssed,
10+
acceleratorPresssedMonaco,
11+
} from "../../utilities/Shortcut";
812
import CommandButton from "../CommandButton";
913
import {
1014
Construction,
@@ -18,11 +22,13 @@ import { DeviceInfo, useIDE } from "../../utilities/IDEContext";
1822
import { useStore } from "../../utilities/StoreContext";
1923
import { useToast } from "react-toast-plus";
2024
import bar from "./MenuBarDefinition";
25+
import { IStandaloneCodeEditor } from "@codingame/monaco-vscode-api/vscode/vs/editor/standalone/browser/standaloneCodeEditor";
2126

2227
export interface MenuBarProps {
2328
callbacks: Record<string, () => void>;
29+
editor: IStandaloneCodeEditor | null;
2430
}
25-
export default function MenuBar({ callbacks }: MenuBarProps) {
31+
export default function MenuBar({ callbacks, editor }: MenuBarProps) {
2632
const menus = useRef<Array<HTMLButtonElement>>([]);
2733
const [menuIndex, setMenuIndex] = useState<null | number>(null);
2834

@@ -36,7 +42,11 @@ export default function MenuBar({ callbacks }: MenuBarProps) {
3642
const { addToast } = useToast();
3743

3844
useEffect(() => {
39-
const items: { shortcut: Shortcut; callback: () => void }[] = [];
45+
const items: {
46+
shortcut: Shortcut;
47+
callback: () => void;
48+
ignoreShortcutInMonaco: boolean;
49+
}[] = [];
4050

4151
for (const menu of bar) {
4252
for (const group of menu.items) {
@@ -64,7 +74,6 @@ export default function MenuBar({ callbacks }: MenuBarProps) {
6474
const element = document.getElementById(
6575
item.componentId as string
6676
);
67-
console.log(element);
6877
if (element) {
6978
(element as HTMLButtonElement).click();
7079
}
@@ -75,6 +84,7 @@ export default function MenuBar({ callbacks }: MenuBarProps) {
7584
items.push({
7685
shortcut,
7786
callback,
87+
ignoreShortcutInMonaco: item.ignoreShortcutInMonaco ?? false,
7888
});
7989
}
8090
}
@@ -94,10 +104,23 @@ export default function MenuBar({ callbacks }: MenuBarProps) {
94104

95105
document.addEventListener("keydown", handleGlobalKeyDown);
96106

107+
const monacoItems = items.filter((item) => !item.ignoreShortcutInMonaco);
108+
let dispose = editor?.onKeyDown((event) => {
109+
if (!acceleratorPresssedMonaco(event)) return;
110+
111+
for (const item of monacoItems) {
112+
if (item.shortcut.pressedMonaco(event)) {
113+
event.preventDefault();
114+
item.callback();
115+
}
116+
}
117+
});
118+
97119
return () => {
98120
document.removeEventListener("keydown", handleGlobalKeyDown);
121+
dispose?.dispose();
99122
};
100-
}, [bar, callbacks]);
123+
}, [bar, callbacks, editor]);
101124

102125
const openNextMenu = () => {
103126
if (typeof menuIndex === "number") {

src/components/Menu/MenuBarDefinition.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,15 @@ export default [
7272
{
7373
name: "Undo",
7474
shortcut: "Ctrl+Z",
75+
ignoreShortcutInMonaco: true,
7576
callback: () => {
7677
alert("Not implemented yet :(");
7778
},
7879
},
7980
{
8081
name: "Redo",
8182
shortcut: "Ctrl+Shift+Z",
83+
ignoreShortcutInMonaco: true,
8284
callback: () => {
8385
alert("Not implemented yet :(");
8486
},

src/components/Menu/MenuGroup.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { DeviceInfo } from "../../utilities/IDEContext";
66
type BaseMenuItem = {
77
name: string;
88
shortcut?: string;
9+
ignoreShortcutInMonaco?: boolean;
910
};
1011

1112
export type MenuItem = BaseMenuItem &

src/components/Tiles/Editor.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ export interface EditorProps {
5050
focusedFile: string | null;
5151
setSaveFile: (save: () => void) => void;
5252
openNewFile: (file: string) => void;
53+
setEditorUpper: Dispatch<
54+
SetStateAction<monaco.editor.IStandaloneCodeEditor | null>
55+
>;
5356
}
5457

5558
export default ({
@@ -58,6 +61,7 @@ export default ({
5861
setSaveFile,
5962
setOpenFiles,
6063
openNewFile,
64+
setEditorUpper,
6165
}: EditorProps) => {
6266
const [tabs, setTabs] = useState<
6367
{
@@ -90,6 +94,7 @@ export default ({
9094

9195
useEffect(() => {
9296
editorRef.current = editor;
97+
setEditorUpper(editor);
9398
}, [editor]);
9499

95100
useEffect(() => {

src/pages/IDE.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import SwiftMenu from "../components/SwiftMenu";
2424
import { restartServer } from "../utilities/lsp-client";
2525
import BottomBar from "../components/Tiles/BottomBar";
2626
import { open as openFileDialog } from "@tauri-apps/plugin-dialog";
27+
import { IStandaloneCodeEditor } from "@codingame/monaco-vscode-api/vscode/vs/editor/standalone/browser/standaloneCodeEditor";
2728

2829
export interface IDEProps {}
2930

@@ -60,6 +61,7 @@ export default () => {
6061
const navigate = useNavigate();
6162
const [projectValidation, setProjectValidation] =
6263
useState<ProjectValidation | null>(null);
64+
const [editor, setEditor] = useState<IStandaloneCodeEditor | null>(null);
6365

6466
useEffect(() => {
6567
if (
@@ -163,7 +165,7 @@ export default () => {
163165

164166
return (
165167
<div className="ide-container">
166-
<MenuBar callbacks={callbacks} />
168+
<MenuBar callbacks={callbacks} editor={editor} />
167169
<Splitter
168170
gutterTheme={theme === "dark" ? GutterTheme.Dark : GutterTheme.Light}
169171
direction={SplitDirection.Horizontal}
@@ -183,6 +185,7 @@ export default () => {
183185
setSaveFile={setSaveFile}
184186
setOpenFiles={setOpenFiles}
185187
openNewFile={openNewFile}
188+
setEditorUpper={setEditor}
186189
/>
187190
<BottomBar />
188191
</Splitter>

src/utilities/Shortcut.tsx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1+
import { IKeyboardEvent, KeyCode } from "monaco-editor";
2+
13
export type Accelerator = "ctrl" | "alt" | "shift" | "super";
24

35
export class Shortcut {
46
accelerators: Accelerator[];
57
key: string;
8+
monacoKey: KeyCode;
69

710
ctrl = false;
811
alt = false;
@@ -18,6 +21,9 @@ export class Shortcut {
1821
if (acc === "super") this.super = true;
1922
}
2023
this.key = key;
24+
this.monacoKey =
25+
KeyCode[`Key${key.toUpperCase()}` as keyof typeof KeyCode] ||
26+
KeyCode[key.toUpperCase() as keyof typeof KeyCode];
2127
}
2228

2329
static fromString(shortcut: string): Shortcut {
@@ -42,8 +48,22 @@ export class Shortcut {
4248
event.key.toLowerCase() === this.key
4349
);
4450
}
51+
52+
pressedMonaco(event: IKeyboardEvent): boolean {
53+
return (
54+
this.ctrl === event.ctrlKey &&
55+
this.alt === event.altKey &&
56+
this.shift === event.shiftKey &&
57+
this.super === event.metaKey &&
58+
event.keyCode === this.monacoKey
59+
);
60+
}
4561
}
4662

4763
export function acceleratorPresssed(event: KeyboardEvent): boolean {
4864
return event.ctrlKey || event.altKey || event.shiftKey || event.metaKey;
4965
}
66+
67+
export function acceleratorPresssedMonaco(event: IKeyboardEvent): boolean {
68+
return event.ctrlKey || event.altKey || event.shiftKey || event.metaKey;
69+
}

0 commit comments

Comments
 (0)