Predictive echo

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 <span> that contains predicted input: an optional text node, the _caretNode, and an optional text node. The node has 3 additional properties: textBefore, textAfter, and pendingEcho. When output arrives from the server, the function _doDeferredDeletion is called, which replaces the span by the textBefore and textAfter, with the _caretNode in between; this is “real” (confirmed) output, before processing the new output. We also _doDeferredDeletion when unable to do echo predication.

Handling keyboard input is as follows: First, if _deferredForDeletion is null, we set it to a fresh span that wraps the _caretNode. As needed, any text node immediately before or after can be moved into the _deferredForDeletion span, also setting textBefore and textAfter. Then, for a printing character, we insert it before the caret, and append it to pendingEcho. For left or right arrow, delete, or backspace, if possible we adjust the _deferredForDeletion span appropriately, and add a special code to pendingEcho. If not possible, we _doDeferredDeletion, which we also do for other keys.

Calling _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 _deferredForDeletion span, whose pendingEcho string is a tail of the previous value. (We only do this if there are no changes to any other (logical) line.)