Code Editor

Monaco-based code editor with syntax highlighting, multi-tab editing, command palette, JSON schema validation, and full programmatic control.

Live Demo

<iframe id="ce-demo" src="/online/webapp/code-editor" width="100%" height="450" frameborder="0" style="border:1px solid #ccc; border-radius:4px;"></iframe>
<script>window._wsConnect('ce-demo', 'ceSocket');</script>

Embed

<iframe src="https://sgapps.io/online/webapp/code-editor"
    width="100%" height="600" frameborder="0" allow="clipboard-write"></iframe>

Events Reference


active-file:codeEditor:value -- Get or Set Editor Content

The most commonly used event. When called with a string, it sets the editor text. When called with only a callback, it returns the current text.

Arg Type Description
value string (optional) New content to set
callback function (value: string) when getting, () when setting

// Set content
socket.fire("webapp::instance::request",
    "active-file:codeEditor:value",
    "function hello() {\n    return 'world';\n}",
    function () { console.log("Content set"); }
);

// Get content
socket.fire("webapp::instance::request",
    "active-file:codeEditor:value",
    function (value) { console.log("Content:", value); }
);

<button onclick="window._ws('ceSocket')&&window.ceSocket.fire('webapp::instance::request','active-file:codeEditor:value','// Hello from the docs page!\nfunction greet(name) {\n return 'Hello, ' + name + '!';\n}\n\nconsole.log(greet('World'));')">Try: Set JS Code</button><button onclick="window._ws('ceSocket')&&window.ceSocket.fire('webapp::instance::request','active-file:codeEditor:value',function(v){alert('Length: '+v.length+' chars\n\nFirst 200 chars:\n'+v.substring(0,200))})">Try: Get Code</button>


active-file:codeEditor:syntax -- Get or Set Language Mode

Changes the syntax highlighting language. Uses Monaco's language identifiers: javascript, typescript, html, css, json, python, markdown, xml, sql, yaml, go, rust, cpp, etc.

Arg Type Description
syntax string (optional) Language ID to set
callback function (err, currentLanguage: string)

// Set to Python
socket.fire("webapp::instance::request", "active-file:codeEditor:syntax", "python");

// Get current language
socket.fire("webapp::instance::request", "active-file:codeEditor:syntax",
    function (err, lang) { console.log("Language:", lang); }
);

<button onclick="window._ws('ceSocket')&&window.ceSocket.fire('webapp::instance::request','active-file:codeEditor:syntax','javascript')">Try: JavaScript</button><button onclick="window._ws('ceSocket')&&window.ceSocket.fire('webapp::instance::request','active-file:codeEditor:syntax','python')">Try: Python</button><button onclick="window._ws('ceSocket')&&window.ceSocket.fire('webapp::instance::request','active-file:codeEditor:syntax','html')">Try: HTML</button>


active-file:codeEditor:options -- Set Monaco Editor Options

Configures the Monaco editor instance. Any Monaco IEditorOptions can be passed.

Arg Type Description
options object Monaco editor options
callback function (err)

// Make read-only with large font
socket.fire("webapp::instance::request", "active-file:codeEditor:options", {
    readOnly: true,
    fontSize: 18,
    wordWrap: "on",
    minimap: { enabled: false }
});

// Restore editable
socket.fire("webapp::instance::request", "active-file:codeEditor:options", {
    readOnly: false,
    fontSize: 14
});

<button onclick="window._ws('ceSocket')&&window.ceSocket.fire('webapp::instance::request','active-file:codeEditor:options',{readOnly:true,fontSize:18})">Try: Read-Only + Large Font</button><button onclick="window._ws('ceSocket')&&window.ceSocket.fire('webapp::instance::request','active-file:codeEditor:options',{readOnly:false,fontSize:14})">Try: Restore Editable</button>


active-file:codeEditor:selection -- Get Selected Text

Returns the current text selection with line/column positions.

socket.fire("webapp::instance::request", "active-file:codeEditor:selection",
    function (err, sel) {
        console.log("Selected:", sel);
        // { startLine: 3, startCol: 5, endLine: 3, endCol: 20, text: "selected text" }
    }
);

<button onclick="window._ws('ceSocket')&&window.ceSocket.fire('webapp::instance::request','active-file:codeEditor:selection',function(e,s){alert(s.text?('Selected: "'+s.text+'" at line '+s.startLine):'No selection')})">Try: Get Selection</button>


active-file:codeEditor:insertText -- Insert Text

Inserts text at a specific position or at the current cursor position. If a position object is provided, text is inserted at that line/column. Otherwise, it replaces the current selection.

Arg Type Description
text string Text to insert
position object (optional) &#x7B; line: number, col: number &#x7D;
callback function (err)

// Insert at line 1, column 1
socket.fire("webapp::instance::request", "active-file:codeEditor:insertText",
    "// Auto-generated header\n",
    { line: 1, col: 1 }
);

// Insert at current cursor position
socket.fire("webapp::instance::request", "active-file:codeEditor:insertText",
    "console.log('inserted');"
);

<button onclick="window._ws('ceSocket')&&window.ceSocket.fire('webapp::instance::request','active-file:codeEditor:insertText','// Inserted from docs!\n',{line:1,col:1})">Try: Insert at Top</button>


active-file:codeEditor:revealLine -- Scroll to Line

Scrolls the editor to center a specific line number in the viewport. Useful when navigating to errors or search results.

Arg Type Description
lineNumber number Line to reveal
callback function (err)

socket.fire("webapp::instance::request", "active-file:codeEditor:revealLine", 42);

active-file:codeEditor:json:schema -- JSON Schema Validation

Sets a JSON Schema for real-time validation of the active editor content. Monaco will show errors/warnings inline when the content doesn't match the schema.

Arg Type Description
schema object JSON Schema object
callback function (err)

socket.fire("webapp::instance::request", "active-file:codeEditor:json:schema", {
    type: "object",
    properties: {
        name: { type: "string" },
        version: { type: "string", pattern: "^\\d+\\.\\d+\\.\\d+$" }
    },
    required: ["name", "version"]
});

active-file:save -- Save Active File

Triggers the save action on the currently active file tab. The file is written back to its original path in the file system.

socket.fire("webapp::instance::request", "active-file:save", function (err) {
    console.log(err || "File saved");
});

active-file:markers -- Set Error/Warning Markers

Programmatically set diagnostic markers (errors, warnings, info) on the editor. This is useful for showing linting results, build errors, or custom validation from your application.

Arg Type Description
markers Array Array of marker objects
callback function (err)

Each marker: &#x7B; startLine, startCol, endLine, endCol, message, severity &#x7D;
Severity levels: 1 = Hint, 2 = Info, 4 = Warning, 8 = Error

socket.fire("webapp::instance::request", "active-file:markers", [
    { startLine: 3, startCol: 1, endLine: 3, endCol: 30,
      message: "Unused variable 'x'", severity: 4 },
    { startLine: 7, startCol: 5, endLine: 7, endCol: 15,
      message: "Syntax error: unexpected token", severity: 8 }
]);

<button onclick="window._ws('ceSocket')&&window.ceSocket.fire('webapp::instance::request','active-file:markers',[{startLine:1,startCol:1,endLine:1,endCol:50,message:'This is a warning from the docs page',severity:4},{startLine:3,startCol:1,endLine:3,endCol:30,message:'This is an error marker',severity:8}])">Try: Set Markers</button><button onclick="window._ws('ceSocket')&&window.ceSocket.fire('webapp::instance::request','active-file:markers',[])">Try: Clear Markers</button>


files:open -- Open a File in a New Tab

Opens a file in a new editor tab. The type field determines the renderer: &#x22;file&#x22; for text editor, &#x22;markdown&#x22; for rendered markdown, &#x22;file-image&#x22; for image viewer.

Arg Type Description
fileConfig object &#x7B; path, type&#x3F;, title&#x3F; &#x7D;
callback function (err)

socket.fire("webapp::instance::request", "files:open", {
    path: "web:///api/applications.json",
    type: "file",
    title: "applications.json"
});

files:list -- List Open Tabs

Returns an array of all currently open tabs with their index, name, path, type, and title.

socket.fire("webapp::instance::request", "files:list", function (err, tabs) {
    console.log(tabs);
    // [{ index: 0, name: "index.js", path: "/home/user/index.js", type: "file", title: "index.js" }]
});

<button onclick="window._ws('ceSocket')&&window.ceSocket.fire('webapp::instance::request','files:list',function(e,t){alert('Open tabs: '+t.length+'\n'+t.map(function(x){return x.index+': '+x.title}).join('\n'))})">Try: List Tabs</button>


files:active:set -- Activate a Tab

Switches to a specific tab by its index (as returned by files:list).

Arg Type Description
tabIndex number Zero-based tab index
callback function (err)

socket.fire("webapp::instance::request", "files:active:set", 0);

files:close:all -- Close All Tabs

Closes all open editor tabs.

socket.fire("webapp::instance::request", "files:close:all");

gui:sidebar:toggle -- Show/Hide Sidebar

Toggle the file tree sidebar visibility.

Arg Type Description
visible boolean true to show, false to hide

socket.fire("webapp::instance::request", "gui:sidebar:toggle", false); // hide
socket.fire("webapp::instance::request", "gui:sidebar:toggle", true);  // show

<button onclick="window._ws('ceSocket')&&window.ceSocket.fire('webapp::instance::request','gui:sidebar:toggle',false)">Try: Hide Sidebar</button><button onclick="window._ws('ceSocket')&&window.ceSocket.fire('webapp::instance::request','gui:sidebar:toggle',true)">Try: Show Sidebar</button>


Complete Example

<!DOCTYPE html>
<html>
<head><title>Embedded Code Editor</title></head>
<body>
    <div style="display:flex;gap:8px;padding:10px;flex-wrap:wrap;">
        <button id="set-code">Load Sample</button>
        <button id="get-code">Read Code</button>
        <button id="set-python">Python Mode</button>
        <button id="readonly">Read-Only</button>
        <button id="add-markers">Show Errors</button>
    </div>

    <iframe id="editor" src="https://sgapps.io/online/webapp/code-editor"
        width="100%" height="500" frameborder="0" allow="clipboard-write"></iframe>

    <pre id="output" style="background:#f6f8fa;padding:10px;max-height:200px;overflow:auto;"></pre>

    <script src="https://sgapps.io/components/window-socket/index.js"></script>
    <script>
        var socket = new WindowSocket(document.getElementById('editor').contentWindow);
        socket.start();

        socket.on("webapp::connection::ping", function () {
            socket.fire("webapp::instance::embed-mode", true);
        });

        document.getElementById('set-code').onclick = function () {
            socket.fire("webapp::instance::request", "active-file:codeEditor:value",
                "def fibonacci(n):\n    a, b = 0, 1\n    for _ in range(n):\n        a, b = b, a + b\n    return a\n\nprint(fibonacci(10))");
            socket.fire("webapp::instance::request", "active-file:codeEditor:syntax", "python");
        };

        document.getElementById('get-code').onclick = function () {
            socket.fire("webapp::instance::request", "active-file:codeEditor:value",
                function (v) { document.getElementById('output').textContent = v; });
        };

        document.getElementById('set-python').onclick = function () {
            socket.fire("webapp::instance::request", "active-file:codeEditor:syntax", "python");
        };

        document.getElementById('readonly').onclick = function () {
            socket.fire("webapp::instance::request", "active-file:codeEditor:options", { readOnly: true });
        };

        document.getElementById('add-markers').onclick = function () {
            socket.fire("webapp::instance::request", "active-file:markers", [
                { startLine: 2, startCol: 1, endLine: 2, endCol: 20, message: "Consider using a list comprehension", severity: 4 }
            ]);
        };
    </script>
</body>
</html>