!7 sS snippetID; sS savedText, remoteText; static EditorFrame e; static int caretPos; static SimpleLiveValue lvSnippetID = new(S.class); static int fontSize = 16; static AutoCompletion autoCompletion; static ReliableSingleThread rstAutoComplete = new(f installAutoComplete); sbool installAutoComplete_first; static Set autoComplete_lastSet; p-substance { autoRestart(); load('savedText); load('fontSize); e = new EditorFrame; e._setFontSize(fontSize); rstAutoComplete.trigger(); onChange(e.textArea, rTrigger(rstAutoComplete)); e.setText(savedText); load('caretPos); setCaretPosition(e.textArea, caretPos); showFrame(e); frameIcon(e, #1101185 /*#1004655*/); addMenu(e, "New", "New text", f newText); addMenu(e, "Load", "Load snippet...", r { selectSnippetID(vf1(f _loadSnippet)); }); addMenu(e, "Save", mapLiveValue(func(S s) -> S { "Save snippet " + s }, S.class, lvSnippetID) /*"Save snippet"*/, r { saveSnippetThen(null) }); addMenu(e, "Transpile", "Save & Quick Transpile", r { transpile(false) }, "Save & Medium Transpile", r { transpile(true) }); addMenu(e, "Activate", "Butter-Reload", f _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))) }); S snippetID = cast readPersistentVar('snippetID); if (snippetID != null) _loadSnippet_noSet(snippetID); hideConsole(); awtCalcEvery(e, 1000, f update); onFrameDeactivated(e, f fullUpdate); } svoid update { update(windowActive(e)); } svoid fullUpdate { update(true); } svoid 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 p = testBracketHygieneExt(text); status += p == null ? "Hygienic" : p.b; silentStatus(trim(status)); } svoid status(S s) { silentStatus(infoBoxAndReturn(s)); } svoid silentStatus(S s) { e.setStatus(s); } svoid saveSnippetThen(final Runnable next) { if (empty(snippetID)) ret; fS text = getText(e.textArea); status("Saving..."); thread { fS page = editSnippet(snippetID, text); remoteText = text; // TODO: check save result status("Saved snippet: " + page); awtCallF(next); } } svoid _butterReload() { time { butterReload(snippetID); } infoBox("Reloaded in " + lastTiming_format100ms()); } svoid transpile(final bool medium) { saveSnippetThen(r { _transpile(medium) }); } svoid _transpile(final bool medium) { status("Transpiling..."); //jdisable(btnEleuReload); thread "Transpiling" { try { final Pair p = transpileOnServer(snippetID, medium ? "medium" : "quick"); awt { if (p.a) status("Transpiled OK!"); else { status("Transpilation error. " + p.b); showText("Transpilation Error", p.b); } } } catch print e { status("Transpilation problem. " + e); } //jenable(btnEleuReload); } } svoid _loadSnippet(S snippetID) { _loadSnippet_noSet(snippetID); e.textArea.setText(remoteText); } svoid _loadSnippet_noSet(S snippetID) { remoteText = loadSnippet(snippetID); setAndSave('snippetID, snippetID); lvSnippetID.set(snippetID); frameTitle(e, snippetID + " - " + snippetTitle(snippetID)); } svoid newText { setAndSave(snippetID := null); lvSnippetID.set(snippetID); remoteText = null; S lastText = e.getText(); if (nempty(lastText)) logQuotedWithDate("saved-texts.log", lastText); e.setText(""); frameTitle(e, programTitle()); } svoid cleanMeUp { update(false); } svoid installAutoComplete { if (installAutoComplete_first) installAutoComplete_first = false; else sleep(500); // don't update too often printWithTime("Updating auto-complete"); temp tempMiniLoadingAnim(); Set set = concatListsToSet(allJavaKeywords(), standardFunctionNames(), deepWords(getText(e.textArea))); if (eq(set, autoComplete_lastSet)) ret; autoComplete_lastSet = set; final new DefaultCompletionProvider provider; provider.addCompletions(map(func(S 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); } }