Transpiled version (67246L) is out of date.
1 | sclass JLeftArrowScriptIDE > MetaWithChangeListeners is Swingable { |
2 | settable IVarWithNotify<S> lvScript = stringLiveValue(); |
3 | settable S sectionTitle = "Left arrow script"; |
4 | settable bool withResultPanel = true; |
5 | |
6 | // how long to wait before compiling after text is changed (seconds) |
7 | settable double compileDelay = 0.1; |
8 | |
9 | sS helpText = !include string #1034045; |
10 | |
11 | transient settableWithVar LASCompileResult compileResult; |
12 | |
13 | transient volatile RSyntaxTextAreaWithSearch taScript; |
14 | transient new RSTADummyParser dummyParser; // for error highlighting |
15 | |
16 | transient ReliableSingleThread rstCompile = new(l0 compile); |
17 | transient gettable JPanel buttons = jline(); |
18 | transient JButton btnRun; |
19 | transient CollapsibleLeftPanel collapsibleResultPanel; |
20 | transient G22ScriptResultPanel resultPanel; |
21 | transient JPopDownButton popDownButton; |
22 | |
23 | transient LeftArrowCompletionProvider completionProvider; |
24 | |
25 | settable transient G22Utils g22utils; |
26 | |
27 | settable double scriptTimeout = 10.0; |
28 | |
29 | settable transient bool showTitle = true; |
30 | |
31 | // set by client |
32 | settable transient O sourceInfo; |
33 | |
34 | transient Runnable rRecompileIfError = l0 recompileIfError; |
35 | |
36 | transient swappable GazelleV_LeftArrowScriptParser makeParser() { |
37 | ret g22utils.leftArrowParser().sourceInfo(sourceInfo); |
38 | } |
39 | |
40 | interface GoToDefinitionHandler { |
41 | Runnable get(TokPtr tokPtr); |
42 | } |
43 | |
44 | transient gettable L<GoToDefinitionHandler> goToDefinitionHandlers = syncL(); |
45 | |
46 | class LeftArrowCompletionProvider extends DefaultCompletionProvider { |
47 | @Override |
48 | public L<Completion> getCompletionsImpl(JTextComponent comp) { |
49 | try { |
50 | S text = main getText(comp); |
51 | GazelleV_LeftArrowScriptParser parser = makeParser(); |
52 | LeftArrowScriptAutoCompleter completer = new(g22utils, parser); |
53 | completer.onAdaptingSearcher(-> g22utils.addingAdditionalAutoCompletes(completer)); |
54 | //enableScaffolding(completer); |
55 | completer.seek(text, getCaretPosition(comp)); |
56 | ret map(completer.searcher().withScores(), completion -> { |
57 | BasicCompletion c = new(this, completion!); |
58 | c.setRelevance((int) completion.score()); |
59 | ret c; |
60 | }); |
61 | } catch print e { ret ll(); } |
62 | } |
63 | } |
64 | |
65 | void goToPosition_noFocus(LineAndColumn lineAndCol) { |
66 | if (lineAndCol == null) ret; |
67 | |
68 | try { |
69 | moveCaretAndScroll(textArea(), lineAndCol); |
70 | } catch e { |
71 | print("Trying again: " + e); |
72 | |
73 | awtLater(1.0, -> { |
74 | moveCaretAndScroll(textArea(), lineAndCol); |
75 | }); |
76 | } |
77 | } |
78 | |
79 | void goToPosition(LineAndColumn lineAndCol) { |
80 | focus(textArea()); |
81 | goToPosition_noFocus(lineAndCol); |
82 | } |
83 | |
84 | JComponent wrapStatusLabel(JComponent lbl) { |
85 | onLeftClick(lbl, -> goToPosition(compileResult?.errorLineAndCol())); |
86 | |
87 | popDownButton = swing(-> new JPopDownButton("Help")); |
88 | popDownButton.onFillingMenu(menu -> addMenuItems(menu, |
89 | "Show Scripting Help", rThread { |
90 | showTextWordWrapped("Gazelle 'Left arrow script' Help", helpText) |
91 | }, |
92 | "Show Global Class Names", rThread showGlobalClassNames, |
93 | "Convert to Java", rThread convertToJava, |
94 | )); |
95 | |
96 | ret |
97 | centerAndEastWithMargin( |
98 | jBorderlessHigherScrollPane(lbl), |
99 | jfullcenter(buttons)); |
100 | } |
101 | |
102 | cachedVisual swing(-> { |
103 | taScript = g22utils.newSyntaxTextArea(l1 wrapStatusLabel); |
104 | |
105 | bindToComponent(textArea(), |
106 | -> g22utils.masterStuff().onNewClassesDefined(rRecompileIfError), |
107 | -> g22utils.masterStuff().removeNewClassesDefinedListener(rRecompileIfError)); |
108 | |
109 | bindTextComponentToVarWithNotify_noInitialUndo(textArea(), lvScript); |
110 | |
111 | dummyParser.install(textArea()); |
112 | //onCtrlEnter(textArea(), rThread runScript); |
113 | |
114 | // F5 to run! |
115 | addKeyListener(textArea(), functionKeyListener(5, rThread runScript); |
116 | |
117 | // Ctrl+B to go to definition |
118 | addKeyListener(textArea(), ctrlLetterKeyListener('b', rThread goToDefinition); |
119 | |
120 | // Permanent auto-compile on any text input |
121 | awtCalcEvery(textArea(), compileDelay, rstCompile); |
122 | |
123 | installCompletionProvider(completionProvider = new LeftArrowCompletionProvider, textArea()); |
124 | |
125 | JComponent vis = taScript.visualize(); |
126 | |
127 | if (showTitle) |
128 | vis = jCenteredSection(sectionTitle, vis); |
129 | vis = wrapSection(vis); |
130 | |
131 | addAll(buttons, |
132 | btnRun = toolTip("Run script (F5)", jbutton("Run" := rThread runScript)), |
133 | popDownButton); |
134 | |
135 | if (withResultPanel) { |
136 | resultPanel = new G22ScriptResultPanel; |
137 | collapsibleResultPanel = new CollapsibleLeftPanel(false, "Output", resultPanel.visualize(), vis); |
138 | collapsibleResultPanel.sidePanelMargins = c -> withTopAndLeftMargin(c); |
139 | ret collapsibleResultPanel.visualize(); |
140 | } else |
141 | ret vis; |
142 | }); |
143 | |
144 | swappable JComponent wrapSection(JComponent c) { ret c; } |
145 | |
146 | RSyntaxTextArea textArea() { |
147 | if (taScript == null) visualize(); |
148 | ret taScript.textArea(); |
149 | } |
150 | |
151 | void setText(S text) { main setText(textArea(), text); } |
152 | |
153 | private void compile { |
154 | var script = lvScript!; |
155 | var result = compileResult; |
156 | if (!g22utils().compileResultValid(result, script)) { |
157 | result = newCompileResult(); |
158 | result.script = script; |
159 | result.makeParser = l0 makeParser; |
160 | result.compile(); |
161 | |
162 | compileResult(result); |
163 | showStatus(str(compileResult)); |
164 | updateRunButtonState(); |
165 | |
166 | // send errors to highlighter |
167 | L<RSTADummyParser.Error> errors = new L; |
168 | if (result.compileError != null) { |
169 | LineAndColumn lineAndCol = result.errorLineAndCol(); |
170 | if (lineAndCol != null) |
171 | errors.add(new RSTADummyParser.Error() |
172 | .msg(result.errorToString()) |
173 | .start(lineAndCol) |
174 | .end(LineAndColumn(lineAndCol.line+1, 1))); |
175 | } |
176 | dummyParser.setErrors(result.script, errors, textArea()); |
177 | } |
178 | } |
179 | |
180 | void updateRunButtonState() { |
181 | setEnabled(btnRun, runButtonShouldBeEnabled()); |
182 | } |
183 | |
184 | swappable bool runButtonShouldBeEnabled() { |
185 | ret compileResult != null && compileResult.runnable(); |
186 | } |
187 | |
188 | LASCompileResult freshCompileResult() { |
189 | rstCompile.triggerAndWait(); |
190 | ret compileResult; |
191 | } |
192 | |
193 | GazelleV_LeftArrowScript.Script parsedScript() { |
194 | ret freshCompileResult().parsedScript; |
195 | } |
196 | |
197 | swappable void runScript() { |
198 | var result = freshCompileResult(); |
199 | if (result.parsedScript != null) { |
200 | var value = runResultWithTimestamps(-> callCompiledObjectWithTimeout(result.parsedScript)); |
201 | showScriptResult(value); |
202 | } |
203 | } |
204 | |
205 | void showScriptResult(OKOrError result) { |
206 | if (result cast RunResultWithTimestamps) |
207 | resultPanel?.logView.setText(str(result.printOutput())); |
208 | |
209 | if (result.isOK()) { |
210 | setStatus(shorten(g22utils.stringify(result!))); |
211 | var objVisualizer = makeObjectVisualizer(result!); |
212 | if (result cast RunResultWithTimestamps) { |
213 | var duration = result.duration(); |
214 | //print(+duration); |
215 | if (duration != null) { |
216 | long nanos = result.duration().toNanos(); |
217 | //printVars(+nanos, +objVisualizer); |
218 | objVisualizer.nanos(nanos); |
219 | } |
220 | } |
221 | if (collapsibleResultPanel != null) |
222 | objVisualizer.withTypeAndTime(false); |
223 | resultPanel?.scpResult.set(objVisualizer); |
224 | if (collapsibleResultPanel != null) |
225 | collapsibleResultPanel.sidePanelName("Output" + appendBracketed(objVisualizer.objectInfos())); |
226 | } else { |
227 | setStatus( |
228 | //exceptionToStringShorter_dontDropOuterExceptions |
229 | exceptionToStringShorter |
230 | (result.error())); |
231 | resultPanel?.scpResult.set(jErrorView(result.getError())); |
232 | } |
233 | collapsibleResultPanel?.expand(); |
234 | } |
235 | |
236 | /* compile result used to include result of execution |
237 | class CompileResult > LASCompileResult { |
238 | OKOrError result; |
239 | }*/ |
240 | |
241 | void setStatus aka showStatus(S status) { |
242 | taScript?.setStatus(" " + unnull(status)); |
243 | } |
244 | |
245 | void showRuntimeError(Throwable e) { |
246 | showStatus(exceptionToStringShorter(e)); |
247 | } |
248 | |
249 | swappable VarContext makeVarContextForExecution() { ret new FlexibleVarContext; } |
250 | |
251 | O callCompiledObjectWithTimeout(double timeoutSeconds default scriptTimeout, |
252 | GazelleV_LeftArrowScript.Script script, |
253 | VarContext ctx default makeVarContextForExecution()) { |
254 | ret g22utils.evalRegisteredCode(timeoutSeconds, str(script), |
255 | -> script.get(ctx)); |
256 | } |
257 | |
258 | /*GazelleV_LeftArrowScriptParser makeParser2() { |
259 | var parser = makeParser(); |
260 | print("Function containers: " + parser.functionContainers); |
261 | ret parser; |
262 | }*/ |
263 | |
264 | void showGlobalClassNames() { |
265 | showText("Global Class Names", pnlToString(toCIMap(makeParser().globalClassNames()))); |
266 | } |
267 | |
268 | // only after visualize |
269 | void setEditable(bool b) { |
270 | main setEditable(textArea(), b); |
271 | } |
272 | |
273 | swappable LASCompileResult newCompileResult() { ret new LASCompileResult; } |
274 | |
275 | void convertToJava { |
276 | pcall-infobox { |
277 | new ConvertLASToJava converter; |
278 | //enableScaffolding(converter); |
279 | showText("Java conversion - " + sectionTitle(), |
280 | strOrNull(converter.get(parsedScript(), true))); |
281 | } |
282 | } |
283 | |
284 | void goToDefinition { |
285 | S text, int iChar = unpair textAndCaretPosition(textArea()); |
286 | LS tok = lasTok(text); |
287 | int iTok = charToTokenIndex_left(tok, iChar); |
288 | TokPtr tokPtr = new(tok, iTok); |
289 | var action = goToDefinitionAction(tokPtr); |
290 | if (action != null) |
291 | pcallF(action); |
292 | else |
293 | flatInfoBox("No definition found"); |
294 | } |
295 | |
296 | Runnable goToDefinitionAction(TokPtr tokPtr) { |
297 | for (handler : cloneList(goToDefinitionHandlers())) |
298 | try object handler.get(tokPtr); |
299 | |
300 | LS tok = tokPtr.list(); |
301 | int iTok = tokPtr.idx(); |
302 | S id = lastIdentifier(subList(tok, iTok-2, iTok+1)); |
303 | //printVars("goToDefinition", +iTok, token := quote(token)); |
304 | if (id != null) { |
305 | S name = lookupStandardFunctionOrClassNameIC(id); |
306 | if (name != null) { |
307 | S snippetID = sfOrSCSnippet(id); |
308 | if (snippetID != null) { // Should always be true |
309 | ret -> { |
310 | infoBox("Opening " + quote(name)); |
311 | g22utils.openInBrowser(snippetURL(snippetID)); |
312 | }; |
313 | } |
314 | } |
315 | } |
316 | |
317 | null; |
318 | } |
319 | |
320 | void recompile { |
321 | compileResult = null; |
322 | rstCompile.trigger(); |
323 | } |
324 | |
325 | void recompileIfError { |
326 | var result = compileResult; |
327 | //print("JLeftArrowScriptIDE.recompileIfError " + result); |
328 | if (result != null && result.hasError()) |
329 | recompile(); |
330 | } |
331 | |
332 | swappable G22JavaObjectVisualizer makeObjectVisualizer(O result) { |
333 | ret G22JavaObjectVisualizer(g22utils, result) |
334 | .allowDescendingIntoListElements(true); |
335 | } |
336 | |
337 | void addGoToDefinitionHandler(GoToDefinitionHandler handler) { |
338 | goToDefinitionHandlers.add(handler); |
339 | } |
340 | |
341 | bool visible aka isShowing() { |
342 | var ta = taScript; |
343 | ret ta != null && main isShowing(ta.textArea); |
344 | } |
345 | |
346 | S getText() { |
347 | var ta = taScript; |
348 | if (ta == null) null; |
349 | ret main getText(ta.textArea); |
350 | } |
351 | } |
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: | 692 / 2299 |
Version history: | 236 change(s) |
Referenced in: | [show references] |