How to Use the Code Playground in Trevor-UI for Live Coding
The Trevor-UI code playground is a CodeMirror 6-based modal that connects to the Nallely Python session via WebSocket, allowing you to write, execute, and save Python code in real time using keyboard shortcuts like Mod-d to run and Mod-s to persist.
The dr-schlange/nallely-midi repository ships Trevor-UI, a React-based web interface for controlling Nallely MIDI sessions. Its integrated code playground lets you live-code Python against connected hardware without leaving the browser, with full persistence across UI reloads.
Opening the Trevor-UI Code Playground
Press Alt-Space (or click the "Playground" button in the device-patching toolbar) to open the modal. The component is lazily loaded from trevor/src/components/modals/Playground.tsx (see the dynamic import pattern in DevicePatching.tsx lines 48-51) to keep the initial bundle size small.
When opened, the playground renders a CodeMirror 6 editor pane and a terminal view. The editor comes pre-loaded with any previously saved code from the Redux store (trevorSlice.ts), ensuring you never lose your work between sessions.
Executing Python Code in Real Time
The playground communicates with the Nallely process through the TrevorWebSocket protocol defined in trevor/src/websockets/websocket.ts.
Running Code with Keyboard Shortcuts
- Mod-d (⌘-d on macOS, Ctrl-d on Windows/Linux): Executes the current line or selected text. The
executefunction (lines 60-88 inPlayground.tsx) forwards the selection totrevorSocket?.executeCode(code)(line 106). - Mod-p: Wraps the selected code in
print(...)before execution, useful for quick inspection. - Mod-l: Clears the terminal pane by resetting the internal
stdoutstate.
Data Flow from Editor to Python Interpreter
When you press Mod-d, the following sequence occurs:
Playground.tsxextracts the selected line(s) and callsexecuteCode.TrevorWebSocket.executeCodeserializes the request as JSON and sends it over the WebSocket.- The Trevor server (running inside the Nallely process) receives the command, runs the code in the active Python interpreter, and streams back
stdoutorerrorevents. - The Playground’s
onMessageHandler(registered in theuseEffectat line 44) updates the terminal view viasetStdoutor displays diagnostics viadisplayError.
Saving Work and Auto-Completion
Persisting Code Across Sessions
Press Mod-s to persist the current buffer. This triggers trevorSocket?.saveCode(code) (line 80 in Playground.tsx), which stores the content in the Nallely session state. The Redux slice (trevorSlice.ts) holds the playground_code field; when the server broadcasts a full-state update, the UI synchronizes the editor content, ensuring your code survives page reloads.
Intelligent Auto-Completion
Invoke completion with Mod-Space or by typing a dot. The askCompletion function (lines 35-38) extracts the last expression and queries the server via websocket.requestCompletion(lastExpression) (line 51). The server returns a JSON array of suggestions that CodeMirror renders as an autocomplete dropdown.
Working with Connected Devices
Use the device drop-downs in the modal header to inject references to MIDI or virtual devices. Selecting a device calls insertAssignmentAtCursor (lines 18-45), injecting a line such as:
mydevice = connected_devices[0]
This lets you immediately script against hardware without manually typing device identifiers.
Programmatic Integration Examples
Opening the Playground from Custom Components
Mirror the lazy-loading pattern used in DevicePatching.tsx:
import { lazy, useState } from "react";
const Playground = lazy(() =>
import("./modals/Playground").then(m => ({ default: m.Playground }))
);
function CustomToolbar() {
const [showPlayground, setShowPlayground] = useState(false);
return (
<>
<button onClick={() => setShowPlayground(true)}>Open Playground</button>
{showPlayground && (
<Playground onClose={() => setShowPlayground(false)} />
)}
</>
);
}
Executing Code Without the UI
For automated testing or headless operation, use the TrevorWebSocket class directly:
import { TrevorWebSocket } from "./websockets/websocket";
async function runHeadless(wsUrl: string, code: string) {
const socket = new TrevorWebSocket(wsUrl);
await socket.waitForReady();
socket.executeCode(code); // Same method the Playground uses
}
runHeadless(
"ws://localhost:6788/trevor",
"print('Hello from automated script')"
);
Adding Server-Side Completion Handlers
Extend the Python side in nallely/session.py to handle the completion command. The Playground already sends requests via requestCompletion; you only need to implement the handler that returns:
{
"command": "completion",
"options": [
{ "label": "my_device", "type": "variable" },
{ "label": "send_note", "type": "function" }
]
}
Summary
- Alt-Space opens the CodeMirror 6-based playground modal, lazily loaded from
Playground.tsx. - Mod-d executes selected Python code via
TrevorWebSocket.executeCode, streaming results back through the WebSocket. - Mod-s persists code to the Nallely session state via
saveCode, with Redux ensuring content survives reloads. - Mod-Space triggers auto-completion through
requestCompletion, querying the server for contextual suggestions. - Device drop-downs inject ready-to-use device references via
insertAssignmentAtCursor.
Frequently Asked Questions
How do I open the code playground in Trevor-UI?
Press Alt-Space on your keyboard, or click the "Playground" button in the device-patching toolbar. The modal is lazily imported from trevor/src/components/modals/Playground.tsx to optimize performance.
What keyboard shortcuts are available for live coding?
Mod-d executes the current line or selection, Mod-p executes with automatic printing, Mod-s saves the buffer to session state, Mod-l clears the terminal, and Mod-? displays a help cheat-sheet in the terminal pane.
How does code execution work behind the scenes?
When you press Mod-d, the execute function in Playground.tsx (lines 60-88) sends the code to TrevorWebSocket.executeCode, which transmits it over the WebSocket to the Trevor server inside Nallely. The server runs the code in the active Python interpreter and pushes stdout or error events back to the UI.
Can I use the playground functionality without the browser UI?
Yes. Import TrevorWebSocket from trevor/src/websockets/websocket.ts and call executeCode directly after waiting for the connection to be ready. This is useful for automated testing or scripting against a headless Nallely session.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →