Automating the Editor
Scripts that work on Divooka Compute's editor itself: the open documents, their graphs, nodes and wires, what is selected, where the canvas looks, running a document, and the status line. Divooka Compute ships three samples, each written three times - in C#, in Lua and in Python - and the three do the same thing. They are examples: press Ctrl+Shift+E for New from examples, choose Editor Automation, pick one and press Open a copy.
| Sample | What it does |
|---|---|
GridLayout |
Lays the selected nodes out in a grid: in the order they read, top to bottom then left to right, as near square as their count allows, each cell as big as the biggest node. |
PrintAfterSelection |
After each selected statement of a Routine, puts a Print Line that prints what the statement gave - and, for a node with nothing after it, prints the editor's reason. |
RunFolder |
Runs every document in the folder Documents beside the script, one after another, without opening them, and says how each went. |
Running a script
Open the script in Divooka Compute - Ctrl+O, or the Workspace panel. A script's toolbar has Run and Automate Editor where a document's has Run and the Interpreted/Compiled switch:
- Automate Editor runs the script inside the editor, with
Editorto work on. These samples are for it. Everything a run changes is one step of each document's history, so oneCtrl+Ztakes the whole run back, and a run that fails or is stopped leaves every document as it was. - Run (
F5) runs the script on its own, as a terminal would -purefor C#,lunafor Lua,spyfor Python - in the script's folder.Editoris not there; what it prints and what it reads are the dock's.
While a script runs, the toolbar's Run reads Stop (Shift+F5), and a line typed into the dock's input row is what the script reads.
Breakpoints. A press on the gutter left of a line's number, or F9 with the caret on the line, sets a breakpoint, and either kind of run stops there: the line is marked, the dock's Locals list the variables and the Call stack the functions the script is in. F5 goes on, F10 steps over a line, F11 into a function, Shift+F11 out of it. F11 with nothing running starts Automate Editor stopped at the script's first line.
Python packages. With a Python script in front, the toolbar's package button opens its environment: a folder of installed packages the script runs with, chosen for the script or for its workspace folder. New environment makes one, Install installs a package into it by name, by requirement (numpy==2.1) or from a wheel file, and the × beside a package uninstalls it. Both Run and Automate Editor import from the environment the script is in.
C# references. A C# file - a script, or one a document references - can begin with Import(...) and Include(...) lines: Import(Newtonsoft.Json@13.0.3), Import("Lib/Tools.dll"), Import("Library.dvk"), Include("Helpers.cs"). A document referencing such a file lists what it imports and includes under it in its References, in a colour of their own.
A document that works on the editor
A document can do what a script does. One built from the Editor Automation toolbox's nodes - documents, graphs, nodes, the selection, the view and the editor - has its own Automate Editor on its toolbar. Pressing it runs the document against the documents you have open, starting with the one you were on before: everything it changes is one undo step, nothing it did stays if it fails or you stop it, and its breakpoints work as on any document. Run, a compiled run and Publish refuse such a document, naming the node that needs Automate Editor. New from examples has two to try: Editor Automation › Greet After Begin, which works on Editor Automation › Steps.
Trying the samples
- GridLayout. Open a document and select the nodes to arrange -
Ctrl+Afor all of them. OpenGridLayout.py(or the.cs, or the.lua) and press Automate Editor. The nodes move into a grid, the console says how many columns, and oneCtrl+Zputs them back. - PrintAfterSelection. Open a document whose entry is a Routine, select its statements with
Ctrl+A, openPrintAfterSelection.pyand press Automate Editor. A Print Line goes in after each statement that has a next one; pressF5on the document to see what each prints. - RunFolder. Make a folder called
Documentsbeside the script and put documents in it, then openRunFolder.pyand press Automate Editor. Each document runs in turn, the status line saying which, and the console says how each went and how many ran to the end. New from examples has a ready-made folder to try it on: Editor Automation › Run Folder.
What a script works with
The same members in every language. C# calls graph.AddNode("Add", 0, 0), Lua graph:AddNode("Add", 0, 0) - a method with a colon, a property with a dot - and Python graph.AddNode("Add", 0, 0). A list - the selection, a graph's nodes - is an array in C#, a table numbered from 1 in Lua, and a sequence in Python; what is null in C# is nil in Lua and None in Python. A relative path is read from the script's folder.
Editor - the one name every script is given.
ScriptPath, ScriptFolder |
the running script's file, and its folder |
Documents |
the open documents, in the order of their tabs |
ActiveDocument |
the document in front - or, with the script's own text in front, the one in front before it; nothing when none is open |
Open(path) |
open a document, or find it open, and bring it forward |
FindDocuments(folder) |
the .dvk and .dvj documents in a folder and the folders in it, in order |
Run(path), Run(path, mode) |
run a document from its file without opening it - "Interpreted" (the default) or "Compiled" - wait, and say how it went |
Status(text) |
say something on the status line |
A document
Name, Path, HasChanges |
its file's name (or its title, never saved), its file, whether it has unsaved changes |
Graphs, ActiveGraph, EntryGraph, FindGraph(name) |
its graphs; the one on its canvas; the one a run starts from |
Selection, Select(node), Select(nodes), ClearSelection() |
what is selected on its canvas, in the order it was selected, and selecting - showing the nodes' graph first |
View |
where its canvas looks |
Assets, AddAsset(file), AddAsset(file, assetPath), RemoveAsset(assetPath), SaveAsset(assetPath, file) |
its asset library: what it holds, by path (/sun.png); a file embedded; an asset taken out; an asset written to a file |
Activate(), Save(), Run() |
bring its tab forward; save it; run it as its Run button would, in its mode, with its changes, results drawn on its canvas |
A graph
Document, Id, Name, Kind |
where it is, and what kind: "Routine", "Flows", "Function", ... |
Nodes, Wires, FindNode(titleOrName), FindNode(id), FindNodes(titleOrName) |
what it holds; a node by its title as the canvas writes it in English, the name it was given, or its identity |
AddNode(name, x, y), AddNode(name, x, y, functional) |
place a node by the name the node library shows - in English, in the editor's language, or its code's name - as Ctrl+Space places it; in a Routine, functional places a value node off the execution path |
Connect(from, to) |
wire an output to an input, in either order; an input's earlier wire is replaced |
Remove(node), Remove(nodes), Tidy(), Show() |
remove nodes and their wires, as Delete does; lay it out as Tidy does; show it on the canvas |
A node
Graph, Id, Title, Name, X, Y, Width, Height |
where it is and how big it is drawn (0 while it is not drawn) |
Inputs, Outputs, Input(title), Input(index), Output(title), Output(index) |
its pins, top to bottom: on a statement, what runs before and after it, then its values |
IsStatement, Value |
whether something runs before and after it; a value node's value - a Number's, a Text's - as its box shows it, set as typing into it |
MoveTo(x, y), MoveBy(dx, dy), Remove() |
|
InsertAfter(name) |
place a statement right of this one and thread it into the execution path behind it - whatever ran after this one runs after the new one |
A pin - Node, IsInput, Index, Title, Type ("Double"), IsFlow (what runs next, rather than a value), Wires, Connected (the pins at the other ends), Value (what is typed into an input; nothing empties it), Connect(other), Disconnect().
A wire - Graph, From, To, Remove().
The view - Zoom (1 is actual size; settable), X, Y (the middle of the view), CenterOn(x, y), Fit(), Reveal(node).
A run's result - Name, Succeeded, Failure, Seconds, Mode, Output (what it printed, a line at a time), and as text one line: Main.dvk: finished in 0.42 s, or Main.dvk: failed - why.
What the editor refuses is an error the script can catch - an exception in C# and in Python, a Lua error that pcall catches - its message saying why: No node called 'Prnt Line' can go in Main (Routine); the nearest are 'Print Line', .... Stop is not one: nothing in a script can catch it.
The languages
- C# is Divooka Pure's: statements at the top level,
Import(...)of a workload, a package, a document or a NuGet package, andInclude(...)of another file. - Lua is Lua 5.2, the standard library included;
requirefinds a module beside the script first, andos.exitends the script, not the editor. - Python is SteelPython's Python 3.12, its standard library and Divooka's packages importable; a module beside the script imports first, and
sys.exit()ends the script, not the editor.
A script Automate Editor runs is in the editor's own process: what it does to the process - leaving a thread running, ending the process - it does to the editor. A script meant to run on its own is what Run is for.