The editor
A code editor bound to the strategy source, compiled on every change through the same path Run uses, with the verdict as a chip, an inline banner naming the line, and an amber dot while the buffer has drifted from its last save.
crates/vike-studio/src/editor.rs's EditorPane is one widget — egui_code_editor's
CodeEditor bound to the strategy source string — and the pieces around it are what make it an
editor rather than a text box: a compile status, an error banner, a save baseline, and the
workspace that restores it.
What you see
The editor renders in the Gruvbox colour theme with line numbers at a 13-pixel font, and it fills
whatever height the panel leaves. rows_for_height is the sizing rule and its doc carries the
measurement: the widget's real row pitch is about font_size × 1.16, measured from a screenshot
capture — 45 rows over roughly 680 logical pixels at font 13 — after a first-guess factor of 1.5
left a dead gap of about a fifth of the panel. The result is clamped to 8..=400 rows so a
degenerate height never yields a zero-row editor.
Highlighting is Rust's. crates/vike-studio/src/syntax.rs's header states the reason: Rhai's
surface — fn, let, const, if/else, while, return, // comments, strings, numbers —
is a subset of Rust's, so the built-in Rust syntax highlights it well; a bespoke Rhai syntax that
colours the host verbs specially is a documented follow-up.
A fresh Studio opens on DEFAULT_SCRIPT, an SMA crossover: FAST = 5, SLOW = 20, QTY = 1.0,
long above and short below, reaching the target through market(...) by the delta from
position(). On later launches the workspace restores the last buffer instead — unless that buffer
was empty, in which case the starter script is kept rather than the editor blanked
(saved and workspace).
The compile status
compile_status compiles the buffer as a RhaiStrategy — the same compile path run_slice uses
— and collapses the outcome to Ok/Err(message). Rhai has no notion of warnings, so this is a
strict green/red split. The shell recompiles in StudioState::poll only when the source has
drifted since the last compile: a single compile costs milliseconds, but compiling every frame
regardless of keystrokes would still be wasteful. The restored script is compiled eagerly at
construction, so the first frame never shows a stale status.
The verdict has two renderings. The chip beside the "Editor" title reads ● compiles in green, or
● error · line N in red — ● error when no line is recoverable — with the full message on hover
either way. Under the header — above the editor, not below it, so the editor's row estimate can
never push it off the panel bottom — a failing compile also gets an inline banner:
✗ line N · message, or ✗ message when no line is recoverable.
Where the line number comes from
error_line parses it out of the message text. vike_script::ScriptError is a stringified rhai
error with no structured position to read, and the parser's doc records the empirical fact it
relies on: verified against rhai 1.25.1, both parse errors and top-level runtime errors end with
a (line N, position M) suffix. It never assumes the suffix is present — a message without one, or
a malformed one, yields None and the banner shows the message alone. format_compile_error drops
the redundant suffix from the body once the prefix already carries the line.
Saving, and the amber dot
StudioState::saved_source is the buffer as of the last Save, Load or template load; while
editor.source differs from it, an amber ● unsaved chip sits beside the compile chip with the
hover "Unsaved changes — Ctrl+S saves to the Saved list". Ctrl+S snapshots the buffer under the
name in the Saved pane's box. With an empty box it re-saves under the last saved name, falling
back to untitled only when the session has never saved — the shell's comment records the
misfiling this replaced: save momo-1, keep editing, Ctrl+S again, and the edits landed under
untitled while momo-1 kept the stale code. Loading a saved entry or a template re-baselines the
dot.
The buffer is also part of the workspace snapshot, written to disk once per drift rather than once per frame, so the editor reopens where you left it.
Collapsing
The ◀ button collapses the editor to a 28-pixel rail with a ▶ to expand it. The collapsed rail is a different panel from the expanded editor on purpose: egui persists panel width by id, and sharing one would store the 28-pixel width and reopen the editor as a minimum-width sliver instead of at the width you dragged.
What the buffer becomes
When the Strategy tool says "Rhai script", the toolbar chip reads 🧩 rhai and every Run, Sweep
and Walk-Forward compiles this buffer; a sweep compiles it once per grid point with that point's
param() overrides bound (crates/vike-studio-core/src/run.rs's build_strategy_with). The
language, the order verbs a script may call, and the resource ceilings the engine enforces are the
scripting tree's: writing a strategy,
the order vocabulary, limits.
Studio
The in-app IDE for a strategy over recorded history — a Rhai editor, a store-backed slice picker, worker-thread Run, Sweep and Walk-Forward, and a tabbed results pane, in one window of the desktop app.
Data and slices
The toolbar picker that lists every runnable series in the store — bars, then ticks — discloses what is recorded but cannot be replayed, and never lets a failed scan wear an empty store's clothes; and the Data tool that browses the whole inventory.