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

251
LINES

< > BotCompany Repo | #1015563 // SFEditor - Snippet/File Editor

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

Uses 2805K of libraries. Click here for Pure Java version (21108L/163K).

concept SFEditor {
  // What are we editing?
  O editing; // File or snippet ID
  S remoteText;
  
  S savedText;
  int caretPos;
  int fontSize = 16;
  S fontID = /*#1400030*/#1400031;
  S snippetTitle;
  
  transient EditorFrame e;
  transient SimpleLiveValue<O> lvEditing;
  transient AutoCompletion autoCompletion;
  transient ReliableSingleThread rstAutoComplete = new(r installAutoComplete);
  transient bool installAutoComplete_first;
  transient Set<S> autoComplete_lastSet;
  transient DynamicHStack smartArea;
  transient int autoCompleteRefreshDelay = 1000;
  transient JTextArea transpilationErrorBox;
  
  !include #1015622 // setAndSave etc.

  void reset {
    cleanMeUp();
    autoCompletion = null;
    autoComplete_lastSet = null;
    start();
  }
  
  void start { swing {
    installAutoComplete_first = true;
    lvEditing = new SimpleLiveValue(O);
    
    e = new EditorFrame;
    e._setFont(deriveFont(loadFont(fontID), e._getFont().getSize()));
    e._setFontSize(fontSize);
    rstAutoComplete.trigger();
    onChange(e.textArea, rTrigger(rstAutoComplete));
    
    addToWindowWithMargin(e, jHigherScrollPane(jfullcenter(smartArea = dynamicHStack())));
    
    e.setText(savedText);
    load('caretPos);
    setCaretPosition(e.textArea, caretPos);
    showFrame(e);
    frameIcon(e, #1101185 /*#1004655*/);
    addFontChangersToTitleMenu(e, r reset);
    onFrameClosing(e, r {
      if (!cleaningUp())
        deleteConcept(SFEditor.this);
    });
    
    addMenu(e, "&New",
      "New text", r newText,
      "New window", r newWindow);
  
    addMenu(e, "&Load", "Load snippet...", r {
      selectSnippetID(voidfunc(S snippetID) { _loadSnippet(snippetID) });
    }, "Load file...", r {
      selectFile("File to load", voidfunc(File f) { _loadFile(f) });
    }, "Reload", r-thread { // TODO: single thread
      if (editing != null) {
        reload();
        setText(e.textArea, remoteText);
      }
    });
    
    LiveValue<S> lvSaveCmd = mapLiveValue(func(O editing) -> S {
      editing instanceof S ? "Save snippet " + editing
        : editing instanceof File ? "Save file " + f2s((File) editing)
        : "{Save}" }, S.class, lvEditing);

    addMenu(e, "&Save",
      lvSaveCmd, r { saveThen(null) },
      "Save as snippet...", r saveAsSnippet);
    
    addMenu(e, "&Transpile",
      "Save & Quick Transpile", r { transpile(false) },
      "Save & Medium Transpile", r { transpile(true) });
    addMenu(e, "&Activate",
      "Run", r runIt,
      "Butter-Reload", r _butterReload);
    
    addMenu(e, "&View",
      "Bigger font", r { e._setFontSize(setAndSave(fontSize := e._getFontSize()+1)) },
      "Smaller font", r { e._setFontSize(setAndSave(fontSize := max(1, e._getFontSize()-1))) });
    
    reload();
  
    awtCalcEvery(e, 1000, r update);
    onFrameDeactivated(e, r fullUpdate);
  }
}

  void reload {
    if (editing instanceof S) _loadSnippet_noSet((S) editing);
    else if (editing instanceof File) _loadFile_noSet((File) editing);
  }
  
  void update { update(windowActive(e)); }
  void fullUpdate { update(true); }
  void update(bool full) {
    S text = e.getText();
    setAndSaveIfChanged(savedText := text);
    setAndSaveIfChanged(caretPos := getCaretPosition(e.textArea));
      
    if (!full) ret;
    S status = remoteText != null && neq(remoteText, text) ? "Changes. " : "";
    Pair<Int, S> p = testBracketHygieneExt(text);
    status += p == null ? "Hygienic" : p.b;
    silentStatus(trim(status));
  }
  
  void status(S s) { silentStatus(infoBoxAndReturn(s)); }
  void silentStatus(S s) { e.setStatus(s); }
  
  void saveThen(final Runnable next) {
    fS text = getText();
    if (editing instanceof S) {
      status("Saving snippet...");
      thread {
        fS page = editSnippet((S) editing, text);
        remoteText = text; // TODO: check save result
        status("Saved snippet: " + page);
        awtCallF(next);
      }
    } else if (editing instanceof File) {
      status("Saving file...");
      thread {
        saveTextFile((File) editing, text);
        remoteText = text;
        status("Saved file");
        awtCallF(next);
      }
    }
  }
  
  void _butterReload() {
    time { butterReload((S) editing); }
    infoBox("Reloaded in " + lastTiming_format100ms());
  }
  
  void transpile(final bool medium) { saveThen(r { _transpile(medium) }); }
  
  void _transpile(bool medium) {
    status("Transpiling...");
    //jdisable(btnEleuReload);
    
    thread "Transpiling" {
      try {
        transpileOnServerWithErrorWindow((S) editing, medium, r { status("Transpiled OK!") },
          onError := voidfunc(S error) {
            status("Transpilation error. " + error);
          });
      } catch print e {
        status("Transpilation problem. " + e);
      }
      //jenable(btnEleuReload);
    }
  }
  
  void _loadSnippet(S snippetID) {
    _loadSnippet_noSet(snippetID);
    e.textArea.setText(remoteText);
  }
  
  void _loadSnippet_noSet(S snippetID) {
    remoteText = loadSnippet(snippetID);
    setAndSave('editing, snippetID);
    lvEditing.set(snippetID);
    frameTitle(e, snippetID + " - " + (snippetTitle = snippetTitle(snippetID)));
  }
  
  void _loadFile(File f) {
    _loadFile_noSet(f);
    e.textArea.setText(remoteText);
  }
  
  void _loadFile_noSet(File f) {
    remoteText = loadTextFile(f);
    setAndSave('editing, f);
    lvEditing.set(f);
    frameTitle(e, f2s(f));
  }
  
  void newText {
    setAndSave(editing := null);
    lvEditing.set(null);
    remoteText = null;
    S lastText = e.getText();
    if (nempty(lastText)) logQuotedWithDate("saved-texts.log", lastText);
    e.setText("");
    frameTitle(e, programTitle());
  }
  
  void cleanMeUp {
    update(false);
    disposeWindow(e);
  }
  
  void installAutoComplete {
    if (installAutoComplete_first) installAutoComplete_first = false;
    else sleep(autoCompleteRefreshDelay); // don't update too often
    
    //temp tempMiniLoadingAnim();
  
    Set<S> set = concatListsToSet(allJavaKeywords(), standardFunctionNames(), deepWords(getText()), deepWords(snippetTitle));
      
    if (eq(set, autoComplete_lastSet)) ret;
    autoComplete_lastSet = set;
    
    final new DefaultCompletionProvider provider;
    provider.addCompletions(map(s -> new BasicCompletion(provider, s), set));
      
    swing {
      if (autoCompletion == null) {
        (autoCompletion = new AutoCompletion(provider)).install(e.textArea);
        call(autoCompletion, 'setHideOnCompletionProviderChange, false);
      } else
        autoCompletion.setCompletionProvider(provider);
    }
  }
  
  void newWindow {
    copyFields(this, new SFEditor(), 'fontSize).start();
  }
  
  void runIt {
    if (editing instanceof S)
      nohupJavax((S) editing);
  }
  
  void saveAsSnippet {
    final JTextField tfTitle = jtextfield();
    final JComboBox cbType = jComboBox_javaxTypes();
    showFormTitled("Save as new snippet",
      "Title:", tfTitle,
      "Type:", cbType,
      r-thread {
        loading {
          int type = parseFirstInt(getSelectedItem(cbType));
          S title = getTextTrim(tfTitle);
          S snippetID = createSnippet(getText(), title, type);
          _loadSnippet_noSet(snippetID);
        }
      });
  }
  
  S getText() { ret e.getText(); }
}

Author comment

Began life as a copy of #1015560

download  show line numbers  debug dex  old transpilations   

Travelled to 15 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, irmadwmeruwu, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt, xrpafgyirdlv

No comments. add comment

Snippet ID: #1015563
Snippet name: SFEditor - Snippet/File Editor
Eternal ID of this version: #1015563/42
Text MD5: bead7eaca9502b5e1e68dfa0a67955e6
Transpilation MD5: f25c105af0a32a4dc55c87de62e48d32
Author: stefan
Category: javax / gui
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2020-06-14 17:40:35
Source code size: 7520 bytes / 251 lines
Pitched / IR pitched: No / No
Views / Downloads: 414 / 1018
Version history: 41 change(s)
Referenced in: [show references]