Editor & Intellisense
The SlangEditor component, its syntax-highlight tokeniser, the useSlangIntellisense autocomplete hook, parameter hints, hover tooltips, and the colour settings system.
SlangEditor
SlangEditor.tsx is a self-contained editor panel. It renders a scrollable code area, a gutter with line numbers, a syntax-highlight overlay, a resizable log panel, and a top toolbar — all built with plain DOM elements and inline styles (no external code-editor library). The editor keeps its text in sync with SlangStore so that external code changes (e.g. loading a script from the library) are reflected without re-mounting.
Props
| Prop | Type | Description |
|---|---|---|
| theme | 'dark' | 'light' | Controls the colour palette for the editor, log panel, toolbar, and syntax highlighting. |
State Variables
codestringCurrent script text, kept in sync with SlangStore via onSlangCodeChange.
logsLogEntry[]Accumulated log entries from slangLogger. New entries are appended via subscribe().
logHeightnumberHeight in px of the resizable log panel (min 40, max 600).
showSavePopupbooleanWhether the "Save to library" name-input popup is visible.
savePopupNamestringUser-entered script name for the save-to-library popup.
savePopupErrorstring | nullValidation or API error shown inside the save popup.
savePopupLoadingbooleanDisables the save button while the API call is in-flight.
currentSlang{ id, name } | nullMetadata of the currently loaded library script (from SlangStore).
saveCurrentLoadingbooleanTrue while an overwrite-save API call is in-flight.
savePopupPos{ top, left } | nullAbsolute pixel position for the save popup (calculated from the Save button rect).
Layout Structure
SlangEditorHeaderTop toolbar: Compile, Decompile, Open, Save buttons. Renders as a sticky row above the editor area.
Line-number gutterA fixed-width column rendered as a <div> containing per-line number spans. Scroll is synced with the textarea via a negative margin-top offset.
Highlight overlay <pre>Positioned absolutely on top of the textarea. Receives the same scroll offset so highlighted text lines up pixel-perfect with the cursor.
Editing <textarea>The actual input element. Transparent background and matching font metrics ensure the overlay is visible through it.
Drag dividerA 4px drag handle between the editor and log panel. Mouse-down/move/up handlers update logHeight with clamping.
Log panelA scrolling list of LogEntry items colour-coded by type (info = muted, success = green, error = red). Auto-scrolls to the latest entry.
Save popup (portal)Rendered via createPortal() into document.body. Positioned with an absolute offset computed from the Save button's bounding rect.
Key Callbacks
| Callback | Description |
|---|---|
| handleCompile | Guards against empty editor, then calls compileSlang(code) from GraphCommands. |
| handleDecompile | Calls compileGraph() (which calls decompile() internally) and sets the returned source text into the editor. |
| handleClearLogs | Empties the local logs state array and calls slangLogger.clear(). |
| handleSave | Opens the save-to-library popup, positioning it below the Save button via getBoundingClientRect(). |
| handleSaveConfirm | Validates the name field, calls apiSaveSlang(), then calls inventoryPrependSlang() to insert the new entry into the library panel without a full reload. |
| handleSaveCurrent | Overwrites the currently loaded script (via API) and calls inventoryReplaceSlang() to update the library panel entry in-place. |
| handleFileSelect | Reads a .slang / .txt / .js / .ts file via FileReader and injects the text into the editor. |
| syncScroll | Copies scrollTop and scrollLeft from the textarea to the highlight <pre>, and updates the gutter inner offset. |
Syntax Highlighting
The highlightLine(line) callback converts each source line into an array of React <span> elements with inline colour styles from the active colour palette. Three line patterns are handled:
Comment line
Standalone call
Assignment
tokeniseArgs()
The inner helper splits the raw args string by comma, then for each token applies:
Comma ,punctuation colour
Quoted string "…" or '…'string colour
Numeric literal -?d+(.d+)?number colour
Any other tokenvariable colour (treated as a node reference)
SlangEditorHeader
A fully controlled, stateless toolbar component. All state lives in the parent SlangEditor.
| Prop | Type | Description |
|---|---|---|
| theme | 'dark' | 'light' | Drives button and border colour tokens. |
| currentSlang | { id, name } | null | When set, the overwrite-save button is enabled and shows the script name in its tooltip. |
| saveCurrentLoading | boolean | Disables the overwrite-save button while the API call is pending. |
| code | string | Current editor text (passed for potential future use; not currently displayed in the header). |
| saveBtnRef | RefObject<HTMLButtonElement> | Ref attached to the Save-to-library icon button so the parent can read its position for popup placement. |
| fileInputRef | RefObject<HTMLInputElement> | Ref for the hidden file input so the parent can trigger it programmatically via onOpen. |
| onCompile | () => void | Called when the ▶ Compile button is clicked. |
| onDecompile | () => void | Called when the ◀ Decompile button is clicked. |
| onOpen | () => void | Triggers fileInputRef.current.click() to open the file picker. |
| onSave | () => void | Opens the save-to-library popup. |
| onSaveCurrent | () => void | Overwrites the currently loaded script via API. |
| onFileSelect | (e) => void | Handles the file input change event. |
Button layout (left → right)
useSlangIntellisense
useSlangIntellisense(editorRef, setCode) is a React hook that attaches keyboard and input event listeners to the textarea ref and computes suggestions in real time. It returns an IntellisenseState object that the editor passes to IntellisensePopup for rendering.
IntellisenseState
interface IntellisenseState {
visible: boolean; // Is the popup currently visible?
items: SuggestionItem[]; // Filtered suggestions to display
selectedIndex: number; // Keyboard-highlighted item index
position: { top: number; left: number }; // px position relative to editor
prefix: string; // Partial text typed so far (for replacement)
mode: 'command' | 'variable' | 'param' | null;
activeCommand: string | null; // Command name when completing params
activeParamIndex: number; // 0-based param position inside ()
activeTypedArgs: string[]; // Already-typed args (for paramGroups resolution)
}Suggestion Modes
Namespace suggestions
Trigger: Cursor is on an unquoted alphabetical token before a dot — e.g. typing "ta"
Items: All namespace prefixes (sc, ta, dm, rm, ex, ch, cg) filtered by the partial text. Insert text appends "." so the next suggestion immediately refines by command.
Command suggestions
Trigger: Cursor is typing the function name part (after a dot, or at start of RHS)
Items: All registered commands filtered by prefix, restricted to the declared namespace when one is present. Config/action commands (def.action) get the "config" kind badge; others get "command".
Variable suggestions
Trigger: Cursor is inside parentheses at an input-reference position (0 … inputs-1)
Items: All variable names declared on prior lines in the current script, filtered by the partial text.
Parameter suggestions
Trigger: Cursor is inside parentheses at a parameter position (≥ inputs)
Items: For known enum-like params (symbol, timespan, operator, tpType, stopType, positionType, channel), a curated list of valid values. For GETVALUE channel, resolves the input variable's outputChannels dynamically. Falls back to a generic <paramName> placeholder hint.
Keyboard Navigation
Moves selectedIndex down (wraps). Prevents default textarea cursor movement.
Moves selectedIndex up (wraps). Prevents default.
Accepts the highlighted suggestion: replaces the current prefix in the textarea with the item's insertText. Closes the popup.
Closes the popup without accepting any suggestion.
Re-triggers suggestion computation when triggerOnAlpha is enabled.
IntellisensePopup Component
A pure presentation component that renders the suggestion list as a fixed-position overlay. Each item shows a kind badge, the label, and the detail string (function signature or param type). Clicking an item calls the onSelect callback.
SuggestionItem kind colours
useCommandHover & CommandHoverTooltip
Hovering the mouse over a command name in the editor shows a rich tooltip with the full function signature (inputs → parameters → outputs). The tooltip is positioned via clientX / clientY mouse coordinates and auto-flips below or above the cursor to stay inside the viewport.
useCommandHover(editorRef)
Attaches a mousemove listener to the textarea. On each move, it calculates the approximate character position under the cursor (using font metrics), extracts the word at that position, and looks it up in the command registry via getCommandDef(). Returns a state object with visible, commandName, def, and position.
CommandHoverTooltip
Renders the tooltip card when hover.visible is true. Shows: command name, input channels, parameters with types, and output channels. Rendered via createPortal() into document.body at a fixed z-index.
SlangConfig — Colour Settings
SlangConfig.ts defines the colour palette and intellisense knobs for the editor. Settings are persisted to localStorage under the key traderoid_slang_editor_settings and broadcast via a CustomEvent so multiple components stay in sync.
SlangColors
| Key | Default (dark) | Default (light) | Applied to |
|---|---|---|---|
| command | #c792ea (purple) | #7c3aed (purple) | Normal command / function names (e.g. SMA, RSI) |
| configCommand | #ffcb6b (gold) | #b45309 (amber) | Action commands (SetWindowSize, AddToChart, …) |
| variable | #82aaff (blue) | #2563eb (blue) | Variable names (left-hand side of =) |
| string | #c3e88d (green) | #16a34a (green) | Quoted string literals |
| number | #f78c6c (orange) | #ea580c (orange) | Numeric literals |
| comment | #546e7a (grey) | #9ca3af (grey) | Comment lines (// or #) |
| punctuation | #89ddff (cyan) | #0891b2 (teal) | = ( ) , and namespace dots |
| plain | #d1d4dc (light grey) | #333333 (dark grey) | Any other token |
SlangIntellisenseSettings
| Setting | Default | Description |
|---|---|---|
| enabled | true | Master toggle for all intellisense features. |
| triggerOnAlpha | true | Re-trigger suggestions whenever an alphabetical character is typed. |
| maxSuggestions | 10 | Maximum items shown in the popup at once. |
| showParameterHints | true | Show inline parameter type hints while typing inside parentheses. |
| showCommandDescriptions | true | Show rich descriptions (from node definitions) for commands. |
| showVariableSuggestions | true | Include previously declared variable names as input suggestions. |
Config API
getSlangEditorSettings()Returns the current settings object.
setSlangEditorSettings(settings)Saves to localStorage and dispatches a CustomEvent so subscribers update immediately.
subscribeToSlangEditorSettings(listener)Adds a listener for the CustomEvent. Returns an unsubscribe function.
getSlangColors(theme)Shorthand — returns the dark or light SlangColors from the current settings.