Like every terminal out there, hterm supports a number of standard (and perhaps not so standard) keyboard shortcuts. All of them can be overridden via user settings. This doc should cover the logic behind each of the shortcuts and the syntax for rebinding keys.
There are two ways to bind keys: for users of programs that integrate hterm (e.g. Secure Shell users), they‘ll set the keybindings
preference. For developers integrating hterm into their own program, they’ll use the hterm.Keyboard.Bindings
JS API. We'll focus on the keybindings
preference as the syntax is the same between them with one exception: developers can bind arbitrary JS code as callbacks.
Keep in mind that some browsers and operating systems do not allow certain key sequences to be rebound depending on the environment. For example, Chrome will not let you rebind Ctrl+N when running in a tab, but will if you're running fullscreen or in a dedicated window. Similarly, Windows never lets you rebind Ctrl+Alt+Delete.
The first part of a keyboard binding is declaring the key sequence to bind. The syntax is quite simple: a key sequence is zero or more key modifiers followed by a key code. Key codes can be a number or an identifier. Modifiers and key codes should be joined by pluses (+) or dashes (-). An asterisk can be used to indicate that the unspecified modifiers are optional.
Capitalization of keys is not important. e.g. Ctrl
, CTRL
, ctrl
, and cTRl
are all equivalent. This applies to modifiers and key codes.
Here are the possible modifiers. We do not currently differentiate between left & right keys, so shift
matches both left shift and right shift. Order does not matter, so Ctrl+Shift+A
is equiavlent to Shift+Ctrl+A
.
Shift
: The shift key.Ctrl
: the control key.Alt
: The alt key (the ⌥ Option key on Apple keyboards).Meta
: The meta key (the ⌘ Command key on Apple keyboards and the ⊞ Windows key on Windows keyboards).*
: The asterisk can be used to match unspecified modifiers.If the key is not listed here, then it cannot be used as a modifier. e.g. You cannot bind Escape+K
or Capslock+D
to something else.
The key codes should be the name of the key, or the keyCode value for that key (either decimal or hexadecimal). So A
will match the “A” key, as will 65
and 0x41
.
The W3C has a Keyboard Event Viewer test page for looking up the keyCode value quickly -- just press the keyboard keys to see what the browser generates.
For the full list of possible key names, see hterm.Parser.identifiers.keyCodes
in hterm_parser_identifiers.js.
Some examples will probably help.
A
: Matches only an unmodified “A” character.65
: Same as above.0x41
: Same as above.Ctrl+A
: Matches only Ctrl+A.Ctrl-A
: Same as above.Ctrl+65
: Same as above.Ctrl+0x41
: Same as above.Ctrl+Shift+A
: Matches only Ctrl+Shift+A.Ctrl+*+A
: Matches Ctrl+A, as well as any other key sequence that includes at least the Ctrl and A keys.For keys that don't have symbolic names, you can match the keyCode only.
219
: Matches only an unmodified “[”.0xdb
: Same as above.Alt+219
: Matches only Alt+[.The second part of a keyboard binding is telling the system what to actually do. It can either be a string (of arbitrary length), or a predefined action. For developers programming the hterm JS API, it can also be a function.
If you want to specify a string, then pass in a quoted string. The embedded quotes are important! e.g. use "'foo'"
if you want to emit the string foo
.
Common escape sequences are supported inside of double quotes. Capitalization here is significant, so you must write \t
and not \T
.
\'
: A single quote.\"
: A double quote.\a
: A bell/alert (0x07 in ASCII).\b
: The backspace key (0x08 in ASCII).\e
: The escape key (0x1b in ASCII).\f
: A form feed (0x0c in ASCII).\n
: A new line (0x0a in ASCII).\r
: A carriage return (0x0d in ASCII).\t
: A tab (0x09 in ASCII).\v
: A vertical tab (0x0b in ASCII).\x##
: A 8-bit hexadecimal sequence. e.g. \x1b
is the same as \e
.\u####
: A 16-bit Unicode codepoint. e.g. \u001b
is the same as \e
.Some basic actions are available too. Capitalization here is significant, so you must write CANCEL
and not cancel
or Cancel
.
Note: The list of actions here is a bit thin. If you want to do something else, please file a feature request with us.
CANCEL
: Prevent the browser, operating system, and hterm from doing anything. Note: Browser & OS restrictions might not let you rebind.DEFAULT
: Have hterm handle the standard key code for this key sequence.PASS
: Pass the key sequence along to the browser or OS, and have hterm ignore it.scrollLineUp
: Scroll up one line in the terminal buffer.scrollLineDown
: Scroll down one line in the terminal buffer.scrollPageUp
: Scroll up one page in the terminal buffer.scrollPageDown
: Scroll down one page in the terminal buffer.scrollToTop
: Scroll to the top of the terminal buffer.scrollToBottom
: Scroll to the bottom of the terminal buffer.copyCurrentSelection
: Copy the current selection to the clipboard.pasteClipboard
: Paste the current clipboard.selectAll
: Select all lines in the terminal buffer.clearScreen
: Clear the screen and move the cursor to (0,0).clearScrollback
: Clear the scrollback buffer.clearTerminal
: Clear the terminal and scrollback, and move the cursor to (0,0).fullReset
: Perform a full terminal reset (like running reset
).softReset
: Perform a soft terminal reset (mostly color/etc... attributes).Since all preferences are stored as strings, the keybindings
object is stored as a JSON string. At runtime, it is converted back to a JSON object. Care must be taken when trying to define your key bindings.
Things to remember:
\a
and \e
, while JSON supports \u{xxxx}
.#
are errors.[1,2]
is valid while [1,2,]
is invalid.Specifically on the topic of quoting:
"foo"
."'foo'"
will bind foo
."\"foo'bar\""
to bind foo'bar
, and "\"foo\\\"b'r\""
to bind foo"b'r
.In the keybindings below (many of which are not terribly useful):
hi
.Ctrl-x o
sequence, which is alternative other-window
key for Emacs when ctrl-tab does not work.{ "Ctrl+A": "'hi'", "Ctrl+N": "PASS", "Ctrl+X": "CANCEL", "Shift+PGUP": "scrollPageUp", "X": "DEFAULT", "Ctrl+Alt+M": "'\u0008'", "Ctrl+*+M": "DEFAULT", "Ctrl+Tab": "'\u0018o'" }
Keybindings OS Defaults turns on an OS-dependent set of key bindings. These bindings can be overridden by any specified in keybindings
. The set of OS-dependent key bindings can be seen in hterm_keyboard_bindings.js in field hterm.Keyboard.Bindings.OsDefaults
.
The default set of key bindings can be seen in hterm_keyboard_keymap.js. Look at the hterm.Keyboard.KeyMap.prototype.reset
function.
If you're a developer and want to look into the source code, then the main files to check out:
hterm.Parser
code responsible for parsing key bindings (sequences and actions).hterm.Parser.identifiers
constants used by the parser and key bindings logic.hterm.Keyboard
code which handles all the runtime logic for processing keyboard events.hterm.Keyboard.Bindings
code which provides adding and removing key bindings at runtime.hterm.Keyboard.KeyMap
code which registers the default keyboard bindings.hterm.Keyboard.KeyPattern
code for defining a runtime key binding object.