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 execute function (lines 60-88 in Playground.tsx) forwards the selection to trevorSocket?.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 stdout state.

Data Flow from Editor to Python Interpreter

When you press Mod-d, the following sequence occurs:

  1. Playground.tsx extracts the selected line(s) and calls executeCode.
  2. TrevorWebSocket.executeCode serializes the request as JSON and sends it over the WebSocket.
  3. The Trevor server (running inside the Nallely process) receives the command, runs the code in the active Python interpreter, and streams back stdout or error events.
  4. The Playground’s onMessageHandler (registered in the useEffect at line 44) updates the terminal view via setStdout or displays diagnostics via displayError.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →