\input texinfo.tex      @c -*-texinfo -*-
@c %**start of header
@setfilename domterm.info
@documentencoding UTF-8
@settitle DomTerm - a terminal emulator and console using DOM and JavaScript

@contents

@syncodeindex fn cp
@syncodeindex vr cp
@syncodeindex pg cp
@codequoteundirected on
@codequotebacktick on

@macro mux-prefix
Ctrl+Shift+A
@end macro


@titlepage
@title DomTerm - a terminal emulator and console using DOM and JavaScript
@end titlepage

@node Top
@top DomTerm

DomTerm is an terminal emulator based on web technologies.
Beyond solid xterm compatibility, it supports
powerful features for REPL (read-eval-print-loop) consoles:
Application output can have images, rich text, and links,
with structure-based line-breaking (pretty-printing), and folding.
There is also input editing; automatic paging;
screen multiplexing (panes and tabs); and session management
(like @code{tmux} or GNU @code{screen}).

@emph{}
@uref{images/domterm-panes-1.png,@image{images/domterm-panes-1}}

This @uref{https://opensource.com/article/18/1/introduction-domterm-terminal-emulator, OpenSource.com article} provides an overview of the functionality.
This @uref{https://lwn.net/Articles/670062/,old LWN article} provides
background, motivation, and a summary of the functionality.

The @code{domterm} command runs a server that manages
sessions (usually shell processes).
The user interface and terminal emulation
is handled by a JavaScript library
that can run in a regular web browser or an embedded browser such as Electron,
using Web Sockets to talk to the server.

The name ``DomTerm'' refers to how it  works by manipulating the
@uref{https://en.wikipedia.org/wiki/Document_Object_Model,Document Object Model (DOM)} of a browser:
the nested structure of elements, text, and attributes.

DomTerm is Free Software (open-source)
available at @uref{https://github.com/PerBothner/DomTerm,https://github.com/PerBothner/DomTerm}.

There is a mailing list at @email{domterm-discuss@@domterm.org}
with an @uref{http://lists.domterm.org/listinfo.cgi/domterm-discuss-domterm.org,information page}
and @uref{http://lists.domterm.org/pipermail/domterm-discuss-domterm.org/,archives}.

@subheading Highlights and recent changes

@emph{}@image{images/domterm-1}
@itemize
@item
@uref{https://en.wikipedia.org/wiki/Sixel,@strong{Sixel graphics}} is now supported.
@item
The @code{domterm} command takes multiple sub-commands,
similar to how @code{tmux} or @code{git}.
The command automatically starts server if not already running.
@item
@ref{Sessions and Windows,Session management}, with detachable sessions, as in
@code{tmux} or GNU @code{screen}.
@item
An experimental package @uref{https://github.com/PerBothner/atom-domterm,atom-domterm} for the @uref{https://atom.io/,Atom editor} is available.
@item
A front-end based on @uref{https://electron.atom.io/,Electron}
is now the preferred one.
@item
We now support draggable tabs and panes.
@item
An experimental @ref{Paging,pager} with optional
automatic pause on each page.
@item
The preferred ``backend` is now @uref{https://libwebsockets.org/,libwebsockets}.
This is light-weight, does not require Java, is actively maintained,
and enables serving http and the WebSockets on the same port.
@item
Support for CJK (Chinese, Japanese, and Korean) characters is improved:
Double-width characters now really are two columns wide.
@end itemize

@menu
* Features:: Features and screenshots
* Downloading and building::
* domterm application:: The domterm command
* Settings:: The settings.ini file
* Applications:: Other domterm applications
* Frontends:: Frontends including browsers
* Remote serving::
* Sessions and Windows::
* Keyboard shortcuts::
* Edit and View modes::
* Styling::
* Tips and solutions::
* Java tools::
* Uses:: Projects using DomTerm
* To do:: Ideas and projects for DomTerm
* Technical documentation::
* Credits:: Credits and thanks
@end menu

@node Features
@chapter Features and screenshots

The goal of DomTerm is to be both a great terminal emulator
as well as great environment for @uref{https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop,REPLs}.

@c The goal of this project is to combine two related but
@c separate tools: a terminal emulator, and a rich-text console,
@c and do it properly.

@c There are many terminal emulators, including quite a few written in JavaScript.
@c However, they generally work with a rectangular grid of characters,
@c and don't integrate rich text (images, math, variable-width text,
@c variable-length lines, interaction) well.

@c There are also various tools designed for REPL-style interaction,
@c chat clients, etc. Examples include @uref{http://ipython.org/,IPython}
@c or the the JavaScript console of a web browser.
@c However, they don't work as terminal emulators, or at best have
@c limited functonality or require switching modes.

@c For rich text applications it seems obvious to use web technologies:
@c DOM and JavaScript.

@c One goal of this project is a stand-alone terminal emulator application
@c that techies can use as a day-to-day terminal emulator, and that also
@c seamlessly provides support for rich text and interaction. That means
@c an embedded web engine.

@c The core of the project is a JavaScript package that can be used and
@c embedded in different modes and applications.

This @uref{https://opensource.com/article/18/1/introduction-domterm-terminal-emulator, OpenSource.org article} provides an overview of DomTerm's functionality.
(It should be merged into the following.)

@c @c The @emph is a dummy to force the @image inside a paragraph
@c @emph{}

@subheading Full-featured terminal emulator

@float
@image{images/domterm-2,,,DomTerm window running mc (Midnight Commander)}
@caption{@b{Figure 1:} Running Midnight Commander}
@end float

DomTerm includes the functionality what you'd expect from modern
terminal-emulator.
@itemize @bullet
@item
It uses an extended @uref{https://invisible-island.net/xterm/,xterm}
protocol, and sets the @code{TERM=xterm-256color} environment variable,
like other modern terminal emulators.
DomTerm does very well on
the @uref{http://invisible-island.net/vttest/,@code{vttest}} terminal test program,
including handling Background Color Erase.
@item
Standard @strong{mouse event handling}.
@item
Supports @strong{24-bit color} (truecolor).
@item
Handles @strong{Unicode}.
Good @strong{CJK} (Chinese, Japanese, Korean) support:
@strong{double-width characters (including Emoiji)} really are two columns wide.
@item
XTerm's @strong{modifyOtherKeys mode} allow applications
such as Emacs to detect special key-combinations.
@item
Remembers @strong{tab characters} so copying selected output
will contain the tab character.
@item
Support for using @strong{Input Methods}.
@item
Resizing the window re-flows long output lines.
@item
Makes URls and file names into clickable links.
Also supports an explicit hyperlink escape sequence.
@end itemize

Here you see the @code{mc} (Midnight Commander) file browser
running in the stand-alone DomTerm application.
Emacs (shown later) and GNU readline also work well.

@subheading Rich output and images

@image{images/domterm-polygon-1}

A back-end @strong{can ``print'' images, graphics, and rich text}.
Here you can see evaluating and ``printing''
@code{Paintable} objects, which are graphical objects such as
filled polygons.
from the @uref{http://www.gnu.org/software/kawa/,Kawa} REPL.

The front page screenshot shows ``printing'' HTML for images and rich text.
(The expressions starting with @code{#<} are
@uref{http://www.gnu.org/software/kawa/XML-literals.html,XML literals},
which evaluate to @code{Element} objects. ``Printing'' an @code{Element}
inserts its HTML representation in the DomTerm output.)

The image later (with the yellow circle) shows printing
@uref{https://en.wikipedia.org/wiki/Scalable_Vector_Graphics,SVG}.

@subsubheading Sixel graphics

@image{images/dt-sixel}

You can directly print
@uref{https://en.wikipedia.org/wiki/Sixel,@strong{Sixel images}},
which is an encoding that some DEC VT terminals supported..

@anchor{help-and-documentation}
@subsubheading Help and other documentation

@image{images/dt-help1}

Displaying inline HTML is very useful for ``help'' output
and other documentation,
such as @ref{pandoc-output,output from pandoc}
and @ref{man-page-output,@code{man} pages}.

The @code{domterm hcat} command
is useful for @strong{printing formatted html}.
The @code{domterm help @var{topic}} command essentially does that.

@subsubheading Python language

@image{images/pyplot}

If you use the Python language,
check out these @ref{Python tips} with more screenshots.

@subsubheading Gnuplot

@image{images/dt-gnuplot1}

The @uref{http://www.gnuplot.info/,GnuPlot graphing utility} (version 5.1+)
supports @uref{http://per.bothner.com/blog/2016/gnuplot-in-domterm/,DomTerm as an output device}.

@subheading Rich interaction

@subsubheading Pretty-printing

@uref{https://domterm.org/saved/dt-prettynested.html,@image{images/dt-pretty1}}
If you click on the image to right,
you get a @strong{dynamic saved page}:
If you resize the screen, the line-breaks in the output
are adjusted to pretty-print the data structures to fit the
available width.  You can also show or hide output by clicking
on the triangles.

@strong{Smart line-wrapping}:
Remembers which lines were too wide (and thus
were wrapped).
The default style add markers to show when wrapping occurred,
as seen in the nearby screenshot.
Window size re-size will automatically re-do line-breaking.
Copying the selection as text will only include hard newlines.
Reports window resize to application.
@uref{http://per.bothner.com/blog/2017/dynamic-prettyprinting/,@strong{Dynamic pretty-printing}} (Common Lisp style) uses special commands to group
logical blocks, and attempts to keep the text of a block on a single line
with automatic re-flow on window re-size.

@subsubheading Show/Hide buttons

``Print'' @ref{Hide/show buttons,hide/show buttons},
using certain escape sequences enables @strong{text folding}.
The nearby screenshot shows the output of @code{ls -l} being hidden.

@subsubheading Smart links

@ref{linkification,Turn URLs and mail adresses in output into links}.
Filename with line number (as in errors messages) are turned into
links for text editors.
(You have to hover over them to see them.)

You can @ref{link-handlers,customize how links are handled}.

@subsubheading Update previous output

An application can print some HTML in an area of the output, and
attach a key string to it.  Later, that area can be updated (replaced),
just by specifing the key, without cursor navigation.

@subheading Choose your front-end

@image{images/emacs-in-firefox-1}

@image{images/dt-atom1}

Most of DomTerm is written in JavaScript and runs in a browser engine.
This can be a desktop web browser, such as Chrome or Firefox, or it can be an embedded browser.
Using a general web browser works fine, but the user experience
isn't quite as nice, and the security model gets in the way,
so using an embedded browser is recommended.

The following are currently supported:
@itemize @bullet
@item
A generic modern (HTML5) browser - both Firefox and Chrome are regularly tested.
(Shown is Emacs running a Firefox browser window.)
@item
qtdomterm, which uses the @uref{ttps://www.qt.io,Qt toolkit} and QtWebEngine.
@item
An @uref{https://electronjs.org/,Electron} embedding.
@item
@code{atom-domterm} runs DomTerm as a package in the
@uref{https://atom.io/,Atom text editor} (which is also based on Electron)
and integrates with the Atom pane system.
(See image.)
@item
A wrapper for JavaFX's WebEngine, which is useful for code written in Java.
@item
Previously, the preferred frontend used Firefox-XUL, but Mozilla has since dropped XUL.
@end itemize

Currently, both the Electron and Qt frontends are quite nice
and recommended.

@subheading Panes and tabs

A DomTerm window can be sub-divided into panes, each of which
can have multiple tabs.  You can create new panes with a domterm sub-command
(like @code{domterm --below new}), a menu button, or a
keyboard shortcut (like @kbd{@mux-prefix Ctrl+@key{Down}}).

If using @code{atom-domterm} the above commands create a new
Atom pane instead.

@subheading Shell/REPL integration

@uref{images/dt-fish1.png,@image{images/dt-fish1}}

If you use a shell or other interactive REPL program with a
settable prompt string, inserting special
@uref{https://gitlab.freedesktop.org/Per_Bothner/specifications/blob/master/proposals/semantic-prompts.md,escape sequences}
in the prompt enables some useful features.

@itemize @bullet
@item
Visual separation between commands.
The default styling that you can see in most of the screenshots
has a thin light green line between commands,
and a light beige for the input lines.
The is meant to be clear though unobstrusive while not wasting screen space.
@item
Distinct (user-settable) styling for prompt (light green) and user input (light yellow),
including support for secondary (continuation) and right-margin prompts.
@item
Show error indication (a red disk in the right gutter) if a command returns an error code:
If you hover the mouse over the red disk you will see the specific exit code.
@item
Hide/show buttons: If you click on the downward-pointing rectangle
in the right gutter, the following input and output of the command are hidden.
(See the @code{ls -l Makefile*} command in the screenshot.)
@item
Clicking the mouse in the input line moves the input cursor.
(Implemented by DomTerm sending the appropriate number of arrow keys.)
@item
Integration with selection and clipboard: If you press shift while using the
arrow keys, the moved-over text becomes the current selection.
@end itemize

See @uref{http://per.bothner.com/blog/2019/shell-integration-proposal/,this article} for more discussion and screenshots.

Optional @strong{input editing}.  In @dfn{character mode},
each character is sent to the application, like a traditional terminal.
In @dfn{line mode}, the browser @ref{Input line editing,does the editing},
and sends the input line to the back-end when Enter is typed.
A history of previous lines is available, accessible
with the Up/Down arrow keys.
@dfn{Automatic mode} switches between character mode and line mode
depending on whether the back-end is in ``@uref{http://www.gnu.org/software/libc/manual/html_node/Canonical-or-Not.html,canonical mode}''.

@subheading Miscelleanous

Easily configured as a @ref{drop down,``@strong{drop-down}'' (``Quake-style'')} terminal.

User @strong{preferences are controlled a CSS stylesheet},
which can be changed by an application.

@strong{Uses a byte-protocol} to communicate with the back-end,
so can run in a browser (using web sockets);
be embedded in an application;
or run as a standard terminal emulator application.

@uref{images/domterm-sh-svg.png,@image{images/domterm-sh-svg}}

Maintains @strong{a clean DOM structure}, and thus @strong{clean HTML export}.
Text selections generally give you what you expect.

@strong{Move cursor using mouse},
@ref{move-cursor-with-mouse,even for mouse-unaware programs}.
Mouse clicks are translated to arrow-key characters.

Optional @ref{Paging,@strong{automatic pagination}}.

@strong{Predictive echo} (similar to @code{mosh}), which is
useful for slow connections.

Nicer @ref{password fields, @strong{password fields}}.

@node Downloading and building
@chapter Downloading and building

@subheading Binary releases

Binary releases may be available
@uref{https://github.com/PerBothner/DomTerm/releases/latest,from GitHub}
on an unpredictable schedule.

A file with an @b{@code{AppImage}} extension
(such as @code{DomTerm-@var{version}.AppImage})
is a pre-compiled application, which can be treated
as the @code{domterm} program with various resources bundled in a single file.
Just download it; make it executable (@code{chmod +x DomTerm-@var{version}.AppImage}); and optionally rename it (maybe to @code{domterm})
and put it on your @code{PATH}.
You should be able to run it on most recent GNU/Linux operating systems,
as well as compatible ones.
Specifically, it runs fine on Windows Subsystem for Linux (WSL 2).
The @code{AppImage} includes the @code{qt} and @code{webview}
front-ends, but they do depend on GUI libraries that might not be
on your platform.  On WSL 2, DomTerm defaults to using
the @code{edge-app} front-end, which works pretty well.

@subheading Getting the DomTerm source code

The sources are in
a @uref{https://github.com/PerBothner/DomTerm,GitHub repository}.
To download the sources do:
@example
git clone https://github.com/PerBothner/DomTerm
@end example

The following instructions assume a Unix-like environment
(Linux, BSD, MacOS, or WSL on Windows).
On other platforms (including plain Windows without WSL)
you may be able to use @ref{electron nodepty} (experimental).

@c Alternatively, it may be easier to grab one of the sporadic
@c @uref{https://github.com/PerBothner/DomTerm/releases,releases}.
@c A file named @code{domterm-@var{version}.tar.gz} is a GNU-style release;
@c it includes some generated files (such as the @code{configure} script),
@c for convenience.
@c A file named @code{domterm-@var{version}-wsl.zip} contains
@c compiled installable files for WSL (Windows Subsystem for Linux).

@subheading Prerequisites

Please help out with instructions for other platforms, especially
MacOS, *BSD, and native (non-WSL) Windows.

@subsubheading Fedora

On Fedora, you need to first:
@example
sudo dnf install gcc make automake autoconf texinfo patch libwebsockets libwebsockets-devel openssl-devel file-devel libcap-devel asciidoctor zlib-devel
@end example
If configuring @code{--with-qt} (recommended), also do:
@example
sudo dnf install gcc-c++ qt5-qtbase-devel qt5-qtwebengine-devel qt5-qtwebchannel-devel qt5-qtx11extras-devel
@end example
If configuring with @code{--enable-compiled-in-resources} (for @code{xxd} - only needed at build time):
@example
sudo dnf install vim-common
@end example
For Java classes, do:
@example
sudo dnf install java-1.8.0-openjdk-devel
@end example
(You can also use Oracle JDK, version 8 or 9.)

If configuring with @code{--with-closure-compiler} do:
@example
sudo dnf install closure-compiler
@end example

If building the documentation and configuring @code{--with-docbook}:
@example
sudo dnf install docbook-style-xsl libxslt
@end example

If configuring with @code{--with-webview} (experimental) do:
@example
sudo dnf install gtk3-devel webkit2gtk3-devel
@end example

If configuring with @code{--with-wry} (experimental) do:
@example
sudo dnf install rust cargo gtk3-devel webkit2gtk3-devel jq
@end example

@subsubheading Ubuntu/Debian

(Tested on Ubuntu 17.10.1)

You need to install the following prerequisites:
@example
sudo apt-get install git gcc make automake pkg-config asciidoctor libmagic-dev zlib1g-dev
@end example
If configuring @code{--with-qt} (recommended), also do:
@example
sudo apt-get install qt5-default libqt5webengine5 libqt5webchannel5-dev qtwebengine5-dev
@end example

In the future you should be able to do @code{apt-get install libwebsockets-dev}, but at the time of writing the available package is too old,
so you have to build libwebsockets from source - see below.

If you need to build libwebsockets from source:
@example
sudo apt-get install cmake
@end example

@subsubheading Windows using WSL (Linux for Windows)

For building from source on WSL (Windows Subsystem for  Linux)
see the @ref{building on WSL,instructions below}.

@anchor{wsl binary release}
Alternatively, you can use of the pre-compiled
@uref{https://github.com/PerBothner/DomTerm/releases,releases}.
Download @code{domterm-@var{version}-wsl.zip}.
Then create a directory on a Windows partition, @code{cd} to it,
and @code{unzip} the downloaded file into the partition.
For example (assuming your Windows user name is @code{@var{wuser}}):
@example
cd /mnt/c/@var{wuser}
mkdir DomTerm
cd DomTerm
unzip /mnt/c/User/wuser/Downloads/domterm-@var{version}-wsl.zip
@end example

These library dependencies are needed:
@example
apt-get install libmagic1 zlib1g
@end example

Optionally you can create a symlink for @code{domterm}:
@example
cd ~/bin
ln -s /mnt/c/@var{wuser}/DomTerm/bin/domterm domterm
@end example

@ref{installing-electron,Installing Electron} is highly recommended.

@subsubheading  MacOS (using Homebrew)

@example
brew install automake libwebsockets asciidoctor pkg-config
@end example

If you want to use the Electron front-end:
@example
brew install npm
npm install electron -g
@end example

If you will be using Qt:
@example
brew install qt5
brew link qt5 --force
@end example

There are some issues about openssl that I'm not clear about.
A reported work-around is to do:
@example
export LDFLAGS="-L/usr/local/opt/openssl/lib -L/usr/local/lib -L/usr/local/opt/expat/lib"
export CFLAGS="-I/usr/local/opt/openssl/include/ -I/usr/local/include -I/usr/local/opt/expat/include"
export CPPFLAGS="-I/usr/local/opt/openssl/include/ -I/usr/local/include -I/usr/local/opt/expat/include"
@end example

A cleaner solution/fix would be welcome.

@subsubheading Building libwebsockets, if needed

The @code{domterm} server requires libwebsockets version 2.2
or newer.  Version 3.2 has reported problems.
As of January 2021, the version in Fedora 33 seems fine,
but the version in Ubuntu is best not used.
If you need to build libwebsockets from source, do the following:

@example
cd $WORKDIR
git clone https://libwebsockets.org/repo/libwebsockets
cd libwebsockets
mkdir build
cd build
cmake -DLWS_WITH_SSL=0 -DLWS_WITHOUT_EXTENSIONS=0 -DLWS_WITH_ZIP_FOPS=1 ..
@end example
The @code{-D} options are suggested but not required:
@code{-DLWS_WITH_SSL=0} avoids a dependency on OpenSSL;
while @code{-DLWS_WITH_ZIP_FOPS=1} is required if configuring
with @code{--disable-compiled-in-resources} (the default).

Finally:
@example
make
@end example

When running @code{./configure} in the @code{DomTerm} sources,
specify @code{--with-libwebsockets=$WORKDIR/libwebsockets/build}.

@anchor{installing-electron}
@subsubheading Optional: Electron

The Electron framework provides a nicer domterm front-end
than a regular web browser.  It is similar to using qtdomterm,
but it is easier to install electron on platforms that don't have
qt/qtwebengine packages easily available.

Grab a suitable package from
@uref{https://github.com/electron/electron/releases/latest,here}.
Get the @code{zip} file with the plainest name (no @code{-symbols}
or @code{-pdb}).
For example, at the time of writing the current release is 7.1.2, so
for Windows you want @code{electron-v7.1.2-win32-x64.zip}.
Unzip into a freshly-created directory.

On Windows Subsystem for Linux (WSL), you need to unzip into a
directory on a Windows partition, not a Linux partition.
For example, assuming the Windows user name is @code{wuser}
and Electron version number @var{version}, do:
@example
cd /mnt/c/User/@var{wuser}
mkdir electron-@var{version}
cd electron-@var{version}
unzip  /mnt/c/User/@var{wuser}/Downloads/electron-v@var{version}-win32-x64.zip
@end example

So that the @code{domterm} executable can find the electron executable,
you can create an entry in @ref{Settings,@code{settings.ini}}:
@example
command.electron = @var{/path/to/electron}/electron
@end example
or (on WSL):
@example
command.electron = /mnt/c/User/@var{wuser}/electron-@var{version}/electron.exe
@end example

Alternatively, you can create a symlink in your @code{PATH} to electron.
For example, on WSL (where @code{~/bin} is in the default @code{PATH}):
@example
cd ~/bin
ln -s /mnt/c/User/@var{wuser}/electron-@var{version}/electron.exe electron
@end example

@anchor{installing-libclipboard}
@subsubheading Optional: libclipboard

Using @uref{https://github.com/jtanx/libclipboard,libclipboard}
is recommended when not using Electron, as it makes Paste work better.
@example
git clone https://github.com/jtanx/libclipboard.git
cd libclipboard
LIBCLIPBOARD_DIR=`pwd`
cmake .
make
@end example

@subsubheading Optional: Qt Docking (experimental)

Managing docking (draggable panes and tabes) using a native
library has some advantages (compared to GoldenLayout).
Specifically, you can drag panes between top-level windows.
There are two candidate Qt libraries that are being considered:
 @uref{https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System,Qt Advanced Docking System} (slightly smaller, more liberal license, nicer defaults - but needs to use a fork for now) and
@uref{https://www.kdab.com/development-resources/qt-tools/kddockwidgets/,KDDockWidgets} (seems slightly more solid, better Wayland support, can be used unpatched).
Both are supported in a proof-of-concept way;
both need more polishing and testing, which may determine a preference.

To use (my fork of) @uref{https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System,@strong{Qt Advanced Docking System}}:

@example
sudo dnf install qt5-qtx11extras-devel  # @emph{(On Fedora)}
git clone https://github.com/PerBothner/Qt-Advanced-Docking-System.git
git checkout multi-main
QT_ADS_DIR=`pwd`/+installed+ #for example
mkdir build
cd build
cmake  -DCMAKE_INSTALL_PREFIX=$QT_ADS_DIR ..
make install
@end example

Then
@example
configure --with-qt-docking=$QT_ADS_DIR
@end example

To use @uref{https://www.kdab.com/development-resources/qt-tools/kddockwidgets/,@strong{KDDockWidgets}}:

@example
git clone https://github.com/KDAB/KDDockWidgets.git
KDDOCK_DIR=`pwd`/+installed+ #for example
mkdir build
cd build
cmake  -DCMAKE_INSTALL_PREFIX=$KDDOCK_DIR ..
make install
@end example

@example
configure ... --with-kddockwidgets=$KDDOCK_DIR
@end example

@subheading Building from source

If building from the @code{git} respository, first do:
@example
autoreconf -i
@end example
This runs the GNU autotools (@code{aclocal}, @code{autoconf},
and @code{automake}).

Then run the @code{configure} script:
@example
./configure @var{configure-options}
@end example
where @var{configure-options} can be:
@table @code
@item --prefix=@var{install-prefix}
Set the root of the tree into which @code{make install}
will install the built domterm.
The default is @code{/usr/local}.
The @code{domterm} and @code{qtdomterm} executables are
installed in @var{install-prefix}@code{/bin},
@code{man} pages are installed in @var{install-prefix}@code{/share/man},
and other ``resources'' are installed
in @var{install-prefix}@code{/share/domterm}.

On WSL the @var{install-prefix} should be on a Windows partition,
at least if you want to use the Electron front-end (which is recommended).

@item --with-libwebsockets[=@var{lws-build}]
Build the C application @code{ldomterm},
which uses @uref{https://libwebsockets.org/,libwebsockets}.
If @var{lws-build} is specified, it should be the path
to the @code{build} subdirectory of the libwebsockets compiled source tree.
(The files @code{@var{lws-build}/lib/libwebsockets.a}
and @code{@var{lws-build}/include/libwebsockets.h} should exist.)

Libwebsockets version 2.2 or newer is required,
as older versions do not support flow control or paging.

This is the recommended ``backend'' and the default.

@item --with-java_websocket
@itemx --with-java_websocket=/path/to/java_websocket.jar
Build a WebSocket server, using
@uref{https://github.com/TooTallNate/Java-WebSocket/,Java WebSockets},
which allows using any modern browser as a front-end.
This server is no longer recommended or enabled by default.

This options adds the classes in @code{java_websocket.jar} to @code{domterm.jar}.
@item --with-asciidoctor
Generates help and man pages using AsciiDoctor.
The default is to do so if @code{asciidoctor} is in the path.
@item --with-javafx[=@var{library-name}]
Enable using JavaFX to run standalone applications.
The @code{@var{library-name}} does not need to be specified if using Java SE 8.
It may be needed for OpenJDK or Java SE 7,
in which case it is either a path to @code{jfxrt.jar},
or (for convenience if using Java SE 7) the @code{JAVA_HOME}.

If using Java 11 or later (which is ``modularized''),
you might set:
@example
export JDK_JAVA_OPTIONS='--module-path /path/to/javafx-sdk-13.0.1/lib --add-modules javafx.controls,javafx.web'
@end example
@item --without-java
Disable building anything that depends on Java.
@item --with-qt
Use Qt and @uref{https://wiki.qt.io/QtWebEngine,QtWebEngine}
to build @code{qtdomterm}, an advanced front-end that
supports multiple tabs, screen re-sizing, and other nice features.

For this you need the Qt development tools including QtWebEngine installed.

For Fedora, you also need:
@example
sudo dnf install qt5-qtbase-devel  qt5-qtwebchannel-devel qt5-qtwebengine-devel
@end example
@item --with-closure-compiler=@var{compiler.jar}
Use Google @uref{https://developers.google.com/closure/compiler/,Closure Compiler} to minimize the size of the JavaScript.
(Current only the ``simple optimizations'' are done.
Using the ``advanced optimizations'' would reduce the JavaScript file
size further, but causes some not-yet-resolved problems.)

@item --with-webview
Build @emph{experimental} support for the @uref{https://github.com/webview/webview,Webview cross-platform framework}.  This creates a binary @code{bin/dt-webview},
which is used if you open a domterm window with the @code{-Bwebview} option.

This has only been tested on Fedora and MacOS.

This @ref{webview-frontend,works ok though with some rough edges}.

@item --with-wry
Build @emph{experimental} support for the @uref{https://github.com/taurri/wry,Wry cross-platform framework}.  This creates a binary @code{bin/dt-wry}.
which is used if you open a domterm window with the @code{-Bwry} option.
If @code{--enable-debug} is specified, does a debug build,
which is needed to get a web instructore.
(Shift-ClickRight then @code{Inspect element}.)

Wry works similar to WebView, but is part of
the @uref{https://tauri.studio/en/,Tauri} project and is written in Rust.
A major advantage of Wry is that it is actively maintained.

@item --with-libclipboard=@var{libclipboard_dir}
Using the @uref{https://github.com/jtanx/libclipboard,libclipboard library}
is recommended if if you a non-Electron front-end, as it makes Paste
menu items work better.

If you followed the
@ref{installing-libclipboard,installation instructions above}
then @var{libclipboard_dir} should be @code{$LIBCLIPBOARD_DIR}.

@item --with-docbook
Use DocBook for generating HTML documentation.
This used to be the default but is no longer recommended with texinfo 6.8.

@item --enable-debug
Build for development and better debugging.
Sets @code{CFLAGS="-O0 -g"} @code{CXXFLAGS="-O0 -g"}.
If @code{--with-wry}, build Wry with the @code{debug} profile.

@item --enable-compiled-in-resources
This feature causes the html, JavaScript and css files needed by DomTerm
to be compiled into the executable.
Otherwise, they are served from the compressed @code{domterm.jar}.

@c @item --enable-ld-preload
@c This is an experimental feature to preload a library to interpose
@c some system functions.  Most importantly it overrides @code{tcgetattr}
@c so that DomTerm gets notified on term terminal mode changes.
@end table

Then just:
@example
make
@end example

To test it, you can try either:
@example
bin/domterm
@end example
or
@example
bin/qtdomterm
@end example
Either starts up a useable terminal emulator in a fresh window.
(The latter is equivalent to @code{bin/domterm --qt}.)

Optionally, you can install the built files
into the configured @var{install-prefix} directory:
@example
make install
@end example

@subsubheading Building an AppImage

After running @code{configure}, do:
@example
make appimage/DomTerm.AppImage
chmod +x appimage/DomTerm.AppImage
@end example
You can run @code{appimage/DomTerm.AppImage}
with the same options as the @code{domterm} command.
It is a single file, which makes it easy to move and install.
(It is reasonable to rename the @code{DomTerm.AppImage} to @code{domterm}.)

For better portability of the resulting @code{DomTerm.AppImage}
you should build it on a machine with a slightly older libraries,
and libwebsockets should be linked statically.
You might also consider configuring
@code{--with-asciidoctor --with-webview --with-libclipboard=$LIBCLIPBOARD_DIR}.
The functionality of @code{--with-webview} and @code{--with-libclipboard}
are more likely to break if libraries are incompatible,
but they're separate executables so shouldn't break core functionality.

@anchor{building on WSL}
@subsubheading Windows using Linux for Windows

Microsoft Windows is now supported using
@uref{https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux, Windows Subsystem for Linux (WSL)}.
This has been tested using the Ubuntu distrubution:
Follow the above Ubuntu instructions for getting prerequsities
(without the optional qt packages),
including (currently) building libwebsockets from source.

Other distributions should work but have not been tested.

If you want to use the Electron front-end,
install @code{electron} as described above.
Electron is a Windows executable, and it needs to be able to read
the ``electron application'' files in @code{share/domterm/electron}.
Hence, if you run @code{domterm} in-place (without @code{make install}),
the @code{clone}'d source directory must be on a Windows partition.
Alternatively, if you run domterm as installed by @code{make install},
then the @var{install-prefix} must be on a Windows partition.

If you want want to use a web browser,
the newer (Chrome-based) Edge works pretty well.
In face @code{--browser=edge-app} is the default on WSL.
Win32 versions of
both Firefox and Google Chrome also work pretty well.
The default location (for Firefox 
@code{c:\Program Files (x86)\Mozilla Firefox\firefox.exe})
should work out-of-the-box.  Otherwise specify
@code{command.firefox} or @code{command.chrome} in
@ref{Settings,@code{settings.ini}}.
(Internet Explorer wll probably never be supported.)

Domterm looks for the user settings file in
@code{c:\Users\@var{USER}\AppData\Roaming\DomTerm\settings.ini}.

The @code{DomTerm.AppImage} (see above) single-file application
works well (at least on WSL2).

@node domterm application
@chapter The domterm command

The @code{domterm} command is the preferred away of using DomTerm.
The command has various sub-commands and options.
Most sub-commands will start a server in the background
if one isn't already running.

If you run @code{domterm} with no arguments, it creates a new terminal
emulator window, just as if you'd start @code{xterm}, say.
You can specify options to specify what kind of window is
created (for example a new tab or a web browser window).
You can also specify a @var{command} to perform other actions
besides creating a new terminal emulator.

@c The actual @code{domterm} program is primarily a server
@c for WebSockets and http.  When it receives a connection,
@c it runs a specified command, by default a shell.

@c Unless @code{--port} is specified, @code{ldomterm} will automatically
@c start a browser session (the ``front-end'') that connects
@c to the server.  The default is currently
@c as if you specified @code{--electron}, or @code{--browser} (if the
@c @code{electron} is not found).

@display
@code{domterm} [@var{options}] [@var{command} @var{arg}...]
@end display

The @var{command} specifies one of a set of commands used to control
@code{domterm}, as described in the following sections.
If @var{command} is not specified, the default command is @code{new},
which creates a new session using a default shell such as @code{/bin/bash}.

@subsubheading Communicating with a remote computer

You can run a @var{command} on a different (remote) computer
named @var{host}, using the following syntax:
@display
@code{domterm} [@var{options}] @var{user}@code{@@}@var{host} [@var{command} @var{arg}...]
@end display
This uses @uref{https://en.wikipedia.org/wiki/SSH_(Secure_Shell),@code{ssh}}.
For details @ref{Remoting over ssh,see here}:

@anchor{session-creating}
@subheading Creating a new session

Creating a new session is done with the @code{new} commands,
possibly abbreviated:

@display
[@b{@code{new}}] [@var{executable} @var{arg}...]
@end display

This creates a new process running the @var{executable}
with the specified command-line arguments.

You can leave out the @code{new} if the @var{executable}
contains a ``@code{/}'' (slash).  For example:

@example
$ domterm /bin/csh -v
@end example

If @var{executable} is not specified, the default shell
(for example @code{bin/bash}) is used.
(See @code{shell.default} in @ref{Settings}.)

The @var{executable} runs a new terminal window,
as specified a @dfn{window specifier}.

The following options control which front-end (usually a browser),
if any, is started.

@subheading Browser specifier option
@anchor{browser specifier}

A @var{browser-specifier} option specifies how to
display a new domterm window. This can be a window or tab in
general-purpose web-browser, a specialized browser without
locatonbar or similar distracting ``chhome'', or a sub-window.

It is used for certain commands like @code{new} and @code{attach}.
For example:

@example
domterm --Belectron new
domterm --below attach 4
domterm --browser /bin/sh
@end example

If there is no @var{browser-specifier} option,
the value of the @code{browser.default} @ref{Settings,setting} is used.

@subsubheading Browser specifiers

@table @asis
@item @code{--browser}
@itemx @code{-B}
Creates a new window or tab in your preferred desktop browser.
Same as @code{-Bbrowser}.
@end table

@table @asis
@item @code{-B}@var{command}
@itemx @code{--browser=}@var{command}
For example either @code{-Bfirefox} or @code{--browser=firefox}
(which are equivalent).

The @var{command} is most commonly one of the browser aliases below.
Can also be a @ref{command value,@var{command}} with an
optional @code{%U}, which is replaced by a URL generated by @code{domterm}.
(If there is no @code{%U} in the @var{command}, then @samp{ '%U'}. is added.)
You can also specify a list of commands or aliases,
separated by semi-colons, which are tried in order.

If @var{program} is specified, instead creates a window
in the specified browser, where @var{program} is the name
of a browser program that takes a single URL argument.
The @var{program} can be a multi-word template,
where @code{%U} is replaced by a URL generated by @code{domterm}.
If @var{program} contains a @samp{$} it is processed by the shell;
the @var{program} should either deamonize itself or otherwise run
in the background (perhaps by using @samp{&}).
If @var{program} does @emph{not} contain a @samp{$}, @code{domterm}
splits it into words and runs it directly (daemonized).
@end table

The following aliases are available.

@table @asis
@item @code{firefox}
@itemx @code{chrome}
@itemx @code{google-chrome}
@itemx @code{edge} @emph{(Windows only)}

Open a new tab or window in the specified desktop browser, either Firefox,
Google Chrome (@code{chrome} and @code{google-chrome} are synonymous),
or Microsft Edge (on Windows only).
DomTerm looks in common platform-specific locations for these browers,
and know which options to pass.

@item @code{chrome-app}
@itemx @code{edge-app} @emph{(Windows only)}
The aliases @code{chrome-app} and @code{edge-app}
open @code{chrome} or @code{edge} in ``application mode''
(with the @code{--app=} option).
This is recommended: you don't get the
clutter of the browser location bar, menubar, or toolbar,
or the browser taking over certain keybindings (like @kbd{ctrl+@key{N}}).

@item @code{electron}
Use a front-end based on @uref{https://electron.atom.io/,Electron}.
This is currently the nicest (and default) front-end.

@item @code{qt}
@itemx @code{qtdomterm}
@itemx @code{qtwebengine}
Either option (they do the same thing)
runs @code{qtdomterm}, a stripped-down browser based on the Qt toolkit
(specifically QtWebEngine).

@item @code{webview}
@itemx @code{wry}
Run the stripped-down @code{dt-webview} or @code{dt-wry} browser,
respectively.
(Available if
configured @code{--with-webview} or @code{with-wry}, respectively.)

Run the stripped-down @code{dt-wry} browser (built if
configured @code{--with-webview}).

@item @code{browser}
Run the default desktop browser.
The option @code{--browser=browser} (or @code{-Bbrowser})
is the same as plain @code{--browser} (or @code{-B}).
@end table

@subsubheading Special window specifiers

The following create sub-window in existing browser windows,
or have other special uses.

@table @asis
@item @code{--left}[@code{=}@var{window}]
@itemx @code{--right}[@code{=}@var{window}]
@itemx @code{--above}[@code{=}@var{window}]
@itemx @code{--below}[@code{=}@var{window}]
Split @var{window} (a window number) in two,
and create a new pane (sub-window) to the left/right/above/below the old one.
If @var{window} is not specified, use the current window.
@item @code{--pane}[@code{=}@var{window}]
Equivalent to either @code{--right} or @code{--below} depending
on the current window's width/height ratio.
@item @code{--tab}[@code{=}@var{window}]
Create new tab.

@anchor{Headless mode}
@item @code{--headless}
Create an ``invisible'' (hidden) browser window.
This runs all the regular display logic except actually displaying on
a screen.  This (experimental) feature is useful for testing
(of DomTerm or of other applications).
It is also useful as a backup of the display in case of network disconnect.
(The headless server runs on the same remote computer as the session.)

You should use the @code{command.headless} setting to specify the
command for running the headless browser.
This can be any command that can take a URL argument (using with a @code{%U} pattern that is filled in by @code{domterm}).
If @code{command.headless} is not set, but 
one of @code{--chrome}, @code{--qt}, or @code{--electron} is specified
the corresponding frontend in used headless mode.
(Using @code{--chrome} seems to work best.)
If none of these are set,
the default is as if @code{--chrome} was specified,
assuming the Chrome browser is available.

@item @code{--detached}
When creating a new session, it is detached, without a window.

@item @code{--print-url}
Only print out the URL that would be passed to a browser command,
but don't actually run a browser.  You can copy the URL into the
location bar of a browser.
@c Roughly equivalent to @code{--browser="echo '%U'"}.

@item @code{--browser-pipe}
@emph{(Internal use.)} Proxy input and output,
usually over an @code{ssh} connection.
@end table

@anchor{window-specifier-option}
@subheading Window specifier option

Certain commands affect an existing window.
These take a @dfn{window-specifier} option
that can specify which window(s) should be acted on.
For example, to minimize windows 2 and 3 do:
@example
domterm -w 2,3 minimize
@end example

@table @asis
@item @code{-w @var{window-specifier}}
@itemx @code{--window @var{window-specifier}}
@itemx @code{--window=@var{window-specifier}}
Specify which windows are affected by the current command.
@end table

A @var{window-specifier} can be one of:
@table @asis
@item @code{@var{window-number}}
The window with the specified @ref{window number,@var{window-number}}.

@item @code{current}
The ``current'' window, which is the one that most recently has received focus.
@item @code{top}
The top-level window containing the current window.
@item @code{all}
All windows, including sub-windows.
@item @code{all-top}
All top-level sub-windows.
@item @var{window-specifier}@code{,}@var{window-specifier}@var{...}
A comma-separated list of window specifiers.
@end table

@subheading Miscellaneous commands

@table @asis
@item @b{@code{help}} [@var{sub-help}]
Print some help.  The @var{sub-help} may be a sub-command.

@item @b{@code{is-domterm}}
Succeeds (exits with code 0) if the current terminal is DomTerm;
fails (exits with code -1) otherwise.

This test does not depend on environment variables,
but instead sends a special request code, and checks the response.
This test works over an @code{ssh} connection.
(The test does require that either @code{DOMTERM} be non-empty,
or that @code{TERM} be either empty or contain the string @code{xterm};
otherwise it does not try to the request code.)

@item @b{@code{status}} [@code{--verbose}] [@code{--by-session}]

Prints various bits of information about the backend,
sessions, windows, and version numbers.
The information displayed and the format are likely to change.
The default groups sessions by top-level window;
the @code{--by-session} groups windows by session.
The @code{--verbose} option adds more detail.

@item @b{@code{settings}} @var{name}@code{=}@var{value} ...
Change the specified @ref{Settings,local settings} for the current session.

If the @var{value} is empty, the local setting with the given @var{name} is
removed, so the global setting (if set) becomes active.

@item @b{@code{browse}} @var{url}
Create a new browser window or sub-window that displays @var{url}.
This is implemented using an @code{iframe}.
Access depends on the permissions of the browser (front-end).
(A future command may proxy via the back-end server.)

One use for this is to view documentation in a sub-window:
@example
$ domterm --above browse http://example.com/
@end example

@item @b{@code{view-saved}} @var{filename}
The @var{filename} is an HTML file of a previously saved session.
Open the session is ``view'' mode: Lines will be re-wrapped
on window re-size, links are clickable, and hide/show buttons work.

@item @b{@code{kill-server}} [@code{--only}]
Kill the @code{domterm} server.
This also kills all local sessions.
Also close any windows, unless @code{--only} is specified.
(This may kill remote sessions if their only window is closed.)
@end table

@subheading ``Printing'' images or html

@table @asis
@item @b{@code{html}} [@code{--base=}@var{base-url}] 
@itemx @b{@code{html}} [@code{--base=}@var{base-url}] @var{html-value} ...
@itemx @b{@code{hcat}} [@code{--base=}@var{base-url}] @var{filename}@code{.html} ...

Use this to embed HTML content info the DomTerm page.
If there are no arguments, read from standard input.
Either of the following work:
@example
echo 'E = mc<sup>2</sup>' | domterm html
domterm html 'E = mc<sup>2</sup>'
@end example
displays: @code{E = mc@sup{2}}.

The @var{html-value} can be a complete html file,
but elements such as @code{<html>}, @code{<body>} or @code{<style>}
are ignored.

Relative URLs are resolved relative to the @var{base-url},
which can be an absolute URL or a filename or directory;
the default is the current working directory.

The @code{hcat} command takes the name of an html file, rather than
literal html.
(With no arguments @code{hcat} is the same as @code{html}.)
The following are equivalent:
@example
domterm hcat /path/to/doc.html
cat /path/to/doc.html | domterm html --base=/path/to/
@end example

@item @b{@code{image}} [@code{-@var{n}}] [@code{--@var{attrname}=@var{attrvalue}}]... @var{filename}
@itemx @b{@code{imgcat}} [@code{-@var{n}}] [@code{--@var{attrname}=@var{attrvalue}}]... @var{filename}

This script ``prints'' the contents of the named image file to domterm.
This uses a ``@code{data:}'' URI with the file contents sent directly to domterm, so it works when working remotely.

The @var{filename} must be a file that can be displayed
by an HTML @code{<img>} element, most commonly a @code{png} or @code{jpg} file.

By default (no @code{-n} is specified),
the image has a @code{display: block} style
(so it is automatically on a ``line'' by itself),'
and gets a horizontal scroll bar if and only if it is too wide to fit.
If @code{-n} is specified, then only a plain @code{<img>} element is written,
which means you can write multiple images and other HTML on the same ``line''.

@table @asis
@item @code{--@var{attrname}=@var{attrvalue}}
Specify the given attribute; for example: @code{--height=200}.
Valid @var{attrnames} are the following, which
are specified in the HTML specification:
@code{alt}, @code{longdesc}, @code{height}, @code{width}, @code{border}, @code{hspace}, @code{vspace}, @code{class}.

For example: @code{--width=600} scales the image width to be the given number
of pixels (in the CSS meaning).  (The height is scaled proportionally,
unless you also specify the @code{--height} option.)
@end table

@item @b{@code{fresh-line}}
If not already at beginning of line, starts a fresh line
@end table

@subheading Sessions

@table @asis
@item @b{@code{attach}} @var{session-specifier}
Create a new window displaying an existing session.
The same session (process) may be displayed in multiple windows.
See @ref{session-specifier}.

@item @b{@code{list}}
List information about running sessions.

The @code{status} command shows more information,
including some information about each window.
@end table

@subheading Windows operations

@table @asis
@item @b{@code{close}}
Close specified window(s), as if you clicked on the ``close'' button.
The default @var{windows-specifier} is @code{current}
@item@b{@code{detach}}
Close specified window(s) (the default is @code{current}),
and (assuming there are no more windows attached to the session)
make the session detached.

@item @b{@code{minimize}}
@emph{(Electron, Qt, and Wry only.)}
Minimize (iconify) the specified top-level windows,
where the default window is @code{top}.
The minimized windows may be still visible in the task bar,
as an icon on the desktop, or during an ``windows expose'' operation
@item @b{@code{hide}}
@emph{(Electron, Qt, and Wry only.)}
Hide the specified top-level windows.
The hidden windows are @emph{not} visible in the task bar,
as icons on the desktop, or during an ``windows expose'' operation
@item @b{@code{show}}
@emph{(Electron, Qt, and Wry only.)}
Show the specified minimized or hidden windows.
If there are no windows, create one.
@item @b{@code{toggle-minimize}}
@emph{(Electron and Qt only.)}
Toggle between normal and minimized state:
If a window is hidden or minimized, show it.
If visible, minimize it.
If there are no windows, create one.
@item @b{@code{toggle-hide}}
@emph{(Electron, Qt, and Wry only.)}
Toggle between normal and hidden state:
If a window is hidden or minimized, show it.
If visible, hide it.
If there are no windows, create one.

@item @b{@code{window}} @var{window-specifier} ... @var{subcommand} @var{options} ...
Do the @var{subcommand} on the windows specified by the @var{window-specifier} list.
Older (deprecated) form equivalent to:
@code{--window=}@var{window-specifier} ... @var{subcommand} @var{options} ...
@end table

@subheading Automation

The following are useful for automatically or remotely controlling DomTerm.
For examples for doing automatic testing for DomTerm
check the file @code{tests/Makefile.am} in the sources.

@table @asis
@item @b{@code{do-keys}} [@var{option}|@var{string}]...
Simulate user keystrokes by sending them to the front-end for interpretation.

@table @asis
@item @code{-w} @var{window-specifier}
If specified, must be the first argument.
Same as if specified before the @code{do-keys} argument.

@item @code{-N} @var{count}
Repeat following actions @var{count} times, until the next @code{-N}.

@item @code{-l} @var{text}
@itemx @code{-e} @var{text}
Send the @var{text} as plain characters, with no interpretation
for special key-bindings.
Acts like a key-press event for each character.
If @code{-e} (``escape'') is used, @ref{string escapes} are processed;
if @code{-l} (``literal'') is used, th @var{text} is used as-in.

@item @var{key-stroke}
The front-end simulates the specified @var{key-stroke},
as a key-down event.
Examples are @code{Enter} or @code{Ctrl+A}.
(@code{Ctrl-A} is accepted in addition to the modern @code{Ctrl+A} style.)
However, if the @var{key-stroke} starts and ends with single-quote, the characters between
the quotes are processed as if with the @code{-l} options.
Also, if the @var{key-stroke} has no action in the current context,
the front-end treats the @var{key-stroke} as if preceeded by @code{-l}
@end table

@item @b{@code{send-input}} @var{send-option}... @var{string}...
Send the specified @var{string} directly to the standard input
of a session.
If there is more than one @var{string}, send them in order,
with a single space in between.

A @var{string} may have @ref{string escapes}.

Usually @code{send-input "text"} has the same effect as @code{do-keys -e "text"}.
However, @code{send-input} feeds the @code{text} directly to the
application input, while @code{do-keys} sends it to the front-end
for processing first.  If the browser is in line-edit mode, it inserts
the @code{text} input the editing area instead of sending it to the application.

A @var{send-option} can be:
@table @asis
@item @code{-s} @var{session-specifier}
Send to the session as specified by the @ref{session-specifier,@var{session-specifier}}.
@item @code{-w} @var{window-specifier}
Send to the session attached to the @ref{window-specifier-option, specified window}.
@end table

@item @b{@code{capture}} @var{capture-option}...
Get the text contents of the @ref{window-specifier-option, specified window}
(defaulting to the @code{current} window).
The text is printed on standard output.
This command is useful for testing.

A @var{capture-options} can be:
@table @asis
@item @code{-B}
Only capture the contents of the current buffer,
as opposed to that of all buffers of the specified window.
@item @code{-l}
Include active soft newlines (i.e. from line-wrap or pretty-printing)
as newlines in the output.
Also skips extra whitespace (@code{" \t\r"}) at end of lines,
and extra newlines at the end.
@item @code{-e}
Include ANSI escape sequences that encode color and style in the output.
These escapes should work on almost all modern terminals.
DomTerm-specific ``logical'' styles (such as prompt or input areas)
are currently ignored.
@item @code{-w} @var{window-specifier}
Same as if specified before the @code{capture} command name.
@end table

In the future some options make be extended to take optional arguments,
so scripts should not combine options:
instead of @code{-Ble} write @code{-B -l -e}.

@item @b{@code{await}} @var{options}... @var{event}...
Wait until one of the specifed @var{events} happen.

The following @var{options} and @var{events} are supported:
@table @asis
@item @code{--match-output} @var{pattern} @var{response} [@var{nlines}]
After each ``block'' of output, try match @var{pattern} (a regular expression)
against the last @var{nlines} (default 1)  lines of the buffers.
(Trailing empty lines are not included in the @var{nlines} count.)
If the match succeds, write @var{response} to standard output.
(A newline is added if @var{response} is non-empty and does
not end in a newline.)

When this test is run depends on buffering (how the application and
network/system break output into blocks), so this test is mainly
intended to detect when output is ``done'' and the application
is waiting for input.
Typically, the @var{pattern} would look for a prompt string.
@item @code{--timeout} @var{time} @var{response}
If after @var{time} seconds none of the other @var{events} have occurred,
return (with a non-zero exit code indicating failure).
If @var{response} is non-empty, write it (plus a newline) to standard error.
@item @code{-w} @var{window-specifier}
A @ref{window-specifier-option,window specifier} for the affected window.
@end table

@end table

@subheading Miscellaneous options

An argument that contains equal-sign (@code{=}),
does not start with a hyphen (@code{-}), and
precedes a @var{command} (if any) is
a @ref{Settings,@dfn{settings option}}.

@table @asis
@item @code{--geometry} @var{size-and-position}
Specify the initial @var{size} and/or @var{position}
of a new top-level window.
See @ref{geometry specifier}.

@item @code{--version}
Print version information and copyright, and then exit.

@item @code{--verbose}
Print information about interesting events.
This works best with @code{--no-daemonize}.
A second @code{--verbose} prints more information.

A single (respectively double) @code{--verbose} prints
the same as @code{-d 7} (respectively @code{-d 15}),
but the latter prints a timestamp on each line.

@item @code{-d} @var{debug-level}
Finer-grained control over debugging level than using @code{--verbose},
plus prints time-stamps before each message.
Sets the @var{debug-level}
as defined by the @uref{https://libwebsockets.org/lws-api-doc-master/html/group__log.html,LWS logging API}.

@item @code{-L} @var{socket-name}
@itemx @code{--socket-name=}@var{socket-name}
DomTerm uses a Unix Domain socket to communicate between
the command-line and the server.
By default the socket is the file @code{$XDG_RUNTIME_DIR/domterm/default.socket},
but this option overrides that.
Using different socket names mean you get different servers
that do not know about each other.
If @var{socket-name} starts with @samp{/} then the filename is absolute;
otherwise @code{$XDG_RUNTIME_DIR/domterm/} is prepended.
If there is no file extension, @code{.socket} is appended.

DomTerm also creates a temporary @code{html} that has the
same name as the socket, but with a @code{.html} extension.
That is by default it is @code{$XDG_RUNTIME_DIR/domterm/default.html}.

@item @code{--settings=}@var{filename}

Specify the location of the @ref{Settings} file containing user preferences.
(The default is @code{.config/domterm/settings.ini} in the user's
home directory, except on WSL (Windows Subsystem for Linux).)

Note this flag won't have much if any effect if you specify it
when there is already a running domterm server.

@item @code{--no-daemonize}
When a domterm backend (server) is created, it normally turns itself
into a @uref{https://en.wikipedia.org/wiki/Daemon_(computing),daemon}.
This option prevents ``daemonizing'' - which is helpful for debugging.

@item @code{--remote-debugging-port=@var{debug-port}}
@emph{Only relevant for the @code{qtdomterm} front-end.}
(For the Electron front-end, use menu item @i{Toggle Developer Tools}.
If using a general web browser, use its debugger.)
Allow @uref{http://doc.qt.io/qt-5/qtwebengine-debugging.html,remote debugging}
(using a Chromium-based browser, such as Google Chrome).
This is useful for debugging DomTerm itself, as well as any
inspecting any unusual HTML, CSS, or JavaScript you might throw at it.

@end table

There are other @code{ldomterm} options which useful
if you want to run DomTerm as a server.

@subheading Starting a web server

The @code{domterm} command normally starts an internal web-server, bur
for security reasons this is only usable by the current user on the
current computer (enforced by the browser having to read a file
in the user's directory).

Sometimes you want a public web-server that other people can
attach to.  For that use the @code{--port} option
and the @code{--ssl} options.
See @ref{Remote serving} for more information.

@table @asis
@item @code{--port} @var{portnum}
Start a server, listening on the specified @var{portnum}.
A @var{portnum} of 0 lets the system choose an available port,
which is printed out.
The server is an @code{http} server, unless @code{--ssl} is specified,
in which case it an @code{https} server.
No front-end is started.

@item @code{--ssl}
Start an @code{https} server rather than an @code{http} server.
Strongly recommended except for testing.

@item @code{--ssl-cert} @var{cert-file}
The name of a file containing the server certificate.
@item @code{--ssl-key} @var{key-file}
The name of a file containing the passphrase needed for the private key.
@item @code{--ssl-ca} @var{ca-file}
CA (certificate authority) filepath.

@item @code{--once}
@emph{(Probably obsolete.)}
Only allow a single connect before shutting down.
This option is the default unless @code{--port} is specified.
@end table

@subheading Working with styles

All of these work with a @ref{window-specifier-option, window-specifier option},
defaulting to the @code{current} window.

@table @asis
@item @b{@code{reverse-video}} @code{on}|@code{off}
@end table

@table @asis
@item @b{@code{add-style}} @var{style-rule} ...

If called for the first time, create and install a temporary
stylesheet.
This temporary stylesheet has a @code{name} attribute
with the value @code{"(temporary-styles)"}.
Add each @var{style-rule} to the temporary stylesheet.

For example, to change the background color to pink:
@example
$ domterm add-style "div.domterm @{ --background-color: pink @}"
@end example

You can also set the @code{background-color} style directly:
@example
$ domterm add-style "div.domterm @{ background-color: pink @}"
@end example
However, it is better to set the @code{--background-color} CSS variable,
as that is required for reverse video and ``Background Color Erase'' to work.

Inverse video (using CSS variables):
@example
$ domterm add-style "div.domterm @{ --background-color: black; --foreground-color: white @}"
@end example

Changing font size:
@example
$ domterm add-style "body @{ font-size: 14pt @}"
@end example

@item @b{@code{list-stylesheets}}
List on the standard output the set of stylesheets associated with
the domterm document, one per line:

@example
$ domterm list-stylesheets
0: enabled  - "style/domterm-core.css"
1: enabled  - "style/domterm-standard.css"
2: enabled  "Default DomTerm styling" "style/domterm-default.css"
3: enabled  - "(temporary-styles)"
@end example
After the sequence number, either @code{enabled} or @code{disabled}
specified whether the stylesheet is disabled.
If the stylesheet has a @code{title}, if is shown next (in json format);
otherwise @code{-} is printed.
If the stylesheet has the @code{href} attribute, it is shown next
(in json format);
otherwise, if it has the @code{code} attribute, that is shown;
otherwise @code{-} is printed.

@item @b{@code{load-stylesheet}} @var{name} @var{filename}

Replace or create a new stylesheet with the given @var{name}.
The content of the stylesheet are read from the given @var{filename}.
If the @var{filename} is @code{-} then standard input is used.

The @var{name} is used to set the non-standard @code{name} attribute
of the created @code{<style>} element.  If there is an existing stylesheet
with a matching @code{name} attribute, then that stylesheet is replaced;
otherwise a new stylesheet is created.
The @var{name} attribute is displayed by the @code{list-stylesheets} subcommand.

@item @b{@code{print-stylesheet}} @var{index}
Print out the style rules of the specified stylesheet,
which is an @var{index} in the @code{list-stylesheets} output.

@item @b{@code{disable-stylesheet}} @var{index}
@itemx @b{@code{enable-stylesheet}} @var{index}
Disable or enable the specified stylesheet.
A @var{index} is an integer index into the
list as shown by @code{list-stylesheets}.

@example
$ domterm disable-stylesheet 2
@end example
@end table

@node Settings
@chapter Settings

A @dfn{setting} is named value that controls how
DomTerm works, depending on user preference or environment.

Settings can be global settings, or local settings.
@dfn{Global settings} are specified in a @code{settings.ini} configuration file,
and apply to all sessions and windows managed by a server.
@dfn{Local settings} are specified on the command line
(or in the future a GUI) and apply to the current command, session, or window.

The settings that are active is the merge of the
global and local settings, with the latter taking precedence.

@subheading Global settings from settings.ini file

User preferences for DomTerm are normally in the file
@code{.config/domterm/settings.ini} in the user's home directory.
This location can be overridden with the @code{--settings} command-line option;
otherwise the location is @code{$XDG_CONFIG_HOME/domterm/settings.ini},
where @code{XDG_CONFIG_HOME} defaults to @code{$HOME/.config}.
(For compatibility reasons, @code{$HOME/.domterm/settings.ini}
is also checked if @code{$XDG_CONFIG_HOME} is unset, but that may go away.)

(On WSL (Windows Subsystem for Linux) the file is
@code{c:\Users\@var{USER}\AppData\Roaming\DomTerm\settings.ini}.)
You can override this default with the @code{-settings} command-line argument.
If the @code{settings.ini} is changed it is automatically re-loaded.

The syntax of @code{settings.ini} is a variant
of the @uref{https://en.wikipedia.org/wiki/INI_file,INI file} format.
A preference is written as:
@example
@var{keyword} = @var{value}
@end example
For example:
@example
window.geometry=800x600
@end example
Spaces before or after @code{=} are optional.
A @var{keyword} should be a sequence of letters, numbers,
periods or hyphens.
The @var{value} is almost any sequence of characters (depending of
the @var{keyword}), up to end of the line.

Multi-line values are written as an empty line following the @samp{=},
and then one or lines starting with a single space followed by @samp{|}.
For example:
@example
style.user =
 |div.domterm @{ --background-color: azure @}
 |div.domterm-spacer @{background: none @}
@end example
In this cases the resulting @var{value} has two lines,
with the two-character prefixes @samp{ |} removed.

Comment lines start with @code{#} in the first column.
Comment lines and all-blank lines are ignored.

@subheading Local settings from command line

On the @code{domterm} command line, you can specify a local setting
with an argument that contains an equal sign (@code{=}) and
that does not start with a hyphen (@code{-}).
A settings argument is specified with other options @emph{before}
the @var{command}, if any.
For example:
@example
domterm style.dark=yes new bash
@end example

Command-line settings are used for the current command,
including creating a new session or window.

For convenience in @ref{command completion, command-completion}, you may
optionally prefix the setting with an initial @samp{=}:
@example
domterm =style.dark=yes new bash
@end example

To change local settings for a current window, you can use the
@code{domterm settings} command.  This modifies the local settings
of the current window.
@example
domterm settings style.dark=yes
@end example

@subheading Settings values

How the raw characters of a settings value is interpreted
depends on the keyword: Each keyword expects the value
to have a specific type and hence syntax.
The raw value is the characters in the settings file or command-file;
the actual value is how those characters are interpreted (parsed).

Some settings specify a list of values.
In that case the values are seperated by newlines or (unquoted) semi-colons.

@subsubheading Boolean values

For a boolean @var{value} any
one of @code{true}, @code{yes}, or @code{on}
enable the preference;
one of @code{false}, @code{no}, or @code{off}  disable the preference.

@subsubheading String values

If the type of value is a string, the actual value is roughly
the characters of the raw value with any non-nested quotoes removed.
``Extra spaces'' (more than one in a row, or at the start or end)
that are not quoted are also removed.
Both single quotes (apostrophes) and double quotes are handled.
Thus the following are all equivalent:
@example
history-storage-key=input history
history-storage-key=    input   history
history-storage-key="input history"
history-storage-key='input history'
@end example

Escape sequences starting with backslash (see below)
are processed within double quotes and outside quotes.
(They are currently also processed within single quotes, but that may change.)

Parsing as a string is the same as parsing as a command
and then joining all the arguments separated by a single space.

@anchor{string escapes}
@subsubheading String escapes

@table @asis
@item @code{\a}
Alert (Bell) (Unicode 0x07).
@item @code{\b}
Backspace (Unicode 0x08).
@item @code{\e}
Escape (Unicode 0x1B).
@item @code{\f}
Formfeed (Unicode 0x0c)
@item @code{\n}
Newline (Unicode 0x0A).
@item @code{\r}
Carriage return (Unicode 0x0D).
@item @code{\t}
Tab (Unicode 0x09).
@item @code{\u}@var{HHHH}
Unicode 0x@var{HHHH} where @var{HHHH} are 4 hex digits.
@item @code{\u@{}@var{HHHHHH}@code{@}}
Unicode 0x@var{HHHHHH} where @var{HHHHHH} are 1-6 hex digits.
@item @code{\v}
Veritcal tab (Unicode 0x0B).
@item @code{\"}
@itemx @code{\\}
@itemx @code{\/}
The character following the backslash:
Quotation Mark (Unicode 0x22), Backslash (Reverse solidus - Unicode 0xC),
or plain slash (Unicode 0x2F - pointless but included for JSON compatibiity).
@end table

This is a superset of JSON.

@subsubheading Command values
@anchor{command value}
A @var{command} is
an application name (executable or script or alias)
followed by optional arguments, separated by spaces.
Special characters (including spaces) can be protected in single quotes
(apostropes) or double quotes, as in typical shells.
Escape sequences starting with backslash (see above)
are processed within double quotes and outside quotes.
(They are currently also processed within single quotes, but that may change.)

Commands that display a session should include the pattern @code{%U}
for URL that is filled in by the server.
If the command does not contain a @code{%U}, it is added at the end.

A @dfn{command-candidates} value is a list of one or more @var{command} values
separated by non-quoted newlines or semi-colons.
For example if @code{fontend.default=firefox;chrome} is set,
then DomTerm will try first look for the @code{firefox} browser,
and if that is not found it will look for @code{chrome}.

@anchor{conditional values}

A @dfn{command-conditionals} value is a
@dfn{command-candidates} where each @var{command}
is prefixed with zero or more conditions in @code{@{}...@code{@}} braces.
All of the conditions must be satisfied for the following value to be selected.
A condition is one or simple @dfn{simple conditions},
optionally negated (by being prefixed by @samp{!}),
separated by vertical bars @samp{|}.
For example the condition @code{@{A|!B|C|!D@}} is true
if either of the simple conditions @code{A} or @code{C} is true,
or if @code{B} or @code{D} is false.

The syntax and meaning of a simple condition depends on the keyword.
For example, the @code{command.ssh} keyword accepts simple conditions
of the form @code{@@@var{hostname}} or @code{@var{user}@@@var{hostname}},
as shown in this example:
@example
command.ssh =
 | @{@@gnu.org@}ssh -E /tmp/gnu-ssh.log
 | ssh -E /tmp/ssh.log
@end example
This runs @code{ssh} with the @code{-E /tmp/gnu-ssh.log}
when connecting remotely to @code{gnu.org},
but with the flag @code{-E /tmp/ssh.log} when connecting to other hosts.

@subheading Available settings

@table @asis
@item @code{@b{shell.default} =} @var{command}
Specify a default ``shell'' command to execute when creating a new terminal.
The command can include arguments, separated by spaces.
You can uses quotes, as in a shell.

The default is the value of the @code{SHELL} environment variable;
if that is not set the default is @code{/bin/bash}.

@item @code{@b{browser.default} = } @var{browser-specifier}

The browser-like program used to create new top-level windows,
unless overridden by a specific browser-specifier option.

The @var{browser-specifier} is a kind of @var{command-candidates} value:
a list of command front-end,
separated by newlines or semi-colons.  The commands are tried
left-to-right, until one is found that exists and is executable.
See @ref{browser specifier} for details.

The default is currently:
@example
browser.default = electron;qt;chrome-app;firefox;browser
@end example
except on windows where it is:
@example
browser.default = edge-app;electron;qt;chrome-app;firefox;browser
@end example

@item @code{@b{command.firefox} =} @var{command}
@itemx @code{@b{command.chrome} =} @var{command}
@itemx @code{@b{command.electron} =} @var{command}
Command to use for respectively @code{firefox},
@code{chrome}, or @code{electron}.

The default for these is to search in the @code{PATH},
possibly with some platform-depending knowledge of default locations.

@item @code{@b{command.headless} =} @var{command}
Command used when the @code{--headless} option requests
an ``invisible'' @ref{Headless mode,headless} window.

@item @code{@b{command.get-clipboard} =} @var{command}
@itemx @code{@b{command.get-selection} =} @var{command}
Command that prints the string contents of the clipsboard (or the selection)
to standard output.
If the command's output ends with a newline, it is removed.
(If your command doesn't write a newline at the end,
you can add it, for example with @code{echo}.)
When the user requests a Paste operation,
the request is (in most cases - except for Electron) forwarded to the server,
which runs the named @var{command}.
The is done because browser security restrictions may limit when
JavaScript can read the clipboard.
If unspecified, the default depends on the platform and what
helper programs are evailable. (See the @code{get_clipboard_command}
function in the @code{lws-term/utils.cc} source file.)

@item @code{@b{window.geometry} =} @var{geometry}
Control the size and/or of new top-level windows
using the syntax of a @ref{geometry specifier}.

The default is @code{800x600}.
@end table

@subsubheading Display styling
@table @asis
@item @code{@b{style.user} =} @var{css-style-rules}
Set the @code{user} stylesheet to the rules in @var{css-style-rules}.
The latter is typically a multi-line value.

See the @ref{Styling} section for examples.

@item @code{@b{style.qt} =} @var{css-style-rules}
@code{qtdomterm} only: Set styling for QT user interface widgets.
For example to specify the color green
for text in @code{QMenu} do:
@example
style.qt =
 |QMenu @{ color: green; @}
@end example
See @uref{http://doc.qt.io/qt-5/stylesheet-examples.html, more examples}.

@item @code{@b{style.dark} =} @var{value}
This option (if set) selects ``reverse video'', which is a color preference
for a darker background and a ligher foreground (text).
The default is @code{auto}, which follows the system/desktop preference
if possible, or otherwise @code{off}, which selects
lighter background and a darker foreground colors.
Currently @code{auto} is only known to work on Firefox running on Gnome.

@item @code{@b{style.blink-rate} =} [@var{hide-time} [@var{show-time}]]
@itemx @code{@b{style.blink-rate} =} @var{hide-time}@code{,}@var{show-time}
Control rate of blinking text.
The text is invisible for @var{hide-time} seconds,
and then visible for @var{show-time} seconds, and then repeats.
Blinking is disabled if @var{hide-time} is zero.
If only one value is specified,
@var{show-time} defaults to @var{hide-time}.
If neither is specified the default is @code{0.3,0.7}.

@item @code{@b{style.caret} =} @var{value}
@itemx @code{@b{style.edit-caret} =} @var{value}
Change the style of the caret (text input cursor).
See @ref{caret styling}.
@end table

@subsubheading Key and mouse handling

@table @asis
@item @code{@b{open.file.application} =} @var{command-conditionals}
@itemx @code{@b{open.link.application} =} @var{command-conditional}
List of applications to try when clicking on a link.
If the link's @code{href} is a @code{file:} URL,
then the @code{open.file.application} list is tried first;
then the @code{open.link.application} list is tried.
For a non-@code{file:} URL, only the @code{open.link.application} list is tried.

For details, see @ref{link-handlers}.

@item @code{@b{keymap.master} =} @var{keymap-overrides}
Add or replace keybindings that are active in all modes.
See @ref{Keyboard shortcuts} for defaults and an example.

@item @code{@b{keymap.line-edit} =} @var{keymap-overrides}
Add or replace keybindings for @ref{Input line editing,input line editing}.
@end table

@subsubheading Remote connnections

@table @asis
@item @code{@b{command.remote-domterm} =} @var{command-conditionals}
When connecting to a remote server over ssh,
the command that runs @code{domterm} on the server.
The default is @code{domterm}, but you may need to use this
option if @code{domterm} is not in the remote @code{PATH} or
you want to pass extra options (perhaps for debugging or logging)
to @code{domterm}.
The value is @ref{conditional values,conditional},
where the simple conditions have the form of either
@code{@@@var{hostname}} or @code{@var{user}@@@var{hostname}}.
For example:
@example
command.remote-domterm =
 | @{@@192.168.1.55@}/home/bothner/DT/bin/domterm
 | @{jones@@mac.example.com@}/Users/jones/bin/domterm -d 15
@end example
The @code{@var{user}} and @code{@var{hostname}} are matched literally
against those used to connect remotelty.
If @code{@var{user}} is specified it must match exactly,
otherwise any (or no) @code{@var{user}} matches.

@item @code{@b{command.ssh} =} @var{command-conditionals}
The command to use instead of @code{ssh} to connect to a remote
server.
The value is a list of alternative commands, optionally
prefixed by @ref{conditional values,conditions},
in the same way as for @code{command.remote-domterm}.

@item @code{@b{predicted-input-timeout} =} @var{timeout}
When the user types a ``simple'' keyboard action (a printable character,
left/right arrow key, backspace, or delete) the keystroke will be sent
from DomTerm to the user application which will then update the
display (``echo'') in the ``standard'' way.  However, there is a delay
caused by the round trip from browser to application and back which may
be noticable, especially if browser and application are separated by a network.
To hide this delay, DomTerm will guess that the keystroke will
have the ``standard'' effect, and tentatively update the display
before it gets the confirming echo.
DomTerm will undo the predicted update unless it received a confirming
echo within @var{timeout} seconds.  The default timeout is 0.4 seconds.
@end table

The following settings are used to timeout if a connection fails.
All these values are in seconds; no timeout happens if the values are zero.
@table @asis
@item @code{@b{remote-input-interval} =} @var{input-interval}
If non-zero, the local browser sends input data at least as
frequently as every @var{input-interval} seconds.
If there is no keyboard or other event, artificial data is sent.
Defaults to 10 seconds,
@item @code{@b{remote-input-timeout} =} @var{input-timeout}
If the remote (application) end has not received any input data
in @var{input-timeout} seconds and @var{input-timeout} is non-zero,
it assume the connection has failed.
Defaults to twice @code{remote_input_interval}.
@item @code{@b{remote-output-interval} =} @var{output-interval}
If non-zero, the remote (application) ends some data to the
local browser at least every @code{remote_output_interval} seconds.
Defaults to 10 seconds.
@item @code{@b{remote-output-timeout} =} @var{output-timeout}
If the local browser end of the connection has not received any output
from the remote application end in @code{remote_output_timeout} seconds
(and it is non-zero), it assume the connection has failed.
(This timeout is both in the browser front-end,
and in the @code{domterm} server on the local end of the ssh connection.)
Defaults to twice @code{remote_output_interval}.
@end table

@subsubheading Debugging and logging
@table @asis
@item @code{@b{log.file} = } @var{specifier}
Send logging output (as controlled by the @code{-d} and @code{--verbose} flags)
to the specified file.
The @var{specifier} can be one of these special values:
@code{stderr} writes log entries to standard error, with timestamps and colors;
@code{stderr-notimestamp} (or @code{notimestamp}) is the same as @code{stderr} without timestamps;
@code{stdout} writes to standard output, with timestamps and no colors.
Otherwise, @var{specifier} is printf-style format string
that is used for a file that is appended to:
@code{%P} is replaced by Process ID of the @code{domterm} process;
@code{%%} is a literal percent symbol.

The default is @code{/tmp/domterm-%P.log}.

@item @code{@b{log.js-verbosity} =} @var{level}
Write more information to the JavaScript console.

@item @code{@b{log.js-to-server} =} @var{setting}
Send diagnostic/logging messages in the browser
(normally written to the JavaScript console as controlled by
by @code{log.js-verbosity}) where it is written using @code{lwsl_notice}
to the location specified by @code{log.file}.

Sets the @code{-d} option to 5 if not specified;
if specified the @code{-d @var{mask}} must have 4 set in the @var{mask}.
(If you divide @var{mask} by 4, the result must be an odd integer.)

@item @code{@b{log.js-string-max} =} @var{length}
If positive, maximum length of strings to print to the JavaScript console.

@item @code{@b{debug.input.extra-delay} = } @var{delay}
Delay an extra @var{delay} seconds before sending keyboard
and other events from client (browser) to server (application).
Especially useful for testing @code{predicted-input-timeout},
which should be higher than @code{debug.input.extra-delay}.
@end table

@subsubheading Miscellaneous settings

@table @asis
@item @code{@b{history.storage-key} =} @var{string}
A string (default @code{"DomTerm.history"} used as an identifier
for the JavaScripr storage mechanism to preserve line-editing history.

@item @code{@b{history.storage-max} =} @var{number}
Maximum number of entries (default 200)
of line-editing history to preserve,

@item @code{@b{password-hide-char} =} @var{string}
Character used to hide characters
in @ref{password fields,password fields}.
The default is @code{"\u25CF"} ``black circle''.
To change it to ``bullet'' you can do:
@example
domterm settings password-hide-char="\u2022"
@end example
@item @code{@b{password-show-char-timeout} =} @var{number}
Number of seconds (default 0.8) to show the actual password character
before it is replaced by the @code{password-hide-char}.

@item @code{@b{terminal.minimum-width} =} @var{width}
Mininum logical width (default 5, in columns/characters) of a terminal:
If the available width is less, use this width for line-wrapping etc.
(This avoids certain pathological behavior.)

@item @code{@b{titlebar} =} @var{mode}
Experimental option (only on Electron and Wry front-ends) to use
a custom titlebar for main (top-level) windows.
The @var{mode} can be @code{system} (the default) to use the system
titlebar, or @code{domterm} to use a custom titlebar (in HTML).
Further options and customization is planned for later.
@end table

@node Applications
@chapter Other DomTerm Applications

The core of DomTerm is the JavaScript @code{terminal.js},
but we also provides a few wrappers and applications that make use of it.

The @code{domterm} command is normally an alias for @code{ldomterm}.

@menu
* qtdomterm application::
* jdomterm script::
@end menu

@node qtdomterm application
@section The qtdomterm terminal emulator

@strong{The plan is to simplify qtdomterm so it just handles display.
It will be invoked by the @code{domterm} command to handle display,
while the @code{domterm} command manages jobs and sessions.}

You start and use @code{qtdomterm} just like other
terminal emulators such as @code{xterm}.
In addition to the regular DomTerm features (colors, stylesheets,
mouse-handling, embedded graphics, etc)
it also supports multiple tabs and windows, convenient text zooming,
and remote debugging,

@display
@code{qtdomterm} [@var{options}] [[@code{-e}] @var{command} @var{argument} ...]
@end display

This runs the @var{command}, with the specified @var{argument}s,
in a sub-process using a pty.
The @var{command} defaults to the value of the @code{SHELL}
environment variable.

The @var{options} include:
@table @asis
@item @code{--connect} @var{host}@code{:}@var{port}
This does not start an inferior @var{command}.
Instead it connects to an already-running WebSocket server,
as you might start with @code{domterm --port @var{port} [@var{command}]}.

This is one way to run commands on a remote server.

@item @code{--help}
Print a help message with options, and then exits.
@item @code{--version}
Print the version number, and then exits.
@end table

@node jdomterm script
@section The jdomterm terminal emulator script

The @code{jdomterm} script is no longer recommended as a general terminal-emulator.
It can be useful when using Java as it does not require native code.

By default it runs a shell (@code{bash}), but there are a number of options.

@display
@code{domterm} [@var{frontend}] [@var{backend-arguments}]
@end display

The @var{frontend} argument specifies the front-end or user interface
application - i.e. some kind of browser.
The @var{backend-arguments} specify which command is run and how it is run.

@subsubheading Front-end (user interface) options

The @var{frontend} is one of the following:
@table @asis
@item @code{--browser}
@itemx @code{--browser=}@var{program}
@itemx @code{--chrome}
@itemx @code{--firefox}
@itemx @code{--qtdomterm}
@itemx @code{--qtwebengine}
Similar to the @code{ldomterm} options.

@item @code{--javafx}
This uses Java and the JavaFX WebView browser component (based on WebKit).
It needs OpenJDK 1.8 (or JDK 7 with JavaFX) but should otherwise
not need anything else.  Instead of a WebSocket server,
it uses JavaFX's Java/JavaScript bridge.

The UI (written in Java using the JavaFX toolkit) is minimal,
but right-clicking will bring up a popup menu.
This supports copy and paste, as well as
switching the input mode between line, character, or auto mode.

There are some glitches, and since JavaFX is not being actively
developed, this port is not a priority.

@item @code{--port} @var{portnum}
Start a WebSocket server, listening on the specified @var{portnum}.
(A @var{portnum} of 0 lets the system choose an available port,
which is printed out.  The default for @code{repl-client.html} is @code{8025}.)

No front-end is started automatically.
Instead, you load @code{repl-client.html} in your preferred web browser,
and it connects to the server.
If the server is listening on port @var{portnum} (rather than port 8025),
browse to @code{file:///path/to/DomTerm/repl-client.html?ws=//localhost:@var{portnum}}.

This allows you to use "any" modern browser as the client.
This is nice for development, as you can use the browser's
JavaScript console and debugger, DOM inspector, and so on.
The browser talks to server using WebSockets,
which modern browsers have built-in.
@end table

@subsubheading Back-end (command) options

The @var{backend-arguments} are one of:
@display
[@code{--pty}|@code{--pipe}|@code{-e}] [@var{command} @var{arg}...]
@code{--class} @var{classname} @var{arg}...
@end display

You can specify some other @var{command} and @var{arg} in
place of the default @code{/bin/bash}.

Specifically:

@table @asis
@item @code{-e} [@var{command} @var{arg}...]
@itemx @code{--pty} [@var{command} @var{arg}...]
This is the default on Unix-like systems (MacOs, GNU/Linux, BSD).
It runs @var{command} under a PTY.
Communication is by default character-by-character, but
can also be line-based.
@item @code{--pipe} [@var{command} @var{arg}...]
The input/output of the @var{command} is connected to DomTerm using
pipes.  Data communication is normally on a line-by-line basis.
(It is also possible to send single keystroke message.)
The implementations uses a Java @code{Process} object.
This should work on Windows, though it has not yet been tested.

@item @code{--class} @var{classname} @var{arg}...
This runs the @code{main} method of a specified Java class,
but with the standard streams (input, output, and error)
re-bound to a DomTerm window.

@example
CLASSPATH=@var{my-application.jar} domterm --class @var{my.ClassName} @var{arg}...
@end example

@end table

@node Frontends
@chapter Frontends including browsers

A @dfn{frontend} is a program that handles the user interface
for a session, in a @dfn{window}.
A frontend is either a web browser, or some application
that has an embedded @dfn{web engine}.
You have a number of options for a frontend, with different
advantages and limitions.
The two most polished frontends at this point are
the Electron and Qt frontends.

You can specify a preferred front-end using a @ref{ browser specifier},
either using a @code{--browser} option (or the shortcut @code{-B})
to the the @ref{domterm application},
or with the @code{browser.default} @ref{Settings,setting}.

Multiple different frontends can talk to the same backend
at the same time.

@anchor{geometry specifier}
@subheading Window size and position (geometry specifier)

You can request the initial size and position
of a top-level window using an X11-style
@dfn{geometry specifier}, using either a @code{--geometry}
@ref{domterm application,command-line option} or
a @code{window.geometry} setting in @ref{Settings,@code{settings.ini}}.
A specifier is either a @var{size} or a @var{position}
or a @var{size} followed by a @var{position} (with no spaces).
For example @code{--geometry=775x600+20+10}
specifies that the window is initially 775 pixels wide,
600 pixels high, and positioned (if possible)
20 pixels right and 10 pixels below the top left corner of the screen.

A @var{size} has the form @var{W}@code{x}@var{H},
where @var{W} and @var{H} are the width and height in pixels,
both positive integers.
The default if not specified on the command-line is that of the previous window,
or the @code{window.geometry} option in the @ref{Settings} file,
or otherwise currently @code{800x600}.
(When creating a new window using a menu entry or keyboard shortcut,
the default size is that of the current window.)

A @var{position} requests an initial position of the window,
in the form @code{[-+]@var{X}[-+]@var{Y}}.
The @var{X} specifies how far (in pixels) the left edge of the
window is from the left edge of the screen, or (if preceded by @code{-})
how far the right edge of the window is from the right edge of the screen.
@var{Y} specifies how far the top edge of the
window is from the top of the screen, or (if preceded by @code{-})
how far the right edge of the window is from the right of the screen.

A @var{position} in @ref{Settings,@code{settings.ini}} is only used
for the initial window.

A @var{size} works for the Electron, qtdomterm, and @code{--chrome-app}
front-ends.  A @var{position} currently only works for Electron.

@subheading Browser quirks and limitions

(These can all change as browsers change or work-arounds are implemented.)

Exiting the inferior process can sometimes fail to automatically
close the DomTerm window, due to browser security limitations.
It currently works on Google Chrome, but not Firefox.

Saving the console display to a file in a browser may
save to the browser's ``Downloads'' area.
You may be able to save the file elsewhere, depending
on the browser and its settings.

Microsoft Edge at time of writing does not handle the @code{tab-size}
CSS property, so on that browser tab characters are always converted to spaces.

@subsubheading Copy and paste

Paste should work on all front-ends
if domterm makes use of @ref{installing-libclipboard,libclipboard}.
Otherwise, only Electron and WebView work as they should,
though the keyboard shortcut Ctrl+Shift+V works on all tested platforms,
(On Qt the Paste menu-item is unreliable if the previous Copy
was from a different application.
On a desktop browsers like Firefox, custom menus can't do Paste though system manus can, because of security concerns.)

The Copy menu-items work on Electron or Qt,
but there are issues on other front-ends.
The keyboard shortcut Ctrl+Shift+C works on all tested platforms.

Middle-button paste seems to work on most frontends (on Linux).
An exception is WebKit-based browsers (Webview, Epiphany aka Gnome Web),
though it works if you use @ref{installing-libclipboard,libclipboard}.

@subsubheading Note on menus

The Electron and Qt front-ends use their respective
menu interfaces, which works well.

On Electron disabling the menubar by clicking ``Show menubar''
is currently not working.

Most other frontends use a menu package written in JavaScript
that works fairly well, but has some minor issues.
One is that all menus are constrained to the main window.
Also (as mentioned above) copy and paste menu items may
not work due to browser security restrictions.

@subheading Electron

Start the Electron frontend (if available) with the @code{--electron} option.

@subheading Qt

Start the Qt frontend (if available) with the @code{--qt} option.

@anchor{webview-frontend}
@subheading Webview

Start the Webview frontend (if available) with the @code{--webview} option.

This is quite usable - nicer than using a web-browser.
It uses JavaScript menus, which is OK except on Mac.

Cat'ing large files is much faster than other browsers, probably due to
deferred re-display.  Window re-sizing is slower.
Both of these may change if we implement smarter lazy line-breaking.

Some known issues:
@itemize
@item
Windows zoom (with @kbd{Ctrl+@key{Minus}} or @kbd{Ctrl+Shift+@key{Plus}})
doesn't work.  You can work around it with CSS styling:
@code{body @{zoom: 120%@}}
@item
Copy from menu doesn't work.  Ctrl+Shift+C works.
@item
Clicking the window close button doesn't shut down cleanly.
Using the @code{File}->@code{Quit} menu item works,
as does typing @code{exit} from a shell.
@item
Middle-button click does a paste from the clipboard,
but it should paste from the selection.
Fixed if you use @ref{installing-libclipboard,libclipboard}.
@item
The @code{About DomTerm} menu item doesn't work.
@end itemize

@subheading Desktop browser

Modern desktop browsers should work ok,
but note the limitations mentioned above (most notabley copy and paste).
However, only Firefox and Chrome are tested frequently.

@subsubheading Firefox

To open a Firefox window or tab use the @code{-Bfirefox} option.
Recent versions of Firefox should work well.

Exiting the inferior process (such as by typing @code{exit} in a shell)
does not automatically close the browser window.

@subsubheading Chrome

To open a Google Chrome window or tab use the @code{-Bchrome} options.

The @code{-Bchrome-app} option creates a top-level Chrome window
without the standard Chrome location bar or other header ``chrome''.

@subheading Embedded in other environments

@subsubheading Atom

There is a fairly nice package for embedding DomTerm panes
in the @uref{https://atom.io/,Atom} text editor framework.
See @uref{https://github.com/PerBothner/atom-domterm,the repository}.

@subsubheading Theia

There is an experimental package for the
@uref{https://www.theia-ide.org/,Theia IDE}.
See @uref{https://github.com/PerBothner/theia,this fork}.

@node Remote serving
@chapter Remote serving

To run a shell or command on a remote computer you
can of course run the @code{ssh} command in a DomTerm window.
This works, but has some limitation, most notably there is no
persistent session on the remote server if the connection fails.
Various tools can be used to provide persistence, but
DomTerm provides integrated functionality.

One option is to use a web browser to connect to DomTerm
as a web server running on the remote host.  This works best
if you want to set up a public-accessible service.
Alternatively, DomTerm can run as a layer on top of ssh;
that is usually easier to use and set up.

@menu
* Remoting over ssh::
* Web serving::
@end menu

@node Remoting over ssh
@section Remoting over ssh

The command syntax:
@example
@code{domterm} [@var{browser-specifier}] [@var{user}]@code{@@}@var{host} [@var{command}]
@end example
runs @code{domterm} [@var{command}] as @var{user} on the remote server @var{host},
using @code{ssh} to connect.  However, if the @var{command} creates a
new session (or attaches to an existing session on @var{host}),
then the session will be displayed in a local window,
as specified by the optional @var{browser-specifier}.  For example.
if the latter is @code{--tab}, a new tab will be created in the current window.

Note each sub-window is independent and can be local
or connected to different remote server.

This mechanism does not require any superuser access, network ports/servers,
or credential/security management beyond those used by standard @code{ssh}.

@ref{Architecture remote over ssh,Here} is a summary of how it works.

@subheading Specifing the remote destination

The general syntax is:
@example
@code{domterm} [@var{options}] @var{remote-destination} [@var{remote-options}] [@var{command} @var{args}]
@end example
where a @var{remote-destination} is
[@var{user}]@code{@@}@var{host}[@code{:@var{port}}] .
Here @var{host} is the name or IP address of the remote computer,
as processed by the @code{ssh} command.
The @var{user} is the user name on the remote @var{host},
by default the same as the current local user name.
The @var{port} is the protocol port which the remote ssh server
listens to, by default 22.

You can also use URL syntax
@code{ssh://[@var{user}@code{@@}]@var{host}}[@code{:@var{port}}],
which is converted to the former syntax.

@subheading Local vs remote state

When you create a remote connection, there are distinct servers running
on the local machine vs the remote machine.
Suppose you have a local window and you create a remote session
as a sub-window:
@example
domterm --below @@192.168.1.55
@end example
If you run the @code{domterm status} you see what the
local server knows about:
@example
Window 1:  qtwebengine: 5.6.1, chrome: 45.0.2454.101
  session#1: pid: 5287, tty: /dev/pts/2
  session#2: ssh to remote @@192.168.1.55#1
@end example
Session 1 is a local session,
while session 2 is a remote session.
Note that what the local server thinks of
as session 2 is a proxy for session 1 on the remote server:
You can also see the status of the remote server
using @code{domterm @@192.168.1.55 status}.
@example
Connection 1 via ssh from 192.168.1.58
  session#1: pid: 6464, tty: /dev/pts/1
@end example

@subheading Attaching and detaching

It you detach from a remote session,
the session will be detached on the remote end,
while the local server will remove all state from its end.

Later you can connect to a detached session @var{number} on @var{host}:
@example
domterm @@@var{host} attach :@var{number}
@end example
Note that the @var{number} is the session number as managed by the remote
server.  This may be different from the local session number
that the session had before you detached it.  To find out which
sessions have been detached on @var{host} you can ask
the remote server for its status, including detached sessions:
@example
domterm @@@var{host} status
@end example

@subheading Slow connections

Normally terminal interaction sends each character (keystroke)
individually to the remove server, and the process on the remote
server will respond with terminal escape sequence to update the
display to match what you typed.  This called echo.
This can be annoying if the round-trip time is noticable.

To alleviate this, DomTerm predicts echo from certain key-presses,
based on what it @emph{expects} the remote server to do.
This is done for regular characters (which are inserted),
left and right arrow (move caret), Backspace (delete previous character),
and Delete (delete following character).
This predication is shown with a gray background to indicate it
is @emph{tentative}.
After a while (controllable by the @code{predicted-input-timeout} setting),
if the predicated echo does not happen, DomTerm will undo its predication.
You should set @code{predicted-input-timeout} to be longer than
the typical round-trip time; the default is 0.4 seconds.

For example suppose you type @code{A},
then @code{B}, the @code{C}. DomTerm tentatively inserts @code{ABC}.
Then it receives echo to insert @code{AB}.
First, DomTerm removes the prediction, and performs whatever updates
have been requested.  Then DomTerm compared the resulting line with what
it predicted.  It sees that the current display corresponds to echo
of @code{A}, and @code{B}, but not @code{C}.  It therefore updates
the display to show a predicted tentative @code{C}.

Another way to deal with a slow connection is to switch to
@ref{Input line editing,line-editing mode}.  Then you can compose
an input line (or even multiple input lines) completely locally,
before you type @kbd{@key{Enter}} to send the line(s) to the server.
You can switch back and forth as much as it is convenient,
even in the middle of a line.  If you have a partial input line
(by default shown with a green border), and then switch to
regular character mode, the partial line is converted to
a predicated insertion and then sent to the server
(which will normally echo it).

@subheading Dealing with connection loss

When connecting over a network, there is always the issue
of how to deal with temporary or permanent connection failure.
Also, what happens if your local laoptop dies (runs out of power or
is re-booted) or you start a session using your work computer,
and want to check on the sesssion using your home computer?

DomTerm offers these strategies:
@itemize
@item
In many cases, after the network freezes or you sleep either
the local or remote computer, reconnecting happens smoothly without problems.
The local display state will persist in the local browser process.
@item
Explicit detaching and re-attaching.
If you have warning you will need to disconnect, especially if you may have
to re-connect from a different computer or network, it is best to
explicitly detach the session.  The local display state will be downloaded
to and saved on the remote server.
The remote server and user process will
remain alive, but no resources will be needed for a browser process
or local server state until you re-attach.
@item
Background headless browser.
If you are concerned you be disconnected without warning and/or
have to re-connect from another computer, you can create a
duplicate @ref{Headless mode,headless} window running on the remote server.
The session will be attached to two connections:
The headless window on the remote server,
and a regular display window on the local computer.
The connections will be synchronized (as long as both are alive and connected),
and both will have the display state.
Even if the local computer dies, if you attach to the
server, it can request the needed display state from the headless window.

It is planned (but not yet implemented)
to have an option to automatically create the background headless window.
@end itemize

@subheading Sharing sessions (experimental)

Multiple people can attach to the same remote session, assuming
they all have ssh login access to the remote computer.

For security reasons, it is probably best to create a separate user
identity for shared sessions.  Using Unix user groups may also
be practical but hasn't been explored.
It would also be useful to be able to grant some users
read-only access and some modification acess (to allow user input).
This should be dynamically switchable a session owner.

In addtion to security, there are practical issues to resolve,
such as what happens when different users have their windows
set to different widths.

@subheading Build domterm for a server

If the @code{domterm} command is not installed on your remote server,
build DomTerm as shown (on a compatible platform).
(The @code{--with-libwebsockets} option
cause that library to be linked statically, which is recommended
if they might not be installed on the remote server.)
@example
./configure --prefix=/tmp/DT --without-java --with-libwebsockets=@var{lws_dir}
make install
cd /tmp
zip -r DT.zip DT
scp DT.zip @var{remote_host}:/tmp
@end example
On the @var{remote_host}, where @var{remote_dir} is some directory you have write access to (could be the home directory):
@example
cd @var{remote_dir}
unzip /tmp/DT.zip
@end example
After that you should be able to connect from your local machine using the @code{command.remote-domterm} setting:
@example
domterm command.remote-domterm=@var{remote_dir}/DT/bin/domterm @var{remote_user}@@@var{remote_host} [@var{command}]
@end example

@node Web serving
@section Web serving

To start DomTerm as a web server, run the @code{domterm} command
with the @code{--port} option.
It is highly recommended that you use https,
with the @code{--ssl} option - see below.

It is of course possible to run the @code{ssh} command from a
DomTerm session, but that does not provide a persistent session on
the remote server if the connection fails.

@subheading Using https

To use https you need a certificate.

A simple self-signed certificate:

@example
openssl req -x509 -nodes -days 7300 -newkey rsa:2048 -keyout server.key -out server.crt -subj "/CN=localhost"
@end example
Start the server with these flags:
@example
domterm --port 8080 --ssl --ssl-cert server.crt --ssl-key server.key
@end example
and then in your browser open @code{https://localhost:8080}.
Note that browsers will complain about self-signed certificates,
so this is only suitable for testing.

@node Sessions and Windows
@chapter Sessions and Windows

DomTerm can ``multiplex'' multiple terminal emulators
(similar to tmux or GNU Screen).

@subheading Sessions

A @dfn{session} is an emulated terminal with a process running under it.
A @code{domterm} @dfn{server} manages one or more sessions.
Typically, for each user there is at most a single @code{domterm} server
running at a time, though it is possible to create more:
The server is created as needed, and exits when there are no
more sessions.
(Note that @code{tmux} uses ``session'' to refer to multiple
processes running under the same server.)

Each session is usually displayed in a
@dfn{domterm window} or @dfn{window} for short.
If the session is not displayed in any window,
we say it is @dfn{detached}.
It is possible to display the same session in multiple windows.

Every session has a unique integer session number.
These numbers are unique with a domterm server:
If you connect to a @ref{Remote serving,remote domterm server}
the session numbers may be different on the local and remote end.

@subheading Windows and connections

A @dfn{window} is an area of the screen
where you can display or interact with a session:
Either a @dfn{top-level window} (a window or tab
managed by a window manager or a web browser),
or a @dfn{sub-window} (managed by DomTerm),
which can be a @dfn{pane} or a @dfn{tab}.
A top-level window may be split vertically and/or horizontally
into one or more panes (or tiles),
which can each have multiple tabs, only one of which is visible at a time,

A @dfn{non-session window} displays something other than
a DomTerm session.  The @code{domterm browse} command creates
a non-session window that displays a specified web page.
One use of this for is viewing documentation.

@anchor{window number}
Every window has a unique window number.
Normally, when a new terminal session is created a window will
be created with the same window number as the session number.
However, there may be detached sessions without windows,
and (rarely) there may be sessions that use multiple windows.

Also the remote server will use a proxy connection with
a connection number that is similar to a window number.

@subheading Managing sessions

Creating a new session is done by invoke the @code{domterm} command with the
@code{new} sub-command, or with no arguments.
See @ref{session-creating,Creating a new session} for details.

The sub-command @code{list} lists active sessions,
as does @code{status} with more detail.

The sub-command @code{attach} connects to an existing session,
often a detached session.  You specify the session
with a @ref{session-specifier}.

The can detach the current session using either the
keyboard short-cur @code{@mux-prefix d} or a menu command (Electron only).
More precisely, it marks the current session as @var{want-to-detach},
and closes the current window.  If there are other windows on the
session, they remain active, but the session is detached (rather than
exits) when the last window on the session closes.

When a session is detached, it saves the display state, so it can
be re-created if the session is later attached.
There is no auto-save in case of unintentional detach, such as
network failure or a browser crash, but there are plans to implement that.

@subsubheading Session specifiers

A session specifier has one of the following forms:
@table @asis
@item @var{number}
Normally a session number.
Can also be a window (connection) number in which case the corresponding session is used.
@item @var{session-name}
The @var{session -name} is a user-friendly name associated with the session,
and displaying in the tab-bar and title-bar of windows displaying the session.
The default @var{session-name} is @samp{DomTerm:@var{session-number}}.
@item @code{$}@var{pid}
The @var{pid} is the process ID (an integer) of the designed session.
@end table

@node Keyboard shortcuts
@chapter Keyboard shortcuts

In normal ``character'' mode most key-presses result
in characters being send to the process (shell),
but certain special key-combinations are handled specially.
This is covered here.

The @ref{Input line editing,line-editing mode} has
short-cuts suitable for editing text,
while the read-only @ref{Paging,Paging mode} mode has short-cuts
useful for navigating around in the buffer, including making selections.

@table @asis
@c FUTURE @item Ctrl+Shift+P
@c Enter/exit pager mode
@c FUTURE @item @mux-prefix
@c Prefix for Screen or TMux
@item @kbd{Ctrl+Shift+@key{C}} (@code{copy-text})
@itemx @kbd{Ctrl+@key{Insert}}
Copy the selection to the clipboard.
It is copied as both plain text (@code{text/plain})
and formatted HTML (@code{text/html}) in case the receiving
application can paste the latter.
(@kbd{Ctrl+@key{C}} also works in line-editing mode.)
@item @kbd{Ctrl+Shift+@key{V}} (@code{paste-text})
@itemx @kbd{Shift+@key{Insert}}  @emph{(Electron and Qt only)}
Paste text from the clipboard.
(@kbd{Ctrl+@key{V}} also works in line-editing mode.)
@item @kbd{Ctrl+Shift+@key{X}} (@code{cut-text})
``Cut'': Restricts the selection to the current input area,
copies that restricted selection to the clipboard,
and then deletes the restricted selection.
(In character mode, the deletion is implemented by sending
the appropriate number of Delete/Backspace characters to the application.)
@item @kbd{Ctrl+Shift+@key{S}} (@code{save-as-html})
Save the display to a file.
@item @kbd{Ctrl+Shift+@key{L}} (@code{input-mode-cycle})
Cycle between the input modes: automatic, to line, to character, and back.
The resulting mode is displayed temporarily.
@item @kbd{Ctrl+Shift+@key{M}}
Enter @ref{Paging,Paging mode}.
@item @kbd{@key{Ctrl}}
Show a popup with useful information about version, mode, size,
or other data.
This is shown if you press and release the @key{Ctrl} key
without pressing some other key.
Easiest way to make the popup go away is to press @key{Ctrl} again.
@end table

The following are implemented by most browsers, rather than DomTerm,
so it may not work on all browsers.
@table @asis
@item @kbd{Ctrl+Shift+@key{Plus}}
Zoom in (makes text bigger).
(Does not work in atom-domterm.)
@item @kbd{Ctrl+Shift+@key{Minus}}
@itemx @kbd{Ctrl+@key{Minus}}
Zoom out (makes text smaller).
(Does not work in atom-domterm.)
@item @kbd{Ctrl+@key{0}}
``Un-zoom'' to normal size.
@item @kbd{@key{F11}} (@code{toggle-fullscreen})
Toggle full-screen mode.
@item @kbd{Shift+@key{F11}} (@code{toggle-fullscreen-current-window})
(Not for Electron or Qt.)
Toggle full-screen mode for the current sub-window.
@item @kbd{Ctrl+Shift+@key{I}}
Toogle Developer Window, useful for debugging or examining
the state of the Document Object Model.
@end table

@anchor{scrolling shortcuts}
@subsubheading Scrolling

In paging and edit modes, these may be modified by a repeat @var{count}.
Otherwise, @var{count} defaults to 1.

@table @asis
@item @kbd{Ctrl+Shift+@key{PageUp}} (@code{scroll-page-up})
@itemx @kbd{Ctrl+Shift+@key{PageDown}} (@code{scroll-page-down})
Scroll @var{count} ``pages'' up or down, respectively.
(Specifically, the viewport height times @var{count} minus a height of one line.)
@item @kbd{Ctrl+Shift+@key{Up}} (@code{scroll-line-up})
@itemx @kbd{Ctrl+Shift+@key{Down}} (@code{scroll-line-down})
Scroll @var{count} lines up or down, respectively.
@item @kbd{Ctrl+Shift+@key{Home}} (@code{scroll-top})
Scroll to top.
@item @kbd{Ctrl+Shift+@key{End}} (@code{scroll-bottom})
Scroll to bottom.
@end table

See also the bindings for @ref{Paging} mode.
@subsubheading Managing subwindows

The prefix key @kbd{@mux-prefix} when followed by some other key
controls sessions and windows.

@table @asis
@item @kbd{Ctrl+Shift+@key{T}}
Create a new terminal in a new tab.
@item @kbd{Ctrl+Shift+@key{N}}
Create a new terminal in a new pane (sub-window).
The new pane is create to the right or below the current pane,
depending on space.
@item @kbd{@mux-prefix Ctrl+@key{Left}}
Create a new terminal pane to the left of the current one.
@item @kbd{@mux-prefix Ctrl+@key{Right}}
Create a new terminal pane to the right of the current one.
@item @kbd{@mux-prefix Ctrl+@key{Up}}
Create a new terminal pane above the current one.
@item @kbd{@mux-prefix Ctrl+@key{Down}}
Create a new terminal pane below the current one.
@item @kbd{@mux-prefix @key{Left}}
Select the previous pane or tab.
@item @kbd{@mux-prefix @key{Right}}
Select the next pane or tab.
@item @kbd{@mux-prefix @key{d}}
Detach from current session and close the (sub-)window.
@end table

@subheading Changing keybindings

You can override the keymap (map from keystrokes to action).
The @code{keymap.line-edit} @ref{Settings,setting} is a list (separated by commas or newlines),
where each item is a quoted keystroke string, followed by a colon,
followed by an action name. An action name is a string,
but quotes are optional.

To enable ``standard'' handling of Ctrl+V for Paste and Ctrl+C for Copy
(while still signalling interrupt when there is no selection) do:
@example
keymap.master =
 | "Ctrl+C": copy-text-or-interrupt
 | "Ctrl+V": paste-text
@end example

@node Edit and View modes
@chapter Edit and View modes

Keyboard bindings vary between these 3 main modes:

@itemize
@item
In @strong{character input mode}
most keystrokes become characters sent directly to the application.
@item
In @strong{line-edit mode} most keystrokes update a local ``input area''.
Plain characters are inserted; other keystrokes are editing commands.
The contents of the input area are only sent to the application
when you press @kbd{@key{Enter}} (normally).
(This mode is similar to @dfn{shell mode} in Emacs.)
@item
@strong{View mode} is designed for read-only movement in the
buffer, as well as selecting text.
The output may also be @strong{paused}, in which case output
from the application is queued up instead of updating the buffer.
@end itemize

On addition:
@itemize
@item
@strong{Automatic input mode} automatically
switches between character mode and line-edit mode.
This is the default.
It is done based on the @uref{https://en.wikipedia.org/wiki/Terminal_mode,terminal mode} of
the application's @uref{https://en.wikipedia.org/wiki/Pseudoterminal,PTY}:
If the terminal is in @dfn{raw mode} it is expecting characters as they
are typed, so DomTerm selects character-at-a-time mode.
If the terminal is in @dfn{cooked mode},
the application reads entire lines that
have been put together by the operating system,
so DomTerm selects line-edit mode (so you get DomTerm's superior
``input cooking'' editor instead of the very basic one
provided by most operating systems).
See @ref{Automatic input mode,here for technical details}.
@end itemize

You can switch between character mode, line mode,
or automatic mode using the @code{Terminal} menu in the menubar;
the @code{Input mode} entry in context (popup) menu;
or the @kbd{Ctrl+Shift+@key{L}} shortcut:

@table @asis
@item @kbd{Ctrl+Shift+@key{L}}
Cycle between input modes: character (character-at-a-time),
line (line-edit), or automatic.
@end table

@menu
* Input line editing::
* Paging:: View mode - Paging and Pausing
* The Selection:: Working with the Selection
* Find text::
@end menu

@node Input line editing
@section Input line editing

In ``line-editing mode'' most keystrokes add to or modify
an editing area in the DomTerm window, but are not sent to
the application until you type Enter.
This enables editing of input lines similar to
Emacs shell mode or GNU readline.

@subsection The input area

@image{images/dt-lineedit1}

The area affected by insertions and edits during line-edit mode
is called the @dfn{input} area, and it is by default
high-lighted using a dashed brown border.
Normally, the input area is a single line
(or the part of a line following a prompt) but it can be multiple lines.

If output arrives while the input area is active the output buffer is
updated as if the input area is not there: The input area is removed,
the output with escape sequence is processed, and then the
input area is re-inserted at the position of the output caret.

A mouse click on a match move the base position to the start of the match,
and selects the match.  A click not on a match sets the base position
to the clicked location, and selects the first following match.
(Id the search direction is backwards ....)

@table @asis
@item @kbd{@key{Enter}} (@code{accept-line})
Send the contents of the input area to the application,
along with a final newline.
Also, if the input area is non-empty, add it to the history list.

If you want to send the contents of the input area without
a final newline, you can switch the input mode to character mode
(using either the menu or one-or-more @kbd{Ctrl+Shift+@key{L}} commands).
This removes the text of the input area, but echo from
the application will normally replace it.
You can then optionally switch back to line mode.
@item @kbd{Alt+@key{Enter}} (@code{insert-newline})
Insert a literal newline.  Splits the current line at the current position,
creating two new lines out of one old line, with the caret after the new break.
@end table

@subsection Using the mouse

A mouse click in the input area moves the caret, as you would expect.
For convenience, clicking outside the input area but on an input line
also works, moving the mouse to the beginning or end of that line.
Clicking on a line that does not contain part of the input area has no
effect (except to make the window active).

Swiping the mouse (mouse-down followed by moving the muse followed
by mouse-up) selects the region of text swiped, as expected.
However, unlike many text editors, the input caret is not moved:
The selection and the input caret are independent.
A reason for difference is that the input caret is restricted to the
input area, while the selection can be any part of the buffer.

Note that the end of the swept area (correspondiong to mouse-up)
is indicated with a special marker (by default a brown I-beam)
called the @dfn{focus caret}. More on that later.

Clicking while the shift key is pressed extends the selection
as if you swept the mouse from the orginal end-point to the new click position.

@subsection Keyboard editing commands

The following special keys are supported.
The word ``caret'' refers to the text cursor
(as opposed to the mouse cursor).
The names in parentheses are the corresponding action names that
can be used if changing the key-bindings.

@subsubheading Repeat count

Many of the following keyboard commands can be modified
by previously-typed @dfn{repeat count}.

@table @asis
@item @kbd{Alt+@var{digit}}
@itemx @kbd{Alt+@key{Minus}}
@itemx @kbd{Alt+@key{.}}
Set or extend a repeat count.
For example @kbd{Alt+1 Alt+2 Left} moves 12 characters left, while
@kbd{Alt+Minus Alt+2 Ctrl+Left} moves 2 words right (because of the minus).

You can also repeat self-inserting characters:
@kbd{Alt+2 Alt+0 *} inserts 20 asterisks.
@end table

Commands that are affected by a repeat count
contain @var{count} in the description.
By default the @var{count} is one, and it is reset after each command.

@subsubheading Moving the editing position

@table @asis
@item @kbd{@key{Left}} (@code{backward-char})
@itemx @kbd{@key{Right}} (@code{forward-char})
Move caret @var{count} characters left or right.
@item @kbd{Ctrl+@key{Left}} (@code{backward-word})
@itemx @kbd{Ctrl+@key{Right}} (@code{forward-word})
Move caret @var{count} words left or right.
@item @kbd{@key{Home}} (@code{beginning-of-line})
@itemx @kbd{@key{End}} (@code{end-of-line})
Move caret to start/end of line.
@item @kbd{Alt+@key{Home}} (@code{beginning-of-input})
@itemx @kbd{Alt+@key{End}} (@code{end-of-input})
Move caret to start/end of the input area.
(Different from start/end of line if there are multiple lines in
the input area.)
@end table

@subsubheading Deleting text

You can also delete using the selection; see later.

@table @asis
@item @kbd{@key{Backspace}} (@code{backward-delete-char})
@itemx @kbd{@key{Delete}} (@code{forward-delete-char})
Delete @var{count} characters to the left or right of the caret.
@item @kbd{Ctrl+@key{Backspace}} (@code{backward-delete-word})
@itemx @kbd{Ctrl+@key{Delete}} (@code{forward-delete-word})
Delete @var{count} words to the left or right of the caret.
@end table

@subsubheading Special characters

The keystrokes @kbd{Ctrl+@key{C}}, @kbd{Ctrl+@key{Z}}, @kbd{Ctrl+@key{Z}}
are handled specially, because of traditional Unix shell functionality.
They are passed to the process - but only under
certain conditions, because of other compatibility issues.
@table @asis
@item @kbd{Ctrl+@key{C}} (@code{copy-text-or-interrupt}) @emph{(Not MacOS)}
@itemx @kbd{Ctrl+@key{C}} (@code{client-action}) @emph{(MacOS only)}
If there is a non-empty selection @emph{and} this is not MacOS.
copy the selection to the clipboard.
Otherwise, send @kbd{Ctrl+@key{C}} literally to the process
(which traditionally interrupts it).
@item @kbd{Ctrl+@key{D}} (@code{delete-char-or-eof})
Send @kbd{Ctrl+@key{D}} literally to the process (which
on Unix system traditionally treats it as end-of-file),
but only if the input area is empty.
Otherwise (for Emacs/readline compatibility), delete the character following
the caret.
@item @kbd{Ctrl+@key{Z}} (@code{client-action})
Send a literal @kbd{Ctrl+@key{Z}} (traditionally used in Unix
to suspend the current job) to the process (following any existing
text in the input area).
@end table

@subsubheading Scrolling

You can use the @ref{scrolling shortcuts,general scrolling shortcuts}
available in all modes, but in line-edit mode you don't
need to press @kbd{@key{Shift}}, and you can use a repeat count.

@table @asis
@item @kbd{Ctrl+@key{PageUp}} (@code{scroll-page-up})
@itemx @kbd{Ctrl+@key{PageDown}} (@code{scroll-page-down})
Scroll @var{count} pages up or down, respectively.
@item @kbd{Ctrl+@key{Up}} (@code{scroll-line-up})
@itemx @kbd{Ctrl+@key{Down}} (@code{scroll-line-down})
Scroll @var{count} lines up or down, respectively.
@item @kbd{Ctrl+@key{Home}} (@code{scroll-top})
@itemx @kbd{Ctrl+@key{End}} (@code{scroll-bottom})
Scroll to top or bottom, respectively.
@end table

@subsubheading Emacs-style keybindings

@table @asis
@item @kbd{Ctrl+@key{A}} (@code{beginning-of-line})
@itemx @kbd{Ctrl+@key{B}} (@code{backward-char})
@itemx @kbd{Ctrl+@key{E}} (@code{end-of-line})
@itemx @kbd{Ctrl+@key{F}} (@code{forward-char})
@itemx @kbd{Ctrl+@key{N}} (@code{down-line-or-history})
@itemx @kbd{Ctrl+@key{P}} (@code{up-line-or-history})
@itemx @kbd{Alt+@key{B}} (@code{backward-word})
@itemx @kbd{Alt+@key{F}} (@code{forward-word})
Emacs-style alternate keybindings.
@item @kbd{Ctrl+@key{D}} (@code{delete-char-or-eof})
If the input area is empty, send the character literally
(usually interpreted as end-of-file on Unix-like system).
Otherwise, delete the character following.
@end table

@emph{Not implemented yet, but planned:}
Emacs-style key-bindings should be controlled by a separate option;
some bindings are missing, such as @kbd{Ctrl+@key{T}},
and the ones prefixed by @kbd{Esc}.
Command-completion, using some protocol to be defined.
A plug-in replacement for GNU @code{readline} using @code{LD_PRELOAD}
would be nice. (The idea is for an enhanced readline to detect it is running
under DomTerm, in which case it would delegate most editing to DomTerm.
This would allow using bash completion logic.)
Auto-completion (completion as you type).


@subsection History

The ``history'' is the list of previously entered input lines.

@table @asis
@item @kbd{@key{Up}} (@code{up-line-or-history})
@itemx @kbd{@key{Down}} (@code{down-line-or-history})
Move up/down in history.
If the current command is multi-line, first moves within the current
command before moving to commands in the history.
@item @kbd{Ctrl+@key{R}} (@code{backward-search-history})
Enter @ref{history-search-mode}.
@end table

@anchor{history-search-mode}
@subsubheading Searching in history

The @kbd{Ctrl+@key{R}} key enters history-search mode.
As you type characters, a search string is created, which
is matched against the items in the history list.

@table @asis
@item @kbd{@var{printable-char}}
Append (or insert) @var{printable-char} to the search string,
which may update the selected history item.
@item @kbd{@key{Left}}
@itemx @kbd{@key{Right}}
Move caret within search string.
@item @kbd{@key{Backspace}}
@itemx  @kbd{@key{Delete}}
Delete character from search string. This may change the selected history item.
@item @kbd{Ctrl+@key{R}}
@itemx @kbd{Ctrl+@key{S}}
Search for previous/next history item matching the current search string.
If the search string is empty, use previous search string.
For example @kbd{Ctrl+@key{R} Ctrl+@key{R}} repeats previous search.
@item @kbd{@key{Enter}}
Exit search mode, accept current item, and send it to the application.
@item @kbd{@key{Up}}
@itemx @kbd{@key{Down}}
Exit search mode, and move to previous/next history item.
@item @kbd{@key{Tab}}
Exit search mode, accept current item, but continue editing it.
@end table

@anchor{password fields}
@subsection Password fields

A ``password field'' is an input area where the typed characters
are hidden or obscured.  DomTerm will display each character
as a black circle instead of the actual character.
(The replacement character is the @code{password-hide-char} setting.)
The most recently typed character is displayed briefly (depending on
the @code{password-show-char-timeout} setting) before it too is replaced
by a black circle.
On @kbd{@key{Enter}}, all circles are removed.

Using these circles makes it easier see how many characters you've typed,
and to move around using the mouse or cursor keys.

A password field is automatically created when we're in line-editing mode
and echoing is turned off by the program reading the input.

@subsection Changing keybindings

You can override the keymap (map from keystrokes to action)
used for input line editing.
The @code{keymap.line-edit} is a list (separated by commas or newlines),
where each item is a quoted keystroke string, followed by a colon,
followed by an action name. An action name is a string,
but quotes are optional.  The following example disables
the binding for @kbd{Ctrl+A} and adds a binding that
maps @kbd{Ctrl+H} to the @code{beginning-of-line} action.

@example
keymap.line-edit =
 | "Ctrl+A": ignore-action
 | 'Ctrl+H': beginning-of-line
@end example

@node Paging
@section View mode -  Paging and Pausing

@c @emph{Naming issue: Which is better: caret mode (like caret browsing), focus mode, or view mode, or pause mode,
@c or paging mode, or select mode, or read mode, or read-only mode [too long]?}
@c Leaning towards ``paging mode'' (paused or non-paused), but ``focus position'' and ``focus caret''

@image{images/dt-viewmode1}

View mode makes the buffer read-only.
It uses a @dfn{focus position} (indicated by a @dfn{focus cursor}),
which is independent of the output cursor and the line-editing cursor.
The key-bindings move the focus cursor around in the buffer,
scrolling as needed to keep the focus cursor visible.
Other key-bindings define or extend @ref{The Selection,the selection}
(which can be copied as needed to the clipboard),
or enable @ref{Find text,find-text mode} for searching the buffer.
No keystrokes or other events are sent to the application,
nor do they modify the input area.

If there is a selection, the focus position is one end (the most ``recent'')
of the selection.  The other end is called the @dfn{anchor position}.

There are two variants of view mode:
@itemize @bullet
@item
In @dfn{view-paused mode} output from the application is suspended.
The line containing the focus caret is shown with a solid outline.
@item
In @dfn{view-running mode} output updates the display,
but it does not automatically scroll.
The line containing the focus caret is shown with a dashed outline.
@end itemize

Key-bindings are similar to @ref{Input line editing,line-edit mode}.

View mode has similar functionality as @code{tmux}'s copy-mode,
the @dfn{caret browsing} modes of common web browsers
(typically entered with F7), emacs's view mode,
or using an external pager like @code{less} or the older @code{more}.

@anchor{auto pause}
@subsection Auto-pause

When @dfn{auto-pause} is enabled, the terminal automatically enters
view-paused mode when there is a screenful of fresh output.
Specifically, if there is output that would require the display to scroll
below the @dfn{pause limit}.  The pause limit is automatically adjusted
as appropriate - typically one screenful past the most recentg interaction.

To enable automatic-pause mode you can
check the @code{Automatic Pager} option in the right-click (context) menu.
You can also type @code{ctrl-shift-M} (to enter pause mode);
then @code{a} (to enable auto-pause and also exit pause mode).

@subsection Entering and exiting view mode

@table @asis
@item @kbd{Ctrl+Shift+@key{M}} (@code{toggle-paging-mode})
@itemx @kbd{@key{F7}}
Enter or exit view-paused mode:
If not in view mode (in character or line-edit mode),
enter view-paused mode.
Otherwise, return to normal mode.
If there is a selection, the focus position is set to the ``most recent''
end of the selection.
Otherwise, the focus position is initialized to the caret position.

If in view mode, return to character or line-edit mode.
@item @kbd{Shift+@key{F7}}
Enter or exit view-running mode:
If not in view mode (in character or line-edit mode),
enter view-running mode.
Otherwise, return to normal mode.
@item @kbd{@key{Space}}
@itemx @kbd{@key{Enter}}
As mentioned @ref{view mode space key,below}: If there isn't
room to move down respectively a page or a line,
exits view mode, after adjusting the pause-limit and enabling auto-pause.
@item @kbd{@key{Esc}}
Exit view mode, returning to character or line-edit mode.

@item @kbd{@key{a}}
Toggling @ref{auto pause, auto-pausing} and then Exit view mode.
@item @kbd{@key{r}}
Toggle between running and paused modes.
@item @kbd{Ctrl+@key{C}}
Interrupt output by sending @kbd{Ctrl+@key{C}} to the application,
and then exit paging mode after scrolling to the end.
@item @kbd{Ctrl+@key{F}}
@itemx @kbd{Ctrl+Shift+@key{F}}
Enter @ref{Find text,find-text} mode.
@end table

@subsection Repeat count

Many of the following keyboard commands can be modified
by previously-typed @dfn{repeat count}.
This is similar to line-edit mode,
but it is optional whether you press the @kbd{@key{Alt}} modifier.

@table @asis
@item @kbd{Alt+@var{digit}}
@itemx @kbd{Alt+@key{Minus}}
@itemx @kbd{Alt+@key{.}}
@itemx @kbd{@var{digit}}
@itemx @kbd{@key{Minus}}
@itemx @kbd{@key{.}}
Set or extend a repeat count.
For example @kbd{1 2 Left} moves 12 characters left, while
@kbd{Minus 2 Ctrl+Left} moves 2 words right (because of the minus).
@end table

Commands that are affected by a repeat count
contain @var{count} in the description.
By default the @var{count} is one, and it is reset after each command.

@subsection Moving the view position

The following commands move the focus position.
If the view caret is not active, it is first set to the position of the
output cursor.

A mouse click (button-1 with no modifiers) will also move the view position.

All of these clear the selection if there is one.
These operations will scroll as needed so the view position remains visible.

Many of the key-binding in view mode are the
same as in line-edit mode.  However, in line-edit mode most
commands move the input caret, but in view mode they move the view position,

@table @asis
@item @kbd{@key{Left}} (@code{backward-char})
@itemx @kbd{@key{Right}} (@code{forward-char})
Move the view position @var{count} characters left or right.
@item @kbd{Ctrl+@key{Left}} (@kbd{Cmd+@key{Left}} on Mac) (@code{backward-word})
@itemx @kbd{Ctrl+@key{Right}} (@kbd{Cmd+@key{Right}} on Mac) (@code{forward-word})
Move the view position @var{count} words left or right.
@item @kbd{@key{Home}} (@code{beginning-of-line})
@itemx @kbd{@key{End}} (@code{end-of-line})
Move the view position to start/end of line.
@item @kbd{Alt+@key{Home}} (@code{beginning-of-buffer})
@itemx @kbd{Alt+@key{End}} (@code{end-of-buffer})
Move the view position to start/end of the buffer.
@item @kbd{@key{Up}}
Move the view position @var{count} lines up.
@item @kbd{@key{Down}}
Move the view position @var{count} lines down.
If that would extend past the end of the buffer
and we are paused, unpause (while keeping
view-mode keybindings) until there is enough output.
@item @kbd{@key{PageUp}}
Move the view position @var{count} pages (screenfuls) up.
@item @kbd{@key{PageDown}}
Move the view position @var{count} pages down.
If that would extend past the end of the buffer
and we are paused, unpause until there is enough output.
(Stay in view-mode, though.)
@anchor{view mode space key}
@item @kbd{@key{Space}}
Move the view position @var{count} pages down.
If that would extend past the end of the buffer
and we are paused, unpause until there is enough output.
(Temporarily set automatic-pause mode, so that we pause again
if the screen fills up again.)
Similar to @kbd{@key{PgDown}}, but @kbd{@key{Space}} exits
view mode and its keybindings.
@item @kbd{@key{Enter}}
Move the view position @var{count} lines down.
Similar to @kbd{@key{Space}}, but only moves the focus position and/or the
pause limit @var{count} lines rather than @var{count} pages.
Similar to @kbd{@key{Down}}, but @kbd{@key{Enter}} exits
view mode and its keybindings.
@item @kbd{@key{p}}
@itemx @kbd{@key{%}}
Move to @var{count} percent of the way between start
and end positions.
@end table

@subsection Scrolling

Scrolling moves the visible view @emph{without} moving
the focus position.
You can use the @ref{scrolling shortcuts,general scrolling shortcuts}
available in all modes, but in paging mode you don't
need to press @kbd{@key{Shift}}, and you can use a repeat count.

@table @asis
@item @kbd{Ctrl+@key{PageUp}} (@code{scroll-page-up})
@itemx @kbd{Ctrl+@key{PageDown}} (@code{scroll-page-down})
Scroll @var{count} pages up or down, respectively.
@item @kbd{Ctrl+@key{Up}} (@code{scroll-line-up})
@itemx @kbd{Ctrl+@key{Down}} (@code{scroll-line-down})
Scroll @var{count} lines up or down, respectively.
@item @kbd{Ctrl+@key{Home}} (@code{scroll-top})
@itemx @kbd{Ctrl+@key{End}} (@code{scroll-bottom})
Scroll to top or bottom, respectively.
@end table

@node The Selection
@section Working with the Selection

The selection is the highlighted region (by default blue) of the buffer.
A Copy operation copies the contents of the selection to the clipboard.
View and line-edit modes have extra shortcuts and other conveniences for working
with the selection.
Unless otherwise noted, this section applies to both.

@image{images/dt-viewselect1}

The two end-points of the selection
are called the @dfn{anchor} and the @dfn{focus} points.
The anchor is where you start the selection (typically on mouse-down),
while the focus is current/active end of the selection:
As you drag the mouse the focus follow the mouse, until mouse-up.
In paging and line-edit modes the focus end is indicated
with a vertical bar, by default purple.

The commands in this section do not move the edit caret, only the focus position.

Commands that move the focus will scroll the view so
the focus remains in the view.

@table @asis
@item @kbd{Ctrl+Shift+@key{C}}  (@code{copy-text})
@itemx @kbd{Ctrl+@key{Insert}}
@itemx @kbd{Cmd+@key{C}} @emph{(Only MacOS)}
Copy selection to clipboard.
(Selection can be partly or fully outside input area.)
@item @kbd{Ctrl+@key{C}} (@code{copy-text-or-interrupt}) @emph{(Not MacOS)}
If there is no selection send Ctrl+C to the process - which
normally interrupts it.
If the previous keycommand was also a Ctrl+C, do as the no-selection case,
so typing Ctrl+C twice will always interrupt.
If there is a selection, copy it to the clipboard.
@item @kbd{Ctrl+@key{!}}  (@code{swap-focus-anchor})
If there is a non-collapsed selection, swap focus and anchor (selection ends).
@end table

@subsubheading Cut and paste (line-edit mode only)

The following commands modify the buffer, so are only available
in line-edit mode, not view mode:
@table @asis
@item @kbd{Ctrl+@key{V}} (@code{paste-text})
@itemx @kbd{Ctrl+Shift+@key{V}}
@itemx @kbd{Shift+@key{Insert}}  @emph{(Only Electron, Qt, Webview)}
Paste selection from clipboard.
@item @kbd{Ctrl+@key{X}} (@code{cut-text})
@itemx @kbd{Ctrl+Shift+@key{X}}
Cut (delete) the selection and copy the contents to clipboard.
Only removes text within the input area.
@end table

@subsubheading Extending the selection

Pressing @key{Shift} while executing a movement command (such as @key{Left})
will @dfn{extend} the selection:
The focus is moved as specified by the unshifted command (such as @key{Left} to
move one character left), but the anchor stays where it was.
The selected area expands or shrinks, depending on the movement.
If there was no selection, the anchor is set to the initial
location of the focus (in view mode) or the edit caret (in line-edit mode).

These operations will scroll as needed so the focus remains visible.

A mouse click (button-1) with @kbd{@key{Shift}} held will extend
the selection by moving the focus position leaving the anchor position in place.

@table @asis
@item @kbd{Shift+@key{Left}} (@code{backward-char-extend})
@itemx @kbd{Shift+@key{Right}} (@code{forward-char-extend})
Extends the current selection by @var{count} characters
(If there is no selection, the caret position is treated as
a zero-size selection.)
@item @kbd{Ctrl+Shift+@key{Left}} (@kbd{Cmd+Shift+@key{Left}} on Mac) (@code{backward-word-extend})
@itemx @kbd{Ctrl+Shift+@key{Right}} (@kbd{Cmd+Shift+@key{Righy}} on Mac) (@code{forward-word-extend})
Extend(or reduce) the current selection by @var{count} words
@item @kbd{Shift+@key{Home}} (@code{beginning-of-line-extend})
@itemx @kbd{Shift+@key{End}} (@code{end-of-line-extend})
Extend selection to start/end of line.
@item @kbd{Shift+@key{Up}} (@code{up-line-extend})
@itemx @kbd{Shift+@key{Down}} (@code{down-line-extend})
Extend selection by moving focus up/down @var{count} lines.
@item @kbd{Alt+Shift+@key{Home}} @emph{(paging mode only)} (@code{beginning-of-buffer-extend})
@itemx @kbd{Alt+Shift+@key{End}} @emph{(paging mode only)} (@code{end-of-buffer-extend})
Extend selection by moving focus position to start/end of the buffer.
@item @kbd{Alt+Shift+@key{Home}}  @emph{(line-edit mode only)} (@code{beginning-of-input-extend})
@itemx @kbd{Alt+Shift+@key{End}} @emph{(line-edit mode only)} (@code{end-of-input-extend})
Extend selection by moving focus position to start/end of the input area.
@end table

@subsubheading Extend mode

@dfn{Extend mode} allows extending (or shrinking) the
selection using keyboard commands without pressing @kbd{@key{Shift}}.
The effect is similar to setting @dfn{the mark} in the Emacs editor.
For example when extend mode is active,
pressing the @kbd{@key{Right}} key extends the selection by one character
(executing @code{forward-char-extend}),
as if @kbd{Shift+@key{Right}} was pressed.

@table @asis
@item @kbd{Ctrl+@@}
Toggle extend mode.

A visual indication of extend mode is that the focus caret changes
color from purple to orange, and the color of the selection changes.
@end table

Generally, if some key @var{X} is pressed in extend mode
and @code{Shift+@var{X}} is bound to a command
whose name ends with @code{-extend}, that command is executed instead.

@table @asis
@item @kbd{@key{Left}} (@code{backward-char-extend})
@itemx @kbd{@key{Right}} (@code{forward-char-extend})
@itemx @kbd{Ctrl+@key{Left}}  (@kbd{Cmd+@key{Left}} on Mac) (@code{backward-word-extend})
@itemx @kbd{Ctrl+@key{Right}}  (@kbd{Cmd+@key{Right}} on Mac) (@code{forward-word-extend})
@itemx @kbd{@key{Up}} (@code{up-line-extend})
@itemx @kbd{@key{Down}} (@code{down-line-extend})
@itemx @kbd{@key{Home}} (@code{beginning-of-line-extend})
@itemx @kbd{@key{End}} (@code{end-of-line-extend})
@itemx @kbd{Alt+@key{Home}} @emph{(paging mode only)} ((@code{beginning-of-buffer-extend})
@itemx @kbd{Alt+@key{End}} @emph{(paging mode only)} ((@code{end-of-buffer-extend})
@itemx @kbd{Alt+@key{Home}} @emph{(line-edit mode only)} (@code{beginning-of-input-extend})
@itemx @kbd{Alt+@key{End}} @emph{(line-edit mode only)} (@code{end-of-input-extend})
Extends the selection, as if @kbd{@key{Shift}} was pressed.
@item @kbd{@key{Esc}}
Exit extend mode, returning to plain view or line-edit mode.
@end table

@node Find text
@section Find text

To search for text in the buffer, use the @dfn{find-text} mode.

@image{images/dt-findtext1}

@table @asis
@item @kbd{Ctrl+Shift+@key{F}} (@code{find-text}) @emph{(except find-text mode)}
@itemx @kbd{Ctrl+@key{F}} @emph{(View or line-edit modes only)}
Enter find-text mode.
@end table

The find command highlights text that matches a search string or regular expression.
Keypresses and standard editing keys (such as @key{Left} or @key{Delete})
update a search string displayed in a ``mini-buffer''.
Matching text is highlighted, by default using a yellow background.
(Specifically, matched text is temporarily wrapped in a @code{<mark>} element.)

@table @asis
@item @kbd{@key{Escape}} (@code{find-exit})
Exit find mode, setting the selection to the current match.
@item @kbd{Shift+@key{F}} (@code{find-select-pattern})
@itemx @kbd{Ctrl+Shift+@key{F}} (@code{find-select-pattern})
If already in find-text-mode, these keystrokes
select the entire pattern minibuffer.
@end table

Assuming we're searching forwards,
the first match that starts at or after the ``base position'' is selected,
with the focus position set to the end of the match.
The base position is initially the caret (focus position if defined,
otherwise the output position).
Each ``selection-next'' sets the base position to the focus position,
and redoes the search.
You can click on either arrow button or use the following keystrokes.

@table @asis
@item @kbd{@key{Down}} (@code{find-next-match})
@itemx @kbd{@key{Enter}}
Select the next match:
Sets the base position to focus position and redoes the search
in forward direction.
Sets the search direction to forwards: Editing the search
will select the first match @emph{after} the base position.
@item @kbd{@key{Up}} (@code{find-previous-match})
@itemx @kbd{Shift+@key{Enter}}
Select the previous match.
Sets the search direction to backwards: Editing the search
will select the first match @emph{before} the base position.
@end table

You can control the search mode either using the shortcus shown below,
or by clicking on the gray mode button, and selecting from the dropdown button.

@image{images/dt-findtext2}

@table @asis
@item @kbd{Alt+@key{C}} (@code{find-toggle-match-case})
Enable or disable case-matching.
@item @kbd{Alt+@key{W}} (@code{find-toggle-match-word})
Enable or disable matching of whole words (match must start and end
on a word boundary).
@item @kbd{Alt+@key{R}} (@code{find-toggle-match-case})
Enable or disable searching using @uref{https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions,regular expressions}.
@end table

@node Styling
@chapter Styling

The appearance of a DomTerm window is controlled by CSS stylesheets.

You can place stylesheet rules in the @ref{Settings,@code{settings.ini}} file.
For example:
@example
style.user=
 |div.domterm @{ background-color: azure @}
@end example

You can also change the stylesheets using @code{domterm add-style} or
@code{domterm load-stylesheet} sub-commands.  For example:
@example
$ domterm add-style "div.domterm @{ background-color: azure @}"
@end example

@subheading Reverse video (dark vs light)

By default DomTerm uses uses dark-colored (black) foreground (text) on a
light-colored (off-white) background.
Reverse video switches these, by using a light-colored text
on a dark background.

You can enable reverse-video mode using the command:
@example
$ domterm reverse-video on
@end example
or in the @code{settings.ini} file:
@example
style.dark=on
@end example

Enabling reverse-video does not change stylesheet rules,
but instead sets the @code{reverse-video} attribute on the
top-level @code{domterm} element.  This is used to select
differe stylesheet rules for reverse-video.  For example
to change the background color input @code{input} lines
to a dark brown do this:
@example
div.domterm[reverse-video] span[std="input"] @{ background-color: #808200 @}
@end example

``Reverse-video mode'' is any style where the background is darker
than the foreground.  You can tweak individual style elements to
achieve such a style, but its better to first explicitly set reverse-video mode
(perhaps using the above command), because that
selects a consistent whole.

@subheading Color variables

DomTerm makes uses of
@uref{https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_variables,CSS Variables}, which is supported by most modern browsers.
The following variables define the main colors.

@table @code
@item --main-light-color
A light color used for the default background in normal mode,
or used for default foreground (text) in reverse-video mode.
@item --main-dark-color
A dark color used for the default foreground (text) in normal mode,
or used for default background in reverse-video mode.
@item --background-color
The color currently used for the main background.
Defaults to @code{--main-light-color} normally, or
@code{--main-dark-color} in reverse-video mode
(or after the SGR reverse-videa escape-sequence).
@item --foreground-color
The color currently used for the main background (text).
Defaults to @code{--main-dark-color} normally, or
@code{--main-light-color} in reverse-video mode
(or after the SGR reverse-videa escape-sequence).
@end table

A common desire is to change the default background color.
You can do any one of:
@example
div.domterm @{ --main-light-color: azure @} /* recommended method */
div.domterm @{ --background-color: azure @}
div.domterm @{ background-color: azure @}
@end example
Using @code{--main-light-color} is recommended because
it integrates better with the rest of the default stylesheets.

If you want to change to a dark background color,
it is recommended to you enable reverse-video mode instead (or in addition).

The following color variables define the standard 16
@uref{https://en.wikipedia.org/wiki/ANSI_escape_code#Colors,``ANSI colors''}:
@code{--dt-black},
@code{--dt-red},
@code{--dt-green},
@code{--dt-yellow},
@code{--dt-blue},
@code{--dt-magenta},
@code{--dt-cyan},
@code{--dt-lightgray},
@code{--dt-darkgray},
@code{--dt-lightred},
@code{--dt-lightgreen},
@code{--dt-lightyellow},
@code{--dt-lightblue},
@code{--dt-lightmagenta},
@code{--dt-lightcyan},
@code{--dt-white}.
The default definitions mostly match xterm.
For example @code{cyan} is @code{#00CDCD}.
It you can to change it to the standard VGA color, you
can add an override rule:
@example
div.domterm @{--dt-cyan: #00AAAA@}
@end example
The @code{mc} file browser by default sets the background to blue.
You can adjust the shade of blue used like this:
@example
div.domterm @{--dt-blue: #4040a0 @}
@end example

@subheading End-of-file background

DomTerm indicates the bottom area past the written
data with pale ``zebra stripes''.
If you want to disable this, do:
@example
div.domterm-spacer @{background: none @}
@end example
The spacer stripes alternatate between transparent and the value of @code{--spacer-color}.  You can change it thus:
@example
div.domterm-spacer @{--spacer-color: LemonChiffon@}
@end example

@subheading Fonts

The main monospace text font is set by the @code{--monospace-family} variable.
For example:
@example
div.domterm @{ --monospace-family: "FreeMono","DejaVu Sans Mono" @}
@end example

@subheading Prompt, input and error output
The @code{std} attribute of a @code{<span>} element is used to
indicate the logical kind of output.
The attribute @code{std='prompt'} marks a prompt before an input line,
while @code{std='prompt'} marks the input line itself.
(These attribute can be set using escape sequences in the prompt.)
You can change the colors used like this:
@example
span[std="prompt"] @{ background-color: lightgray @}
span[std="input"] @{ color: blue; background-color: inherit @}
@end example
Note the use of @code{inherit} to override the setting in the
default stylesheet.

If you want to change the style of the entire input line,
you can use the @code{input-line} property:
@example
div.input-line @{ background-color: #FFFFE8 @}
@end example

An application or library can use escape sequences to distinguish
the error output (@code{stderr}) from regular output (@code{stdout}).
(Most programs don't emit these escape sequences.
It is difficult to do this reliably without modifying the
program or the tty subsystem.)
If so, by default, the text color is @code{red}; to turn this off, do:
@example
span[std="error"] @{ color: inherit @}
@end example

@subheading Background image

Setting a background image:
@example
/* Note: browser security may disallow file: URLs. */
div.domterm @{
  background-image: url('file:/usr/share/backgrounds/gnome/Mirror.jpg');
  opacity: 0.4 @}
div.domterm-spacer @{background: none @} /* optional but recommended */
@end example
You can reduce the opacity to make the text more visible.

Note browsers may restrict the use of @code{file:} URLs
because of the @uref{https://en.wikipedia.org/wiki/Same-origin_policy,same-origin policy}.
Work-arounds are being considered; please contact the maintainer if this
is a feature you want.

@anchor{caret styling}
@subheading Text caret (input cursor)

You can change the look of the caret (text input cursor)
using the @code{style.caret} and @code{style.edit-caret}
settings in @ref{Settings,@code{settings.ini}}.
@example
@code{@b{style.caret} =} @var{value}
@code{@b{style.edit-caret} =} @var{value}
@end example
The @code{style.caret} setting is used for normal terminal ``character'' mode,
while @code{style.edit-caret} is used when the terminal is in line-edit mode
or the minibuffer.

The @var{value} can be one of these (unquoted) words:
@code{block}, @code{blinking-block},
@code{underline}, @code{blinking-underline},
@code{bar}, or @code{blinking-bar}.
(The experimental value @code{native} uses the native
text caret (a vertical bar, typically),
but does not work properly and it interacts awkwardly with the selection.)

The default is @code{blinking-block} for @code{style.caret},
and @code{blinking-bar} for @code{style.edit-caret}
Note that
@code{blinking-block}, @code{blinking-underline}, and @code{blinking-bar}
only blink 20 times after each change or focus.
To change the number of blinks set the CSS variable @code{--caret-blink-count}.
For example to blink indefinitely, add this to @code{settings.ini}:
@example
style.user= div.domterm @{ --caret-blink-count: infinite @}
@end example

You can also change the character-mode caret style with an
escape sequence (DECSCUSR).  For example this shell command:
@example
echo -en "\e[3 q"
@end example
changes the style to @code{blinking-underline}.
Instead of 3, you can use 0 (default - reset to the @code{style.caret} value), 1 (blinking-block), 2 (steady block),
3 (blinking-underline), 4 (steady underline), 5 (blinking-bar), 6 (steady bar), or 7 (native),

@subheading Example: A ``solarized'' theme

The @uref{http://ethanschoonover.com/solarized,Solarized colorscheme}
aims for muted balanced colors for both light and dark styles.
Put the following in your @ref{Settings} for a
solarized dark look.

@example
style.dark=yes
style.user=
 | div.domterm @{ --solar-base03: #002b36; --solar-base02: #073642;
 |   --solar-base01: #586e75; --solar-base00: #657b83;
 |   --solar-base0: #839496; --solar-base1: #93a1a1;
 |   --solar-base2: #eee8d5; --solar-base3: #fdf6e3;
 |   --solar-yellow: #b58900; --solar-orange:  #cb4b16; --solar-red: #dc322f;
 |   --solar-magenta: #d33682; --solar-violet: #6c71c4;
 |   --solar-blue: #268bd2; --solar-cyan: #2aa198; --solar-green: #859900 @}
 | div.domterm @{  --main-light-color: var(--solar-base3);
 |   --main-dark-color: var(--solar-base03) @}
 | div.domterm[reverse-video] @{ --background-color: var(--solar-base03);
 |   --foreground-color: var(--solar-base0) @}
 | div.domterm span[std="input"] @{ background-color: var(--solar-base2) @}
 | div.domterm[reverse-video] span[std="input"] @{
 |   background-color: var(--solar-base02) @}
 | div.domterm-spacer @{background: none @}
 | div.domterm div.input-line, div.domterm[reverse-video] div.input-line @{
 |   background-color: var(--background-color); @}
@end example

The above is merely a suggested start.  The last few lines are optional.
You might want to tweak prompt and error colors. You could also change
the ``standard'' colors, for example:
@example
 | div.domterm @{--dt-blue: var(--solar-blue) @}
@end example

For a light solarized look, change the @code{style.dark=yes}
to @code{style.dark=no}.

@subheading Session-specific styles

Each ``session'' (terminal window) has a session number
and an optional settable session name.
See @ref{Names and titles} for the details.
The session number sets the @code{session-number} attribute
in the top-level @code{<div class="domterm">} element,
while the session name sets the @code{session-name} attribute.

You can use these to set different styles for different terminal windows.
For example:

@example
div.domterm @{ background-color: #FFE @}
div.domterm[session-number="1"] @{ background-color: #FEE @}
div.domterm[session-name="compile"] @{ background-color: #EEF @}
div.input-line @{ background-color: inherit @}
@end example

@node Tips and solutions
@chapter Tips and solutions

This section covers various topics, and may evolve to
a Frequently-Asked-Questions page.

See also @ref{Frontends,the page about frontends}
for how they may support some features differently.

@menu
* Tips::  Miscellaneous tips
* Link handling::
* Detecting domterm terminal::
* Shell prompts::  Shell prompts and tricks
* drop down:: Use as a drop-down terminal
* Python tips::
* Names and titles::
@end menu

@node Tips
@section Miscellaneous tips

@subheading Copy and Paste

In character mode the ``standard'' keyboard shortcuts for copy and paste
(ctrl-C and ctrl-V) are sent to the backend program.
So instead DomTerm uses ctrl-shift-C to copy the selection to the clipboard,
and ctrl-shift-V to paste the contents of the clipboard.

Some front-end also have menu entries for copy and paste.

The selection is copied as both plain text (@code{text/plain})
and formatted HTML (@code{text/html}) in case the receiving
application can paste the latter.
The HTML is slightly cleaned up from the raw DOM
(in the same way @code{Save as HTML} does).
Note that only inline styling is copied; no attempt is made
to merge in style rules from stylesheets.

The @code{Copy as HTML} command places the formatted HTML
in the clipboard as @code{text/plain} so you can paste the HTML
into a text editor.

@emph{Front-end support}:
Middle-button paste (i.e. clicking the middle button pastes the
contents of the @emph{selection}, rather than the clipboard)
works on qtdomterm, and chrome-based browsers.
It does not work in a Firefox browser window.

@subheading Save the console contents as HTML

Use the keyboard shortcut ctrl-shift-S to save the contents
of the DomTerm console as an HTML file.
Both qtdomterm and the Electron front-end also offer menu entries for this.

The saved file should be viewed with various css stylesheet
files in the @code{hlib} subdirectory.  You can create a symlink
to the @code{hlib} subdirectory in the DomTerm distribution.
The saved file also optionally makes use of some JavaScript,
in the same directory.
The JavaScript isn't essential, but it enables features like
hide/show buttons and dynamic line-(re-)breaking.

Images will preserve their URLs.
Relative URLs may need to be fixed, but absolute ones should be fine.
``Embedded'' images using a @code{data:} URL (including those
loaded with the @code{image} sub-command) will be saved embedded,
and Just Work.

The resulting file is actually an XHTML file, so you can use
XML tools to extract parts from or transform the output.

@emph{Front-end support}: The qtdomterm and the Firefox/XUL applications
bring up a file chooser, and let you save the file in any writable directory.
Other front-end bring up a prompt pop-up and only allow
saving to the Downloads area.
The JavaFX front-end currently does not support saving.

Note that if DomTerm is running in a browser window,
the browser's @code{Save page as ...} command is not useful.
It will save the original bare web page, before any DomTerm interactions
or other JavaScript modification.

@subheading Adding domterm or qtdomterm to the desktop

@subsubheading On Gnome or KDE

Copy @code{domterm/domterm.desktop} or
@code{qtdomterm/qtdomterm.desktop} to either
@code{/usr/share/applications} (if @code{domterm} is installed
in @code{/usr/bin} and you want it accessible to everyone),
or in @code{~/.local/share/applications} (if you only wish to make
accessible to a single user).

@subheading Environment variables set

The DomTerm back-ends set various enviromnent variable
when they start up a process.

@code{TERM} is set to @code{"xterm-256color"}.
@code{COLORTERM} is set to @code{"truecolor"}.

The @code{DOMTERM} variable is set to a semicolon-separate
list of information about DomTerm and how it was invoked.
The specific list is subject to change.

An example when running on @code{qtdomterm}:
@example
QtDomTerm;version=0.80;tty=/dev/pts/3
@end example
The Electron front-end may yield:
@example
version=0.80;electron=1.3.13;libwebsockets=2.1.1;tty=/dev/pts/1
@end example

Checking the @code{DOMTERM} variable is a simple way to
check if we're running in a DomTerm terminal.  It is not
foolproof, as explained @ref{Detecting domterm terminal, here}.

@code{WINDOWID} is not set - in fact @code{qtdomterm} unsets it.
There seem to be some problems setting it with Qt.
This variable is not set by Wayland.

@subheading Various programs

@subsubheading ls - showing files as links

Newer versions of the GNU @code{ls} programs support a
@code{--hyperlink} option that creates a @code{file:}
link for each filename.
The escape sequence is also recognized by gnome-terminal,
and should be harmless for other xterm-like terminals.
Consider adding this to your shell init file:
@example
case "$TERM" in
  *xterm*) alias ls='ls --hyperlink=auto';;
esac
@end example

@subsubheading gnuplot

The @uref{http://www.gnuplot.info/,gnuplot} graphing application
has builtin support for
@uref{http://per.bothner.com/blog/2016/gnuplot-in-domterm/,``printing'' graphical output}
to the DomTerm console

@anchor{pandoc-output}
@subsubheading pandoc Printing markdown and other document types

The @uref{https://pandoc.org/,pandoc} program can convert
documents between multiple document formats.
To view a Markdown document @code{doc.md} you can do:
@example
pandoc -t html doc.md | domterm hcat
@end example
You might optionally use the @code{--self-contained} flag to force
images to be ``inlined'' in the terminal output:
@example
pandoc -t html --self-contained --metadata pagetitle=dummy doc.md | domterm hcat
@end example
(The @code{--metadata pagetitle=dummy} is to silence an annoying warning.)

@anchor{man-page-output}
@subsubheading Showing man pages as html

To view the @code{bash} man page inline you can do the following.
This works best with Automatic Pager set.

@example
man -Hcat bash 2>/dev/null|domterm hcat
@end example

@c @subheading Mouse and link handling
@c A program can request notification of mouse events,
@c using protocol used by xterm and other common terminal emulators.
@c If no notification has been explicitly requested,
@c the following default actions are implemented.

@anchor{move-cursor-with-mouse}
@subheading Moving input cursor using mouse clicks

Many interactive programs support simple editing of the current input line.
There are a number of libraries for this (for example as GNU readline),
that support moving the cursor using arrow keys but do not handle the mouse.

In ``readline mode'' a mouse click is translated into arrow key presses
that should move the cursor to the clicked position, assuming
the interactive program understands arrow keys.

There are two ways to enable readline mode for a mouse click:
@itemize
@item
If the Alt key is pressed at the same time as the mouse click.
@item
If both the mouse click target and the current cursor position are in the
same @code{input-line} group (i.e. they're in the same @code{<div>} element
with a @code{class} attribute specifying @code{input-line}).

To create an @code{input-line} group you set the appropriate
escape sequence @samp{\e[15u} in the end of the prompt string,
as show in tip for @ref{bash shell prompt}.
If using an input editor library that handles multi-line input commands
(such as JLine3), use the escape sequence @samp{\e[15;2u} instead.
@end itemize

@node Link handling
@section Link handling

The buffer can contain clickable links.
These can be created implicitly, by recognizing a URL or other pattern in the buffer.
Links can also be created explicitly, using a special escape sequence,
or by emitting HTML.

@image{images/dt-linkhover}

There are two kinds of links:
@itemize @bullet
@item
A @dfn{regular link} displays in the ``normal'' link style (typically blue text with underline).
(If the @code{class} attribute includes the word @code{plain}
then no underline is added, but normal link styling applies otherwise.)
A click opens a browser window/tab or an application, as described below,
as does right-click (context menu) and then selecting @code{Open Link}.
@item
A @dfn{subtle link} is only active
if you also hold the the @key{Ctrl} key; you can also use the context menu.
This is to reduce accidental clicks.
Links created implicitly using pattern-matching are subtle,
and additionally have no special styling except when mouse hovered.
Internally, a subtle link is distinguished by its @code{class} attributes containing @code{subtle}.
@end itemize

@anchor{linkification}
@subheading Automatic creating of links

DomTerm will scan the output for text that "looks" like a URL or
a mail address, and turn it into a clickable ``subtle'' link.

The links are only visible when you hover the mouse over them.
(This is because what is a link is a guess, and so we don't want to clutter
the display with links that aren't explicitly created.)
You can change the styling: The @code{class} attribute for these links
contains both @code{matched} (because they are generated by pattern matching),
and @code{subtle} (because you don't want them styled except when hovering).

By default the only recognized URL schemes
(the part before the colon) are
@code{http}, @code{https}, @code{ftp}, @code{file}, and @code{mailto}.
If the preference @code{open.file.application} or @code{open.link.application}
mentions a URL scheme in a @var{condition} (see @ref{link-handlers,below})
that scheme is added to to the set of recognized URL patterns.

A string starting with @code{www.} is treated as
it it starts with @code{http://www.}.
A string that looks like an email address
(matching the regex pattern @code{^[^@@]+@@[^@@]+\.[^@@]+$})
is treated as if it starts with @code{mailto:}.

Many programs emit error messages that start with
@code{@var{filename}:@var{line}:} or
@code{@var{filename}:@var{line}:@var{column}}.
These are turned to links of the form
@code{file:/@var{filename}#position=@var{line}}
or @code{file:/@var{filename}#position=@var{line}:@var{column}:}.
If @var{filename} is relative, it is made absolute
if the process directory is set.
(The directory can be set using the escape
sequence @code{"\e]7;file://@var{hostname}/@var{directory}\a"}.
See @ref{tracking-cwd,the shell function @code{print_path_url}} above.)
You can specify an editor or other handler for these special links,
as described below.

@anchor{link-handlers}
@subheading Specifying handlers for clicked links

If you click on a link (with a full URL, not one starts with @samp{#}),
then the request is sent to the backend,
which will invoke an appropriate viewer, such as a browser.

Which application to use depends on two preference variables:
@code{open.file.application} and @code{open.link.application}.
Both are @ref{conditional values,conditional} lists of templates,
separated by semi-colons or newlines.
When opening a @code{file:} link both template lists are used
(first @code{open.file.application} is tried then @code{open.link.application});
otherwise, only @code{open.link.application} is tried.
Here is the default, in @code{settings.ini} multi-line format:
@example
open.file.application =
 |@{in-atom@}@{with-position|!.html@}atom
 |@{with-position|!.html@}emacsclient
 |@{with-position|!.html@}emacs
 |@{with-position|!.html@}atom
open.link.application =
 |@{!mailto:@}chrome
 |@{!mailto:@}firefox
 |default
@end example

The following templates are supported:
@table @asis
@item @code{emacs}
Invoke the Emacs editor on the specified file and
optional (line,column)-position.
Equivalent to @code{"emacs %+P '%F' > /dev/null 2>&1 &"}.
@item @code{emacsclient}
Ask the Emacs server to open en editor window on the specified file and
optional (line,column)-position.
Equivalent to @code{"emacsclient -n %+P '%F'"}.
@item @code{atom}
Invoke the Atom editor on the specified file and
optional (line,column)-position.
Equivalent to @code{"atom '%F'%:P"}.
@item @code{firefox}
@itemx @code{chrome}
@itemx @code{google-chrome}
Open the specified web browser (@code{chrome} and @code{google-chrome} are
the same).
Equivalent to the browser's executable path followed by @code{" '%U'"}.
@item @code{default}
@itemx @code{browser}
Open the default browser or other registered application.
@item @code{@{}@var{condition}@code{@}}@var{template}
@itemx @code{@{}@var{condition}@code{|}@var{condition}...@code{@}}@var{template}
Skip the @var{template} unless one of the @var{condition}s succeeds.
There can be multiple @code{@{}@var{condition}@code{@}}-groups,
in which cases all must succeed.

A condition can be one of the following:
@table @asis
@item @code{in-atom}
Succceeds if using @code{atom-domterm}.
@item @code{with-position}
Succceeds if the URL ends with @code{#position=@var{position}}.
@item @code{@var{scheme}:}
Matches if the URL-scheme is @var{scheme}.
This is the part before the first colon, such as @code{http:}.
The default uses @code{!mailto:} to supress using firefox or chrome
for email addresses.
@item @code{.@var{ext}}
Matches if the URL has an "extension" matching @var{ext}.
For example @code{.html} matches html files.
@item @code{!}@var{condition}
Suceeds if @var{condition} fails and vice versa.
@end table
@item @var{custom template}
Using @samp{%}-escapes to create a system command.
The following escapes are supported:
@table @asis
@item @code{%U}
Substitute the URL (the @code{href} attribue of the link).
@item @code{%P}
Substitute the value of the (line,colon) file position
from the @code{#position=@var{position}} or the URL.
@item @code{%:P}
@itemx @code{%+P}
Same as respectively @code{:%P} or @code{+%P} if the position
is specified in the URL. Expands to nothing otherwise.
@item @code{%F}
Only succeeds for @code{file:} URL, which is converted to a file name.
You should use quotes: @code{command '%F'}.
@item @code{%%}
A literal @samp{%}.
@end table
After expansion, if there are any unquoted shell special characters
(any of @code{<>|&$}), then the command is executed by a shell.
Otherwise, it is executed directly (in the background, as a daemon).
@end table

@node Detecting domterm terminal
@section Detecting domterm terminal

The @code{DOMTERM} environment variable is normally set when running
under DomTerm. However, using @code{DOMTERM} to determine if the
current terminal is DomTerm is not reliable:
If you @code{ssh}, @code{DOMTERM} will not be automatically set
(a false negative).
On the other hand, if you start some other terminal emulator
like @code{xterm} from within DomTerm, the @code{xterm} will
misleadingly inherit the @code{DOMTERM} variable (a false positive).

The following snippet will unset @code{DOMTERM}
if it does not match the output from the @code{tty} command:
@example
# Check if the DOMTERM variable includes the string "tty=@var{ttyname}"
# where @var{ttyname} is the output from the tty command
case ";$DOMTERM;" in
  *";tty=`tty`;"*) ;;
  *";tty="*) unset DOMTERM;;
esac
@end example
(In a C/C++ program you can use the @code{ttyname} function.)
This takes care of false positives (like running an @code{xterm}
started within DomTerm), assuming DomTerm is started in the normal
way (the @code{domterm} command creating a pty).
However, it does not handle false negatives, such as using @code{ssh}.

More robust is to probe the terminal itself.
You can use the @code{domterm is-domterm} command:

@example
if domterm is-domterm
then
  execute domterm-specific actions
fi
@end example

If you're not sure whether the @code{domterm} program
will be in the @code{PATH}, you can use the following shell code.
It works by sending a special request code
(``Send [Secondary] Device Attributes'') to the terminal; the terminal
sends a response unique to DomTerm.
(While modern terminals will respond to this request, some older ones may not.
Just in case, the script includes a timeout.  Also, it only sends
the request if @code{TERM} includes the string @code{"xterm"}, which
most terminal emulators do, or if @code{DOMTERM} is set.)

@example
probe_domterm() @{
  # probe if TERM unset, or contains "xterm", or DOMTERM is set
  case "$TERM/$DOMTERM" in
    /* | *xterm*/* | */?*)
      echo -en "\e[>0c" >/dev/tty
      read -s -t 1 -d c </dev/tty
      case "$@{REPLY@}" in
        ?"[>990;"*";"*) DOMTERM_REPLY="$@{REPLY@}" ;;
        "") DOMTERM_REPLY="-timeout)" ;;
        *) DOMTERM_REPLY="-non-match"
      esac
      ;;
    *) DOMTERM_REPLY="-not-tried"
  esac
@}

is_domterm() @{
  test -z "$DOMTERM_REPLY" && probe_domterm
  case "$DOMTERM_REPLY" in
    -*) return -1;;
    *) return 0;;
  esac
@}

if is_domterm
then
  execute domterm-specific actions
fi
@end example

The @code{is_domterm} function only tests if the current terminal
is domterm; it does not check if standard input/output have been re-directed.
To check that, you can use the @code{test} builtin with the @code{-t} option:
@example
if test -t 0 -a -t 1 -a -t 2 && is_domterm
then
  execute domterm-specific actions
fi
@end example

@node Shell prompts
@section Shell prompts and tricks

Many interactive REPL-style programs (such as a ``shell") allow
you to customize the string used to prompt for input.
Putting certain DomTerm-specific @ref{Wire byte protocol,escape sequences}
in the prompt enables some
@uref{http://per.bothner.com/blog/2019/shell-integration-proposal/,nice features}.

The following discussion tests @code{$DOMTERM} to decide
whether to do domterm-specific actions.
See @ref{Detecting domterm terminal,how to more reliably test for DomTerm}.

@anchor{bash shell prompt}
@subheading Setting the Bash shell prompt

Download @uref{tools/shell-integration.bash,shell-integration.bash}
and @uref{tools/bash-preexec.sh,bash-preexec.sh}.
Then in your @code{~/.bashrc} put something like:

@example
if [ "$PS1" != "" ]
then
  # Optionally override the system default - for all terminals
  PS1='$ ' # or whatever

  if [ -n "$DOMTERM" ]
  then
    source /path/to/bash-preexec.sh
    source /path/to/shell-integration.bash
  fi
fi
@end example

This causes the prompt to have the @code{prompt} style
(specifically to be in a @code{<span std="prompt">} element),
while the remainder of the current line gets the @code{input} style
(specifically, in a @code{<span std="input">} element).
The appearance of these styles can be customized with CSS stylesheets.
Furthermore, this prompt enables text folding:
a @ref{Hide/show buttons,hide/show button}
(click on the @code{▼} character), which hides/shows the output
from the command.

@anchor{zsh-shell-prompt}
@subheading Setting the Zsh shell prompt

Zsh is similar to bash.
Download @uref{tools/shell-integration.zsh,shell-integration.zsh}.
Then in your @code{~/.zshrc} put something like:

@example
if [ "$PS1" != "" ]
  # Maybe change PS1 from the default
then
  if [ -n "$DOMTERM" ]
  then
     source /path/to/shell-integration.zsh
  fi
fi
@end example

@anchor{fish shell prompt}
@subheading Setting the Fish Shell (fish) prompt

For @code{fish} (the Fish Shell),
copy @uref{tools/shell-integration.fish,shell-integration.fish}
into the Fish configuration directory @code{$__fish_config_dir}
(which defaults to @code{.config/fish}).
Then place the following in the main fish configuration file
@code{$__fish_config_dir/config.fish}:
@example
if test -n "$DOMTERM"
  source $__fish_config_dir/shell-integration.fish
end
@end example

@anchor{command completion}
@subheading Command-completion (tab completion) for Bash

Command completion enables you to type
an initial part of a command, and have the computer ``fill in''
the next part.  Completion is also called tab completion,
because it its commonly requested by typing @kbd{@key{Tab}}.

To set up tab-completion in @code{bash} for the @code{domterm} command
execute the following command (perhaps in your @code{~/.bashrc}):
@example
complete -o nospace -C  'domterm "#complete-for-bash" "$COMP_LINE" "$COMP_POINT"' domterm
@end example
This instructs @code{bash} when completing the @code{domterm} command
it should invoke the @code{domterm} executable with certain options that
cause a list of candidate completions to be printed.
(Delegating command-completion to the @code{domterm} command itself
makes it easier to keep completion consistent with the command.)

There is currently no completion support for other shells
such as @code{fish} or @code{zsh}.

@anchor{tracking-cwd}
@subheading Tracking current working directory

It is useful for DomTerm to track the working directory of
the process.  One reason is @ref{linkification,creating links} from
compiler error messages.

If you're using the Bash shell, you can set the @code{PROMPT_COMMAND}
to send a special escape sequence, like the following.

@example
# Based on Orwellophile's answer to
# @uref{https://stackoverflow.com/questions/296536/how-to-urlencode-data-for-curl-command,https://stackoverflow.com/questions/296536/how-to-urlencode-data-for-curl-command}
# adding the LC_ALL=C trick from /etc/profile.d/vte.sh (on Fedora27)
print_path_url() @{
  local LC_ALL=C
  local string="$PWD"
  local strlen=$@{#string@}
  local encoded=""
  local pos c o

  for (( pos=0 ; pos<strlen ; pos++ )); do
     c=$@{string:$pos:1@}
     case "$c" in
        [-_.~a-zA-Z0-9/] ) o="$@{c@}" ;;
        * )               printf -v o '%%%02x' "'$c"
     esac
     encoded+="$@{o@}"
  done
  printf "\033]7;file://%s%s\007" "$@{HOSTNAME:-@}" "$@{encoded@}"
@}
test "$PROMPT_COMMAND" = __vte_prompt_command || \
    PROMPT_COMMAND="$PROMPT_COMMAND;print_path_url"
@end example

(On some platforms Gnome Terminal loads @code{vte.sh}
which sets @code{PROMPT_COMMAND} to @code{__vte_prompt_command},
which sends the same escape sequence as @code{print_path_url}.)

@subheading Directory tracking of make

Sometimes @code{make} will recurse into sub-directories.
Error message in those sub-directories may be relative.
The following @code{make} wrapper causes @code{make} to
report to DomTerm the current directory, so it can resolve
relative files names to absolsute @code{file:} links.

@example
BASE_MAKE=/usr/bin/make
if test -t 1 && is_domterm
then
  print_path_url
  export MAKE=`command -v $0`
  $BASE_MAKE "$@@"
  ex=$?
  print_path_url
  exit $ex
else
  $BASE_MAKE "$@@"
fi
@end example
This uses the @code{is_domterm} and @code{print_path_url}
functions defined above.

@node drop down
@section Use as a drop-down terminal

A @dfn{drop-down terminal} (sometimes called
@uref{https://en.wikipedia.org/wiki/Console_(video_game_CLI),@dfn{Quake-style}})
is one that can be quickly invoked and hidden with a keystroke.

This can be easily done by setting up a system keybinding
for either @code{domterm window toggle-minimize}
or @code{domterm window toggle-hide}.
These currently only work for the @ref{Frontends,Electron front-end}.

These commands will create a window if it doesn't exist,
make it visible if it is minimized/hidden,
and minimize/hide it if it is visible.
The difference between @code{toggle-minimize} and @code{toggle-hide}
is that an minimized window may be still visible in the task bar,
as an icon on the desktop, or during an ``windows expose'' operation;
a hidden window is not.  (This depends on the desktop environment.)

@subheading Configuring for Gnome desktop manager

@image{images/dropdown-gnome}

If you're using the Gnome desktop (common on GNU/Linux systems),
enter the system (desktop) @code{Settings} application,
and select @code{Devices} and @code{Keyboard shortcurs}.
Click the @code{+} at the bottom to add a new custom shortcut.
You can then bind your preferred keybinding (@code{F5} in the screenshot)
to the @code{domterm toggle-minimizew} (or @code{toggle-hide}) command.
(The screenshot uses a fully-qualifed path for @code{domterm},
just in case.)

@subheading Configuring for Windows/WSL

We need to bind a shortcut key (hotkey) to a command like:
@example
wsl -e /mnt/c/path-to-domterm/bin/domterm --geometry=775x600+20+10 window toggle-minimize
@end example
where the @code{--geometry} option is an optional @ref{geometry specifier},
and @code{/mnt/c/path-to-domterm} is the location of your DomTerm installation.
Note this needs to be a Unix-style path (since it is executed by @code{wsl})
to a Windows directory (so Electron can find the needed files).

(The @code{-e} flag is an optimization so WSL doesn't create a shell
to parse the command arguments; remove that flag if shell expansion is needed.)

We will look at some possible ways to bind the ``hot-key''.

@subsubheading Using AutoHotkey

@uref{https://www.autohotkey.com/,AutoHotkey} is a popular,
flexible and somewhat complex tool.
After @uref{https://www.autohotkey.com/docs/Tutorial.htm#s11,downloading and installing it},
you need to @uref{https://www.autohotkey.com/docs/Tutorial.htm#s12,create a script} (in a file with extension @code{.ahk}).

The following @code{.ahk} script file will toggle domterm
when you type @kbd{Ctrl+Alt+@key{t}}, specified by the @code{^!t} pattern:

@example
^!t::
run, wsl -e "/mnt/c/path-to-domterm/bin/domterm" --geometry=775x600+20+10 window toggle-minimize,,hide
return
@end example

The @code{hide} option prevents briefly flashing a temporary console window.

@subsubheading Using myhotkey

A simpler application is @uref{https://github.com/rustyx/myhotkey,myhotkey}.
A minor disadvantage (compared to AutoHotkeys) is that you can't
hide the flash of the temporary console window.

@subsubheading Using standard desktop shortcuts

Using standard Windows desktop shortcuts is simple and doesn't require
installing new tools.  Unfortunately, they are are suspectible to multi-second
delays, because of because of @uref{https://devblogs.microsoft.com/oldnewthing/?p=7723,this issue}.

One way is to do define a desktop shortcut.
(This @uref{https://winaero.com/blog/pin-a-batch-file-to-the-start-menu-or-taskbar-in-windows-10/,article with screenshots} as well
on @uref{https://superuser.com/questions/418533/run-a-cmd-comand-from-a-key-stroke/418534,this article} may be helpful.)
Start by right clicking on the desktop and select @code{New}->@code{Shortcut}.
At @code{Type the location of the item:}
type the above @code{wsl ...} command,
and the Next screen I suggest a name like @code{toggle-domterm}.
This add a new entry on the desktop.
Right-click it, select @code{Properties}->@code{Shortcut}.
In the @code{Shortcut key} field, type @code{T}
which is converted to @code{Ctrl + Alt + T}
(or use some other key you prefer).
In the @code{Run} field, select @code{Minimized} (to
avoid the flicker of a temporary command window).

Unfortunately, you are likely to experience
a multi-second delay,
because of @uref{https://devblogs.microsoft.com/oldnewthing/?p=7723,this issue}.

@subheading Specifying initial position

By default the terminal will have a default size and position,
though if you resize and move the window, it should remember the
size and position if you then hide and unhide it.
You can use a @ref{geometry specifier,geometry specifier} to give an
explicit position when it is created,
either in the @ref{Settings} file, or with a @code{--geometry} option:
@example
domterm --geometry 775x600+20+10 window toggle-minimize
@end example

@node Python tips
@section Python tips

Here are some ideas for using the Python (Python3)
language with DomTerm.
I am not a Python expert, so recommendations for better
ways to do these things are welcome.

@subheading Setup and prompts

In your shell startup file (e.g @code{.bashrc}),
define @code{PYTHONSTARTUP} and @code{PYTHONPATH},
for example:
@example
export PYTHONSTARTUP=$HOME/.config/python/python-startup.py
export PYTHONPATH=$HOME/.config/python
@end example

Copy the following to @code{$PYTHONSTARTUP}:

@example
import os
import sys
is_domterm = os.getenv("DOMTERM", "")!=""
session_key = 'Py%d' % os.getpid()
sys.ps1 = '>>> '
sys.ps2 = '... '

if is_domterm :
    sys.ps1 = '\001\033]133;N;aid=' + session_key + ';cl=m\007\002'+ sys.ps1 + '\001\033]133;I\007\002'
    sys.ps2 = '\001\033]133;P;k=c\007\002' + sys.ps2 + '\001\033]133;I\007\002'
    import domterm.utils as dtutils
    dtutils.set_notebook_mode()
@end example

@uref{images/python-repl.png,@image{images/python-repl}}

Setting @code{sys.ps1} and @code{sys.ps2} wraps the prompts
with DomTerm-specific escape sequences that provide some benefits:

@itemize @bullet
@item
Logical and visual separation between commands,
with different colors for prompt, input, and output.
@item
A ``fold'' (hide/show) mini-button (in the right column):
Clicking on the downward triangle hides all but the first line of the command.
You can see that for the command starting @code{"""Another}:
Input lines beyond the first plus all the output is hidden,
and the button changed to a right arrow.
@item
Clicking with the mouse within the current input line causes the
editing position in the line to be changed.
@end itemize

Installing @uref{tools/python/domterm/utils.py,domterm/utils.py}
defines the following useful functions.

@deffn Function dtutils.print_html (@var{html_string})
Send the @var{html_string} to the terminal, and display it
as would be done in a browser.
@end deffn

@deffn Function dtutils.display_html (@var{html}, overwrite=False, name='python_image', inline=False)
Similar to @code{print_html}, but supports replace-in-place of
existing output:
If @code{overwrite} is @code{False}, it wraps the @var{html} in another
element (a @code{<span>} if @code{inline} or a @code{<div>} otherwise), and
attaches a key @code{name} to that wrapper element.
(This key does not use the @code{id} attribute, and need not be unique.)

If @code{overwrite} is @code{True}, DomTerm searches for the most
recent element that has a key matching @code{name}.
If found, it replaces the contents (child nodes) of that
wrapper element with @var{html}.
@end deffn

@deffn Function dtutils.set_notebook_mode(@var{enable=True})
Controls how auto-display (the ``print'' part of the Python REPL)
handles objects that have a @code{_repr_html_} attribute:
If @var{enable} is True, then @code{_repr_html_} is called,
and the result is printed as if by @code{dtutils.print_html}.
Otherwise, the default display is done.
The @code{python-startup.py} above starts out with @var{enable}@code{=True}.
@end deffn

@subheading Clickable errors

@uref{images/python-error.png,@image{images/python-error}}

The @code{domterm.utils} module overrides Python's @code{sys.excepthook},
as show in the screenshot.  The error message is wrapped in
@code{<span std="err">} elements, which is by default styled with red.

Lines of the form @code{File "@var{filename}", line @var{line}}
are converted to clickable links (visible when you hover over it).
(Note the effective URL in the blue box.)
Right-clicking on the link brings up an @code{Open Link} menu entry,
which normally brings up a text editor at the specified line;
you can @ref{link-handlers,customize this action}.

@subheading Dynamic pretty-printing

@uref{images/python-pretty1.png,@image{images/python-pretty1}}

The @code{domterm.utils} module overrides the @code{sys.displayhook}
uses for printing expression results.
It replaces the default @code{repr} with one that checks if an
object has a @code{_repr_html_} attribute;
if so it uses that instead of the @code{_repr} method.

Lists, tuples, and dictionaries are pretty-printed.
The width used for line-breaking is the current terminal line-width;
if the terminal width is changed, previously printed lines
are automatically re-formatted.
The screenshot shows the same terminal session in
two panes with different widths.

@subheading Using Pandas

@uref{images/python-pandas.png,@image{images/python-pandas}}

Here is an example using Pandas,
the @uref{https://pandas.pydata.org/,Pandas Data Analysis Library}.

Note how a @code{DataFrame} by default is displayed as an HTML table
(assuming @code{dtutils.set_notebook_mode(True)} has been called).

@subheading Using matplotlib

@image{images/pyplot}

@uref{https://matplotlib.org/,Matplotlib} is popular
plotting library.
If you do:
@example
import domterm.matplot
@end example
it will ``patch'' matplotlib so graphical output is
displayed inline in a DomTerm terminal.
(Note that domterm.matplot is very experimental, so the API may change.)

@deffn Function plt.show (overwrite=do_overwrite, format=@code{"svg"})
Display the current image inline.
By default, the image is presented using SVG (Structured Vector Graphics),
but you can also specify the @code{format} as @code{"png"} or @code{"jpg"}.

The @code{overwrite} argument specifies whether to create a new display
area (@code{overwrite=False}) or re-use the most recent previous one
(if (@code{overwrite=True}); the default is @code{False} for the first
call to @code{show} and @code{True} for subsequent calls.
@end deffn

@node Names and titles
@section Names and titles

Some notes on how sessions and windows are named and identified.

@subsubheading Session name

The session name is an optional user-specified name for a terminal session.
It is recommended that this be unique, but that is not enforced.
The session name can be specified with the @code{-session-name}
(or @code{--sn}) option in the @code{domterm new} command.
You can also dynamically change the session name with an escape sequence:
@example
echo -en "\e]30;@var{session-name}\007"
@end example

It is recommended (but not required) that a session name
have the format of an ``identifier'': The first character should be a letter,
and the rest should be letters, digits, hyphen, or underscore.

@subsubheading Session number

The session number is a positive integer associated with a terminal
session.  It is unique within a domterm server.

@anchor{session-specifier}
@subsubheading Session specifier

The @code{domterm attach} command requires a @dfn{session specifier},
which can be any one of:
@itemize
@item
A session name.
@item
A colon followed by a session number.
@item
A process number (pid).
@end itemize

@subsubheading DomTerm element attributes

Each DomTerm instance in a browser has a corresponding
@code{<div>} element which has @code{domterm} in its
@code{class} attribute.
The @code{<div class="domterm">} element also has the following
identifying attributes, which can be used for session-specific @ref{Styling,styling}:
@itemize
@item
@code{session-number=}@var{session-number}
@item
@code{pid=}@var{pid}
@item
@code{session-name=}@var{session-name}
(but only if the @var{session-name} has been set).
@end itemize

@subsubheading Window name

The window name is a short name displayed for each terminal
in the window title or tab.
It is constructed from up to 3 parts:
@enumerate
@item
The session name, or @code{DomTerm} if the session name is not specified.
@item
If the session name is unset or not unique,
we add a colon and the session number.
@item
If there is more than one window attached to the same terminal,
then we add a period followed by window number.
@end enumerate

@subsubheading Window title and icon title

The window and icon titles are strings sent by the application.
The escape sequences are those of xterm.
They are commonly sent by shells (for example using bash's
@code{PROMPT_COMMAND}) and may include the current directory and maybe
other information.
Most terminal emulators include the window title string
in the window title bar.

@subsubheading Window and tab title bars

When tabs are used, DomTerm displays the window name in each tab.
For active tabs, DomTerm displays both the window name (normally the session name)
and the window title (typically the current directory).
This information may be shown in the main window title bar
as well as the currently active tab.

@node Java tools
@chapter Java tools

The @code{domterm.jar} by default includes various useful Java classes
(in addition
to all the JavaScript and styling for DomTerm itself).

The class @code{org.domterm.javafx.WebTerminalApp} creates a DomTerm
window in the current Java process, without requiring a server.
It is used by the @uref{https://www.gnu.org/software/kawa/REPL-Console.html#Running-a-Command-Interpreter-in-a-new-Window,Kawa @code{-wjavafx} option}.
This does require JavaFX.

The @code{org.domterm.DomHttpServer} is a webserver that can be used
as a server (back-end) component of DomTerm.
It does not use WebSockets but uses plain HTTP (with ``Ajax'') instead.
It only depends on the @code{HttpServer} that is a standard part of the JDK.

The @code{jdomterm} script starts up @code{DomHttpServer} along with
an optional front-end.

@node Uses
@chapter Projects using DomTerm

When you run the @uref{http://www.gnu.org/software/kawa/,@b{Kawa}} REPL
under Domterm, some extra niceties are enabled:
If you print out a @uref{www.gnu.org/software/kawa/tutorial/Pictures.html,picture value} it is shown as an (SVG) image.
You can also print ``html values''.
The default prompt adds folding (a hide/show button), and some structure.
Printing lists and other structures does
@uref{http://per.bothner.com/blog/2017/dynamic-prettyprinting/,dynamic pretty-printing}.
Debug printing of expressions includes folding and pretty-printing.

@uref{https://github.com/jingyuewang/DtCalc.jl,@b{DtCalc.jl}} turns
Julia's REPL into an advanced graphical calculator.

The @uref{http://www.gnuplot.info/,@b{gnuplot}} graphing utility will print
@uref{https://per.bothner.com/blog/2016/gnuplot-in-domterm/,graphical output}
directly to the terminal if using DomTerm.

The Python
@uref{https://github.com/albertz/py_better_exchook,@b{better_exchook}}
package prints stack traces with extended information such as relevant
local variables. When run in DomTerm, it folds all the details of each
stack frame away by default, and thus provides a much more
comprehensive overview, while still providing all the details when needed.

The @uref{https://github.com/PerBothner/atom-domterm,@b{atom-domterm}}
package for the @uref{https://atom.io/,Atom text editor}
provides a text editor in an Atom pane, fairly well integrated.

There is an @uref{https://github.com/PerBothner/theia,experimental fork}
of the @uref{https://github.com/PerBothner/theia,@b{Theia} IDE} to
use DomTerm for its terminal emulator.

@node To do
@chapter Ideas and projects for DomTerm

@subheading Roadmap

Planned improvements (without any promises or timeline),
from higher priority to lower.

@itemize @bullet
@item
Polish paging/pausing and update documentation.
@item
Polish and finish remote-ssh facility.
Get auto-backup implemented.
@item
Continue converting lws-term to make better use of C++.
@item
Do line-breaking lazily.
@item
Implement ``infinite lines'': Escape sequences or mode so application
(or library like @code{readline}) can ignore line-length,
soft line-breaks, and window resize.  This will also allow
variable width-fonts.
@item
Bundle documentation and add command to browse it.
Use a zip file, with compressed images (with link to full images on website).
@item
Port backend to native MS-Windows (without WSL).
@item
Allow loading JavaScript extension code.
@item
Improve integration for selected applications: fish and other shells.
Nushell.
Mutt email client (handle html).  Info reader replacement supporting html.
@item
Open a text editor in a pane.  Probably either Monaco or CodeMirror 6.
@end itemize

@subheading New line structure

@subsubheading Goals
Better support for one session with multiple windows with differing widths.
Support ``logical line'' (infitinely wide) terminal model.
Lazy line-breaking (on a per-line basis) for better performance
(at least faster re-size).

@subsubheading Terminology
The @dfn{controlling window} (or @dfn{primary window}?) has the controlling window size (width and height).
The @dfn{window width} (or height) is the width (or height)
(in characters unless specified) of a given window.
The @dfn{terminal width} (or height) is the width (or height)
of the controlling window.

A @dfn{line} is logical line (represented as a block element),
ignoring soft line-breaks.
Line-breaking splits a line into one or more @dfn{rows}.
A given line may be split in two different ways (at the same time):
A @dfn{terminal row} is the result of splitting a line based on
terminal width; standard xterm commands work in therms of terminal rows.
A @dfn{window row} is the result of splitting a line based on
window width; this is how the line is displayed in a given window.

@subsubheading Line properties
These are properties of line object.  We use the DOM block element.

@table @asis
@item endTRows
If this line contains N terminal rows, then @code{endTRows}
is an array of length N, pointng to @code{line} elements that
mark the end of the N'th terminal row.
(The last element of the array may be null if the line is
terminated by an implicted end-of-block.)
@item endWRows
Similar to endTRows, but an array of ends of window rows.
If this is the controlling windows, same as @code{endTRows},
unless @code{noTBreak}.
@item endTValid
True if endTRows is valid.  Cleared if controlling window is re-sized.
@item endWValid
True if endTRows is valid.  Cleared if current window is re-sized.
@item measured
True @code{breakLine1} has been run on the line (since it was last modified).
@item noTBreak
No terminal breaks, only visual breaks:
Treat this line as if the terminal width is infinite,
thus it always has a single terminal row.
In this case, @code{endTRows} has size 1.
Cursor motion ignores soft line breaks (in this line).
@end table

@subsubheading Shorting line-break changes

New property @code{outputAtEnd}: If output cursor at end of logical line
(possibly nested in style-span or pprint-group).
In @code{insertSimpleOutput} if @code{outputAtEnd} just append the current line.
(Note a deferred line-break may overwrite following lines.)

Window resize:
Set @code{rebreakNeeded} on all lines.
On all likes that might becomes visible,
if @code{measureNeeded} call unbreakLines, then breakLine1 (to measure).

@subsubheading custom heading / titlebar

Custom window decoration (including possible ``hamburger menu'')
could reduce some wasted vertical space.
Consider how it works with panes and tabbars.
Here is @uref{https://www.qt.io/blog/custom-window-decorations,how it can be done with Qt}.
For Gtk one can use Gtk.HeaderBar.
The @uref{https://github.com/tauri-apps/wry,Wry library} has an example of
a draggable custom titlebar.

@subheading Terminal emulator functionality

@subsubheading Document any discrepancies from xterm and ANSI

While implementing all of the
@uref{http://invisible-island.net/xterm/ctlseqs/ctlseqs.html,features of xterm}
is probably not feasible, we should at least have a list of
anything we don't implement, or implement differently from xterm.

See also the @uref{http://www.ecma-international.org/publications/standards/Ecma-048.htm,ECMA-48 standard}.

Error recovery and state transitions should follow
@uref{http://www.vt100.net/emu/dec_ansi_parser,this}.

@subsubheading Embedded HTML

If the @code{src} attribute of @code{<img>} is a relative URL
(or optionally a @code{file:} URL), then
the @code{domterm html} command should read the file
and embed it as a @code{data:} URL.
(As long as no @code{--base} option is specified.)

@c @subsubheading Support Sixel graphics
@c
@c @uref{https://en.wikipedia.org/wiki/Sixel,Sixel} is an old raster
@c image format supported by DEC terminals and some programs, including xterm.
@c It is interesting because some programs (such as gnuplot) can use Sixel
@c to interleave graphics and text, without requiring separate windows.
@c
@c This @uref{http://www.xarg.org/2010/03/generate-client-side-png-files-using-javascript/,JavaScript utility} may be useful in converting raster data (post-sixel-decoding) to PNG, which could the be displayed with a @code{data:} URI.

@subsubheading Highlighting

We may want to support syntax coloring (including in REPL input lines)
and other highlighting.
If the DomTerm element is not the only element in the @code{<document>}'s
@code{<body>} then the selection may be lost to another ``widget''
unless we simulate the selection as a highlighted range.

@subsubheading Improve copy and paste

Think about how to do multi-line paste.

Copying to HTML should convert @code{<div class='domterm-pre'>} to
@code{<pre>} so pasting without stylesheets works better.

@subsubheading Scroll limit

Handle saving and truncating scrolled-out output.
Most terminal emulators have ``max number of lines in scroll buffer'' setting.
What makes this a little tricky is because there may multiple
windows attached to the same session.  So this would require changes
to the protocol for saving/restoring and syncorinizing sessions.

@subheading Support other embeddable browsers

Some toolkits to explore for integrated browser/application:
@itemize
@item
@uref{https://bitbucket.org/chromiumembedded/cef,Chromium Embedded Framework}
@item
@uref{http://lwn.net/Articles/647921/,Mozilla Servo}
@item
@item
@uref{https://tauri.studio/en/Tauri} aims to similar to Electron
but ligher-weight.
@uref{https://github.com/tauri-apps/wry,WRY} is wrapper
similar to (based on) WebView, written for Tauri but
can use it by itself.
@item
@uref{http://nwjs.io/,NW.js} (formerly node-webkit).
Seems to have slightly lower resouce usage than Electron,
and using @code{nw} executable is better supported.
@item
@uref{http://webkitgtk.org/,WebKitGtk+}.
Could use @uref{https://github.com/webview/webview/,webview} as a starting point.
@end itemize

@anchor{window-manager-notes}
@subsubheading Using alternate window managers

DomTerm includes a ``window manager''
(implemented
using @uref{http://golden-layout.com/,GoldenLayout})
that supports panes and tabs.
If DomTerm is integrated in an application with its
own window manager, such as Atom or Visual Studio Code,
it would make sense to instead integrate with the latter manager.

The @uref{https://neomjs.github.io/pages/,neo.mjs} project has
@uref{https://medium.com/geekculture/web-based-multi-screen-apps-including-drag-drop-5e161da6507b,cross-window drag-and-drop}.

For @code{qtdomterm} there is experimental support
for more advanced Qt docking librariers:
@uref{https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System,Qt Advanced Docking System} and
@uref{https://www.kdab.com/development-resources/qt-tools/kddockwidgets/,KDDockWidgets}.

Theia and Jupyter use @uref{https://phosphorjs.github.io/,PhosphorJS}, now archived.
A newer version is part of @uref{https://jupyterlab.readthedocs.io/en/stable/,JupyterLab}.

Similarly, when running under a
@uref{https://en.wikipedia.org/wiki/Tiling_window_manager,tiling window manager}
using the latter to manage panes and tabs is likely preferable.

@subsubheading Compare other terminal emulators

@uref{https://termysequence.io/,TermySequence}
has lots of features.
@uref{https://github.com/TermySequence/termysequence,Source code.}

@subsubheading Tools and examples for Atom or Electron

Atom packages are in @code{~/.atom/packages}.
Seemingly helpful tutorial:
``@uref{https://www.sitepoint.com/write-atom-packages-using-vanilla-javascript/,
How to Write Atom Packages Using Vanilla JavaScript}''.

Web browsers for Atom include
@uref{https://github.com/gabceb/atom-web-view,atom-web-view} (aka web-view),
or @uref{https://github.com/gstack/atom-browser-webview,atom-browser-webview}.
Neither of them work well, probably because of Atom API changes.

Terminal emulators for Electron:
@url{https://github.com/sedwards2009/extraterm,Extraterm} (interesting, uses CodeMirror).
@url{https://github.com/vshatskyi/black-screen,Black Screen} (extra shell features).

Terminal emulators for Atom:
@uref{https://atom.io/packages/term3,Term 3}.
@uref{https://atom.io/packages/terminal-plus,terminal-plus}.
@uref{https://atom.io/packages/atom-terminal-panel,atom-terminal-panel}.
@uref{https://github.com/romgrk/termrk,Termrk}.

@uref{https://www.npmjs.com/package/electron-tabs,Tabs for Electron}
(compatible with @uref{https://github.com/bevacqua/dragula,dragula}).

Various Electron @uref{https://github.com/sindresorhus/awesome-electron,Awesome links}
@uref{https://electron.atom.io/community/,Community links}.

@subheading Readline style hooks and improvements

The idea is the line-editing mode would provide the
functionality of readline or similar programs.

@subsubheading Readline hooks to recognize when it's running under DomTerm

The idea is readline would delegate basic line editing
(and re-display) to DomTerm, while DomTerm would call back
to readline for command completion, history, etc.

This has a couple of advantages over plain readline:
One is to have mousing actually work (i.e. no more
readline not being able to move the cursor on mouse-clicks).
Another advantage is local editing, which is a benefit
over slow links (such as satellites) or when you don't
want to interrupt the server needlessly.

Readline should at least behave as if the screen width were infinite,
delegating line-wrapping to DomTerm.

@subsubheading Event forwarding to inferior

A process may "print"/paint graphics with event handlers.
For example a button.  On clicking the button, the click
should be bundled as an event objects sent back to the inferior.

@subsubheading Shift selection

Zsh editor (zle) supports Emacs-like mark and region.
Emacs has a ``shift-selection'' state, which we would like to emulate.

On mouse selection, or a shift-motion command (such as Shift+Right),
should set the region in shift-selection mode:
We send Ctrl+Space to the client (setting the mark) at the ``anchor''
and move the cursor as needed.  We also (locally to DomTerm) set the
``shift-selection'' mode.
If when in shift-selection mode any (special) key is pressed @emph{without} the shift
modfier, then shift-selection mode is turned off, the selection is collapsed,
and Escape - Ctrl+Space is sent to decativate the region.

Can do this lazily, so we only get the selection highlighting:
On mouse selection or shift-motion command

@subheading JavaScript extension

It may be useful to load new JavaScript libraries into DomTerm.
We can do this when loading a DomTerm web-page, by
having the server add @code{<script>} elements to the
generated web page.
More flexible is do it dynamically:
@example
domterm load-javascript "foo.js"
@end example
This works by essentialy doing @code{createElement("script")}.

For this to be useful we need to better define the DomTerm JavaScipt
API with extension hooks.

@subsubheading Plotting

A useful extension library would be a plotting library.
The @uref{https://plot.ly/javascript/,Plotly} looks powerful
(and big), and controlled by a JSON-able data structure.

@subheading Saved notebooks

A "notebook" is a saved (and potentially executable)
representation of a session.

IPython/Jupyter has a
@uref{https://ipython.org/ipython-doc/3/notebook/nbformat.html,JSON encoding for "notebooks"}.
This is flexible and extensible, but requires special tools.
See also @uref{https://medium.com/netflix-techblog/open-sourcing-polynote-an-ide-inspired-polyglot-notebook-7f929d3f447,Polynote}.

The DomTerm notebook format should just be a simple html page.
Essentially a serialization of the DOM.  The page may include
some generated header information and metadata.  It may include
references to JavaScript that would allow former execution,
as well as viewing actions (like hide/unhide, wrap-to-fit, etc).
This references should be simple and relative, so the actual
JavaScript loaded can depend on context.

The format must be XML-compatible (XHTML) so it can be
parsed by XML tools such as XSLT.

Specific format TBD.

The html page must be viewable and look reasonable in a browser even
if JavaScript library or style files are missing or JavaScript is
disabled.

A notebook may be include additional resources in other files,
such as images.  If notebook  consists of multiple files,
they should be bundled in a zip archive (like LibreOffice does).

Tools to convert to and from Jupyter format would be nice,
so we should avoid gratuitous conceptual incompatibility.

@subheading Detachable sessions

Detachable sessions (similar to GNU Screen and tmux) means that a front-end
can disconnect from a session, while the session (child process) persists.
The same or a different front-end can later re-attach to the session.

DomTerm implements detachable sessions using a combination
of check-pointing the display state, plus having the backend
recording output commands since last check-point.

This can can handle unexpected detaches, as when a
connection dies. However, it's a bit heavy-handed:
check-pointing should only save parts of the state that have changed.
(This gets a bit tricky when there may be multiple windows displaying
the same session, combined with not-yet-implemented auto-trunctating of
old output.)

See also @uref{https://mosh.org/,Mosh} (also @uref{https://lwn.net/Articles/722923/,LWN article}), and @uref{https://mistertea.github.io/EternalTCP/,EternalTerminal}.

@subheading Remote sessions [mostly implemented]

A DomTerm front-end can used used to display
sessions running on remote backends.
The challenge is having the remote sessions persist if connection is lost.
Managing state for a detached session is handled by the domterm backend,
which therefore needs to run remotely.  However, the part that
manages windows and commands needs to run locally.

The solution is to run the backend in proxy mode.
Supposed the user types:
@example
domterm [@var{user}]@@@var{host} @var{command}
@end example
This can be implemented bying having the (local) backend do:
@example
ssh [@var{user}@@]@var{host} domterm --browser-pipe @var{command}
@end example
(A password may have to be requested.)
The @code{--browser-pipe} option is a special kind of browser-specifier:
Instead of output being sent to the browser, it is written to stdout;
input from stdin is (mostly) sent to the @var{command}.
(``Mostly'' because the remote domterm processes certain
escape sequences.  For example the @code{"WS"} sequences
is used to change the pty window size.)

The local domterm backend acts as a proxy for the remote backend.

It is also useful to be able to connect to a remote backend, directly from
a browser, without having to install a local @code{domterm} command.
That requires a remote @code{https} server, and has some more
permission and security complications.

@subheading Documentation

Create screencasts, maybe using @uref{https://github.com/phw/peek,Peek},
or Byzanz.
Consider using @uref{https://github.com/critiqjo/key-mon,key-mon}
(available on Fedora) to display clicks etc.

@node Technical documentation
@chapter Technical documentation

@menu
* Terminology::
* DOM structure::
* Wire byte protocol::
* electron nodepty:: Using node for background server
* The DomTerm JavaScript class::
* Processes and security::
* Architecture notes::
@end menu

@node Terminology
@section Terminology and Concepts

The DomTerm architecture is split into
@uref{https://en.wikipedia.org/wiki/Front_end_and_back_end,front-end and back-end},
each of which could have different implementations.

@example
            ┌─────────────────────────────────────┐
 Front-end  │  Window, input devices (keyboard)   │
            ├─────────────────────────────────────┤
            │  Browser engine (runs terminal.js)  │
            ├─────────────────────────────────────┤
            │  Communication stub                 │
            └-────────────────────────────────────┘
                  🠉
               connection (optional network)
                  🠋
            ┌─────────────────────────────────────┐
  Back-end  │  Communication stub                 │
            ├─────────────────────────────────────┤
            │  Application (session)              │
            └─────────────────────────────────────┘
@end example

The @dfn{front-end} runs the actual terminal emulator.
It manages the display and user interaction.
It runs in a @dfn{browser engine},
which is the core part of a web browser that loads
and displays web pages, and processes JavaScript.
For DomTerm you can use a window or tab in a general-purpose browser
(such as Firefox or Chrome), or you can use a framework for writing
applications that provide a browser engine for the user interface
(such as Electron, Qt, or JavaFX).

The @dfn{back-end} runs the actual applications that the user cares about.
An application can be a shell process running under a PTY,
or a custom application,
such as a programming language run-time or a chat server.

A @dfn{session} is a specific application instance (a process).

A @dfn{window} is a @dfn{top-level window} or a @dfn{sub-window} (tile or tab)
in a DomTerm front-end.
A @dfn{session window} is one that interacts with a session.
A @dfn{non-session window} is created by a @code{domterm} commands
that do not create or connect to sessions, such as @code{domterm browse}
or @code{domterm view-saved}.

A @dfn{connection} communicates between a window (front-end)
and the back-end, and thence usually to a specific session.
The connection usea a @ref{Wire byte protocol,byte-stream protocol}
that is based on the xterm protocol: text and escape sequences
from the application to the front-end; keystrokes and encoded events
sent the other way.
These data streams can be layered on top of other protocols,
such as @uref{https://en.wikipedia.org/wiki/WebSocket,WebSocket}, pipes, or ssh.
Using WebSocket is convenient because it is portable
and is built in to modern browser engines.

A @dfn{(domterm) server process} is a kind of back-end
that can manage multiple sessions, commands, and connections.
It can also open windows in browser engines.
It normally runs in the background,
as one process for a given user and host (computer),
though you can override that if you use the @code{--socket-name} option.
The server listens for requests on the @dfn{command socket}.

A @dfn{setting} is a pair of a @dfn{setting name}
and @dfn{setting value} that controls how DomTerm behaves.
The @dfn{global settings} are defined in a configuration
file normally named @code{settings.ini}.
The @dfn{local settings} can be specified on the @code{domterm} command
line, and apply to the current command, current session, or current window.
The local settings take priority over the global setings.

@node DOM structure
@section DOM structure

The JavaScript code works by DOM manipulations of
a top-level @code{div} element, and assume that element
has a certain well-behaved form.

@table @asis
@item @var{domterm-element} ::= @code{<div class="domterm">} @var{domterm-toplevel} @code{</div>}
A top-level ``DomTerm window'' is a @code{<div>} element
whose @code{class} is @code{domterm}.

@item @var{domterm-toplevel} ::= @var{internal-div-elements} @var{domterm-buffer}@sup{+} @var{spacer}@sup{*}

You don't need to create @var{domterm-toplevel} - it is created and managed by
DomTerm, based on data from the back-end.

@item @var{domterm-buffer} ::= @code{<div class="dt-buffer" buffer="@var{name}">} @var{block-content}@sup{*} @code{</div>}

There are one or two @var{domterm-buffer} elements,
for respectively the ``normal'' and ``alternative'' screen buffer.
These contain all the ``actual'' content.
If there is a single buffer, the @var{name} is @code{"main only"};
if there are two buffers, the respective values for @var{name}
are @code{"main"} and @code{"alternate"}.

@item @var{internal-div-elements}
One or more invisible @code{<div>} elements used by the implementation.

@item @var{spacer} ::=  @code{<div class="domterm-spacer"/>}

Blank space at the bottom, used to support scrolling.

@item @var{block-content} ::= @var{logical-line} | @code{<div>} @var{block-content}@sup{*} @code{</div>} | @var{opaque-line}

@item @var{logical-line} := @code{<div class="domterm-pre">} @var{line-content}@sup{*} @var{hard-nl} @code{</pre>}
@itemx @ @  | @code{<pre>} @var{line-content}@sup{*} @var{hard-nl} @code{</pre>}
@itemx @ @  | @code{<p>} @var{line-content}@sup{*} @var{hard-nl} @code{</p>}
A @var{logical-line} is one or more ``rows'' (separated by @var{soft-line}s),
consisting of character and other @code{inline} data,
ending with @var{hard-nl} representing an explicit newline.

The intent is that @code{<div class="domterm-pre">}, @code{<pre>} and @code{<p>} are treated logically
the same, but @code{<div class="domterm-pre">} (or @code{<pre>}) will be monospace,
while @code{<p>} can use other fonts and styling.
The line-breaking algorithm uses the width of the line,
not the number of characters, so it should also work for @code{<p>} elements.

Normal terminal output will create @code{<div class="domterm-pre">} elements,
rather than @code{<pre>}, because @code{Copy} command on some browsers (at least
current Firefox) adds extra newlines.

@item @var{line-content} ::= @var{text} | @code{<span>} @var{line-content}@sup{*} @code{</span>} | @var{soft-nl} | @var{input-line} | @var{other-content}

@item @var{hard-nl} ::= @code{<span line="hard">&#A;</span>}
An explicit newline. Has a @code{"\n"} text node as its sole child.

@item @var{soft-nl} ::= @code{<span line="soft"></span>}
An implicit newline, inserted by DomTerm when a line overflows.
Has no explicit text content, but CSS adds a @code{"\n"}
as @code{before} content.
CSS by default also add a continuation arrow.

@item @var{input-line} ::= @code{<span id="input1" std="input" contenteditable="true">} @var{text} @code{</span>}
The location of the input cursor.
In char-mode the @var{text} is empty.  In line-mode contains
the current input line.  Also used for previous input lines,
but without @code{contenteditable} set.
Referenced by the @code{inputLine} field of the DomTerm object.

@item @var{opaque-line}
A non-empty block-level element that isn't navigable
at the level of rows and columns.
For example a @code{<table>}.
It is treated as a single empty line.
@end table

@subsubheading Lines and columns

This section discusses the mapping between the nested DOM structure
and the terminal's lines and columns.

In a well-formed tree, all line-breaks have the form
of @code{<span>} element with a @code{line} attribute.
The child of a @code{<span>} element is either a text node
consisting of only a newline, or there are no children
(and a newline is added using CSS styling).  Either way it is
treated as a single line-break.

Inserting HTML may also include @code{<br>} elements and text
containing newlines.  These are not handled consistently.
Ideally, we should convert newlines in @code{pre}-style elements
to @code{<span line="hard">} elements.

The last child of a non-empty block-level element (@code{<div>}, @code{<pre>}
etc) should be either another block-level element or a line-break.
(We could also allow a @code{<span>} whose last element is a line-break,
but isn't clear if this is useful or desirable.)
Inserting HTML should insert if needed final line-break (though
it currently doesn't).  Alternatively, we can treat a missing line-break
as an implicit line-break; currently this is not handled consistently.

A ``line'' is then the text and elements between two
(explicit or implicit) line-breaks.

``Opaque elements'' include @code{<img>}, @code{<svg>},
@code{<object>}, and @code{<iframe>}.  These are treated
as single character, taking up a single ``column''.

The ``characters'' of a line are those in text nodes in the line, plus
opaque elements.

@anchor{command group}
@subsubheading Command groups

A @dfn{command group} is the set of input and output lines for a single
user command.

@table @asis
@item @var{command-group} ::= @code{<div class="command-group">} @var{command-input-line}@sup{+} @var{command-output}@sup{?} @code{</div>}
Usually there is a single @var{command-input-line},
but there may be more than one if there are continuation lines.
@item @var{command-input-line} ::= @code{<pre>} @code{<span std="prompt">} @var{prompt-text} @code{</span>} @code{<span std="input">} @var{input-text} @code{</span>} @code{</pre>}
A @var{command-input-line} is @code{logical-line} which (at least normally)
has the form of a prompt followed by the typed input command.
@item @var{command-output} ::= @code{<div class="command-output">} @var{block-content}@sup{+} @code{</div>}
The output from the command.
Normally, each @var{block-content} is a @var{logical-line}.
The @code{<div class="command-output">} element may have the
@code{domterm-hidden} attribute if it is hideable.
@end table

@anchor{Hide/show buttons}
@subsubheading Hide/show buttons

A hide/show button is a clickable toggle ``button'' that controls
whether certain ``associated output'' is shown or hidden.
For example the ``associated output'' of a shell command could be the
set of output lines from the command.  Initially, the output is in
the shown state, and the button displays a ``hide'' icon.
Clicking the button will hide output lines, as well as changing the
button to display a ``show'' icon.  Clicking the button again
changes the icon to the ``hide'' icon and unhides the output lines.

@table @asis
@item @code{<span std="hider"} [@code{domterm-hiding="true"} or @code{"false"}]@code{>} @var{hide-icon} @code{</span>}
This is a hide/show button.  The @var{hide-icon} is either empty or one of
the strings with odd-numbered index in DomTerm's
@code{showHideMarkers} property.
The value of the @code{showHideMarkers} property is an array of strings,
where the even-numbers elements are ``show'' icons, and
the following odd-numbered elements are the corresponding ``hide'' icons.
It is suggested (but not required) that these icons be single
graphic characters.
Good choices are @code{"\u25B6"} (@code{@U{25B6}} ``black right-pointing triangle'')
for ``show'', and
@code{"\u25BC"} (@code{@U{25BC}} ``black down-pointing triangle'') for ``hide''.

The attribute @code{domterm-hiding} must be @code{"true"}
or @code{"false"}; if missing it defaults to @code{"false"}.
Its value is flipped on each click,

If you are unsatisfied with the existing icon choices you can
either set @code{showHideMarkers} to other strings,
or you can use CSS to change the look of the icons.
For example to use @code{[-]} and @code{[+]} use these CSS rules:
@example
span[std="hider"][domterm-hiding="true"]:after @{ content: "[+]" @}
span[std="hider"]:after @{ content: "[-]" @}
@end example
In this case, you probably want the @var{hide-icon} text in
the @code{<span>} to be empty.
@end table

The ``associated output'' for a hide/show button
is the set of sibling elements following the button,
as well as sibling elements of the button's parent
(assuming that parent is a @code{<pre>} or @code{<p>} element).
Only elements that have the @code{domterm-hidden} attribute are affected.
Hiding is done by changing the value the @code{domterm-hidden} from
@code{"false"} to @code{"true"}; un-hiding changes it back to @code{"false"}.
This is using a CSS style rule that sets the @code{display} property
of an element to @code{none} when @code{domerm-hidden} is @code{true}

A future extension would allow @emph{lazy} associated output:
The initial state is hidden, and the back-end does not provide
the output until it is requested, by clicking the hide/show button.
Lazy output is useful for displaying and inspecting large
(or even infinite) data structures, such as as a directory hierarchy
or a complex object graph.

@subsubheading Alternate screen buffers

Xterm supports an ``alternate screen buffer'' which is used
by character-based programs like emacs.
DomTerm allows an arbitrary number of buffers
(not just two), with the most recent (bottom-most) being the active one.
Each buffer is a @code{<div class="dt-buffer">} element.
An alternate buffer has a @code{buffer="alternate"} attribute.
It is the sibling of the normal screen buffer,
which has a @code{buffer} attribute valued @code{"main"}.
The @code{"dt-buffer"} element contains one or more @var{logical-line}s.
Returning to the normal screen deletes the @code{<div>} for the
alternative screen, along with all of its contents,
and changes the @code{buffer} attribute back to @code{"main only"}.

@anchor{DOM pretty printing}
@subsubheading Pretty-printing and line-breaking

@table @asis
@item @code{<span class="pprint-group">} @var{contents} @code{</span>}

A ``logical block'' of content that should be printed together,
on the same line, if possible.
If there is a prefix, it precedes the @code{"pprint-group"} element.
If there is a per-line prefix,
it is in a @code{<span class="pprint-prefix">} preceding element.
If there is a block suffix, it follows the @code{"pprint-group"} element.

@item @code{<span class="pprint-prefix">} @var{per-line-prefix} @code{</span>}
A per-line prefix.  This must be the previous sibling
of a @code{<span class="pprint-group">} element.
It is displayed just before the logical group, and also
for each continuation line, at the same indentation.

@item @code{<span class="pprint-indent" delta="@var{num-chars}" />}
@itemx @code{<span class="pprint-indent" block-delta="@var{num-chars}" />}
@itemx @code{<span class="pprint-indent">@var{text}"</span>}

Specify extra indentation to add to following continuation lines
(in current group).  (These @code{pprint-indent} elements are non-visible.)
A @code{delta="@var{num-chars}"} changes the indentation
to @var{num-chars} characters relative to the current horizontal position.
A @code{block-delta="@var{num-chars}"} changes the indentation to
@var{num-chars} characters relative to the start of the current logical block.
Specifying @var{text} children specifies @var{text}
as an extra per-line prefix.
The extra indentation is reset at the end of the logical block.

@item @code{<span line="@var{kind}" />}
Represents a conditional newline of the specified @var{kind},
which can be @code{fill}, @code{linear},
@code{miser} (currently the same as @code{fill}),
or @code{required}.


@item @code{<span line="@var{kind}" [breaking="yes"]> [@var{pre-break-child}] [@var{non-break-child}] [@var{newline}] @var{indentation}* [@var{post-break-child}] </span>}
@itemx @code{@var{pre-break-child} ::= <span class="pprint-pre-break">@var{contents}</span>}
@itemx @code{@var{post-break-child} ::= <span class="pprint-post-break">@var{contents}</span>}
@itemx @code{@var{non-break-child} ::= <span class="pprint-non-break">@var{contents}</span>}
@itemx @var{indentation} ::= @code{<span class="pprint-indent">..</span>} | @var{text}
A generalized optional line-break, where @code{kind}
is one of @code{"linear"}, @code{"fill"}, @code{"miser"}
(currently same as @code{"fill"}), or @code{"required"}.
The @code{breaking} attribute is set when a line-break should be shown;
the attribute is removed when the break is no longer wanted.

You can specify contents to
insert @emph{before} the break (when there is a break)
with a @code{pprint-pre-break} element.
Similarly, content after the break
can be specified using a @code{pprint-post-break} element.
To specify contents to be used when there is no break,
use a @code{pprint-non-break} element.

A @var{newline} is inserted when the line is actually breaking
(though not for @code{soft} line-breaks).
The @var{indentation}, if any, is a mix of cloned outer @code{pprint-indent}
elements and text that represent actual calculated indentatation.
They automatically inserted before the post-break-content
when the line is actually breaking,
and removed if the line-break is removed.
A @code{pprint-indent} element is a (visible) clone
of a (non-visible) outer @code{pprint-indent} element.
@end table

@subsubheading The caret node
@table @asis
@item @code{<span std="caret">}@var{caret-text}@code{</span}
@itemx @code{<span std="caret" value="}@var{caret-text}@code{"></span}

This is used to display the caret position.  If the caret is a block
or underline, then the @var{caret-text} is the character at the caret
that is styled with inverse video or an underline.
If the caret is at the end of the line, then the @var{caret-text}
is a single space, and we use a @code{value} attribute, because the
space is not actually part of the line.
If the caret is followed by other text (on the same line),
then the @code{caret-text} is a text node consisting of the
first character of the following text (which is removed from
the following text).

If the caret is a vertical-bar then there may still be a @code{caret} element,
but the @var{caret-text} is empty.
@end table

@subsubheading Predictive update

If you type a printing character (while in char-mode), DomTerm
sends the character to the process, which will then echo (display) it.
If there is a slow network connection the delay between when you type
the character and the echo can be disconcerting and slow down your typing.
To avoid this, DomTerm will @emph{tentatively display} it right after
you type it, without waiting for the echo.
The tentative text is displayed in a @code{pending} element, as
a @var{new-text} text child:
@table @asis
@item @code{<span class="pending" old-text="@var{old-text}">}@var{new-text}@code{</span>}
@end table
Text (specifically the @var{new-text}) is by default
displayed with a light gray background to show that it is tentative.

Typing the Left or Right arrow keys may create a @code{Pending}
element where both the @var{old-text} and the @var{new-text}
are the same string - the text that was moved over.
Typing Delete or Backspace has just an @var{old-text} attribute
for the text that has been (tentatively) deleted.
Either Left or Backspace adds a @code{direction="Left"} attribute;
either Right or Delete adds a @code{direction="Right"} attribute.

There is usually at most a single @code{pending} element, but in principle
there can be many.  A @code{pending} node may contain children that are nested
@code{pending} or @code{std="caret"} elements.

Before output is processed (or after a timeout) all existing pending nodes
are ``undone'' (in reverse order) so the DOM state matches that
expected by the application:
All @var{new-text} elements are reverted back to the @var{old-text} values,
and the caret may also be adjusted.
Typically the received output wil be ``echo'' that has the effect of
updating the state to match the pending operations - but now
as definite updates from the application, rather than pending.

@node Wire byte protocol
@section Wire byte protocol

DomTerm mostly handles standard @uref{https://en.wikipedia.org/wiki/ANSI_escape_code,ansi/xterm escape sequences}.
This section documents DomTerm-specific extensions.
(@emph{Future:} We should also document what xterm features aren't implemented.)

@strong{The following code sequences
may change based on experience and feedback.}

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

@menu
* Sequences handled by DomTerm::
* Sequences sent by DomTerm::
@end menu

@node Sequences handled by DomTerm
@subsection Special sequences sent by back-end and handled by DomTerm

@menu
* Miscellaneous sequences::
* Command parts::
* Window operations::
* Urgent messages::
* Diagnostic (error) messages::
* Stylesheet manipulation::
* Alterate screen buffers::
* Pretty printing escapes::  Pretty-printing
@end menu

@node Miscellaneous sequences
@subsubsection Miscellaneous sequences

@table @asis
@item @code{"\e[3J"}
Erase the scrollback buffer (i.e. any lines above the home line).
(This is an xterm feature.)
@item @code{"\e[7J"}
Delete all lines in the buffer (including scrolled lines),
except the current line.

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

@item @code{"\e]7;file://" @var{hostname} "/"@var{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 @code{/etc/profile.d/vte.sh}.)

@item @code{"\e]8;"} @var{options} @code{";"} @var{url} @code{"\a"} @var{text} @code{"\e]8;;\a"}

Create a link with the given @var{url} and
display @var{text} (which can contain other escape sequences for styling).
The @var{options} are ignored.  The link has @code{class="subtle plain"}.
See @uref{https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda,this link}.

@item @code{"\e]30;" @var{name} "\a"}
Sets the ``session name'' to @var{name}, which is shown in the window title.
Specifically sets the @code{name} attribute of the top-level
domterm @code{<div>} node to @var{name}.  This can be used
to enable stylesheet rules to only apply to specfic DomTerm windows.
If an active CSS stylesheet contains:

@example
div.domterm[name="@var{name}"] @{ @var{rules} @}
@end example

then the @var{rules} are only active for a DomTerm element whose
session name is @var{name}.

@item @code{"\e]72;" @var{html-text} "\a"}
Insert HTML text (a fragment).
The @var{html-text} can be a complete html file,
but elements such as @code{<html>}, @code{<body>} or @code{<style>}
are ignored.

The HTML is sanity-checked for safety.

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

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

@item @code{"\e]721;" @var{key} @code{";"} @var{html-text} "\a"}

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

@item @code{"\e]73;" @var{keyName} "\a"}
@itemx @code{"\e]74;" keyName "\a"}
@itemx @code{"\e]73;" @var{keyName} "\t" @var{kstr} "\a"}
@itemx @code{"\e]74;" @var{keyName} "\t" @var{kstr} "\a"}
Simulate pressing @var{keyName}.  Used by auto-line mode.
The @code{73} variant supresses echo.

@item @code{"\e[20u"}
Starts a "fresh line": If at the beginning of line, does nothing.
Otherwise moves to the start of a new line.

@item @code{"\e[80;97u"}
@itemx @code{"\e[80;99u"}
@itemx @code{"\e[80;108u"}
@itemx @code{"\e[80;112u"}
Set input editing mode.
The value 99 (@code{'c'}) sets character mode;
the value 108 (@code{'l'}) sets line-editing mode.
The value 97 (@code{'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 (@code{'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.

@item @code{"\e[81u\n"}
Requent to send the state of the window as a @code{WINDOW-CONTENTS} response.

@item @code{"\e]88;"} @var{object} @code{"\a"}
Set or update local settings to @var{object},
which is a map from keys to values, in JSON object format.
Existing local settings not in @var{object} are not changed.
If a value is @code{null}, the corresponding setting is removed
from the local settings, so the global settings (or default) will apply.

@item @code{"\e[89;"} @var{settings} @code{"\a"}

@emph{Internal use: }
Update user @ref{Settings,settings}.

@item @code{"\e[92;" @var{op} "u"}
Temporarily enable auto-pause if @var{op} is 1.
Disables it if @var{op} is 2 (- only if temporarily enabled).
A simplified @code{more} program could temporarily enable auto-pause,
print some amount of output, and then revert the state.
This used by the @code{domterm help} command.

@item @code{"\e[99;99u"}
End-of-file on the output stream.
Calls the @code{eofSeen} method of @code{DomTerm},
which may close the current window or other appropriate action.

@item @code{"\e]103;"} @var{state} @code{"\a"}
Send saved state to new window.

@item @code{"\e]231;"} @var{jtext} @code{"\a"}
Paste the contents of the JSON-encoded string @var{jtext}.

@item @code{"\e]97;"} @var{command} @code{"\a"}
Execute the named @var{command}.
If @var{command} starts with a left-brace, it is a JSON object,
whose preperties may include @code{cmd} (a command-name),
@code{id} (a number to identify the requester, copied to a @code{RESPONSE}, if any),
and possibly other properties, depending on the @code{cmd}.
@end table

@node Command parts
@subsubsection Command parts (shell integration)

The escape sequences will be deprecated
in favor @uref{https://gitlab.com/PerBothner/terminal-specifications/blob/master/proposals/semantic-prompts.md,these sequences} (not yet finalized).

@table @asis
@item @code{"\e[12u"}
Start of error output.
DomTerm places the following text inside a @code{<span>} element
whose @code{std} attribute has the value @code{"error"}.
The default style is to display the text in red.

@item @code{"\e[11u"}
End of error output.

@item @code{"\e[14u"}
Start of prompt.
DomTerm places the following text inside a @code{<span>} element
whose @code{std} attribute has the value @code{"prompt"}.
The default style is to display the text in green.

@item @code{"\e[13u"}
End of prompt.
The prompt is included in selections that surround it.

@item @code{"\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 @code{PS2} prompt.

@item @code{"\e[15u"}
@itemx @code{"\e[15;"} @var{edit-mode} @code{"u"}
Start of an input line.
This also implicitly ends a (selectable) prompt.
The input line is implicitly terminated by a @code{'\n'}
(carriage return).

The @var{edit-mode} specifies what kind of input-line-editing is
in effect, which affects how mouse clicks are handled.
If @var{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 @uref{https://github.com/jline/jline3,JLine3}).

@item @code{"\e[16u"}
@itemx @code{"\e[17u"}

Delimit a @ref{Hide/show buttons,hide/show "button"}, with @code{"\e[16u"} before
and @code{"\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
@code{showHideMarkers} table, then the second character
defaults to the corresponding "show" entry.

@item @code{"\e[83;"} @var{mode} @code{"u"}
Delimit a span to be controlled by a show/hide button (previously printed).
If @var{mode} is 1 or 2 it starts a span, while @var{mode} 0 ends the span.
The span is initially visible if @var{mode} is 1, and
is hidden if @var{mode} is 2.

@item @code{"\e]119;"} @var{group-id} @code{"\a"}
@itemx @code{"\e[19u"}  (deprecated)

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

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

@item @code{"\e]120;"} @var{group-id} @code{"\a"}
(Experimental) Enter a new command-group without closing any current group.

@item @code{"\e]121;"} @var{group-id} @code{"\a"}
(Experimental) Exit the command-group with the given @var{group-id}.

@item @code{"\e]122;"} @var{pattern} @code{"\a"}

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

@item @code{"\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.
@end table

@node Window operations
@subsubsection Window operations

@table @asis
@item @code{"\e[90;" @var{op} "u"}
Create a new sub-window (pane), based on the @var{op}.

@item @code{"\e]104;" @var{op} @code{,} @var{url} "a\n"}
Create a new sub-window (pane), based on the @var{op}.
This displays the @var{url} webpage in an @code{<iframe>}.

@item @code{"\e]105;" @var{op} @code{,} @var{saved-url} "a\n"}
Create a new sub-window (pane), based on the @var{op}.
This displays the @var{saved-url}, a previously saved terminal session.

@item @code{"\e[1t"}
@emph{(Electron and Qt only.)} Un-minimize (de-iconify) current window.
This undoes buth minimize and hide operations.
[In xterm.]
@item @code{"\e[2t"}
@emph{(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.]
@item @code{"\e[2;72t"}
@emph{(Electron and Qt only.)} Hide current window.
The minimized window is @emph{not} visible in the task bar,
as an icon on the desktop, or during an ``windows expose'' operation
@item @code{"\e[2;73t"}
@emph{(Electron and Qt only.)}
Toggle between normal and minimized state:
If hidden or minimized, show it.
If visible, minimize it.
@item @code{"\e[2;74t"}
@emph{(Electron and Qt only.)}
Toggle between normal and hidden state:
If hidden or minimized, show it.
If visible, hide it.
@item @code{"\e[8;"} @var{columns} @code{";"} @var{rows} [@code{";"} @var{mode}] @code{"t"}
Resize the text area to (@var{columns}, @var{rows}).
If @var{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 @var{mode}.]
@item @code{"\e[14t"}
Report the text area size in pixels.  [In xterm.]
@item @code{"\e[14;2t"}
Report window size in pixels.  [In xterm.]
@item @code{"\e[18t"}
Report size of text area in characters. [In xterm.]
@item @code{"\e[22t"}
Save window and icon title to stack. [In xterm.]
@item @code{"\e[23t"}
Restore window and icon title from stack. [In xterm.]
@end table

@node Urgent messages
@subsubsection Urgent messages

@table @asis
@item @code{"\x13"} @code{"\x15"} @var{sequence} @code{"\x14"}
This is an ``out-of-band'' command sequence, which is the
same as @var{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 @var{sequence}, and restore the state.
@item @code{"\x13"} @code{"\x17"} @var{sequence} @code{"\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.

@item @code{"\x13"} @var{sequence} @code{"\x14"}
@itemx @code{"\x13"} @code{"\x16"} @var{sequence} @code{"\x14"}
@emph{These variants are reserved for the domterm backend (server).}
These are similar to the previous variants,
but the @var{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.
@end table

@node Diagnostic (error) messages
@subsubsection Diagnostic (error) messages

@table @asis
@item @code{"\e]44;"} @var{options} @code{"\a"}

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

@item @code{"\e[44;0u"}

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

@item @code{"\e[44;"} @var{parameter} @code{"u"}

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

@end table

@node Stylesheet manipulation
@subsubsection Stylesheet manipulation

@table @asis
@item @code{"\e]94;"} @var{rule} @code{"\a"}
If necessary, create a new temporary stylesheet,
and add the specified JSON-quoted rule to the end of it.
@end table

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

@table @asis
@item @code{"\e]90;\a"}

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

Result to client: @code{"\x9D"} @var{stylesheets} @code{"\n"}

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

@item @code{"\e]91;"} @var{index} @code{"\a"}
Disable the stylesheet that has index @var{index} in the list of
stylesheets in the document.

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

@item @code{"\e]92;"} @var{index} @code{"\a"}
As above, but enable the specified stylesheet.

@item @code{"\e]93;"} @var{index} @code{"\a"}
Return the contents of the specified stylesheet.

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

@item @code{"\e]95;"} @var{name} @code{","} @var{styles} @code{"\a"}
@itemx @code{"\e]96;"} @var{name} @code{","} @var{styles} @code{"\a"}

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

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

@node Alterate screen buffers
@subsubsection Alterate screen buffers

@table @asis
@item @code{"\e[84;2u"}
@itemx @code{"\e[84;3u"}
@itemx @code{"\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 @code{"\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 @code{"\e[84;5u"},
and a "main" buffer otherwise. There isn't much difference
between them, though they may be styled differently.)

Using @code{"\e[84;3u"} (or @code{"\e[84;5u"}) scrolls the top of the
new buffer to the start of visible window;
using @code{"\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.

@item @code{"\e[84;1u"}
Pop the most recent buffer.
(Ignored if it is the only buffer.)
@end table

@anchor{escapes-pretty-printing}
@node Pretty printing escapes
@subsubsection 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 @uref{https://dspace.mit.edu/bitstream/handle/1721.1/6503/AIM-1102.pdf,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.

@table @asis
@item @code{"\e]110\a"}
@itemx @code{"\e]110;"} @var{per-line-prefix} @code{"\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 @var{per-line-prefix}
(a JSON-quoted string) it will written both at the current position,
and at the same position in any continuation lines.

@item @code{"\e]111\a"}
End a logical block.
If there is a "suffix", send it to DomTerm after this command.

@item @code{"\e]112;"} @var{amount} @code{"\a"}

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

@item @code{"\e]113;"} @var{amount} @code{"\a"}

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

@item @code{"\e]114;"} @var{prefix} @code{"\a"}

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

@item @code{"\e]115\a"}

Add a ``fill''-type conditional newline.

@item @code{"\e]116\a"}

Add a ``linear''-type conditional newline.

@item @code{"\e]117\a"}

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

@item @code{"\e]118\a"}

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

@item @code{"\e]115;"}@var{prebreak}@code{","}@var{postbreak}@code{","}@var{nonbreak} @code{"\a"}
@itemx @code{"\e]116;"}@var{prebreak}@code{","}@var{postbreak}@code{","}@var{nonbreak} @code{"\a"}
@itemx @code{"\e]117;"}@var{prebreak}@code{","}@var{postbreak}@code{","}@var{nonbreak} @code{"\a"}
@itemx @code{"\e]118;"}@var{prebreak}@code{","}@var{postbreak}@code{","}@var{nonbreak} @code{"\a"}

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

For example to insert a hyphenation point, you might
write:
@example
\e]115;"-","",""\a
@end example

German used to  have a rule where ``ck'' would be hyphenated as ``k-k'',
as in Zucker (sugar):
@example
Zu\e]115;"k-","k","ck"\aer
@end example
@end table

@node Sequences sent by DomTerm
@subsection 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 @code{"\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.)

@table @asis
@item @code{0xFD "\n"}
Escape sequence to send raw @code{0xFD} to application.

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

@item @code{0xFD "WS " @var{rows} " " @var{cols} " " @var{height} " " @var{width} "\n"}
Report window size from DomTerm to the back-end.

@item @code{0xFD "KEY " @var{keyname} "\t" @var{seqno} "\t" @var{kchars} "\n"}
Used by auto-line mode to report a key event to back-end.
The @var{keyName} is an encoding of the key event in the
style of @uref{https://github.com/marijnh/browserkeymap,browserkeymap};
@var{kchars} is a string literal (JSON-formatted)
of the characters that are normally transmitted to the back-end.
The @var{seqno} is a sequence number, modulo 1024.
In auto-line mode, if the pty is in canonical mode, then @var{keyName}
is returned to DomTerm (using @code{"\e]74;" @var{keyName} "\t" @var{seqno} "\t" @var{kchars} "\a"});
otherwise @var{kchars} are sent to the pty.

@item @code{0xFD "LINK " @var{ref-info} "\n"}
Sent by the DomTerm browser when the user clicks on an @code{<a>} link.
The @var{ref-info} is a JSON-encoded object with information
about the link. The object must have at least an @code{href} property.
Typically,  backend should open @var{href}
in the default browser of the user's desktop,
though this is contomizable.

@item @code{0xFD "RECEIVED " @var{count} "\n"}
This is used for flow-control.
The @var{count} is the number of bytes received and processed
by the front-end.

@item @code{0xFD "SESSION-NAME " @var{session-name} "\n"}
Set @var{session-name} (a JSON-quoted string)
as the name for this session.

@item @code{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.)

@item @code{0xFD "FOCUSED\n"}
The current (sub-)window has focus.

@item @code{0xFD "WINDOW-CONTENTS " @var{rcount} "," @var{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 @var{state} is a JSON-encoded structure.
The @var{rcount} is similar to the value reported @code{RECEIVED},
but as of the start of the most recent urgent message.

@item @code{0xFD "VERSION " @var{version-info} "\n"}
Sends @var{version-info} to the back-end.  Used during initialization.

@item @code{0xFD "REQUEST-CLIPBOARD-TEXT" "\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 on its behalf,
and send the contents using an OSC 231 sequence.

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

@end table

@node electron nodepty
@section electron-nodepty: Using node for background server

The @code{electron-nodepty} directory contains an experimental version
of DomTerm as a combined frontend and backend using Electron and node.js.
This re-uses the JavaScript front-end code,
but replaces the @code{lws-term} server part with Electron code.

@subheading Advantages

Using @code{node.js} may make building and install domterm easier,
as there are fewer dependencies, and they can mostly be handled by @code{npm}.

The code is more compact and easier to understand than the C code.

Runs on native Windows (without needing WSL),
using @uref{https://github.com/microsoft/node-pty,node-pty}.

Uses Electron ipc instead of WebSockets.

@subheading Issues

The Electron instance is not daemonized.  Could use @code{nohub}
or @uref{https://www.npmjs.com/package/daemon,daemon node module}.

The @code{domterm} command (using lws-term) has lots of
options and sub-commands.  Re-implementing this would be some work.
Probably use node @uref{https://nodejs.org/api/net.html,@code{net}} module;
see @uref{https://blog.xathrya.id/2015/12/09/nodejs-unix-sockets/,this blog}.

No support for auto-input-mode due to missing tcgetattr hook.
No way to put process pid and ttyname in @code{DOMTERM} environment variable.
(Maybe fix by hacking @code{node-pty}.)

No support for using other non-Electron front-ends,
including using a web-browser.  (Could be implemented, of course,
by adding server for http and WebSockets.)

@subheading Builing and running

You will probably need to
run @uref{https://github.com/electron/electron-rebuild,electron-rebuild};
the easiest way is to use @code{npm}:

@example
cd $DOMTERM_DIR/electron-nodepty
npm install
npm install --save-dev electron-rebuild
$(npm bin)/electron-rebuild --version $(electron --version)
@end example

The file @code{hlib/domterm-version.js} built from
@code{hlib/domterm-version.js.in} by the @code{configure} script.
If you don't have the shell and other Unix-style tools to
generate and run @code{configure}, you can cheat by
just copying @code{hlib/domterm-version.js.in} over:
@example
cd $DOMTERM_DIR/hlib && cp domterm-version.js.in domterm-version.js
@end example

To start DomTerm do:

@example
electron $DOMTERM_DIR/electron-nodepty
@end example

@node The DomTerm JavaScript class
@section The DomTerm JavaScript class

A DomTerm instance encapsulates the
state of a terminal emulator / console.

Functions and properties not documented here should be considered
internal and (more) likely to change.

@deftypefun new DomTerm (@var{name})
Create a new DomTerm instance.
The parameter @var{name} is a string.
If you have multiple DomTerm instances, it is a good idea
for the names to unique, but currently nothing depends on that.
@end deftypefun

@defun initializeTerminal (element)
Initialize the DomTerm, and associate it with the give @var{element}
(which should be a @code{<div>} element that has @code{class="domterm"}).
This creates the @ref{DOM structure,sub-structure} of child elements
of @var{element}.
@end defun

@defun insertString (str)
Interpret and insert the characters of @var{str}.
It may have ANSI/xterm @ref{Wire byte protocol,escape sequences}.
This method is called by the DomTerm client code.
@end defun

@defun eofSeen ()
This method is called by the DomTerm client code
to notify DomTerm that the client has terminated.
The backend repeatedly calls @code{insertString} and then
finally calls @code{eofSeen} to signal end-of-file.

This function may be overridden.
The default action is to call the @code{close} function of the current window.
@end defun

@defun processInputCharacters (str)
Send @var{str} to the client,
where @var{str} consists of typed characters and other events.
This is a callback function that must be set by the client.
This is called by the DomTerm code in @code{terminal.js}.
@end defun

@defun reportEvent (name, data)
Called by DomTerm to notify the client that some (non-character) event happened.
The default action calls @code{processInputCharacter}
with a special sequence starting with @code{0xFD} followed
by the @var{name}, space, the @var{data} and a newline.
@end defun

@defun setWindowSize (numRows, numColumns, availHeight, availWidth)
Called by DomTerm when the window changes size, or the (font) style changes
so the number of rows or columns has changed.
Is used to notify the client.  The default behavior is to
call @code{reportEvent} with a @code{"WS"} event type.
@end defun

@defun doPaste ()
Handles a @code{paste} operation.
May be called by client code.
May also be overridden if needed; the default uses @code{execCommand},
which triggers a @code{paste} event.
It is called by DomTerm if the user types Ctrl+Shift+V.
@end defun

@defun pasteText (text)
Called by the @code{paste} event handler.
Actually handle a paste event.
@end defun

@defun doCopy ()
Handles a @code{copy} operation.
May be called by client code.
May also be overridden if needed; the default uses @code{execCommand}.
It is called by DomTerm if the user types Ctrl+Shift+C.
@end defun

@defun setInputMode (mode)
Set the input editing mode.
The value 99 (@code{'c'}) sets character mode
(each keystroke is sent to the client);
the value 108 (@code{'l')} sets line mode
(local line editing with a complete line sent on enter);
the value 97 (@code{'a'}) sets automatic mode
(switch between line and character modes depending on client pty state);
the value 112 (@code{'p'}) sets pipe mode
(like line mode but with local echoing).
@end defun

@defun doLineEdit (key, str)
Handle keyboard event when doing input line editing ourselves,
rather than depending on the default action.
This is used  if the @code{useDoLineEdit} property is set.
It is also used for the first character in automatic input editing mode.
(In that case we can't use the browser default action, since we
first have to check the input mode of the client.)
@end defun

@defun handleBell ()
Called when ctrl-G (the @code{bell} character) is seen.
The default action is to do nothing.
@end defun

@defun handleLink (event, href)
Called on a click event on a @code{<a>} link element.
The default action is to call @code{preventDefault} on the @var{event},
and then call @code{reportEvent} with an @code{"ALINK"} type event.
(We can't let the browser do its default action since that would
replace the current DomTerm page.)
@end defun

@defun setWindowTitle (title, option)
Set the title of the containing window.
Called by DomTerm when it sees certain @code{xterm}-style escape sequences.
Calls @code{updateWindowTitle(formatWindowTitle())}.
@end defun

@defun formatWindowTitle ()
Returns a suitable string for a window title,
based on various properies.
@end defun

@defun updateWindowTitle (title)
Actualy set the window title - which is usually the
result of @code{formatWindowTitle()}.
@end defun

@defun elementInfo (tag, parents)
Overridable function called by the HTML sanitizer.
@end defun

@defun allowAttribute (name, value elementInfo, parents)
Overridable function called by the HTML sanitizer.
@end defun

@node Processes and security
@section Processes and security

Normally, there is is a single per-user domterm server process.
When you run the @code{domterm} command it will look for a
domterm server process; if there is no running server, the
@code{domterm} command will ``daemonize'' itself and become the server.
Otherwise, the @code{domterm} process will be a client,
and forward the requested action to the server.

Communication between a @code{domterm} client and a server
uses Unix domain sockets.  By default, this socket will
be bound to the file @code{$XDG_RUNTIME_DIR/domterm/default.socket}.
We make use of Unix file permission to
ensure that the client and the server run on behalf of the same user.
(This could be generalized to allow groups to co-operate, by setting
permissions appropriately, but this has not been explored.)

When you run a new session, that creates a new user process,
under control of the domterm server.

The above client-server architecture is same as used by @code{tmux}.

The @dfn{front-end} is a separate program that handles the user interface.
It is a web browser or an application that embeds a web browser, like
Electron.  The domterm server is also a web server that
supports both http and the WebSockets protocols.
The domterm server forwards output from a user process
to the associated browser and vice versa: The server uses a pty
for the input/output of the user process, and forwards that input/output
to the browser using a websocket connection.  Normally, the server
creates a new browser instance, with a specified URL.  When
the corresponding page is loaded, the browser runs JavaScript that requests
a WebSocket connection with the server.

The obvious concern is that a different malicious browser might try
to establish a connection with the server, which would allow executing
arbitrary commands on behalf of the user.  To thwart that, the server
generates a 60-bit random key, and requires this server key to be present
in any connection attempts.  This means the browser JavaScript process
must know the server key when it creates a websocket connection.
The server must pass the key to the browser in a secure way.
A simple way is to pass the key along with the URL used to start
the browser, but that would typically require the key to be
part of the browser's command-line, which is not secure.
(It can can viewed with tools like @code{ps}.)

FIXME - OBSOSLTE:
Instead, the server creates a new file @code{.domterm/default.html}
in the user's home directory, and uses that as the URL:
@example
$ $@{BROWSER@} "file://$@{HOME@}/.domain/default.html"
@end example
This file (only readable by the user) includes the following:
@example
DomTerm.server_key = '$@{SERVER_KEY@}';
@end example
The @code{$@{SERVER_KEY@}} is substituted when the file is created,
and used when the browser needs to make a websocket connection to the
server.
Again, we depend on Unix file permissions so only a process running
as the correct user can read @code{default.html}, extract the
server key, and make a valid connection back to the server.

Obviously, it could be very useful to handle networked connections,
with a browser on one machine managing a user process on another.
While one can always run @code{ssh}, this does not support
detaching from and re-attaching to a session smoothly.
For now, you have to use @code{ssh} in combination with @code{tmux}
or @code{screen}; we hope to have a smoother interface after studying
the issue. It would presumably use forwarding using ssh,
or @code{https}, or a combination.

Some @uref{https://en.wikipedia.org/wiki/Web-based_SSH,related links}

@node Architecture notes
@section Architecture notes

@menu
* Automatic input mode::
* Line structure::
* Colors and high lighting::
* Remote connection over ssh::
* Predictive echo::
* Connection closing and detaching::
* Line breaking:: Line-breaking / pretty-printing
@end menu

@node Automatic input mode
@subsection Automatic input mode

There are two possible ways DomTerm can detect cooked vs raw mode:
@itemize
@item
The operating system's terminal driver can send an indication
when the terminal switches between cooked and raw.

Unfortunately, few modern operating systems provide a good way
to request such notication.
Linux has the @code{EXTPROC} flag which is inspired by
the @uref{https://en.wikipedia.org/wiki/STREAMS,System V Streams} packet mode.
This adds an extra indicator byte to the terminal input stream.
This mode is enabled by the @code{domterm} @code{--tty-packet-mode=extproc}
command-line option.
This is the default when available.

@item
DomTerm can lazily check.
When you type a character in the DomTerm terminal,
it sends a special encoding to the @code{domterm} server,
which checks the mode of the terminal:
If the PTY is in raw mode, the character is sent to the application.
If the PTY is in cooked mode, the character is sent back to the
DomTerm front-end, which enters line-edit mode, inserting
the character in the input area.
Subsequent characters (until @kbd{@key{Enter}}) are handled
locally by DomTerm without a trip to the backend.
@end itemize

@node Line structure
@subsection Line structure

"Line" here refer to "visual line": A section of the DOM that should be
treated as a line for cursor movement.  Line breaks may come from the
back-end, or be inserted by the line break algorithm.

The lineStarts array maps from a line number to the DOM location
of the start of the corresponding line.

The lineEnds array maps to the end of each line.
Always points to a span node with the line attribute set.
Normally lineEnds[i] == lineStarts[i+1]; however, sometimes
lineStarts[i] is the start of a @code{<div>} or other block element.

@node Colors and high lighting
@subsection Colors and high-lighting

@emph{This needs updating.}

Escape sequences (for example @code{"\e[4m"} - "underlined", or
@code{"\e[32m"} - "set foreground color to green") are translated to
<span> elements with "@code{style}" attributes (for example
`<span style="text-decoration:underline">` or `<span style="color: green">`).
After creating such a `<span>` the current position is moved inside it.

If we've previously processed "set foreground color to green", and we
see a request for "underlined" it is easy to ceate a nested `<span>`
for the latter.  But what if we then see "set foreground color to red"?
We don't want to nest <span style="color: red">` inside
<span style="color: green">` - that could lead to some deep and
ugly nesting.  Instead, we move the cursor outside bot existing
spans, and then create new spans for red and underlined.

The `<span>` nodes are created lazily just before characters are
inserted, by `_adjustStyle`, which compares the current active styles
with the desired ones (set by `_pushStyle`).

A possibly better approach would be to match each highlight style into
a `class` attribute (for example `green-foreground-style` and
`underlined-style`).  A default stylesheet can map each style class to
the correspoding CSS rules.  This has the advantage that one could
override the highlighting appearance with a custom style sheet.

@anchor{Architecture remote over ssh}
@node Remote connection over ssh
@subsection Remote connection over ssh

The support for remote connections is a relatively thin
layering on top of @uref{https://www.ssh.com/ssh/,ssh}.
When you type:
@example
domterm @var{user}@@@var{host} @var{command}
@end example
it basically translates to:
@example
ssh @var{user}@@@var{host} domterm --browser-pipe @var{command}
@end example

All connection setup and logging in are handled by @code{ssh}.
If you do a command like:
@example
domterm @var{user}@@@var{host} status
@end example
this will run @code{domterm --browser-pipe status} on the @var{host}.
In this case the @code{--browser-pipe} option is irrelevant:
Output from the command will be printed on standard output
which @code{ssh} then sends back to the local @code{domterm},
which prints in on the local terminal.

If the command creates a window, things get more interesting.  For example:
@example
domterm --qt @var{user}@@@var{host} attach :1
@end example
Again, @code{ssh} will execute @code{domterm --browser-pipe attach :1}
on the remote @var{host}.  This will attach to existing session 1.
Then, when @code{domterm} would normally create a a new window,
it sees the @code{--browser-pipe}.  It prints a special escape character,
which is sent back to the local @code{domterm} server, which switches
from command-proxy mode to display-proxy mode, opening up a window.
(A Qt window because of the @code{--qt} option.)
In display-proxy mode, characters and other events from the window
are written to the input of the @code{ssh} process,
while output from the remote user process are sent
via the remote domterm server over ssh to the local domterm server,
which displays them in the window.

@example
            ┌─────────────────────────────────────┐
 Front-end  │  Window, input devices (keyboard)   │
            ├─────────────────────────────────────┤
            │  Browser engine (runs terminal.js)  │
            └-────────────────────────────────────┘
                  🠉
               WebSockets connection (local)
                  🠋
            ┌─────────────────────────────────────┐
 Local      │  Proxy (local end)                  │
 back-end   ├─────────────────────────────────────┤
            │  Ssh client (local session)         │
            └-────────────────────────────────────┘
                  🠉
               ssh connection (network)
                  🠋
            ┌─────────────────────────────────────┐
  Remote    │  Proxy (remote end)                 │
  back-end  ├─────────────────────────────────────┤
            │  Application (session)              │
            └─────────────────────────────────────┘
@end example
(Compare with diagram at @ref{Terminology}.)

@node Predictive echo
@subsection Predictive echo

@uref{https://mosh.org/,Mosh} implements local ``tentative echo'', which
makes network latency less a problem.
DomTerm implements this leveraging the ``deferred deletion''
mechanism (used for line mode echo).

To do this we use a @code{<span>} that contains predicted input:
an optional text node, the @code{_caretNode}, and an optional text node.
The node has 3 additional properties: @code{textBefore}, @code{textAfter},
and @code{pendingEcho}.  When output arrives from the server,
the function @code{_doDeferredDeletion} is called,
which replaces the span by the @code{textBefore} and @code{textAfter},
with the @code{_caretNode} in between; this is ``real'' (confirmed) output,
before processing the new output.
We also @code{_doDeferredDeletion} when unable to do echo predication.

Handling keyboard input is as follows:
First, if @code{_deferredForDeletion} is null, we set it to a fresh span
that wraps the @code{_caretNode}.
As needed,  any text node immediately before or after can be moved
into the @code{_deferredForDeletion} span, also setting @code{textBefore}
and  @code{textAfter}.
Then, for a printing character, we insert it before the caret,
and append it to @code{pendingEcho}.
For left or right arrow, delete, or backspace, if possible we adjust the
@code{_deferredForDeletion} span appropriately,
and add a special code to @code{pendingEcho}.
If not possible, we @code{_doDeferredDeletion}, which we
also do for other keys.

Calling @code{_doDeferredDeletion} just before handling output
is correct but suboptimal if the output only contains part
of the pending echo.
In that case we try to create (after handling output) a new
@code{_deferredForDeletion} span, whose @code{pendingEcho} string
is a tail of the previous value.
(We only do this if there are no changes to any other (logical) line.)

@node Connection closing and detaching
@subsection Connection closing and detaching

A session can have one or more open windows,
or it can be in a @dfn{detached} state, in which case the
process (and pty) still exist, along with @dfn{preserved state}
that can be used to attach a new window to the session.
Onc can also attach a new window to a session that has
open windows, in which case the open windows can provide
the state needed to create the new window.

Preserved state is currently represented in two parts:
a snapshot (the DOM slightly sanitized and serialized, plus
terminal state properties), and a replay log: the session output sent
to the terminal since the last snapshot.

For each session, the sever maintains a @dfn{detach-count},
which is rougly the number of windows that have been explictly closed.
This is also the number of attaches ``pending`` before a session is closed.
When a new non-detached session is created, the detach-count is zero;
when a window is detached, the detach-count is incremented;
it a window is connected to an existing session, the detach-count is decremented.
(If a new session is created in detached state,
should the initial connect-count be zero or one?)

A connection (between session and window) can be closed in 4 ways:
@itemize
@item
Session process exits, perhaps because the user typed @code{exit}.
The server sends all windows a request to close themselves.
@item
User explicitly closed window (menu item or close button).
If the detach-count is zero, the session is terminated.
((Possible actions: Exit process and close window;
detach process and close window; ask user.
Latter may depend on whether ``process is running'' (as
checked by Gnome Terminal, Konsole).))
@item
User explicitly requests the session be detached.
The detach-count is incremented
@item
Connection closes for unknown reason, such as network failure, or laptop sleep.
Treat as a detach.
The detach-count is incremented.
@end itemize

@node Line breaking
@subsection Line-breaking / pretty-printing

For a terminal emulator we need to preserve (not collapse) whitespace,
and (usually) we want to line-break in the middle of a word.

These CSS properties come close:
@example
white-space: pre-wrap; word-break: break-all
@end example
This is simple and fast.  However:
@itemize
@item
It doesn't help in inserting a visual indicator, like Emacs's arrow,
  to indicate when a line was broken.
@item
It doesn't help managing the line table.
@item
It doesn't help with pretty-printing (for example grouping).
@item
Chrome (version 52) seems to have from problems with @code{break-all}.
@end itemize

Hence we need to do the job ourselves.

@node Credits
@chapter Credits and thanks

DomTerm is implemented by Per Bothner, but
makes use of multiple libraries and tools.

The back-end uses Andy Green's @uref{https://libwebsockets.org/,libwebsockets}
for its http and websockets server and event polling library.

The C back-end was based on Shuanglei Tao's @uref{https://github.com/tsl0922/ttyd,ttyd}.

JSON in the backend is handled by @uref{https://json.nlohmann.me/,Niels Lohmann's json library}.
(In the past the @uref{https://github.com/json-c/json-c,json-c library} was used.)

An older version of the back-end was Java-based.
It made use of @uref{https://github.com/TooTallNate/Java-WebSocket/,Java WebSockets}.
This is no longer supported, but a simplified Java server is still supported.
It uses @code{XMLHttpRequest} (``ajax'') and the @code{com.sun.net.httpserver.HttpServer}
bundled with JDK.

The older @uref{https://github.com/PerBothner/JWebTerminal,JWebTerminal} project
was based on similar ideas as DomTerm, but was mostly written in Java using
@uref{https://docs.oracle.com/javafx/2/webview/jfxpub-webview.htm, Javafx WebView}.
Some optional Java code (not used by the default @code{domterm} command),
including a JavaFX embedding, 
was written while I worked at Oracle, and is copyright Oracle.

@uref{https://golden-layout.com/,GoldenLayout} provides tiling and tabs.

Menubar and context (popup) menus on ``generic'' platforms
(i.e. not Electron, Atom, or Qt) are implemented using
@uref{https://github.com/PerBothner/jsMenus,jsMenus}, which is
based on Sam Wray's @uref{https://github.com/2xAA/nwjs-menu-browser, nwjs-menu-browser} library.

The @uref{https://github.com/sindresorhus/screenfull.js/,screenfull.js} library
by Sindre Sorhus is provides a browser-independent wrapper for entering and exiting Full Screen.

ResizeSensor is used to watch when a DomTerm window or sub-window is re-sized.
It is part of  Marc J. Schmidt's
@uref{https://github.com/marcj/css-element-queries,CSS Element Queries}.

Marijn Haverbeke's @uref{https://github.com/marijnh/browserkeymap,Browser Keymap} package
provides a simple key-binding manager.

Gregory Pakosz's @uref{https://github.com/gpakosz/whereami,Where Am I?} library
is used to get the absolute path for the current @code{domterm} executable.

Eli Gray's @uref{https://github.com/eligrey/FileSaver.js/,FileSaver.js} is
for the ``Save as HTML'' feature.

Reading Sixel images uses the @uref{https://github.com/jerch/node-sixel,@code{node-sixel}} library
written by Jörg ``Jerch'' Breitbart.

The Python tools were largely inspired or based on similar tools
in @uref{https://github.com/mitotic/graphterm,GraphTerm},
written by R. Saravanan (who also wrote the older XMLTerm,
which was a big inspiration).

Building of the @code{qtdomterm} directory makes use of
@uref{https://github.com/tsuna/autotroll,AutoTroll} by
Benoit Sigoure and Werner Lemberg.

Unicode Extended Grapheme breaking and determination of wide character
uses @uref{https://github.com/PerBothner/unicode-properties,unicode-properties},
which are based on code by Devon Govett
(@uref{https://github.com/devongovett/unicode-trie,unicode-trie},
@uref{https://github.com/foliojs/tiny-inflate,tiny-inflate},
and @uref{https://github.com/foliojs/unicode-properties,unicode-properties}),
and by Taisuke Fukuno
(@uref{https://github.com/taisukef/grapheme-breaker-mjs,grapheme-breaker-mjs}).
The @code{wcwidth} library is no longer used.

The find-text facility uses Julian Kühnel's @uref{https://markjs.io/,mark.js}.
