Per's DomTerm blog entries
Using web technologies for the GUI of a desktop application makes a lot of sense: they're portable, familiar, and powerful. A popular option is to use a comprehensive framework such as Electron. However, you might want the option of using a regular desktop browser — maybe you want to be able to access your application remotely, or you might prefer a lighter-weight embedded browser such as webview.
I finally found Sam Wray's nwjs-menu-browser, which satisfied most of
It was strandalone, modest size, handled menubars as well
as popups, and had an API similar to NW.js (which is similar to that of Electron).
However, it had some issues. Missing features included keyboard navigation,
share menu-items between menus,
and some smaller problems.
I also found the build process too complicated for me.
Finally, here is screenshot of jsMenus in action. This is DomTerm,
using the Chrome browser.
Chrome was started with the
--app command-line option,
which (among other things) disables the default menubar and location bar.
The screenshot below shows 3 sub-windows.
The lower one has two tabs, domterm-2 and domterm-3.
The latter has focus (indicated by the magenta border),
and is running the
mc file manager.
The upper left pane (domterm-1) shows how to embed html from the shell.
The domterm-4 pane shows using Kawa to
which are displayed using embedded SVG.
You can resize panes by dragging the separator between them, and you can re-arrange panes or tabs by dragging a title bar. The screenshot shows as we are dragging the splitter between the two upper panes; the blue rectangles temporarily display the resulting sizes.
Compared to GNU screen or tmux, DomTerm supports more flexible layouts and easier manipulation using either mouse or keyboard. However, DomTerm does not yet support sessions that can be detached or accessed by multiple users at once, though I do hope to add it. Until then, I suggest using abduco or dtach to handle session management.
The goal of pretty-printing is to split a text into lines with appropriate indentation, in a way that conforms to the logical structure of the text.
For example if we need to print the following list:
((alpha-1 alpha-2 alpha-3) (beta-1 beta-2 beta-3 beta-4))in a window 40 characters wide, we want:
((alpha-1 alpha-2 alpha-3) (beta-1 beta-2 beta-3 beta-4))but not:
((alpha-1 alpha-2 alpha-3) (beta-1 beta-2 beta-3 beta-4))
Pretty-printing is common in Lisp environments to display complicated nested data structures. Traditionally, it is done by the programming-language runtime, based on a given line width. However, the line width of a console can change if the user resizes the window or changes font size. In that case, previously-emitted pretty-printed lines will quickly become ugly: If the line-width decreases, the breaks will be all wrong and the text hard to read; if the line-width increases we may be using more lines than necessary.
Modern terminal emulators do
dumb line-breaking: Splitting a long
lines into screen lines, but regardless of structure or even word boundaries.
Some emulators remember for each line whether an overflow happened, or
hard newline was printed.
Some terminal emulators (for example Gnome Terminal) will use this
to re-do the splitting when a window is re-sized.
However, that does not help with pretty-printer output.
Below is a screenshot from Kawa running in DomTerm at 80 colutions.
We reduce the window size to 50 columns.
The user input (yellow background) is raw text, so its line is split
but the output (white background) gets
(Note the window size indicator in the lower-right.)
We reduce the window size to 35 columns:
It also works with saved pages
DomTerm allows you to save the current session as
a static HTML page.
hlib directory, then dynamic line-breaking
happens even for saved
(The lazy way is to create
hlib as a symbolic link
hlib directory of the DomTerm distribution.)
Try it yourself on a saved session.
--debug-print-expr flag causes Kawa to print out each command
before it is compiled and evaluated. The result (shown in red because it
is sent to the standard error stream) is pretty-printed dynamically.
This is how it works.
When an application pretty-prints a structure, it calls
procedures to mark which parts of the output logically belong
and where line-breaks and indentation may be inserted.
In Kawa the default print formatting for lists and vectors automatically calls
these procedures when the output is a
The pretty-printing library calculates where to put line-breaks and indentation,
based on these commands and the specified line length.
However, when the output stream is a DomTerm terminal, Kawa's pretty-printing library does not actually calculate the line-breaks. Instead it encodes the above-mentioned procedure calls as special escape sequences that get sent to DomTerm.
When DomTerm receives these escape sequences, it builds a nested DOM structure that corresponds to the orginal procedure calls. DomTerm calculates how to layout that structure using a variant of the Common Lisp pretty-printing algorithm, inserting soft left-breaks and indentation as needed.
When DomTerm detects that its window has been re-sized or zoomed, it first removes old soft line-breaks and identation. It does re-runs the layout algorithm.
Hyphenation and word-breakingDomTerm supports general soft (optional) line breaks: You can specify separate texts (optionally with styling) for each of the following: The text used when the line is not broken at that point; the text to use before the line-break, when broken (commonly a hyphen); the text to use after the line-break (following indentation). One use for this words that change their spelling when hyphenated, as may happen in German. For example the word
bak-ken. You can handle this using
as the non-break text;
as the pre-break text; and
as the post-break text.
I have recently spent a lot of time on
is becoming a fairly decent terminal emulator.
Being based on HTML5 technologies lets you do many
interesting things, including embed graphics.
qtdomterm standalone terminal
emulator is especially nice;
alternatively, you can also use the
command to start a process that uses a window/tab in your default
package is a powerful graphing package.
It has a command-line that lets you specify complicated
functions and plots, and then give a
to display the resulting plot. Unfortunately, it is difficult
to find a a good front-end that is usable for both command-line
interaction and graphics. People usually have to
specify output to either a file or an external viewer.
Would that one could insert the plots directly in the REPL output stream!
The development version of gnuplot (i.e. 5.1, available from CVS)
has native support for DomTerm.
domterm as a new terminal type, which you can select
explicitly (with the command
set term domterm),
or use by default (since
DOMTERM environment variable,
which is set by DomTerm).
This works by using the pre-existing
svg output driver
to generate SVG, but surrounding the SVG by escape sequences, and then printing
the result to standard output. DomTerm recognizes the escape sequence,
extracts the SVG (or more generally clean HTML) and inserts it
at the cursor.
You can save the session output to an html file.
Here is an example.
In qtdomterm you can use the
Save As menu item;
otherwise ctrl-shift-S should work.
This is a single html file, with embedded SVG;
images are embedded with a
The file is actually XML (xhtml), to make it easier to process.
readable, so you need to link or copy
hlib directory in the DomTerm source distribution.