.--~~~~~~~~~~~~~------. /--===============------\ | |```````````````| | | | | | | | >_< | | | | | | | |_______________| | | ::::| '=======================' //-'-'-'-'-'-'-'-'-'-'-\\ //_'_'_'_'_'_'_'_'_'_'_'_\\ [-------------------------] \_________________________/ hterm Developer Guide
See /HACK.md for general information about working with the source control setup.
./bin/mkdist.sh script can be used to generate the
./dist directory, which contains the hterm library source concatenated into
./dist/js/hterm_all.js. This is the file you should copy into your own projects.
See the libapps hacking document for details.
You can re-run the tests by reloading the web page as long as you haven't made changes to
hterm/concat/hterm_resources.concat. If you do change resources, run
./bin/mkdist.sh to re-create them.
./bin/vtscope.py script can be used to step through a pre-recorded VT session on multiple terminals. This is extremely useful for finding and debugging how hterm responds to terminal escape sequences.
The idea is that you record (using the
script utility on your Unix-like system) a terminal session that doesn't seem to be working right. You can then play that recording back through vtscope.py. Vtscope.py has the ability to play back simultaneously into two or more terminals.
When the two terminals start to diverge (say, the cursor moved to 0,0 in xterm, but somewhere else in hterm) you know where the trouble is. You can also say what should have happened based on what xterm did.
You can try it out with some of the pre-recorded test data.
First start vtscope.py...
$ cd libapps/hterm/bin $ ./vtscope.py
Tell vtscope to wait for two clients...
vtscope> accept 2
Then open Secure Shell, and log in to the machine with the hterm source. Start the netcat utility with
nc 127.0.0.1 8383. (If you don't have netcat, get it.)
Next, launch some other terminal (say, xterm) on the same machine. Start netcat again with the same command line.
Now you can load a recorded terminal session in vtscope...
vtscope> open ../test_data/vttest-01.log
And start stepping through the escape sequences...
vtscope> step vtscope> step vtscope> step
You should see the two connected terminals changing in lock-step as they receive the escape sequences.
If you‘re going to hand-edit your test data in emacs, don’t forget to add...
# -*- coding: no-conversion -*-
...as the first line of the file (using vi, of course). Otherwise emacs will likely munge your escape sequences the first time you save.
Check out the comments in
./bin/vtscope.py for some more tricks.
The vast majority of the code here lives under js/.
Keyboard related code
Testing related code
hterm_mock_*.js: Various object mocks to simplify unittests.
*_tests.js: Each module has a corresponding set of unittests. The filename follows the convention of adding
hterm_tests.jscontains the tests for
The hterm.js code will initialize defaults for the various objects. You can override them yourself (such as setting up
hterm.defaultStorage) before you instantiate anything.
hterm.Terminal instance is created and initialization code attached to
onTerminalReady. That callback creates a new
hterm.Terminal.IO object by calling
this.io.push, and then binding its callbacks. Finally the terminal is attached to the DOM via a call to
decorate. The terminal is now ready to accept data.
In order for the terminal itself to handle keyboard shortcuts and such, a call to
installKeyboard is made. This binds all the relevant input callbacks to be captured by hterm. It will handle things like pressing “X” and “Ctrl-X” and sending the resulting data to the IO object.
At this point, all data runs through the IO object created earlier. When the user inputs text (typing on the keyboard, pasting, etc...), the IO callbacks are called such as
onVTKeystroke. The data is then sent to the remote process (via network socket/whatever). When new data is available from the remote process, it is passed to the IO object via the
println functions. The logic to communicate with the remote process is left entirely in the hands of the developer and is outside the scope of hterm.
Drilling down a bit, user input is processed first by
hterm.Keyboard. It looks up the keypress in
hterm.Keyboard.KeyMap (for the default action), and the keybindings in
hterm.Keyboard.Bindings (for user/custom actions). The resolved action is then performed. If it expands into text (as most do), it is sent to the IO object callbacks (
onVTKeystroke). Or it might trigger an action in which case it is called.
When data is printed to the IO object, it is sent to the terminal's VT layer to be interpreted (control sequences and such).
As new lines are generated in the VT layer, they‘re sent to
hterm.Terminal which adds to the active
hterm.Screen, and any excess lines are moved to the terminal’s scrollback. When the user scrolls the output,
hterm.ScrollPort loads rows on the fly from
hterm.Terminal (as a “RowProvider”).