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.

Line vs character input mode

DomTerm lets you switch between these modes:

You can switch between character mode, line mode, or automatic mode using the Terminal menu in the menubar; the Input mode entry in context (popup) menu; or the Ctrl-Shift-L shortcut:

Ctrl-Shift-L

Cycle between input modes: character (character-at-a-time), line (line-edit), or automatic.

The input area and input lines

The area affected by insertions and edits during line-edit mode is called the 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.

Enter (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 Ctrl-Shift-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.

Alt-Enter (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.

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 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.

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.

Repeat count

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

Alt-digit
Alt-Minus
Alt-.

Set or extend a repeat count. For example Alt-1 Alt-2 Left moves 12 characters left, while Alt-Minus Alt-2 Ctrl-Left moves 2 words right (because of the minus).

You can also repeat self-inserting characters: Alt-2 Alt-0 * inserts 20 asterisks.

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

Moving the editing position

Left (backward-char)
Right (forward-char)

Move caret count characters left or right.

Ctrl-Left (backward-word)
Ctrl-Right (forward-word)

Move caret count words left or right.

Home (beginning-of-line)
End (end-of-line)

Move caret to start/end of line.

Alt-Home (beginning-of-input)
Alt-End (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.)

Deleting text

You can also delete using the selection; see later.

Backspace (backward-delete-char)
Delete (forward-delete-char)

Delete count characters to the left or right of the caret.

Ctrl-Backspace (backward-delete-word)
Ctrl-Delete (forward-delete-word)

Delete count words to the left or right of the caret.

Special characters

The keystrokes Ctrl-C, Ctrl-Z, Ctrl-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.

Ctrl-C (copy-text-or-interrupt) (Not MacOS)
Ctrl-C (client-action) (MacOS only)

If there is a non-empty selection and this is not MacOS. copy the selection to the clipboard. Otherwise, send Ctrl-C literally to the process (which traditionally interrupts it).

Ctrl-D (delete-char-or-eof)

Send Ctrl-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.

Ctrl-Z (client-action)

Send a literal Ctrl-Z (traditionally used in Unix to suspend the current job) to the process (following any existing text in the input area).

Scrolling

You can use the general scrolling shortcuts available in all modes, but in line-edit mode you don’t need to press Shift, and you can use a repeat count.

Ctrl-PageUp (scroll-page-up)
Ctrl-PageDown (scroll-page-down)
PageUp (scroll-page-up)
PageDown (scroll-page-down)

Scroll count pages up or down, respectively.

Ctrl-Up (scroll-line-up)
Ctrl-Down (scroll-line-down)

Scroll count lines up or down, respectively.

Ctrl-Home (scroll-top)
Ctrl-End (scroll-bottom)

Scroll to top or bottom, respectively.

Emacs-style keybindings

Ctrl-A (beginning-of-line)
Ctrl-B (backward-char)
Ctrl-E (end-of-line)
Ctrl-F (forward-char)
Ctrl-N (down-line-or-history)
Ctrl-P (up-line-or-history)
Alt-B (backward-word)
Alt-F (forward-word)

Emacs-style alternate keybindings.

Ctrl-D (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.

Not implemented yet, but planned: Emacs-style key-bindings should be controlled by a separate option; some bindings are missing, such as Ctrl-T, and the ones prefixed by Esc. Command-completion, using some protocol to be defined. A plug-in replacement for GNU readline using 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).

Working with the selection

Line mode has extra shortcuts and other conveniences for working with the selection.

The “initial” end of the selection is called the anchor position, and the “final end” is called the focus position. The latter is indicated by a special focus caret, by default a brown I-beam caret.

The commands in this section do not move the edit caret, only the focus position. These shortcuts are the same as line-edit mode, unless otherwise noted.

Ctrl-Shift-C (copy-text)
Ctrl-Insert
Cmd-C (Only MacOS)

Copy selection to clipboard. (Selection can be partly or fully outside input area.)

Ctrl-C (copy-text-or-interrupt) (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.

Ctrl-V (paste-text)
Ctrl-Shift-V
Shift-Insert (Only Electron, Qt, Webview)

Paste selection from clipboard.

Ctrl-X (cut-text)
Ctrl-Shift-X

Cut (delete) the selection and copy the contents to clipboard. Only removes text within the input area.

Ctrl-! (swap-focus-anchor)

If there is a non-collapsed selection, swap focus and anchor (selection ends).

Extending the selection

Pressing Shift during a mouse click also extends the selection.

Shift-Left (backward-char-extend)
Shift-Right (forward-char-extend)

Extends the current selection by count characters (If there is no selection, the caret position is treated as a zero-size selection.)

Ctrl-Shift-Left (backward-word-extend)
Ctrl-Shift-Right (forward-word-extend)

Extends the current selection by count words

Shift-Home (beginning-of-line-extend)
Shift-End (end-of-line-extend)

Extend selection to start/end of line.

Shift-Up (up-line-extend)
Shift-Down (down-line-extend)

Extend selection by moving focus up/down count lines.

Shift-Alt-Home (beginning-of-buffer-extend)
Shift-Alt-End (end-of-buffer-extend)

Extend selection by moving focus position to start/end of the buffer.

Extend mode

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

Ctrl-@

Toggle extend mode.

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

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

Left (backward-char-extend)
Right (forward-char-extend)
Ctrl-Left (Cmd-Left on Mac) (backward-word-extend)
Ctrl-Right (Cmd-Right on Mac) (forward-word-extend)
Up (up-line-extend)
Down (down-line-extend)
Home (beginning-of-line-extend)
End (end-of-line-extend)
Alt-Home (beginning-of-buffer-extend)
Alt-End (end-of-buffer-extend)

Extends the selection, as if Shift was pressed.

History

The “history” is the list of previously entered input lines.

Up (up-line-or-history)
Down (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.

Ctrl-R (backward-search-history)

Enter history-search-mode.

Searching in history

The Ctrl-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.

printable-char

Append (or insert) printable-char to the search string, which may update the selected history item.

Left
Right

Move caret within search string.

Backspace
Delete

Delete character from search string. This may change the selected history item.

Ctrl-R
Ctrl-S

Search for previous/next history item matching the current search string. If the search string is empty, use previous search string. For example Ctrl-R Ctrl-R repeats previous search.

Enter

Exit search mode, accept current item, and send it to the application.

Up
Down

Exit search mode, and move to previous/next history item.

Tab

Exit search mode, accept current item, but continue editing it.

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 password-hide-char setting.) The most recently typed character is displayed briefly (depending on the password-show-char-timeout setting) before it too is replaced by a black circle. On 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.

Changing keybindings

You can override the keymap (map from keystrokes to action) used for input line editing. The 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 Ctrl-A and adds a binding that maps Ctrl-H to the beginning-of-line action.

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