Skip to content

Selection Sync

With selection sync enabled, selecting a block highlights its corresponding lines in every text view — and clicking a line in a text view selects the block. It works across all views: workspaces, codespaces (read only ones too) and the code editor.

Selection sync is on by default whenever mount() sets up more than one view. Turn it off with mount({ selectionSync: false }), or enable it later yourself:

// once a text view or the code editor is set up
engine.enableSelectionSync();

Code generation produces metadata alongside the text — for each block, the line range it occupies, including statement-input body ranges (generateJavaScriptWithMetadata() exposes the same data). Selection sync uses that mapping in both directions:

  • Block → code: selecting a block in the workspace highlights its range in each text view.
  • Code → block: clicking a line in a text view selects the block that owns it — and highlights its ranges in the other text views too.

Clicking an empty area in a text view clears the highlight everywhere.

Pass the options to mount(), or to enableSelectionSync():

engine.mount({
// …containers
selectionSync: {
blockToCode: true,
codeToBlock: true,
},
});
Option Default Purpose
blockToCode true Enable the block → code direction
codeToBlock true Enable the code → block direction

Each text view highlights in a lighter tint of its own selectionBackground (from editorTheme or themes), so the highlight shows on light and dark themes alike. To use a color of your own, set the CSS variable --morphic-highlight-color; it wins over the theme:

.cm-content { --morphic-highlight-color: rgb(85 189 203 / 0.25); }

Turn it off with engine.disableSelectionSync().

Linked highlighting is what makes side-by-side modes teach: a learner clicks print("hi") in the Python codespace and sees the same statement light up in the block workspace and the read only JavaScript view: three representations, visibly one program.