Skip to content

Commit

Permalink
Support Ctrl+Enter to run scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
WardBrian committed Jul 30, 2024
1 parent f0c7de1 commit 9fe0e40
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 16 deletions.
36 changes: 22 additions & 14 deletions gui/src/app/FileEditor/TextEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Editor, loader, useMonaco } from "@monaco-editor/react";
import monacoAddStanLang from "@SpComponents/stanLang";
import { ToolBar, ToolbarItem } from "@SpComponents/ToolBar";
import { CodeMarker } from "@SpStanc/Linting";
import { editor, MarkerSeverity } from "monaco-editor";
import { editor, KeyCode, KeyMod, MarkerSeverity } from "monaco-editor";
import {
FunctionComponent,
useCallback,
Expand All @@ -27,6 +27,7 @@ type Props = {
label: string;
codeMarkers?: CodeMarker[];
contentOnEmpty?: string | HTMLSpanElement;
actions?: editor.IActionDescriptor[];
};

const TextEditor: FunctionComponent<Props> = ({
Expand All @@ -40,6 +41,7 @@ const TextEditor: FunctionComponent<Props> = ({
label,
codeMarkers,
contentOnEmpty,
actions,
}) => {
const handleChange = useCallback(
(value: string | undefined) => {
Expand Down Expand Up @@ -99,28 +101,34 @@ const TextEditor: FunctionComponent<Props> = ({
};
}, [text, editorInstance, editedText, contentOnEmpty]);

/////////////////////////////////////////////////

// Can't do this in the usual way with monaco editor:
// See: https://github.com/microsoft/monaco-editor/issues/2947
const handleKeyDown = useCallback(
(e: React.KeyboardEvent<HTMLDivElement>) => {
if ((e.ctrlKey || e.metaKey) && e.key === "s") {
e.preventDefault();
useEffect(() => {
if (!editorInstance) return;
editorInstance.addAction({
id: "save",
label: "Save",
keybindings: [KeyMod.CtrlCmd | KeyCode.KeyS],
run: () => {
if (!readOnly) {
onSaveText();
}
}
},
[onSaveText, readOnly],
);
},
});
}, [editorInstance, onSaveText, readOnly]);

useEffect(() => {
if (!editorInstance) return;
if (!actions) return;
for (const action of actions) {
editorInstance.addAction(action);
}
}, [actions, editorInstance]);

const edited = useMemo(() => {
return editedText !== text;
}, [editedText, text]);

return (
<div className="EditorWithToolbar" onKeyDown={handleKeyDown}>
<div className="EditorWithToolbar">
<ToolBar
items={toolbarItems || []}
label={label}
Expand Down
2 changes: 1 addition & 1 deletion gui/src/app/FileEditor/ToolBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export const ToolBar: FunctionComponent<ToolbarProps> = ({
type: "button",
icon: <Save />,
onClick: onSaveText,
tooltip: "Save file",
tooltip: "Save file (Ctrl-S)",
label: "Save",
});
editorItems.push({
Expand Down
18 changes: 17 additions & 1 deletion gui/src/app/Scripting/ScriptEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
} from "react";
import { InterpreterStatus } from "./InterpreterTypes";
import { Split } from "@geoffcox/react-splitter";
import { editor, KeyCode, KeyMod } from "monaco-editor";

const interpreterNames = { python: "pyodide", r: "webR" } as const;

Expand Down Expand Up @@ -72,6 +73,20 @@ const ScriptEditor: FunctionComponent<ScriptEditorProps> = ({
return content !== editedContent;
}, [content, editedContent]);

const runCtrlEnter: editor.IActionDescriptor = useMemo(
() => ({
id: "run-script",
label: "Run Script",
keybindings: [KeyMod.CtrlCmd | KeyCode.Enter],
run: () => {
if (runnable && !unsavedChanges) {
runCode();
}
},
}),
[runCode, runnable, unsavedChanges],
);

const toolbarItems: ToolbarItem[] = useMemo(() => {
return makeToolbar({
status,
Expand Down Expand Up @@ -102,6 +117,7 @@ const ScriptEditor: FunctionComponent<ScriptEditorProps> = ({
onSaveText={onSaveText}
toolbarItems={toolbarItems}
contentOnEmpty={contentOnEmpty}
actions={[runCtrlEnter]}
/>
<ConsoleOutputWindow consoleRef={consoleRef} />
</Split>
Expand Down Expand Up @@ -129,7 +145,7 @@ const makeToolbar = (o: {
if (runnable) {
ret.push({
type: "button",
tooltip: "Run code to generate data",
tooltip: "Run code (Ctrl-Enter)",
label: "Run",
icon: <PlayArrow />,
onClick: onRun,
Expand Down

0 comments on commit 9fe0e40

Please sign in to comment.