diff options
-rw-r--r-- | src/NeoRuntimeManager/index.js | 13 | ||||
-rw-r--r-- | src/SocketIO/index.js | 3 | ||||
-rw-r--r-- | src_frontend/ComponentLib/Button/EditorActionButton.svelte | 2 | ||||
-rw-r--r-- | src_frontend/Components/Editor/Editor.svelte | 306 | ||||
-rw-r--r-- | src_frontend/Components/Editor/Output.svelte | 28 | ||||
-rw-r--r-- | src_frontend/stores/IDEStore.js | 235 |
6 files changed, 306 insertions, 281 deletions
diff --git a/src/NeoRuntimeManager/index.js b/src/NeoRuntimeManager/index.js index 1a56b04..5989f61 100644 --- a/src/NeoRuntimeManager/index.js +++ b/src/NeoRuntimeManager/index.js @@ -235,6 +235,12 @@ function setVariable(name, value) { * */ function debugModeEmitState() { + eventEmitter.emit("debugger:state", { + mode: modeDebuggerId, + running: runtimeProcess.isRunning, + debugMode: modeDebuggerActive, + matrix: matrix + }); } /** @@ -261,8 +267,7 @@ function startDebugger(debuggerModeId) { } if (debugModeStateEmitIntervall == null) { - debugModeStateEmitIntervall = setInterval(() => { - }, 500); + debugModeStateEmitIntervall = setInterval(debugModeEmitState, 1000); } modeDebuggerActive = true; @@ -294,6 +299,10 @@ function stopDebugger() { modeDebuggerActive = false; eventEmitter.removeAllListeners("proc:start", modeDebuggerProcStartHandler); modeDebuggerProcStartHandler = null; + + clearInterval(debugModeStateEmitIntervall); + debugModeStateEmitIntervall = null; + ipc.sendCommand(IPC.COMMAND.SET_SEND_STRIP_BUF, false); return {success: true} } diff --git a/src/SocketIO/index.js b/src/SocketIO/index.js index ff8f378..675efc5 100644 --- a/src/SocketIO/index.js +++ b/src/SocketIO/index.js @@ -269,12 +269,14 @@ function createAuthorizedNamespace(io) { let onProcStop = (code) => socket.emit("editor:proc:exit", code); let onProcStdout = (stdout) => socket.volatile.emit("editor:proc:stdout", stdout); let onProcStderr = (stderr) => socket.volatile.emit("editor:proc:stderr", stderr); + let onDebuggerState = (state) => socket.volatile.emit("editor:debugger:state", state); let closeDebugger = () => { debuggerOpen = false; neoModules.neoRuntimeManager.event.removeListener("proc:start", onProcStart); neoModules.neoRuntimeManager.event.removeListener("proc:stop", onProcStop); neoModules.neoRuntimeManager.event.removeListener("proc:stdout", onProcStdout); neoModules.neoRuntimeManager.event.removeListener("proc:stderr", onProcStderr); + neoModules.neoRuntimeManager.event.removeListener("debugger:state", onDebuggerState); return neoModules.neoRuntimeManager.stopDebugger(); }; socket.on("editor:open", (modeId, fn) => { @@ -282,6 +284,7 @@ function createAuthorizedNamespace(io) { neoModules.neoRuntimeManager.event.on("proc:exit", onProcStop); neoModules.neoRuntimeManager.event.on("proc:stdout", onProcStdout); neoModules.neoRuntimeManager.event.on("proc:stderr", onProcStderr); + neoModules.neoRuntimeManager.event.on("debugger:state", onDebuggerState); let res = neoModules.neoRuntimeManager.startDebugger(modeId); if (!res.success) { fn(res); return; } logger.info(`Starting debugger for ${modeId}.`) diff --git a/src_frontend/ComponentLib/Button/EditorActionButton.svelte b/src_frontend/ComponentLib/Button/EditorActionButton.svelte index 148720c..2b3c61d 100644 --- a/src_frontend/ComponentLib/Button/EditorActionButton.svelte +++ b/src_frontend/ComponentLib/Button/EditorActionButton.svelte @@ -3,6 +3,7 @@ export let fullWidth = false; export let backgroundColor = "#444242"; export let color = "white"; + export let alt = null; export let loadingPromise = null; $: listen(loadingPromise); @@ -63,6 +64,7 @@ on:click class:fullWidth={fullWidth} class:iconButton={faIcon != false} + alt={alt} style="--bg-color: {backgroundColor}; --color: {color};"> diff --git a/src_frontend/Components/Editor/Editor.svelte b/src_frontend/Components/Editor/Editor.svelte index 36390ce..511eef7 100644 --- a/src_frontend/Components/Editor/Editor.svelte +++ b/src_frontend/Components/Editor/Editor.svelte @@ -1,17 +1,6 @@ -<script context="module"> - let debuggerInitialised = false; -</script> <script> import { onMount, onDestroy } from "svelte"; - import { get } from "svelte/store"; import { pop } from "svelte-spa-router"; - import { EditorState, basicSetup } from "@codemirror/basic-setup" - import { EditorView, keymap } from "@codemirror/view" - import { indentWithTab } from "@codemirror/commands" - import { indentUnit } from '@codemirror/language' - import { python } from "@codemirror/lang-python" - import { HighlightStyle, tags as t } from "@codemirror/highlight" - import { notif } from "../../stores/notifs"; import EditorActionButton from "../../ComponentLib/Button/EditorActionButton.svelte"; import TopBar from "./TopBar.svelte"; import Pane from "./Pane.svelte"; @@ -21,257 +10,57 @@ import { authorizedSocket, authorizedSocketNeeded, openSocketConnected } from "../../stores/socketStore"; authorizedSocketNeeded.set(true); + import { attachCodeEditorView, initDebugger, closeDebugger, procIsRunning, codeEditorHasChanges, saveCode, notifErr } from "../../stores/IDEStore"; export let modeId; - let codeEditorView; let codeEditorEl; - let codeEditorHasChanges = false; - let procIsRunning = false; - let failCount = 0; - let reconnecting = false; - - function initDebugger() { - if (debuggerInitialised) { return; } - addSocketListeners(); - debuggerInitialised = true; - console.log("emitting editor:open"); - authorizedSocket.emit("editor:open", `user/${modeId}`, (res) => { - handleError(res); - }); - } - - function addSocketListeners() { - authorizedSocket.on("editor:proc:start", onEditorProcStart); - authorizedSocket.on("editor:proc:exit", onEditorProcExit); - authorizedSocket.on("editor:debugger:state", onEditorDebuggerState); - authorizedSocket.on("editor:code", createCodeEditor); - console.log("Attempted to add listeners"); - } - - function removeSocketListeners() { - authorizedSocket.off("editor:proc:start", onEditorProcStart); - authorizedSocket.off("editor:proc:exit", onEditorProcExit); - authorizedSocket.off("editor:debugger:state", onEditorDebuggerState); - authorizedSocket.off("editor:code", createCodeEditor); - //authorizedSocket.removeAllListeners("editor:proc:start"); - //authorizedSocket.removeAllListeners("editor:proc:exit"); - //authorizedSocket.removeAllListeners("editor:debugger:state"); - //authorizedSocket.removeAllListeners("editor:code"); - console.log("Listeners attempted removed"); - } - - function closeDebugger() { - saveCode((res) => { - handleError(res); - console.log("emitting editor:close"); - authorizedSocket.emit("editor:close", res => { - handleError(res); - debuggerInitialised = false; - }); - }); - } - - function onEditorProcStart() { - console.log("received editor:proc:start"); - procIsRunning = true - } - - function onEditorProcExit(code) { - console.log("received editor:proc:exit"); - procIsRunning = false; - } - - function onEditorDebuggerState(state) { - console.log(state); - } - - function notifErr(err) { - if (err.hasOwnProperty("detail")) { - notif({title: err.reason, type: "danger"}); - } else { - notif({title: err.reason, text: err.detail, type: "danger"}); - } - } - - function handleError(err) { - if (err.success) { return; } - failCount++; - if (failCount < 10) { - if (err.reason == "debugger not open") { - if (!reconnecting) { - reconnecting = true; - console.log("emitting editor:open"); - authorizedSocket.emit("editor:open", `user/${modeId}`, (res) => { - reconnecting = false; - handleError(res); - }); - } - } else { - notifErr(err); - } - } else { - notifErr(err); - } - } - - function createCodeEditor(modeId, code) { - console.log("received editor:code"); - console.log(code); - const chalky = "#e5c07b", - coral = "#e06c75", - cyan = "#56b6c2", - invalid = "#ffffff", - ivory = "#abb2bf", - stone = "#7d8799", - malibu = "#61afef", - sage = "#98c379", - whiskey = "#d19a66", - violet = "#c678dd", - darkBackground = "#21252b", - highlightBackground = "#2c313a", - background = "#282c34", - selection = "#3E4451", - cursor = "#528bff" - - console.log(codeEditorEl); - codeEditorView = new EditorView({ - state: EditorState.create({ - extensions: [ - basicSetup, - keymap.of([indentWithTab]), - python(), - indentUnit.of(" "), - EditorView.updateListener.of(update => { - if (update.docChanged) { - codeEditorHasChanges = true; - } - }), - EditorView.theme({ - "&": { - color: ivory, - }, - - ".cm-content": { - caretColor: cursor - }, - - "&.cm-focused .cm-cursor": {borderLeftColor: cursor}, - "&.cm-focused .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection": {backgroundColor: selection}, - - ".cm-panels": {backgroundColor: darkBackground, color: ivory}, - ".cm-panels.cm-panels-top": {borderBottom: "2px solid black"}, - ".cm-panels.cm-panels-bottom": {borderTop: "2px solid black"}, - - ".cm-searchMatch": { - backgroundColor: "#72a1ff59", - outline: "1px solid #457dff" - }, - ".cm-searchMatch.cm-searchMatch-selected": { - backgroundColor: "#6199ff2f" - }, - - ".cm-activeLine": {backgroundColor: highlightBackground}, - ".cm-selectionMatch": {backgroundColor: "#aafe661a"}, - ".cm-matchingBracket, .cm-nonmatchingBracket": { - backgroundColor: "#bad0f847", - outline: "1px solid #515a6b" - }, - - ".cm-gutters": { - backgroundColor: "transparent", - color: stone, - border: "none" - }, - - ".cm-activeLineGutter": { - backgroundColor: highlightBackground - }, - - ".cm-foldPlaceholder": { - backgroundColor: "transparent", - border: "none", - color: "#ddd" - }, - - ".cm-tooltip": { - border: "1px solid #181a1f", - backgroundColor: darkBackground - }, - ".cm-tooltip-autocomplete": { - "& > ul > li[aria-selected]": { - backgroundColor: highlightBackground, - color: ivory - } - } - }, {dark:true}), - HighlightStyle.define([ - {tag: t.keyword, - color: violet}, - {tag: [t.name, t.deleted, t.character, t.propertyName, t.macroName], - color: coral}, - {tag: [t.function(t.variableName), t.labelName], - color: malibu}, - {tag: [t.color, t.constant(t.name), t.standard(t.name)], - color: whiskey}, - {tag: [t.definition(t.name), t.separator], - color: ivory}, - {tag: [t.typeName, t.className, t.number, t.changed, t.annotation, t.modifier, t.self, t.namespace], - color: chalky}, - {tag: [t.operator, t.operatorKeyword, t.url, t.escape, t.regexp, t.link, t.special(t.string)], - color: cyan}, - {tag: [t.meta, t.comment], - color: stone}, - {tag: t.strong, - fontWeight: "bold"}, - {tag: t.emphasis, - fontStyle: "italic"}, - {tag: t.strikethrough, - textDecoration: "line-through"}, - {tag: t.link, - color: stone, - textDecoration: "underline"}, - {tag: t.heading, - fontWeight: "bold", - color: coral}, - {tag: [t.atom, t.bool, t.special(t.variableName)], - color: whiskey }, - {tag: [t.processingInstruction, t.string, t.inserted], - color: sage}, - {tag: t.invalid, - color: invalid}, - ]), - ], - doc: code - }), - parent: codeEditorEl - }) - } + //let failCount = 0; + //function handleError(err) { + // if (err.success) { return; } + // failCount++; + // if (failCount < 10) { + // if (err.reason == "debugger not open") { + // if (!reconnecting) { + // reconnecting = true; + // console.log("emitting editor:open"); + // authorizedSocket.emit("editor:open", `user/${modeId}`, (res) => { + // reconnecting = false; + // handleError(res); + // }); + // } + // } else { + // notifErr(err); + // } + // } else { + // notifErr(err); + // } + //} function startProc() { saveCode((res) => { - handleError(res); - console.log("emitting editor:startmode"); + if (!res.success) { notifErr(res); }; + console.debug("emitting editor:startmode"); authorizedSocket.emit("editor:startmode", (res) => { - handleError(res); + if (!res.success) { notifErr(res); }; }); }); } function stopProc() { - console.log("emitting editor:stopmode"); + console.debug("emitting editor:stopmode"); authorizedSocket.emit("editor:stopmode", (res) => { - handleError(res); + if (!res.success) { notifErr(res); }; }); } function restartProc () { saveCode((res) => { - handleError(res); - console.log("emitting editor:restartmode"); + if (!res.success) { notifErr(res); }; + console.debug("emitting editor:restartmode"); authorizedSocket.emit("editor:restartmode", (res) => { - handleError(res); + if (!res.success) { notifErr(res); }; }); }); } @@ -288,36 +77,13 @@ } } - function saveCode(fn) { - if (codeEditorView == null) { return; } - console.log("emitting editor:save"); - authorizedSocket.emit("editor:save", `user/${modeId}`, codeEditorView.state.doc.toString(), res => { - handleError(res); - if (fn != null) { fn(res) } - }); - codeEditorHasChanges = false; - } - onMount(() => { - console.log("onMount"); - codeEditorHasChanges = false; - procIsRunning = false; - failCount = 0; - reconnecting = false; - initDebugger(); + initDebugger(modeId); + attachCodeEditorView(codeEditorEl); }); onDestroy(() => { - console.log("onDestroy"); - if (debuggerInitialised) { - debuggerInitialised = false; - removeSocketListeners(); - } - if (get(openSocketConnected)) { - closeDebugger(); - } else { - debuggerInitialised = false; - } + closeDebugger(); }) document.addEventListener("keydown", function(e) { @@ -328,7 +94,7 @@ }, false); setInterval(() => { - if (codeEditorHasChanges) { + if ($codeEditorHasChanges) { saveCode(); } }, 5000); @@ -376,12 +142,12 @@ </style> <TopBar modeId={modeId} - hasChange={codeEditorHasChanges} + hasChange={$codeEditorHasChanges} on:closedebugger={pop} on:start={startProc} on:stop={stopProc} on:restart={restartProc} - bind:procIsRunning={procIsRunning} /> + bind:procIsRunning={$procIsRunning} /> <main> <div class="simulation"> <Pane header="simulation" contentBackground={simulationBackgrounds[simlulationBackgroundI]}> diff --git a/src_frontend/Components/Editor/Output.svelte b/src_frontend/Components/Editor/Output.svelte index 19fa600..5822d71 100644 --- a/src_frontend/Components/Editor/Output.svelte +++ b/src_frontend/Components/Editor/Output.svelte @@ -7,6 +7,7 @@ let htmlCode = ""; let buffer = []; let flushBufferInterval; + let flushBufferIntervalSpeed = 50; let lagAmount = 0; function addData(data, classname) { @@ -28,26 +29,34 @@ if (buffer.length > 0) { htmlCode += buffer.shift(); } - lagAmount = buffer.length; + lagAmount = (buffer.length * flushBufferIntervalSpeed) / 1000; }; afterUpdate(() => { scrollBox.scrollTo(0, scrollBox.scrollHeight); }); - authorizedSocket.on("editor:proc:start", () => htmlCode = ""); - authorizedSocket.on("editor:proc:exit", (code) => addData(`\nMode exited with ${code}\n\n`, "exit")); - authorizedSocket.on("editor:proc:stdout", (stdout) => addData(stdout, "stdout")); - authorizedSocket.on("editor:proc:stderr", (stderr) => addData(stderr, "stderr")); + function onEditorProcStart() { htmlCode = ""; } + function onEditorProcExit(code) { addData(`\nMode exited with ${code}\n\n`, "exit"); } + function onEditorProcStdout(stdout) { addData(stdout, "stdout"); } + function onEditorProcStderr(stderr) { addData(stderr, "stderr"); } onMount(() => { htmlCode = ""; buffer = []; - flushBufferInterval = setInterval(flushBufferPart, 50); + flushBufferInterval = setInterval(flushBufferPart, flushBufferIntervalSpeed); + authorizedSocket.on("editor:proc:start", onEditorProcStart); + authorizedSocket.on("editor:proc:exit", onEditorProcExit); + authorizedSocket.on("editor:proc:stdout", onEditorProcStdout); + authorizedSocket.on("editor:proc:stderr", onEditorProcStderr); }); onDestroy(() => { clearInterval(flushBufferInterval); + authorizedSocket.off("editor:proc:start", onEditorProcStart); + authorizedSocket.off("editor:proc:exit", onEditorProcExit); + authorizedSocket.off("editor:proc:stdout", onEditorProcStdout); + authorizedSocket.off("editor:proc:stderr", onEditorProcStderr); }); </script> @@ -56,7 +65,8 @@ height: 100%; width: 100%; box-sizing: border-box; - display: grid; + display: flex; + flex-direction: column; } pre { height: 100%; @@ -83,9 +93,9 @@ </style> <div> - {#if lagAmount > 3} + {#if lagAmount > 1.5} <span class="lag-alert"> - Output cannot keep up, and is {lagAmount} chunks behind realtime. + Output cannot keep up, and is around {lagAmount.toFixed(1)}s behind realtime. </span> {/if} <pre bind:this={scrollBox}> diff --git a/src_frontend/stores/IDEStore.js b/src_frontend/stores/IDEStore.js new file mode 100644 index 0000000..ce4308c --- /dev/null +++ b/src_frontend/stores/IDEStore.js @@ -0,0 +1,235 @@ +import { writable, derived, get } from "svelte/store"; +import { notif } from "./notifs"; +import { authorizedSocket, authorizedSocketNeeded, openSocketConnected } from "./socketStore"; +authorizedSocketNeeded.set(true) + +import { EditorState, basicSetup } from "@codemirror/basic-setup" +import { EditorView, keymap } from "@codemirror/view" +import { indentWithTab } from "@codemirror/commands" +import { indentUnit } from '@codemirror/language' +import { python } from "@codemirror/lang-python" +import { HighlightStyle, tags as t } from "@codemirror/highlight" + +export let socketListenersAdded = writable(false); +export let debuggerInitialised = writable(false); +export let procIsRunning = writable(false); +export let state = writable(null); +export let codeEditorViewEl = writable(null); +export let codeEditorView = writable(null); +export let codeEditorHasChanges = writable(false); + +export function attachCodeEditorView(node) { + codeEditorViewEl.set(node); + let _codeEditorView = get(codeEditorView); + if (_codeEditorView == null) { + console.warn("Attempted to attach codeEditorView, but it is not initialized"); + return; + } + node.appendChild(_codeEditorView.dom); + console.debug(`Attached code editor to`, node); +} + +export function initDebugger(modeId) { + if (get(debuggerInitialised)) { return; } + debuggerInitialised.set(true); + console.debug("emitting editor:open"); + authorizedSocket.emit("editor:open", `user/${modeId}`, (res) => { + if (!res.success) { notifErr(res); }; + }); +} + +export function closeDebugger() { + saveCode((res) => { + if (!res.success) { notifErr(res); }; + console.debug("emitting editor:close"); + authorizedSocket.emit("editor:close", res => { + if (!res.success) { notifErr(res); }; + debuggerInitialised.set(false); + + get(codeEditorView).destroy(); + codeEditorView.set(null); + }); + }); +} + +export function saveCode(fn) { + if (get(codeEditorView) == null) { return; } + console.debug("emitting editor:save"); + authorizedSocket.emit("editor:save", get(state).mode, get(codeEditorView).state.doc.toString(), res => { + console.debug("save:code callback", res); + if (!res.success) { notifErr(res); }; + if (fn != null) { fn(res) } + }); + codeEditorHasChanges.set(false); +} + +export function notifErr(err) { + console.error(err); + if (err.hasOwnProperty("detail")) { + notif({title: err.reason, type: "danger"}); + } else { + notif({title: err.reason, text: err.detail, type: "danger"}); + } +} + +function addSocketListeners() { + if (get(socketListenersAdded)) { return; } + socketListenersAdded.set(true); + authorizedSocket.on("editor:debugger:state", onEditorDebuggerState); + authorizedSocket.on("editor:code", createCodeEditor); + console.debug("Listeners attemted added"); +} + +function removeSocketListeners() { + if (!get(socketListenersAdded)) { return; } + socketListenersAdded.set(false); + authorizedSocket.off("editor:debugger:state", onEditorDebuggerState); + authorizedSocket.off("editor:code", createCodeEditor); + console.debug("Listeners attempted removed"); +} + +function onEditorDebuggerState(_state) { + state.set(_state); + procIsRunning.set(_state.running); +} + +function createCodeEditor(modeId, code) { + console.debug(`received editor:code for mode ${modeId}`); + if (get(codeEditorView) != null) { + get(codeEditorView).destroy(); + codeEditorView.set(null); + } + const chalky = "#e5c07b", + coral = "#e06c75", + cyan = "#56b6c2", + invalid = "#ffffff", + ivory = "#abb2bf", + stone = "#7d8799", + malibu = "#61afef", + sage = "#98c379", + whiskey = "#d19a66", + violet = "#c678dd", + darkBackground = "#21252b", + highlightBackground = "#2c313a", + background = "#282c34", + selection = "#3E4451", + cursor = "#528bff" + + let _codeEditorView = new EditorView({ + state: EditorState.create({ + extensions: [ + basicSetup, + keymap.of([indentWithTab]), + python(), + indentUnit.of(" "), + EditorView.updateListener.of(update => { + if (update.docChanged) { + codeEditorHasChanges.set(true); + } + }), + EditorView.theme({ + "&": { + color: ivory, + }, + + ".cm-content": { + caretColor: cursor + }, + + "&.cm-focused .cm-cursor": {borderLeftColor: cursor}, + "&.cm-focused .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection": {backgroundColor: selection}, + + ".cm-panels": {backgroundColor: darkBackground, color: ivory}, + ".cm-panels.cm-panels-top": {borderBottom: "2px solid black"}, + ".cm-panels.cm-panels-bottom": {borderTop: "2px solid black"}, + + ".cm-searchMatch": { + backgroundColor: "#72a1ff59", + outline: "1px solid #457dff" + }, + ".cm-searchMatch.cm-searchMatch-selected": { + backgroundColor: "#6199ff2f" + }, + + ".cm-activeLine": {backgroundColor: highlightBackground}, + ".cm-selectionMatch": {backgroundColor: "#aafe661a"}, + + ".cm-matchingBracket, .cm-nonmatchingBracket": { + backgroundColor: "#bad0f847", + outline: "1px solid #515a6b" + }, + + ".cm-gutters": { + backgroundColor: "transparent", + color: stone, + border: "none" + }, + + ".cm-activeLineGutter": { + backgroundColor: highlightBackground + }, + + ".cm-foldPlaceholder": { + backgroundColor: "transparent", + border: "none", + color: "#ddd" + }, + + ".cm-tooltip": { + border: "1px solid #181a1f", + backgroundColor: darkBackground + }, + ".cm-tooltip-autocomplete": { + "& > ul > li[aria-selected]": { + backgroundColor: highlightBackground, + color: ivory + } + } + }, {dark:true}), + HighlightStyle.define([ + {tag: t.keyword, + color: violet}, + {tag: [t.name, t.deleted, t.character, t.propertyName, t.macroName], + color: coral}, + {tag: [t.function(t.variableName), t.labelName], + color: malibu}, + {tag: [t.color, t.constant(t.name), t.standard(t.name)], + color: whiskey}, + {tag: [t.definition(t.name), t.separator], + color: ivory}, + {tag: [t.typeName, t.className, t.number, t.changed, t.annotation, t.modifier, t.self, t.namespace], + color: chalky}, + {tag: [t.operator, t.operatorKeyword, t.url, t.escape, t.regexp, t.link, t.special(t.string)], + color: cyan}, + {tag: [t.meta, t.comment], + color: stone}, + {tag: t.strong, + fontWeight: "bold"}, + {tag: t.emphasis, + fontStyle: "italic"}, + {tag: t.strikethrough, + textDecoration: "line-through"}, + {tag: t.link, + color: stone, + textDecoration: "underline"}, + {tag: t.heading, + fontWeight: "bold", + color: coral}, + {tag: [t.atom, t.bool, t.special(t.variableName)], + color: whiskey }, + {tag: [t.processingInstruction, t.string, t.inserted], + color: sage}, + {tag: t.invalid, + color: invalid}, + ]), + ], + doc: code + }) + }); + codeEditorView.set(_codeEditorView); + if (get(codeEditorViewEl) != null) { + attachCodeEditorView(get(codeEditorViewEl)); + } +} + +addSocketListeners(); |