in gui/frontend/src/components/ui/CodeEditor/CodeEditor.tsx [958:1283]
private prepareUse(): void {
const { language, allowedLanguages = [] } = this.props;
const editor = this.backend;
if (!editor) {
return;
}
const precondition = "editorTextFocus && !suggestWidgetVisible && !renameInputVisible && !inSnippetMode " +
"&& !quickFixWidgetVisible";
const mixedLanguage = language === "msg";
this.disposables.push(editor.addAction({
id: "executeCurrentAndAdvance",
label: mixedLanguage ? "Execute Block and Advance" : "Execute Script",
keybindings: [KeyMod.CtrlCmd | KeyCode.Enter],
contextMenuGroupId: "2_execution",
contextMenuOrder: 1,
precondition,
run: () => {
this.doExecuteContext({ advance: true });
},
}));
this.disposables.push(editor.addAction({
id: "executeCurrent",
label: mixedLanguage ? "Execute Block" : "Execute Script and Move Cursor",
keybindings: [KeyMod.Shift | KeyCode.Enter],
contextMenuGroupId: "2_execution",
contextMenuOrder: 2,
precondition,
run: () => { return this.doExecuteContext({}); },
}));
this.disposables.push(editor.addAction({
id: "executeCurrentStatement",
label: "Execute Current Statement",
keybindings: [KeyMod.Shift | KeyMod.CtrlCmd | KeyCode.Enter],
contextMenuGroupId: "2_execution",
contextMenuOrder: 3,
precondition,
run: () => { return this.doExecuteContext({ atCaret: true }); },
}));
this.disposables.push(editor.addAction({
id: "executeToText",
label: "Execute and Print as Text",
keybindings: [KeyMod.Alt | KeyCode.Enter],
contextMenuGroupId: "2_execution",
contextMenuOrder: 4,
precondition,
run: () => { return this.doExecuteContext({ atCaret: true, advance: true, asText: true }); },
}));
if (appParameters.embedded) {
this.disposables.push(editor.addAction({
id: "executeOnHost",
label: "Execute on all visible DB Notebooks",
keybindings: [KeyMod.Alt | KeyMod.CtrlCmd | KeyCode.Enter],
contextMenuGroupId: "2_execution",
contextMenuOrder: 5,
precondition,
run: () => {
const options = { atCaret: false, advance: true, asText: false };
this.executeCurrentContextOnHost(options);
this.doExecuteContext(options);
},
}));
// In embedded mode some key combinations don't work by default. So we add handlers for them here.
this.disposables.push(editor.addAction({
id: "paste",
label: "Paste",
keybindings: [KeyMod.CtrlCmd | KeyCode.KeyV],
run: () => {
editor.trigger("source", "editor.action.clipboardPasteAction", null);
},
}));
this.disposables.push(editor.addAction({
id: "copy",
label: "Copy",
keybindings: [KeyMod.CtrlCmd | KeyCode.KeyC],
precondition,
run: () => {
editor.trigger("source", "editor.action.clipboardCopyAction", null);
},
}));
this.disposables.push(editor.addAction({
id: "cut",
label: "Cut",
keybindings: [KeyMod.CtrlCmd | KeyCode.KeyX],
precondition,
run: () => {
editor.trigger("source", "editor.action.clipboardCutAction", null);
},
}));
}
if (mixedLanguage) {
if (allowedLanguages.includes("sql")) {
this.disposables.push(editor.addAction({
id: "switchToSQL",
label: "Switch Language of Current Block to SQL",
contextMenuGroupId: "3_language",
contextMenuOrder: 1,
precondition,
run: this.switchCurrentLanguage.bind(this, "sql", false),
}));
}
if (allowedLanguages.includes("typescript")) {
this.disposables.push(editor.addAction({
id: "switchToTypeScript",
label: "Switch Language of Current Block to TypeScript",
contextMenuGroupId: "3_language",
contextMenuOrder: 2,
precondition,
run: this.switchCurrentLanguage.bind(this, "typescript", false),
}));
}
if (allowedLanguages.includes("javascript")) {
this.disposables.push(editor.addAction({
id: "switchToJavaScript",
label: "Switch Language of Current Block to JavaScript",
contextMenuGroupId: "3_language",
contextMenuOrder: 3,
precondition,
run: this.switchCurrentLanguage.bind(this, "javascript", false),
}));
}
if (appParameters.embedded) {
this.disposables.push(editor.addAction({
id: "sendBlockUpdates",
label: "Update SQL in Original Source File",
keybindings: [KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KeyU],
contextMenuGroupId: "4_linked",
precondition,
run: () => { this.runContextCommand("sendBlockUpdates"); },
}));
}
// Special key handling for our blocks.
this.disposables.push(editor.addAction({
id: "deleteBackwards",
label: "Delete Backwards",
keybindings: [KeyCode.Backspace],
run: () => { this.handleBackspace(); },
precondition,
}));
this.disposables.push(editor.addAction({
id: "deleteForward",
label: "Delete Forward",
keybindings: [KeyCode.Delete],
run: () => { this.handleDelete(); },
precondition,
}));
this.disposables.push(editor.addAction({
id: "jumpToBlockStart",
label: "Move Cursor to the Start of the Current Statement Block",
keybindings: [KeyMod.WinCtrl | KeyMod.CtrlCmd | KeyCode.UpArrow],
contextMenuGroupId: "navigation",
precondition,
run: () => { this.jumpToBlockStart(); },
}));
this.disposables.push(editor.addAction({
id: "jumpToBlockEnd",
label: "Move Cursor to the End of the Current Statement Block",
keybindings: [KeyMod.WinCtrl | KeyMod.CtrlCmd | KeyCode.DownArrow],
contextMenuGroupId: "navigation",
precondition,
run: () => { this.jumpToBlockEnd(); },
}));
}
this.disposables.push(editor.addAction({
id: "selectAll",
label: "Select All",
contextMenuGroupId: "9_cutcopypaste",
keybindings: [KeyMod.CtrlCmd | KeyCode.KeyA],
run: () => {
this.handleSelectAll();
},
precondition,
}));
this.disposables.push(editor.addAction({
id: "saveAs",
label: "Save As ...",
contextMenuGroupId: "10_save",
keybindings: [KeyMod.Shift | KeyMod.CtrlCmd | KeyCode.KeyS],
run: () => {
void requisitions.execute("editorSaveNotebook", undefined);
},
precondition,
}));
this.disposables.push(editor.addAction({
id: "save",
label: "Save",
contextMenuGroupId: "10_save",
keybindings: [KeyMod.CtrlCmd | KeyCode.KeyS],
run: () => {
void requisitions.execute("editorSaveNotebook", "viaKeyboardShortcut");
},
precondition,
}));
this.disposables.push(editor.addAction({
id: "acceptSuggestion",
label: "Accept Selected Suggestion",
keybindings: [KeyMod.CtrlCmd | KeyCode.Enter],
precondition: "suggestWidgetVisible",
run: () => {
editor.trigger("source", "acceptSelectedSuggestion", null);
},
}));
this.disposables.push(editor.addAction({
id: "removeAllResults",
label: "Remove All Results",
contextMenuGroupId: "3_results",
contextMenuOrder: 1,
precondition,
run: () => { void this.removeAllResults(); },
}));
this.disposables.push(editor.addAction({
id: "useNotebookAsTemplate",
label: "Use Notebook as Template",
contextMenuGroupId: "9_cutcopypaste",
contextMenuOrder: 5,
precondition,
run: () => { this.useNotebookAsTemplate(); },
}));
this.disposables.push(editor.addAction({
id: "appendFromTemplate",
label: "Append Codeblock from Template",
keybindings: [KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KeyP],
contextMenuGroupId: "9_cutcopypaste",
contextMenuOrder: 6,
precondition,
run: () => { this.appendFromTemplate(); },
}));
this.disposables.push(editor.addAction({
id: "focusExecutionBlockResultAbove",
label: "Focus Execution Block Result Above",
keybindings: [KeyMod.Alt | KeyCode.UpArrow],
run: () => { this.focusExecutionContextResult(true); },
precondition,
}));
this.disposables.push(editor.addAction({
id: "focusExecutionBlockResultBelow",
label: "Focus Execution Block Result Above",
keybindings: [KeyMod.Alt | KeyCode.DownArrow],
run: () => { this.focusExecutionContextResult(false); },
precondition,
}));
this.disposables.push(editor);
this.disposables.push(editor.onDidChangeCursorPosition((e: Monaco.ICursorPositionChangedEvent) => {
if (language === "msg") {
const model = this.model;
if (model && model.executionContexts) {
model.executionContexts.cursorPosition = e.position;
}
}
void requisitions.execute("editorCaretMoved", e.position);
}));
this.disposables.push(editor.onDidChangeModelContent(this.handleModelChange));
this.disposables.push(editor.onDidPaste(this.handlePaste));
this.disposables.push(editor.onDidScrollChange((e) => {
if (e.scrollTopChanged) {
this.scrolling = true;
if (this.scrollingTimer) {
clearTimeout(this.scrollingTimer);
}
this.scrollingTimer = setTimeout(() => {
this.scrolling = false;
if (this.scrollingTimer) {
clearTimeout(this.scrollingTimer);
}
this.scrollingTimer = null;
}, 500);
}
if (e.scrollLeftChanged) {
const viewZones = editor.getDomNode()?.getElementsByClassName("view-zones");
if (viewZones && viewZones.length > 0) {
(viewZones[0] as HTMLElement).style.left = `${e.scrollLeft}px`;
}
}
if (e.scrollWidthChanged) {
// Need to delay view zone resizing, as the content width is not yet updated at this point.
setTimeout(() => {
this.resizeViewZones();
}, 0);
}
}));
this.disposables.push(editor.onDidChangeModelOptions(() => {
const { onOptionsChanged } = this.props;
onOptionsChanged?.();
}));
requisitions.register("settingsChanged", this.handleSettingsChanged);
requisitions.register("editorExecuteSelectedOrAll", this.executeSelectedOrAll);
requisitions.register("editorExecute", this.executeContext);
requisitions.register("editorFind", this.executeFind);
requisitions.register("editorFormat", this.executeFormat);
requisitions.register("editorSelectStatement", this.handleSelectStatement);
}