Editing superpowers

The input of the playground is a code editor, and RTCode adds tools to it that edit by gesture. Nudge a number with the arrow keys, edit many places at once with selections and chords, encode and decode a selection, evaluate expressions, and select and inspect HTML. This guide shows each tool and its keys. Commands lists every command, and Keyboard shortcuts the keys alone.

Nudge numbers and booleans

With a number selected, the arrow keys change it. It is the quickest way to tune a size, a delay or a color channel while the output follows.

What counts as a number

A selection is a number only when its whole text is an optional sign, digits with at most one dot, and then letters or % for a unit. Underscores in the digits are allowed and ignored.

Counts as a numberDoes not
10rem, -5%, .5, 1_000px, 0071e3, 10 px, #fff, calc(…), px, 1.2.3

Nudge with the arrow keys

Select a number and press ↑ or ↓. While a number is selected the arrow keys change every selected number, and the others stay as they are, instead of moving the cursor, extending the selection, scrolling or moving lines. Press Esc or click to collapse the selection first when you want the cursor keys back.

KeysStep
↑ and ↓1
Shift+↑ / ⇧+↑ and Shift+↓ / ⇧+↓10
Ctrl+↑ / ⌘+↑ and Ctrl+↓ / ⌘+↓100
Alt+↑ / ⌥+↑ and Alt+↓ / ⌥+↓0.1, with the result rounded to one decimal
Alt+Shift+↑ / ⌥+⇧+↑ and Alt+Shift+↓ / ⌥+⇧+↓0.01, with the result rounded to two decimals

The toolbar shows the delta controls while a selection holds a number: ↑ and ↓ nudge by 1, and a press that you hold repeats every 40 ms after 200 ms. They always take the step of 1, whatever modifier you hold. Select 3rem below and try the keys.

html
<meta name=color-scheme content="light dark">
<h1 style=font-size:3rem>Nudge me</h1>

How the result is written

A nudge keeps the shape of what you wrote: the unit stays, a leading dot stays, zero padding stays, and so do the underscores, counted from the right.

BeforeNudgeAfter
.5+0.1.6
007+1008
1_000+11_001
10+0.0110.01
1.5+12.5

The number of decimals is the one you wrote, and grows to two at most when the result needs them. A selection with two dots is left unchanged.

Booleans

With true or false selected, in any case, plain ↑ and ↓ flip every selected boolean. The result is lower case, so TRUE becomes false. The Shift, Ctrl and Alt variants are not bound for booleans. If the selections hold numbers and booleans, the arrows change only the numbers.

Undo

Presses less than 600 ms apart, as when you hold a key or a toolbar button, merge into one undo step. The step ends 600 ms after the last edit, when you undo, when you press another key after a repeat, when you switch to a different nudge key, and before a deploy or another undoable edit of RTCode.

The delta expression

Every step runs an expression, (x + d) by default, where x is the number, i the index of its selection and d the step. Press Alt+= / ⌥+= with a selection, or the = button of the toolbar, to change it. The prompt shows the current expression, and an empty answer restores the default. The = button shows ✱ when the expression is not the default, and it is disabled while booleans are selected.

Only x, i, d and the members of Math, such as abs, round, min, max, random and PI, are defined. Any other name, including Number and parseInt, throws … is not defined when a nudge runs. A failing nudge shows a toast with the message, and the badge of the = button pulses red for two seconds.

Each ↑ below grows the value by d percent, so ↑ adds 1% and Shift+↑ / ⇧+↑ adds 10%.

js
round(x * (1 + d / 100) * 100) / 100

Expressions can use i to stagger several selections. With five selections on five 0ms values, this expression gives 0ms, 100ms, 200ms, 300ms and 400ms in one press of ↑. The index follows the order of the selections in the editor, which is not always the order of the document.

js
x + d * 100 * i

Example: staggered delays

Open the page below, select each 0ms with multiple cursors, set the expression to x + d * 100 * i, and press ↑.

html
<style>
  li { animation: wave 1s ease-in-out infinite alternate }
  @keyframes wave { to { translate: 5rem } }
</style>
<ul>
  <li style=animation-delay:0ms>One
  <li style=animation-delay:0ms>Two
  <li style=animation-delay:0ms>Three
  <li style=animation-delay:0ms>Four
  <li style=animation-delay:0ms>Five
</ul>

Edit with multiple cursors

Selection chords

Alt+S / ⌥+S followed by a letter changes the selections themselves. A chord is two steps: press Alt+S, then press the letter on its own. These chords need at least one non-empty selection. Without one, Alt+S inserts a style snippet instead.

ChordDoes
Alt+S R / ⌥+S RReverse Directions: flips the direction of every selection.
Alt+S U / ⌥+S UUnify Directions: gives every selection the direction of the last one.
Alt+S V / ⌥+S VSplit to Cursors: turns each non-empty selection into cursors at its start and end.
Alt+S I / ⌥+S IInvert: selects every unselected span, then unselects line breaks.
Alt+S L / ⌥+S LInvert in Line: selects the unselected parts of each touched line.
Alt+S F / ⌥+S FFill…: repeats a text, one space by default, to the length of each selection.
Alt+S X / ⌥+S XReplace…: replaces every selection with a literal string, and inserts it at cursors too.
Alt+S H / ⌥+S HEnclose with HTML Element…: wraps each selection in an element.
Alt+S P / ⌥+S PSplit at Fixed Width…: joins chunks of a width with a separator, 2,- by default.
Alt+S D / ⌥+S DDelete Lines Without: deletes every line that no selection or cursor touches.
Alt+S N / ⌥+S NUnselect Line Breaks: splits multi-line selections per line, then removes the cursors.
Alt+S C / ⌥+S CRemove Cursors: removes the empty selections.
Alt+H L / ⌥+H LExtend to Whole Lines: extends each selection to whole lines and merges those that share a line. It needs no selection.

Fill, Replace and Enclose push the result to the output. A void element such as img is refused with img is self-closing; cannot surround.

Example: wrap three words in links

Select three words with multiple cursors, press Alt+S H / ⌥+S H and type a href=//example.com. Each word becomes <a href=//example.com>word</a>.

Reorder the selected texts

The chords that start with Alt+M / ⌥+M move the selected texts among the selections, in the order of the selections in the editor. Each one is a single undo step. Rotate needs only one selected text, so it can move text into empty cursors. Without the selections a chord needs, Alt+M inserts a module script snippet instead.

ChordDoesNeeds
Alt+M → / ⌥+M →Rotate →: moves the last text to the first selection.One selected text, and other cursors
Alt+M ← / ⌥+M ←Rotate ←: moves the first text to the last selection.One selected text, and other cursors
Alt+M ↑ / ⌥+M ↑Shuffle: puts the texts in random order.Two selected texts
Alt+M S / ⌥+M SSort as string: sorts with localeCompare.Two selected texts
Alt+M N / ⌥+M NSort as number: sorts by Number(text).Two selected texts
Alt+M ↓ / ⌥+M ↓ or Alt+M R / ⌥+M RReverse: reverses the order of the texts.Two selected texts

Move the selections

Ctrl+M / ⌘+M turns Selection Move on or off, with a toast that lists the keys. While it is on, Alt+↑ / ⌥+↑, Alt+↓ / ⌥+↓, Alt+← / ⌥+← and Alt+→ / ⌥+→ move the selections themselves, not the text: up and down by a line, with wrap-around at the first and last line, and left and right by a column across line ends. When a number is selected, Alt+↑ and Alt+↓ still nudge it.

Paste with Positions

Paste with Positions…, in the palette and the context menu, pastes clipboard text in which | creates a cursor and |>…<| creates a selection. Text with markers replaces every selection, and plain text goes to the primary selection only. An unclosed |> is pasted as it is. A paste with markers is one undo step and pushes to the output. If the browser blocks the clipboard, the command shows Clipboard blocked by browser and asks you to type the text.

Copy this text, put the cursor on an empty line, and run the command. You get a list with the first label selected and a cursor in the second item.

html
<ul>
  <li>|>First<|</li>
  <li>|</li>
</ul>

The editor's own keys

The editor's multi-cursor gestures, such as Alt and click, keep working, except where a key of RTCode replaces them. Keyboard shortcuts lists the replaced keys.

Encode and decode selections

Select text and choose an Encode or Decode command from the palette or the context menu, where they sit in the js group. Each command maps every selection and pushes the result to the output. A selection that throws shows its index and the message, and stays unchanged.

TransformEncodeDecodeWhat it does
URI componentAlt+Shift+U E / ⌥+⇧+U EAlt+Shift+U D / ⌥+⇧+U DencodeURIComponent and decodeURIComponent.
Base64Alt+Shift+B E / ⌥+⇧+B EAlt+Shift+B D / ⌥+⇧+B DUTF-8 bytes to standard Base64, and back.
HexAlt+Shift+H E / ⌥+⇧+H EAlt+Shift+H D / ⌥+⇧+H DUTF-8 bytes to lower-case hex pairs, and back.
HTML entitiesAlt+Shift+H E / ⌥+⇧+H EAlt+Shift+H D / ⌥+⇧+H DEscapes <, >, &, " and ' as &lt;, &gt;, &amp;, &quot; and &#39;, and decodes any entity.
JSONAlt+Shift+J E / ⌥+⇧+J EAlt+Shift+J D / ⌥+⇧+J DEncode parses and pretty-prints with two spaces. Decode parses and minifies.
URLAlt+Shift+L E / ⌥+⇧+L EAlt+Shift+L D / ⌥+⇧+L DencodeURI and decodeURI.
PunycodeAlt+Shift+P E / ⌥+⇧+P EAlt+Shift+P D / ⌥+⇧+P DConverts a hostname with new URL, and leaves the text unchanged on an error. Decode loads the converter on first use.

Note: Two pairs share a key with another command. With a selection, Alt+Shift+B / ⌥+⇧+B opens a popup output instead of starting the Base64 chords, and the Hex chords belong to HTML entities. Use the palette or the context menu for Base64 and Hex. See Keyboard shortcuts.

Evaluate expressions

Three commands apply JavaScript to the selections. All of them need a selection and sit in the eval group of the context menu.

CommandKeysWhat it does
Eval SelectionsAlt+E E / ⌃+⌘+E EEvaluates the text of each selection as JavaScript and replaces it with the result, formatted as a number. A selection that throws stays unchanged. Select 2+3 and the result is 5.
Eval Expression on Selections… (Number)Alt+E ` / ⌘+E `Asks for an expression, x by default, with x the number of the selection and i its index. It first evaluates each selection as Eval Selections does, then replaces each number with the result, keeping its unit and shape.
Eval Expression on Selections… (String)Alt+E S / ⌘+E SAsks for an expression, `${x}` by default, with x the text of the selection and i its index. A selection that throws shows index: message and stays unchanged.

For example, select the lines of a list, run the String command, and answer with the expression below to number them.

js
`${i + 1}. ${x}`

Note: On macOS, ⌘+E also opens the first route, and that command wins, so the two expression chords open the route there. Use the palette or the context menu.

HTML helpers

Select by element

Ctrl+Shift+I / ⌘+⇧+I, Ctrl+Shift+O / ⌘+⇧+O and Ctrl+Shift+U / ⌘+⇧+U select, for every cursor, the inner content of the enclosing element, the whole element, or its opening and closing tags. They use the markup as you wrote it. Repeating Outer on an exact element selection climbs to the parent. The same commands are in Playground ▸ Input ▸ Select ▸ HTML.

Ctrl / ⌘ and click on text in the input selects the inner content of the clicked element, or its whole element when it has no inner content. Clicking inside an exact selection climbs to the enclosing element.

Element statistics

HTML: Element Stats…, Alt+H S / ⌥+H S, analyzes the selections, or the whole input when nothing is selected, and shows a table of the elements: the tag, the count, and the total, maximum, average and minimum length of their outer and inner HTML, with a totals row, sorted by the total outer length. Click a column header, or press Enter or Space on it, to sort.

Get HTML

Selection: Get HTML, Alt+H H / ⌥+H H, serializes each selection again, which normalizes the markup. It does not push to the output.

Fetch, empty and compare

  • Ctrl+I F / ⌘+I F Input: Fetch [i:] replaces the content of every element that has a non-empty i: URL, within the selections or the whole input, with the fetched text. Ctrl+I E / ⌘+I E Input: Empty [i:] empties them again.
  • Ctrl+K C / ⌘+K C compares the input with the clipboard on diff.rt.ht, with the input as the original. Ctrl+I O / ⌘+I O and Ctrl+I M / ⌘+I M compare the selection, or the whole input when nothing is selected, as the original or as the modified side. The clipboard is read after the browser asks you.
  • Count Unique Lines, in the palette and the context menu, replaces the input with each distinct line and its count, most frequent first, as one undo step. Its chord Ctrl+L C / ⌘+L C may not reach it.

Insert snippets

Snippet commands insert at every cursor. In the inserted text, | marks where the cursor lands and |>…<| what ends up selected. Each insertion is one undo step and pushes to the output. They sit in the html group of the context menu.

CommandKeyInserts
New StyleAlt+S / ⌥+S<style>|</style>. With a selection, Alt+S starts a chord instead.
New ScriptAlt+X / ⌥+X<script>|</script>
New Script ModuleAlt+M / ⌥+M<script type=module>|</script>. With several selections, Alt+M starts a chord instead.
New Markdown (MD)noneA zero-md module script and a <zero-md> with an inline Markdown script, and ## Welcome selected.
New Script Worker (simple)Alt+G / ⌥+GNeeds a single empty cursor. A full-page style, <iframe src=:></iframe> and a <script type=worker edge> whose fetch returns the pathname.
New Script WorkernoneNeeds a single empty cursor. A longer example: a module that calls :hello, an edge worker that signs the request URL and a separate copy:redact worker for its secret.

Note: Read the longer worker example before you deploy it, and keep your own secrets out of any playground that you share. copy:redact hides an element only when you copy; see copy:redact.

Variation selectors

Eight palette-only commands insert an escape for VS-15, which asks for the text form of a character, or VS-16, which asks for the emoji form, at every cursor:

LanguageText (VS-15)Emoji (VS-16)
HTML&#xFE0E;&#xFE0F;
CSS\FE0E\FE0F
JS\uFE0E\uFE0F
URL%EF%B8%8E%EF%B8%8F

Emmet abbreviations Experimental

Emmet is enabled in the input. RTCode adds abbreviations of its own:

AbbreviationExpands to
z<style>
x<script>
xsa script with src
xma module script with src
w, worker<script type=worker> with a fetch stub
we, worker:edge<script type=worker edge> with the same stub
wu, worker:usagea module script that logs a call to :1
pf, ppa <pdf-file> and a <pdf-page>
twthe Tailwind browser script

These abbreviations are experimental and may change.

Undo, redo and cursor history

Ctrl+Z / ⌘+Z undoes in the editor first. When the editor has nothing left to undo and the playground has routes, it loads the previous deployment of the first route that differs from the current text, up to the 100 newest versions. Ctrl+Y / ⌘+Y or Ctrl+Shift+Z / ⌘+⇧+Z goes forward again, once you went back. Editing resets the position. The items are in Playground ▸ Input ▸ Code ▸ Edit. See Versions and Smart Undo.

Ctrl+U / ⌘+U undoes the last cursor movement, and Select ▸ History ▸ Redo redoes it.

Small helpers

See also