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.1; sS helpText = !include string #1034045; transient settableWithVar LASCompileResult compileResult; transient RSyntaxTextAreaWithSearch taScript; transient new RSTADummyParser dummyParser; // for error highlighting transient new Q compileQ; transient gettable JPanel buttons = jline(); transient JButton btnRun; transient CollapsibleLeftPanel collapsibleResultPanel; transient G22ScriptResultPanel resultPanel; 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) { onLeftClick(lbl, -> { LineAndColumn lineAndCol = compileResult?.errorLineAndCol(); if (lineAndCol != null) { moveCaretToLineAndCol(textArea(), lineAndCol); focus(textArea()); } }); 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, "Convert to Java", rthead convertToJava, ); }); ret centerAndEastWithMargin( jBorderlessHigherScrollPane(lbl), jfullcenter(buttons)); } cachedVisual swing(-> { taScript = g22utils.newSyntaxTextArea(l1 wrapStatusLabel); bindTextComponentToLiveValue_bothWays_noInitialUndo(textArea(), lvScript); dummyParser.install(textArea()); 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) { resultPanel = new G22ScriptResultPanel; collapsibleResultPanel = new CollapsibleLeftPanel(false, "Output", resultPanel.visualize(), 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)) { result = newCompileResult(); result.script = script; result.makeParser = l0 makeParser; result.compile(); compileResult(result); showStatus(str(compileResult)); updateRunButtonState(); // send errors to highlighter L errors = new L; if (result.compileError != null) { LineAndColumn lineAndCol = result.errorLineAndCol(); if (lineAndCol != null) errors.add(new RSTADummyParser.Error() .msg(result.errorToString()) .start(lineAndCol) .end(LineAndColumn(lineAndCol.line+1, 1))); } dummyParser.setErrors(result.script, errors, textArea()); } } 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 = runResultWithTimestamps(-> callCompiledObjectWithTimeout(result.parsedScript)); showScriptResult(value); } } void showScriptResult(RunResultWithTimestamps result) { resultPanel.logView.setText(str(result.printOutput())); showScriptResult(result.result()); } void showScriptResult(OKOrError result) { if (result.isOK()) { setStatus(shorten(g22utils.stringify(result!))); var objVisualizer = G22JavaObjectVisualizer(g22utils, result!); if (collapsibleResultPanel != null) objVisualizer.withTypeAndTime(false); resultPanel.scpResult.set(objVisualizer); if (collapsibleResultPanel != null) collapsibleResultPanel.sidePanelName("Output" + appendBracketed(objVisualizer.objectInfos()); } else { setStatus(exceptionToStringShorter_dontDropOuterExceptions(result.error())); resultPanel.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 g22utils.evalRegisteredCode(timeoutSeconds, str(script), -> 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; } void convertToJava { pcall-infobox { new ConvertLASToJava converter; showText("Java conversion", strOrNull(converter.get(compile().parsedScript))); } } }