TerminalCapabilities 3 C++ library nosh
TerminalCapabilities terminal capabilities class

    class TerminalCapabilities;

## Description

The `TerminalCapabilities` class decodes the process environment, passed as a `ProcessEnvironment` object, into a suite of terminal capabilities. These capabilities are used by, for example, the `ECMA48Output` and `ECMA48Decode` classes, and their users, to determine how to behave.

### Environment variables

The `TERM` environment variable is its primary source of information. Its value is expected to follow the terminfo 5 and termcap 5 convention (laid out in term 7) of a root name followed by zero or more hyphen-separated feature suffixes (such as, for example, teken-256color). The `TerminalCapabilities` class only cares about the root name, which it takes to denote a family of terminal types (e.g. putty), and whether there are -24bit, -truecolor, -256color, or -square suffixes in the value. Other feature suffixes are ignored.

The class also uses the values of a few other environment variables, mainly to disambiguate the cases where the `TERM` environment variable has been misconfigured as xterm (which it is far too often):

`COLORTERM`

  The existence of this variable signifies extra colour capabilities of some sort. If it has the value truecolor or the value 24bit then the terminal is taken to understand ISO 8613-6/ITU T.416 Direct colour SGR 38 and SGR 48 control sequences. Otherwise it indicates that the terminal understands the additional 8 (de facto) standard colours (from AIXTerm) set by SGR 90–97 and SGR 100–107.

  For the terminal type families linux and teken it signifies that the terminal is a user-space virtual terminal rather than a kernel virtual terminal. User-space virtual terminals support features extra to what KVTs support; including DEC Locator reports, extended DECSUSR, the HPA and CTC control sequences, the full suite of C1 control characters and their 7-bit aliases, DECFNK reports that contain modifier information, and the invisible attribute.

`XTERM_VERSION`

  Set by the XTerm program in the child processes that it spawns for terminal sessions, this indicates the version number of XTerm. It is used to attempt to determine when a user or a programmer has incorrectly used xterm when the terminal emulator program is not in fact XTerm, and disable the use of some features that genuine XTerm has that other programs incorrectly ascribed the xterm terminal type have not. These include extended DECSCUSR, DEC Locator, XTerm-style ECMA-48-conformant mouse reports, the HPA and CTC control sequences, and the NEL control character.

`VTE_VERSION`

  Set by the VTE library in the child processes that terminal emulators using that library spawn for terminal sessions, this indicates the version number of VTE. From the version number of VTE it can be determined whether it is possible to use DECSCUSR and ISO 8613-6/ITU T.416 SGR sequences using sub-parameters.

`KONSOLE_PROFILE_NAME`

  Set by the Konsole program in the child processes that it spawns for terminal sessions, this indicates the Konsole profile in use. Its value is ignored. Its existence indicates that it is possible to use XTerm-style ECMA-48-conformant mouse reports.

`TERM_PROGRAM`

  Set by the iTerm.app program in the child processes that it spawns for terminal sessions, this indicates the name of the terminal program (a convention that only that terminal emulator program actually adheres to). If it has the value iTerm.app, then if the terminal type is xterm it is considered to be iterm.

`ROXTERM_ID`

  Set by the ROXTerm program in the child processes that it spawns for terminal sessions, this is an internal identifier of the terminal emulator. Its value is ignored. Its existence indicates that it is possible to use ISO 8613-6/ITU T.416 Direct colour SGR control sequences and DECSCUSR.

### Capabilities

Terminals are expected to support a popular subset of ECMA-48 and the private control sequences of DEC VT 52x terminals. The capabilities determine variations from this. Some standard control sequences are unimplemented, incompletely implemented, or cause the wrong thing in some terminal emulators. For example: The ECMA control sequence decoders in the Interix terminal emulator and in Konsole do not simply discard CSI control sequences that they do not implement, but instead print parts of them as character output.

#### Deficiencies and bugs

`lacks_pending_wrap`

  The console-terminal-emulator 1 manual describes a mechanism where the automatic line wrap at the right margin is held pending until the next printing character is processed, in order to allow full-screen TUI programs to write right up to the lower-right-hand corner. This mechanism is formally documented almost nowhere else, but is implemented in almost all terminal types. The few exceptions are the dumb, cygwin, and interix terminal type families.

  Writing in the lower-right-hand corner is not the only situation where applications must be aware of the effect of pending right margin wrap. In the pending state, the terminal cursor is in a different position to where an application would have expected it to wrap to, and relative cursor motions, including BackSpace and Next Line, need to account for this.

`lacks_NEL`

  The dumb and interix terminal type families, and erroneously labelled xterm family terminals that are not genuine XTerm, do not implement the ECMA-48 standard Next Line control character. Applications must fall back to Carriage Return followed by Line Feed.

`lacks_RI`

  The dumb and interix terminal type families do not implement the ECMA-48 standard Reverse Index control character.

`lacks_IND`

  The dumb and interix terminal type families do not implement the ECMA-48 standard Index control character.

`lacks_CTC`

  Only genuine XTerm and console-terminal-emulator 1 are capable of the Cursor Tabulation Control control sequence. For others, applications have to fall back on a combination of the TBC control sequence and the HTS control charcter.

`lacks_HPA`

  Only genuine XTerm and console-terminal-emulator 1 are capable of the Horizontal Position Absolute control sequence. For others, applications have to fall back on the CHA control sequence.

`lacks_REP`

  Only genuine XTerm, PuTTY, Microsoft Terminal, and console-terminal-emulator 1 are capable of the Repeat control sequence. For others, applications have to fall back on explicitly repeating the characters.

`lacks_invisible`

  The dumb, konsole, linux, and teken terminal type families do not implement the ECMA-48 standard invisible attribute, with the exception to the latter twain that console-terminal-emulator 1 implements it. konsole actively complains about its use.

`lacks_strikethrough`

  The dumb and konsole terminal type families do not implement the ECMA-48 standard strikethrough attribute, and the latter actively complains about its use.

`lacks_reverse_off`

  The dumb and interix terminal type families do not implement the ECMA-48 standard reverse video off SGR control sequence.

`faulty_reverse_video`

  The rxvt terminal type family does not implement reverse video correctly. If the foreground and background colours are the same, instead of swapping foreground and background (as a real DEC VT does) it switches to the default colour.

`faulty_inverse_erase`

  There is wide disagreement on what the ED and EL control sequences do, when the DECECM private mode is off; with respect to the DECSCNM private mode. §2.9.7 of the VT520/VT525 Video Terminal Programmer Information EK-VT520-RM states that when the DECECM private mode is off the background color used when text is erased or new text is scrolled on to the screen is the current text background color. Everyone, that supports the DECECM private mode in the first place, agrees with this and always erases to the current background and foreground colours. The DEC documentation is silent on the point, but everyone also agrees that the reverse video attribute, and all other text attributes, are always off, thereby choosing (per ECMA-48:1991 §6.1.1) that an erased character glyph be indistinguishable from SPC.

  However:

  - For console-terminal-emulator 1, realizers like console-fb-realizer 1 then invert the sense of the reverse video attribute when the DECSCNM private mode is on ("light background"). As do the putty and konsole terminal type families.

  - The xterm, rxvt, and ms-terminal terminal type families then invert the sense of the reverse video attribute when the DECSCNM private mode is off ("dark background").

`faulty_SP_REP`

  Although Microsoft Terminal supports the REP control sequence, it has a bug if it is applied to Unicode characters in Supplementary Planes.

`linux_editing_keypad`

  The linux terminal type family, because of a long-standing bug, swaps the DECFNK codes for the Home and End keys on the editing keypad with those for the Find and Select keys.

`interix_function_keys`

  The interix terminal type family reports function keys as Start of Selected Area followed by a character. To decode function keys from an Interix terminal emulator an ECMA decoder has to (mis)treat the SSA character as another single-character shift, like SS2 and SS3. It is effectively "Single Shift level A".

`teken_function_keys`

  The pcvtXX, wsvt25, netbsd6, cons, and teken terminal type families generate the function key sequences that were generated by the SCO Unix Multiscreen virtual terminal, but not for unmodified F1 to F4, which they treat as DEC VT PF1 to PF4 instead. (In the case of the teken family, this is part of an admixture of DECFNK, SS3, and SCOFNK control sequences.) These SCO function key control sequences overlap with the control sequences for the cursor keypad and with the function key sequences generated by the rxvt terminal type family. Applications must only decode them as function keys when a terminal type that generates these sequences is in effect.

`sco_function_keys`

  The SCO Unix Multiscreen virtual terminal generates control sequences for function keys. These SCOFNK sequences overlap with the control sequences for the cursor keypad and with the function key sequences generated by the rxvt terminal type family. (SCO Unix Multiscreen did no translation of F1 to F5 into DEC VT PF1 to PF5, and so never generated SS3 sequences for any function keys.) Applications must only decode them as function keys when a terminal type that generates these sequences is in effect.

`rxvt_function_keys`

  The rxvt terminal type family generates erroneous ECMA control sequences for function keys, where $ is a final character instead of an intermediate character as the standard says. Applications must tweak their ECMA control sequence decoders to (mis)handle this character.

#### Augmentations

`use_DECPrivateMode`

  The interix terminal type family does not correctly handle CSI sequences containing private characters, emitting parts of them as printable output. In particular, this means that it does not implement any DEC Private modes at all.

`use_SCOPrivateMode`

  The interix terminal type family does not correctly handle CSI sequences containing private characters, emitting parts of them as printable output.

`use_DECLocator`

  Only genuine XTerm and console-terminal-emulator 1 understand DECELR and DECSLE. (Other terminal types actually process the control sequences incorrectly.)

`use_DECSTR`

  Only genuine XTerm and console-terminal-emulator 1 understand DECSTR.

`use_DECST8C`

  Only console-terminal-emulator 1 understands DECST8C. (So too does a Windows NT utility named ansicon, outwith the worlds of Linux and the BSDs.)

`use_DECSNLS`

  Only genuine XTerm and console-terminal-emulator 1 are capable of the DEC Set Number of Lines control sequence. For others, applications have to fall back on the DECSLPP control sequence and deal with the fact that DECSLPP 0 to DECSLPP 24 may be DTTerm extensions rather than number of lines.

`use_DECSCPP`

  ROXTerm and the VTE library actively wrongly decode the DEC Set Columns Per Page control sequence, treating parts of it as printable output. For those, applications have to fall back on the DECSLPP 8 control sequence if they can.

`use_DECSLRM`

  ROXTerm and the VTE library actively wrongly decode the DEC Set Left and Right Margins control sequence, treating parts of it as printable output.

`use_DECNKM`

  PuTTY is known to not support DECNKM, and one has to fall back to DECKPAM and DECKPNM.

`has_DECECM`

  Only console-terminal-emulator 1 understands DECECM. For other terminal types, the erase colour mode is fixed.

`initial_DECECM`

  For terminal types where `has_DECECM` is true, this is just the initial DECECM state. For other terminal types, it is the single fixed DECECM state.

`has_DTTerm_DECSLPP_extensions`

  The dtterm, xterm, teraterm, and rxvt terminal type families, Konsole, and VTE library terminal emulators are all capable of extensions pioneered by DTTerm that repurpose DECSLPP 0 to DECSLPP 24. DECSLPP 8 in particular sets both height and width in one control sequence. For those terminal types, DECSLPP 8 or DECSNLS (if supported) are the only ways to set heights less than 25. For other terminal types, DECSLPP can set all heights and widths have to be set with DECSCPP (if supported).

`has_XTerm1006Mouse`

  The dumb terminal type family, the rxvt terminal type family, and erroneously labelled xterm family terminals that are not XTerm, not the VTE library, and not Konsole, are not capable of generating XTerm-style ECMA-48-conformant mouse reports. (Other forms of XTerm-style mouse report are not ECMA control sequences, are problematic to decode, and have been deprecated in favour of the ECMA-48-conformant form since the 2000s.)

`has_square_mode`

  Only console-terminal-emulator 1 has a mode where all characters are full-width (i.e. "square"). Others display some characters half-width, and applications have to account for different character widths. This is also set true where the value of the `TERM` environment variable contains the -square feature suffix.

`reset_sets_tabs`

  The linux, teken, and rxvt terminal type families, and console-terminal-emulator 1, effectively perform the action of DECST8C at terminal hard/soft reset, making explicitly setting regular tabs at 8 column intervals superfluous. (Real DEC VTs do not do this, and the initial state is for all tabstops to be cleared.)

`has_extended_underline`

  The putty and gnome/vte terminal type families, and console-terminal-emulator 1 recognize sub-parameters to SGR 4, specifying various types of underline.

#### Variable abilities

`colour_level`

  There are four different mechanisms for specifying colour: the original 8 SGR foreground and background colour sequences standardized by ECMA-48, an additional 8 SGR sequences (originally from AIXTerm) for a total of 16 (de facto and de jure) standard colours, ISO 8613-6/ITU T.416 Indexed colour (which conventionally has the 16 standard colours as the first 16 entries in the colour palette), and ISO 8613-6/ITU T.416 Direct RGB colour. Compounding this is that there are, because of a historical misreporting of ISO 8613-6/ITU T.416, two forms for the two ISO 8613-6/ITU T.416 mechanisms.

  - The dumb terminal type family is taken to not have any colour support at all.

  - Interix is taken to only support the 8 ECMA-48 colours.

  - Where the value of the `TERM` environment variable contains the -24bit or -truecolor feature suffixes, the terminal is taken to support ISO 8613-6/ITU T.416 Direct colour (with the historic error). Several terminal types are taken to always support ISO 8613-6/ITU T.416 Direct colour even without such a feature suffix. The VTE Library, iTerm, and (if fake 24-bit colour is permitted) genuine XTerm are taken to always support it, without the historic error. User-space virtual terminals, Konsole, Simple Terminal, GNOME/MATE/XFCE Terminal, RoXTerm, and (if fake 24-bit colour is permitted) the Linux kernel virtual terminal and rxvt are taken to always support it, but with the historic error.

  - Some terminal types are taken to support ISO 8613-6/ITU T.416 Indexed colour, but not Direct colour. PuTTY, rxvt, the Linux kernel virtual terminal, Teken, tmux, and anything falsely claiming to be XTerm are taken to support it, with the historic error.

  - Otherwise, terminals are taken to only support the 8 ECMA-48 colours.

  - Where the `COLORTERM` environment variable exists and its value is the string "truecolor" or "24bit", the terminal is taken to support ISO 8613-6/ITU T.416 Direct colour, with the historic error.

  - Where the `COLORTERM` environment variable exists, the terminal is taken to support at least the two mechanisms for the 16 standard colours.

  - Where either the `COLORTERM` or the `TERM` environment variable value contains the string "256", the terminal is taken to support at least ISO 8613-6/ITU T.416 Indexed colour (with the historic error). The former comes from a convention of specifying the terminal type without the -256color feature suffix in the `TERM` environment variable and the "real" terminal type in the `COLORTERM` environment variable. This was to cope with databases to which the -256color name variants had not yet spread, back when they were a new idea, and is largely obsolete nowadays. It is the latter that should nowadays be used.

  - The `COLORTERM` environment variable is largely obsolete nowadays as a mechanism for specifying ISO 8613-6/ITU T.416 Indexed colour support, and most terminal type families are simply assumed to support it. It is nowadays pretty much base level functionality for GUI terminal emulators, with most also supporting Direct colour (even without the historic error in the cases of recent versions of the VTE library and iTerm). Thus even not employing the -256color suffix in the value of the `TERM` environment variable implies Indexed colour support.

  - Base level functionality for the linux terminal type family is both Indexed and Direct colour support, since Linux version 4.8. Although Linux does not actually implement 24-bit colour, it instead faking it by mapping RGB to its Indexed color palette (oftentimes not particularly well).

  - Base level functionality for the teken terminal type family is Indexed colour support; unless it is console-terminal-emulator 1, which supports Direct colour as well.

  - Base level functionality for the interix, pcvt, and cons terminal type families is only the original standard 8 colours being supported.

`cursor_shape_command`

  Emulating DEC VTs being the de facto standard of modern (character mode) terminal emulators, the de facto standard way to alter the cursor shape has been the DECSCUSR control sequence since the time of the DEC VT510/VT520/VT525. Being independently developed at around the same time, the Linux kernel's built-in terminal emulator has a quite different and idiosyncratic control sequence (LINUXSCUSR). XTerm extended the DECSCUSR control sequence with more possible cursor shapes.

  - The linux terminal type family is taken to understand only the LINUXSCUSR control sequence, except for console-terminal-emulator 1.

  - The linux and teken terminal type families when they are console-terminal-emulator 1, genuine XTerm, and the rxvt and teraterm terminal type families are taken to understand extended DECSCUSR.

  - The putty, tmux, and screen terminal type families, ROXTerm, and newer versions of the VTE library are taken to understand standard DECSCUSR.

  Unfortunately, DECSCUSR is one of the control sequences that several terminals not only do not support but actively decode wrongly, treating parts of it as printable output. So applications cannot just emit it and leave it to be ignored where not implemented.

## See also

`TERM` 7

  the `TERM` and other environment variables that signify terminal type

## Author

Documentation by

Jonathan de Boyne Pollard