sclass JLeftArrowScriptIDE > MetaWithChangeListeners is Swingable { settable SimpleLiveValue lvScript = stringLiveValue(); settable S sectionTitle = "Left arrow script"; settable bool withResultPanel = true; // how long to wait before compiling after text is changed (seconds) settable double compileDelay = 0.25; sS helpText = !include string #1034045; transient settableWithVar LASCompileResult compileResult; transient RSyntaxTextAreaWithSearch taScript; transient new Q compileQ; transient gettable JPanel buttons = jline(); transient JButton btnRun; transient CollapsibleLeftPanel collapsibleResultPanel; transient SingleComponentPanel scpResult = singleComponentPanel(); transient JPopDownButton popDownButton; transient LeftArrowCompletionProvider completionProvider; settable transient G22Utils g22utils; settable double scriptTimeout = 10.0; settable transient bool showTitle = true; transient swappable GazelleV_LeftArrowScriptParser makeParser() { ret g22utils.leftArrowParser(); } class LeftArrowCompletionProvider extends DefaultCompletionProvider { @Override public L getCompletionsImpl(JTextComponent comp) { try { S text = getText(comp); GazelleV_LeftArrowScriptParser parser = makeParser2(); LeftArrowScriptAutoCompleter completer = new(g22utils, parser); enableScaffolding(completer); completer.seek(text, getCaretPosition(comp)); ret map(completer.searcher().withScores(), completion -> { BasicCompletion c = new(this, completion!); c.setRelevance((int) completion.score()); ret c; }); } catch print e { ret ll(); } } } JComponent wrapStatusLabel(JComponent lbl) { popDownButton = swing(-> new JPopDownButton("Help")); popDownButton.onFillingMenu(menu -> { addMenuItems(menu, "Show Scripting Help", rThread { showTextWordWrapped("Gazelle 'Left arrow script' Help", helpText) }, "Show Global Class Names", rThread showGlobalClassNames); }); ret centerAndEastWithMargin( jBorderlessHigherScrollPane(lbl), jfullcenter(buttons)); } cachedVisual swing(-> { taScript = g22utils.newSyntaxTextArea(l1 wrapStatusLabel); bindTextComponentToLiveValue_bothWays(textArea(), lvScript); onCtrlEnter(textArea(), rThread runScript); awtCalcEvery(textArea(), compileDelay, -> compileQ.add(r compile)); installCompletionProvider(completionProvider = new LeftArrowCompletionProvider, textArea()); JComponent vis = taScript.visualize(); if (showTitle) vis = jCenteredSection(sectionTitle, vis); vis = wrapSection(vis); addAll(buttons, btnRun = jbutton("Run" := rThread runScript), popDownButton); if (withResultPanel) { collapsibleResultPanel = new CollapsibleLeftPanel(false, "Result", scpResult, vis); collapsibleResultPanel.sidePanelMargins = c -> withTopAndLeftMargin(c); ret collapsibleResultPanel.visualize(); } else ret vis; }); swappable JComponent wrapSection(JComponent c) { ret c; } RSyntaxTextArea textArea() { if (taScript == null) visualize(); ret taScript.textArea(); } void setText(S text) { main setText(textArea(), text); } bool visible() { ret isShowing(textArea()); } void compile { var script = lvScript!; var result = compileResult; if (result == null || !eq(result.script, script)) { try { result = newCompileResult(); result.script = script; result.parser = makeParser(); result.parsedScript = result.parser.parse(result.script); print(result.parsedScript); } catch e { print(e); result.compileError = e; } compileResult(result); showStatus(str(compileResult)); updateRunButtonState(); } } void updateRunButtonState() { setEnabled(btnRun, runButtonShouldBeEnabled()); } swappable bool runButtonShouldBeEnabled() { ret compileResult != null && compileResult.runnable(); } LASCompileResult freshCompileResult() { runInQAndWait(compileQ, r compile); ret compileResult; } GazelleV_LeftArrowScript.Script parsedScript() { ret freshCompileResult().parsedScript; } swappable void runScript() { var result = freshCompileResult(); if (result.parsedScript != null) { var value = okOrError(-> callCompiledObjectWithTimeout(result.parsedScript)); showScriptResult(value); } } // TODO: show print log & timing void showScriptResult(RunResultWithTimestamps result) { showScriptResult(result.result()); } void showScriptResult(OKOrError result) { if (result.isOK()) { setStatus(shorten(g22utils.stringify(result!))); scpResult?.set(G22JavaObjectVisualizer(g22utils, result!)); } else { setStatus(exceptionToStringShorter_dontDropOuterExceptions(result.error())); scpResult?.set(jErrorView(result.getError())); } collapsibleResultPanel.expand(); } /* compile result used to include result of execution class CompileResult > LASCompileResult { OKOrError result; }*/ void setStatus aka showStatus(S status) { taScript?.setStatus(" " + unnull(status)); } void showRuntimeError(Throwable e) { showStatus(exceptionToStringShorter(e)); } swappable VarContext makeVarContextForExecution() { ret new VarContext; } O callCompiledObjectWithTimeout(double timeoutSeconds default scriptTimeout, GazelleV_LeftArrowScript.Script script, VarContext ctx default makeVarContextForExecution()) { ret evalWithTimeoutOrTypedException(timeoutSeconds, -> script.get(ctx)); } GazelleV_LeftArrowScriptParser makeParser2() { var parser = makeParser(); print("Function containers: " + parser.functionContainers); ret parser; } void showGlobalClassNames() { showText("Global Class Names", pnlToString(toCIMap(makeParser().globalClassNames()))); } // only after visualize void setEditable(bool b) { main setEditable(textArea(), b); } swappable LASCompileResult newCompileResult() { ret new LASCompileResult; } }