|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
SGR (Select Graphical Representation) escape sequences are CSI escape
sequences ending in the final byte 'm'. They are described in the
ECMA-48 standard, but we also support a compatible extension which is
commonly used nowadays, namely extended colors (256 colors and true 24
bit colors) which are specified in ITU-T Rec. T.416.
SGR sequences are probably the most commonly used escape sequences and
a lot of CLI tools now feel much more familiar in saneterm. The
implemented SGR sequences for example allow:
* to change the current text's foreground and background color in the
three commonly used color modes 8/16 colors, 256 colors and 24 bit
true color.
* to change the current text's appearance: italic, bold, underline,
strikethrough and more are supported.
The current implementation uses a new TextStyle object which is added
to pty.Parser's state to track the inherintly stateful changes in text
appearance described by SGR escape sequences.
When the TextStyle object changes, a TEXT_STYLE event is emitted and
the a Gtk.TextTag is created from the TextStyle and registered in the
widget's TextBuffer.
For the most part this is quite straightforward, just two areas
deserve more attention:
* The extended colors (256 colors and 24 bit true color) are a bit
more complicated to parse which is handled by parse_extended_color().
This function doesn't fully support everything the recommendation
mandates. Especially true color will need more real world testing,
e. g. lolcat(1) a heavy user of true color doesn't even emit true
color escape sequences conforming to the standard.
* Color handling in general contributes to most of the complexity:
* There are three ways to specify colors via SGR escape sequences
we support which all need to be converted to Gdk.RGBA objects.
This is handled by saneterm.color.Color. True color is trivial,
for 256 colors we implement the conversion instead of generating a
lookup table (like XTerm does). For the 8 basic colors in their
normal and bright variants, we use hard coded list of X11 color
names for now. This probably should become configurable in the
future.
* Many implementation use the intensity escape sequences to
influence color vibrance: SGR 2 is interpreted as dim wrt
to colors and SGR 1 not only makes the text bold but also
chooses brighter colors. So far we interpret SGR 1, 2 and 22
only in terms of font weight. EMCA-48 permits both. Changing the
color intensity as well increases complexity and has little
benefit, so this should probably be kept this way.
* Instead we implement the 90-97 and 100-107 non-standard bright
color SGR escape sequences.
The current implementation is, however, not without issues:
* Tracking the text style state in the parser is probably a layer
violation — pty.Parser should instead translate the escape sequences
into events and the state tracking done in saneterm.terminal.
* Performance is poor if a lot of escape sequences are in the input.
This is due to two reasons: a) insert_data is called with little
chunks of text which decreases performance and b) a lot of anonymous
Gtk TextTags are created which hurts performance a lot. We should
investigate a way to deduplicate the created TextTags (by using
names?) and possibly decouple the application of tags from the
insertion of text itself.
|