Wire byte protocol

DomTerm mostly handles standard ansi/xterm escape sequences. This section documents DomTerm-specific extensions. (Future: We should also document what xterm features aren’t implemented.)

The following code sequences may change based on experience and feedback.

Notation: Literal characters are written as quoted string literals with escape sequences as understood by bash’s echo -e. Specifically "\e" is an escape; "\a" is alert (bell); "\xHH" is the 8-bit characters whose value is HH (hexadecimal).

Special sequences sent by back-end and handled by DomTerm

Miscellaneous sequences

"\e[3J"

Erase the scrollback buffer (i.e. any lines above the home line). (This is an xterm feature.)

"\e[7J"

Delete all lines in the buffer (including scrolled lines), except the current line.

"\e[>0c"

Request Secondary Device Attributes. (This is a standard request for xt100style terminals, including xterm.) DomTerm responds "\e]990;XXYYYZZ;0c", where the number XXYYYZZ is derived from the DomTerm version number "XXX.YYY.ZZ".

"\e]7;file://" hostname "/"directory "\a"

Specifies the current directory of the process. (This is generated by some shells by default. On Fedora this is done by the script /etc/profile.d/vte.sh.)

"\e]8;" options ";" url "\a" text "\e]8;;\a"

Create a link with the given url and display text (which can contain other escape sequences for styling). The options are ignored. The link has class="subtle plain". See this link.

"\e]30;" name "\a"

Sets the “window name” to name, which is shown in the window title. Specifically sets the window-name attribute of the top-level domterm <div> node to name. This can be used to enable stylesheet rules to only apply to specfic DomTerm windows. If an active CSS stylesheet contains:

div.domterm[name="name"] { rules }

then the rules are only active for a DomTerm element whose session name is name.

"\e]72;" html-text "\a"

Insert HTML text (a fragment). The html-text can be a complete html file, but elements such as <html>, <body> or <style> are ignored.

The HTML is sanity-checked for safety.

A <base href="base-url"/> element in the html-text is skipped, except that the base-url is used for subsequent relative URLs (for src attributes for <img> elements, and for href attributes for <a> elements) in the same html-text.

The actual policy for allowed elements and attributes can be changed by overwriting the elementInfo and allowAttribute functions in terminal.js. The default policy is a work-in-progress.

"\e]721;" key ";" html-text "\a"

Replace previously-inserted HTML. Looks for the latest element (in document order) whose class includes can-replace-children and that has a replace-key="key" attribute. Essentially sets the innerHTML to html-text (after safety-scrubbing).

"\e]73;" keyName "\a"
"\e]74;" keyName "\a"
"\e]73;" keyName "\t" kstr "\a"
"\e]74;" keyName "\t" kstr "\a"

Simulate pressing keyName. Used by auto-line mode. The 73 variant supresses echo.

"\e[20u"

Starts a "fresh line": If at the beginning of line, does nothing. Otherwise moves to the start of a new line.

"\e[80;97u"
"\e[80;99u"
"\e[80;108u"
"\e[80;112u"

Set input editing mode. The value 99 ('c') sets character mode; the value 108 ('l') sets line-editing mode. The value 97 ('a') set automatic mode, which switches between character mode and line-editing mode based on the mode of the inferior process (when using a PTY). The value 112 ('p' for "pipe") is like line-editing mode, but the inferiors doesn’t echo the input, so we have to do it. This mode is useful when the input is a pipe or some other non-tty stream.

"\e[81u\n"

Requent to send the state of the window as a WINDOW-CONTENTS response.

"\e]88;" object "\a"

Set or update local settings to object, which is a map from keys to values, in JSON object format. Existing local settings not in object are not changed. If a value is null, the corresponding setting is removed from the local settings, so the global settings (or default) will apply.

"\e[89;" settings "\a"

Internal use: Update user settings.

"\e[92;" op "u"

Temporarily enable auto-pause if op is 1. Disables it if op is 2 (- only if temporarily enabled). A simplified more program could temporarily enable auto-pause, print some amount of output, and then revert the state. This used by the domterm help command.

"\e[99;99u"

End-of-file on the output stream. Calls the eofSeen method of DomTerm, which may close the current window or other appropriate action.

"\e]103;" state "\a"

Send saved state to new window.

"\e]231;" jtext "\a"

Paste the contents of the JSON-encoded string jtext.

"\e]97;" command "\a"

Execute the named command. If command starts with a left-brace, it is a JSON object, whose preperties may include cmd (a command-name), id (a number to identify the requester, copied to a RESPONSE, if any), and possibly other properties, depending on the cmd.

Command parts (shell integration)

The escape sequences will be deprecated in favor these sequences (not yet finalized).

"\e[12u"

Start of error output. DomTerm places the following text inside a <span> element whose std attribute has the value "error". The default style is to display the text in red.

"\e[11u"

End of error output.

"\e[14u"

Start of prompt. DomTerm places the following text inside a <span> element whose std attribute has the value "prompt". The default style is to display the text in green.

"\e[13u"

End of prompt. The prompt is included in selections that surround it.

"\e[18u"

End of non-selectable prompt. The prompt is not part of the text content of the document, and is not included in selections. The prompt string must be plain text with no styling. You can use this for all prompts, but it is especially recommended for continuation lines, such as the shell’s PS2 prompt.

"\e[15u"
"\e[15;" edit-mode "u"

Start of an input line. This also implicitly ends a (selectable) prompt. The input line is implicitly terminated by a '\n' (carriage return).

The edit-mode specifies what kind of input-line-editing is in effect, which affects how mouse clicks are handled. If edit-mode is 0, it means there is no input-line-editing, and no arrow key support by the client; the value 1 (the default) means single-line editing (like GNU readline); the value 2 means the first line of a multi-line editing group (as JLine3).

"\e[16u"
"\e[17u"

Delimit a hide/show "button", with "\e[16u" before and "\e[17u" after. The text between should be 1 or 2 characters (code points). The first character is displayed when contents are visible (shown) and that when clicked causes contents to be hidden. If there is a second character, it is the character used when contents are hidden and that when clicked causes contents to be shown. If the first character matches a "hide" entry in the predefined showHideMarkers table, then the second character defaults to the corresponding "show" entry.

"\e[83;" mode "u"

Delimit a span to be controlled by a show/hide button (previously printed). If mode is 1 or 2 it starts a span, while mode 0 ends the span. The span is initially visible if mode is 1, and is hidden if mode is 2.

"\e]119;" group-id "\a"
"\e[19u" (deprecated)

Start a command group. This command implicitly does a "fresh line" and ends any existing command group with the same group-id. (The "\e[19u" variant is equivalent to an empty group-id - i.e. "\e]119;\a".) Creates a nested command-group if there is no existing command group with the same group-id.

You can write this string before writing an input prompt string. The content-id is commonly the process-id of the REPL.

"\e]120;" group-id "\a"

(Experimental) Enter a new command-group without closing any current group.

"\e]121;" group-id "\a"

(Experimental) Exit the command-group with the given group-id.

"\e]122;" pattern "\a"

Set continuation prompt template. This is used for non-initial lines in a multi-line input editing area. The template uses print-style % escapes to indicate things to fill out. It is similar to the one used for JLine.

"\e]123;\a"

Extend previous input line for editing. Typically used after reading an input line that is syntactically incomplete, but valid “so far“. The previous input is “re-opened” for editing, and a fresh empty line added.

Window operations

"\e]204;" op [, oldwin] , options "a\n"

Create a new sub-window (pane). The new window is placed relative to oldwin (default: current window), based on the op. The options specify the kind of window and various options. (Internal.)

"\e[1t"

(Electron and Qt only.) Un-minimize (de-iconify) current window. This undoes buth minimize and hide operations. [In xterm.]

"\e[2t"

(Electron and Qt only.) Minimize (iconify) current window. The minimized window may be still visible in the task bar, as an icon on the desktop, or during an “windows expose” operation. [In xterm.]

"\e[2;72t"

(Electron and Qt only.) Hide current window. The minimized window is not visible in the task bar, as an icon on the desktop, or during an “windows expose” operation

"\e[2;73t"

(Electron and Qt only.) Toggle between normal and minimized state: If hidden or minimized, show it. If visible, minimize it.

"\e[2;74t"

(Electron and Qt only.) Toggle between normal and hidden state: If hidden or minimized, show it. If visible, hide it.

"\e[8;" columns ";" rows [";" mode] "t"

Resize the text area to (columns, rows). If mode is 8, used to synchronize between primary and secondary windows: It is ignored for a primary window (except in replay mode), and is used by a secondary window so cursor motion matches. [In xterm, except for the optional mode.]

"\e[14t"

Report the text area size in pixels. [In xterm.]

"\e[14;2t"

Report window size in pixels. [In xterm.]

"\e[18t"

Report size of text area in characters. [In xterm.]

"\e[22t"

Save window and icon title to stack. [In xterm.]

"\e[23t"

Restore window and icon title from stack. [In xterm.]

Urgent messages

"\x13" "\x15" sequence "\x14"

This is an “out-of-band” command sequence, which is the same as sequence. However, if the terminal is in the middle of some other escape sequence (or a multi-byte UTF-8 sequence), save the state, evaluate sequence, and restore the state.

"\x13" "\x17" sequence "\x14"

Same as the above, but ”urgent” (at higher priority): When DomTerm receives a sequence of bytes that contains this sequence, it will execute that before handling preceding bytes.

"\x13" sequence "\x14"
"\x13" "\x16" sequence "\x14"

These variants are reserved for the domterm backend (server). These are similar to the previous variants, but the sequence is not counted in the running count (used for flow control), nor is it included if an output log is saved (in case it is needed detach+attach). For the second form only: When DomTerm receives a sequence of bytes that contains an urgent sequence, it will execute that before handling preceding bytes.

Diagnostic (error) messages

"\e]44;" options "\a"

Start of a new diagnostic - an error message or similar. This creates and enters a node <span> element with class="diagnostic", and info="options". The options should be a JSON-formatted object with the outer { and } stripped off. Currently the only options defined is repl: true to indicate this was an error/warning in a previous REPL command.

"\e[44;0u"

End of current diagnostic. This exits the previously-entered <span class="diagnostic">.

"\e[44;" parameter "u"

Furure extension, planned for marking start and/or end of specific parts of a diagnostic.

Stylesheet manipulation

"\e]94;" rule "\a"

If necessary, create a new temporary stylesheet, and add the specified JSON-quoted rule to the end of it.

The following escape sequences are no longer used by the domterm command, and may be removed in the future.

"\e]90;\a"

A request to return a list of the stylesheets in the document.

Result to client: "\x9D" stylesheets "\n"

Each stylesheet is a JSON-formatted string, separated by "\t", suitable for printing by the list-stylesheets command.

"\e]91;" index "\a"

Disable the stylesheet that has index index in the list of stylesheets in the document.

Result to client: "\x9D" message "\n" where message is empty if there was no problem, and is otherwise an error message.

"\e]92;" index "\a"

As above, but enable the specified stylesheet.

"\e]93;" index "\a"

Return the contents of the specified stylesheet.

On success the result is "\x9D" rule* "\x9D" where each is a JSON-quoted string. On failure, the result is a (non-quoted) error message.

"\e]95;" name "," styles "\a"
"\e]96;" name "," styles "\a"

Create or replace a stylesheet with the given name. If there is a <style> with a name attribute equal to name, it is replaced; otherwise a new one is created, with its name set to name. The styles is the literal contents of the new stylesheet; it becomes the child of the <style> element (as a single text node). Both name and styles are strings in quoted (JSON) format.

If the code is 96, no response is sent. If the code is 95, the result to the client is "\x9D" index "\n" where index is the index of the replaced or created stylesheet.

Alterate screen buffers

"\e[84;2u"
"\e[84;3u"
"\e[84;5u"

Push a new buffer, and set the cursor to the upper left of the new buffer. This is similar to the standard xterm sequence "\e[?1049h", but it creates a buffer even if already using the alternate buffer. (The new buffer is marked as an "alternate" buffer if using "\e[84;5u", and a "main" buffer otherwise. There isn’t much difference between them, though they may be styled differently.)

Using "\e[84;3u" (or "\e[84;5u") scrolls the top of the new buffer to the start of visible window; using "\e[84;2u" does not automatically scroll. In either case the default styling separates the new buffer from the previous buffer with a double line.

"\e[84;1u"

Pop the most recent buffer. (Ignored if it is the only buffer.)

Pretty-printing

"Pretty-printing" refers to breaking a text info multiple lines in a way to minimize the number of lines needed while preserving logical structure and adding helpful indentation. DomTerm implements the features and concepts of the Common Lisp pretty-printing feature. The following uses the latter’s terminology. Doing line-breaking in DomTerm means it can dynamically adjust for varying line width.

"\e]110\a"
"\e]110;" per-line-prefix "\a"

Start a logical block, followed by sections of the output that logically belong together, and that DomTerm will try to group on the same line. If the group needs to be broken into multiple lines, continuation lines will be indented to the current horizontal position.

If there is a “prefix” before the group, send it to DomTerm before this command. On the other hand, if there is a per-line-prefix (a JSON-quoted string) it will written both at the current position, and at the same position in any continuation lines.

"\e]111\a"

End a logical block. If there is a "suffix", send it to DomTerm after this command.

"\e]112;" amount "\a"

Adjust identation of future lines (in the current block). The amount is measured in characters, and is relative to the current position. A negative amount is allowed, as long as you don’t end up to the left of any per-line prefixes.

"\e]113;" amount "\a"

Similar to the 112 command, but amount is relative to the start of the current block (after any per-line prefix).

"\e]114;" prefix "\a"

Adds an extra per-line prefix for future lines, specified by prefix, a JSON-quoted string.

"\e]115\a"

Add a “fill”-type conditional newline.

"\e]116\a"

Add a “linear”-type conditional newline.

"\e]117\a"

Add a “miser”-type conditional newline (which is currently treated the same as a “fill” newline).

"\e]118\a"

A required newline. This should be used (rather than a plain newline) when inside a logical-block.

"\e]115;"prebreak","postbreak","nonbreak "\a"
"\e]116;"prebreak","postbreak","nonbreak "\a"
"\e]117;"prebreak","postbreak","nonbreak "\a"
"\e]118;"prebreak","postbreak","nonbreak "\a"

Line-breaks of the types given above, but with specific strings to be used. Each string is JSON-quoted. The nonbreak string is used if the line is not broken here. If there is a break, the prebreak string is used before the break, and the postbreak string is used after the break (following any indentatioon and per-line prefixes).

For example to insert a hyphenation point, you might write:

\e]115;"-","",""\a

German used to have a rule where “ck” would be hyphenated as “k-k”, as in Zucker (sugar) or Zuk-ker.

Zu\e]115;"k-","k","ck"\aer

Special sequences sent by DomTerm to back-end

The prefix byte 0xFD is used to report an event or other information from the browser to the server. The value 0xFD is “out-of-band” because it cannot appear when encoding a string to UTF-8. If the browser needs to send an actual 0xFD, send it as the two-byte sequence "\xFD\n". (The only known way this can happen is for a large row number with the old X10 mouse reporting protocol. However, future extensions may need to send raw bytes.)

0xFD "\n"

Escape sequence to send raw 0xFD to application.

0xFD name " " data "\n"

General format for reporting events, where name is the name of the event (an identifier). The data can be any text not including a "\n" (or other control character); JSON format is used in some cases.

0xFD "WS " rows " " cols " " height " " width "\n"

Report window size from DomTerm to the back-end.

0xFD "KEY " keyname "\t" seqno "\t" kchars "\n"

Used by auto-line mode to report a key event to back-end. The keyName is an encoding of the key event in the style of browserkeymap; kchars is a string literal (JSON-formatted) of the characters that are normally transmitted to the back-end. The seqno is a sequence number, modulo 1024. In auto-line mode, if the pty is in canonical mode, then keyName is returned to DomTerm (using "\e]74;" keyName "\t" seqno "\t" kchars "\a"); otherwise kchars are sent to the pty.

0xFD "LINK " ref-info "\n"

Sent by the DomTerm browser when the user clicks on an <a> link. The ref-info is a JSON-encoded object with information about the link. The object must have at least an href property. Typically, backend should open href in the default browser of the user’s desktop, though this is contomizable.

0xFD "RECEIVED " count "\n"

This is used for flow-control. The count is the number of bytes received and processed by the front-end.

0xFD "WINDOW-NAME " window-name "\n"

Set window-name (a JSON-quoted string) as the name for this session.

0xFD "DETACH\n"

Don’t destroy the session when the last window is closed; instead detach it. (Don’t necessary detach now, if there are other windows on the session.)

0xFD "FOCUSED\n"

The current (sub-)window has focus.

0xFD "WINDOW-CONTENTS " rcount "," state "\n"

Report enough of the browser part of the session state so that it can be reproduced when a window is sttached to the session. The state is a JSON-encoded structure. The rcount is similar to the value reported RECEIVED, but as of the start of the most recent urgent message.

0xFD "VERSION " version-info "\n"

Sends version-info to the back-end. Used during initialization.

0xFD "REQUEST-CLIPBOARD-TEXT" ["OSC52"] "\n"
0xFD "REQUEST-SELECTION-TEXT" ["OSC52"] "\n"

Sent by the front-end on a Paste request when the browser doesn’t have access to clipboard. Requests the server to access the clipboard (if REQUEST-CLIPBOARD-TEXT) or the most recent selection (if REQUEST-SELECTION-TEXT) on its behalf. If OSC52 sends the contents to the process as an OSC 52 response (see xterm specification); otherwise replies back with an OSC 231 sequence.

0xFD "RESPONSE" response-data "\n"

Response to a request from the server. For example, a print-stylesheet command will send a query to the browser, which sends a RESPONSE to the server, which prints the result. The response-data is a JSON object, with at least an id property (an integer matching the request, used to send the response to the right file), along with either an out property (response text to print out), or an err property (error message to print on the request process’s standard error).