Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

351
LINES

< > BotCompany Repo | #1034022 // JLeftArrowScriptIDE

JavaX fragment (include) [tags: use-pretranspiled]

Transpiled version (67246L) is out of date.

sclass JLeftArrowScriptIDE > MetaWithChangeListeners is Swingable {
  settable IVarWithNotify<S> 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 volatile RSyntaxTextAreaWithSearch taScript;
  transient new RSTADummyParser dummyParser; // for error highlighting
  
  transient ReliableSingleThread rstCompile = new(l0 compile);
  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;
  
  // set by client
  settable transient O sourceInfo;
  
  transient Runnable rRecompileIfError = l0 recompileIfError;
  
  transient swappable GazelleV_LeftArrowScriptParser makeParser() {
    ret g22utils.leftArrowParser().sourceInfo(sourceInfo);
  }
  
  interface GoToDefinitionHandler {
    Runnable get(TokPtr tokPtr);
  }
  
  transient gettable L<GoToDefinitionHandler> goToDefinitionHandlers = syncL();
  
  class LeftArrowCompletionProvider extends DefaultCompletionProvider {
    @Override
    public L<Completion> getCompletionsImpl(JTextComponent comp) {
      try {
        S text = main getText(comp);
        GazelleV_LeftArrowScriptParser parser = makeParser();
        LeftArrowScriptAutoCompleter completer = new(g22utils, parser);
        completer.onAdaptingSearcher(-> g22utils.addingAdditionalAutoCompletes(completer));
        //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(); }
    }
  }
  
  void goToPosition_noFocus(LineAndColumn lineAndCol) {
    if (lineAndCol == null) ret;
    
    try {
      moveCaretAndScroll(textArea(), lineAndCol);
    } catch e {
      print("Trying again: " + e);
      
      awtLater(1.0, -> {
        moveCaretAndScroll(textArea(), lineAndCol);
      });
    }
  }
    
  void goToPosition(LineAndColumn lineAndCol) {
    focus(textArea());
    goToPosition_noFocus(lineAndCol);
  }
  
  JComponent wrapStatusLabel(JComponent lbl) {
    onLeftClick(lbl, -> goToPosition(compileResult?.errorLineAndCol()));
    
    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", rThread convertToJava,
    ));

    ret
      centerAndEastWithMargin(
        jBorderlessHigherScrollPane(lbl),
        jfullcenter(buttons));
  }
  
  cachedVisual swing(-> {
    taScript = g22utils.newSyntaxTextArea(l1 wrapStatusLabel);
    
    bindToComponent(textArea(),
      -> g22utils.masterStuff().onNewClassesDefined(rRecompileIfError),
      -> g22utils.masterStuff().removeNewClassesDefinedListener(rRecompileIfError));
    
    bindTextComponentToVarWithNotify_noInitialUndo(textArea(), lvScript);
    
    dummyParser.install(textArea());
    //onCtrlEnter(textArea(), rThread runScript);
    
    // F5 to run!
    addKeyListener(textArea(), functionKeyListener(5, rThread runScript);
    
    // Ctrl+B to go to definition
    addKeyListener(textArea(), ctrlLetterKeyListener('b', rThread goToDefinition);
    
    // Permanent auto-compile on any text input
    awtCalcEvery(textArea(), compileDelay, rstCompile);

    installCompletionProvider(completionProvider = new LeftArrowCompletionProvider, textArea());

    JComponent vis = taScript.visualize();

    if (showTitle)
      vis = jCenteredSection(sectionTitle, vis);
    vis = wrapSection(vis);
    
    addAll(buttons,
      btnRun = toolTip("Run script (F5)", 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); }
  
  private void compile {
    var script = lvScript!;
    var result = compileResult;
    if (!g22utils().compileResultValid(result, script)) {
      result = newCompileResult();
      result.script = script;
      result.makeParser = l0 makeParser;
      result.compile();
      
      compileResult(result);
      showStatus(str(compileResult));
      updateRunButtonState();
      
      // send errors to highlighter
      L<RSTADummyParser.Error> 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() {
    rstCompile.triggerAndWait();
    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(OKOrError result) {
    if (result cast RunResultWithTimestamps)
      resultPanel?.logView.setText(str(result.printOutput()));
    
    if (result.isOK()) {
      setStatus(shorten(g22utils.stringify(result!)));
      var objVisualizer = makeObjectVisualizer(result!);
      if (result cast RunResultWithTimestamps) {
        var duration = result.duration();
        //print(+duration);
        if (duration != null) {
          long nanos = result.duration().toNanos();
          //printVars(+nanos, +objVisualizer);
          objVisualizer.nanos(nanos);
        }
      }
      if (collapsibleResultPanel != null)
        objVisualizer.withTypeAndTime(false);
      resultPanel?.scpResult.set(objVisualizer);
      if (collapsibleResultPanel != null)
        collapsibleResultPanel.sidePanelName("Output" + appendBracketed(objVisualizer.objectInfos()));
    } else {
      setStatus(
        //exceptionToStringShorter_dontDropOuterExceptions
        exceptionToStringShorter
        (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 FlexibleVarContext; }
  
  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;
      //enableScaffolding(converter);
      showText("Java conversion - " + sectionTitle(),
        strOrNull(converter.get(parsedScript(), true)));
    }
  }
  
  void goToDefinition {
    S text, int iChar = unpair textAndCaretPosition(textArea());
    LS tok = lasTok(text);
    int iTok = charToTokenIndex_left(tok, iChar);
    TokPtr tokPtr = new(tok, iTok);
    var action = goToDefinitionAction(tokPtr);
    if (action != null)
      pcallF(action);
    else
      flatInfoBox("No definition found");
  }
  
  Runnable goToDefinitionAction(TokPtr tokPtr) {
    for (handler : cloneList(goToDefinitionHandlers()))
      try object handler.get(tokPtr);
      
    LS tok = tokPtr.list();
    int iTok = tokPtr.idx();
    S id = lastIdentifier(subList(tok, iTok-2, iTok+1));
    //printVars("goToDefinition", +iTok, token := quote(token));
    if (id != null) {
      S name = lookupStandardFunctionOrClassNameIC(id);
      if (name != null) {
        S snippetID = sfOrSCSnippet(id);
        if (snippetID != null) { // Should always be true
          ret -> {
            infoBox("Opening " + quote(name));
            g22utils.openInBrowser(snippetURL(snippetID));
          };
        }
      }
    }
    
    null;
  }
  
  void recompile {
    compileResult = null;
    rstCompile.trigger();
  }
  
  void recompileIfError {
    var result = compileResult;
    //print("JLeftArrowScriptIDE.recompileIfError " + result);
    if (result != null && result.hasError())
      recompile();
  }
  
  swappable G22JavaObjectVisualizer makeObjectVisualizer(O result) {
    ret G22JavaObjectVisualizer(g22utils, result)
      .allowDescendingIntoListElements(true);
  }
  
  void addGoToDefinitionHandler(GoToDefinitionHandler handler) {
    goToDefinitionHandlers.add(handler);
  }
  
  bool visible aka isShowing() {
    var ta = taScript;
    ret ta != null && main isShowing(ta.textArea);
  }
  
  S getText() {
    var ta = taScript;
    if (ta == null) null;
    ret main getText(ta.textArea);
  }
}

download  show line numbers  debug dex  old transpilations   

Travelled to 4 computer(s): bhatertpkbcr, ekrmjmnbrukm, mowyntqkapby, mqqgnosmbjvj

No comments. add comment

Snippet ID: #1034022
Snippet name: JLeftArrowScriptIDE
Eternal ID of this version: #1034022/237
Text MD5: ad9e63682a81b873860223040be0b7be
Author: stefan
Category: javax / gui
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2022-12-27 19:14:08
Source code size: 11255 bytes / 351 lines
Pitched / IR pitched: No / No
Views / Downloads: 623 / 2202
Version history: 236 change(s)
Referenced in: #1034062 - JMiniJavaIDE
#1034167 - Standard Classes + Interfaces (LIVE, continuation of #1003674)
#1034363 - JLeftArrowScriptIDE (backup with two status bars)
#1034371 - aicDemo - AdaptiveIdentifierCompression
#1034372 - AICDemo - AdaptiveIdentifierCompression
#1034729 - JLeftArrowScriptIDE backup
#1034955 - JLeftArrowScriptIDE backup