JetBrains / jediterm

Pure Java Terminal Emulator. Works with SSH and PTY.
GNU Lesser General Public License v3.0
675 stars 171 forks source link

Correct handling of function/cursor key modifiers #245

Closed shoaniki closed 1 year ago

shoaniki commented 2 years ago

tl;dr: Jediterm's handling of modifiers with function/cursor keys appears to be incorrect, and this PR changes it to match the behavior of other xterm-compatible terminal emulators.

Some examples of how jediterm 2.69 differs from xterm when modifier keys are used:

input in xterm +shift in jediterm +shift
left ^[[D ^[[1;2D ^[[D ^[[2D[^1]
left (DECCKM) ^[OD ^[[1;2D ^[OD ^[O2D
f1 ^[OP ^[[1;2P ^[OP ^[OP
f5 ^[[15~ ^[[15;2~ ^[[15~ ^[[15~
f12 ^[[24~ ^[[24;2~ ^[[24~^H ^[[24~^H
del ^[[3~ ^[[3;2~ ^[[3~ ^[[3~
tab ^I ^[[Z ^I ^I

[^1]: The patch for IDEA-283023 fixed some specific examples of this case by hardcoding a few special cases, but did not address the root cause. This PR leaves the special cases in place, as they aren't causing any problems.

The cause (for everything other than tab) is found in TerminalKeyEncoder's getCodeWithModifiers method. This has a comment "Refer to section PC-Style Function Keys in [http://invisible-island.net/xterm/ctlseqs/ctlseqs.html]()", which is indeed the documentation of how this should all work. Comparing it to the jediterm code, there are several problems:

  1. The method is only called at all for cursor keys, home, and end -- it should also be called for function keys etc.
  2. The method should be replacing SS3 with CSI when inserting modifiers. SS3 only modifies a single character, so SS3 2D means SS3 2 (which is not defined) followed by a literal D.
  3. Since the modifier is encoded as an extra parameter to the control sequence, it is necessary to provide explicit values for any previous parameters. e.g. CSI D needs to become CSI 1;<x>D, because CSI <x>D means "move left \ characters".
  4. jediterm adds an ESC to F11 and a BS to F12 that I believe should not be there.

This PR fixes those four issues, so that jediterm emits the same code sequences as xterm for these keypresses.

segrey commented 1 year ago

@shoaniki Thank you!