terminal
terminal copied to clipboard
Add support for Kitty/VTE extended underlines (4:x) [SGR]
depends on #4321
Re underline:
The Kitty terminal emulator came up with the awesome idea of supporting curly and colored underlines, with the obvious intent of supporting user-friendly spell checking in terminal-based text editors. The choice of the escape sequence was coordinated between Kitty and VTE. The feature was then implemented so far at least in Kitty, VTE, Mintty, Hterm, probably a few more as well, and feature requests are filed to even more, including iTerm2, Konsole, xterm.js. Some have even added dotted and dashed underlines, too.
It would be lovely if you also considered these extensions.
(A bit of technical info: With truecolor support I assume you already have like 25 bits for the foreground and background color each (in order to be able to store the 256 legacy palette values as well as "default", in addition to 24 bit RGB). At least this is how we do in VTE. And we didn't want to waste another 25 bits for this rarely used feature. So we approximate truecolor underline colors to 4+5+4 bits of R, G, B, respectively. This way all the color information of a charcell fits in an int64.) from egmontkob in #2916
For what it's worth I've extended this a little, and my programs support the following subparameters:
- single
- double
- (short wavelength) curly
- (closely spaced) dotted (8 dots per cell)
- (short) dashed (4 eighth-width dashes per cell)
- long dashed (2 quarter-width dashes per cell)
- extra long dashed (1 half-width dash per cell)
- medium spaced dotted (4 dots per cell)
- widely spaced dotted (2 dots per cell)
- long wavelength curly
from @jdebp in #2916
I added this to xterm.js last week, currently the sequences get ignored by conpty, we need them to pass through. https://github.com/xtermjs/xterm.js/pull/3921
I suspect even the premptive flushing of #13462 wouldn't fix this for conpty consumers either. We'd need to actually specifically note this category of sequence and then return false (or just, handle ourselves). Though, handling ourselves might be fairly engineering expensive (parsing, storing, re-rendering to conpty, rendering in dx/atlas), so maybe it does make sense to include the no-op passthrough for a smaller conpty package update.
FYI, passthrough for sequences like this is not workable, even with flushing. Testing with a simple printf may briefly give the impression that it's working, but any reasonably complicated application is bound to fail eventually.
To understand why, have a look at the debug tab while scrolling through a file in vim. Notice how it appears to redraw the entire screen every time you scroll down the page? That's not vim doing the redrawing - that's conpty. Vim is just using something like a linefeed combined with scroll margins.
So what happens when vim decides to output some wavy underlines? They may appear to work the first time the screen is rendered, but as soon as you scroll, it'll be conpty that does the redrawing. And since conpty knows nothing of those attributes, it's just going to obliterate them.
Bottom line: Unless conpty stores and forwards the extended attributes, they're not going to work.
Yep, these need to be stored in conpty's model, as opposed to OSC 133 and the like which just need pass-through and don't need to be emitted again on redraw
Technically OSC 133 can break in a similar manner - it's just less likely in typical usage. The only way we can guarantee perfect fidelity with passthrough is if we're doing it for everything, with no conpty buffering at all (i.e. the passthrough mode of #1173). So our choices are either buffer everything and then rerender to conpty, or buffer nothing and pass everything through directly. Mixing the two is always going to be flaky.
Any status on this one?
Nope, but you can "Subscribe" for updates by clicking the "Subscribe" button on the right side of the screen! That will also help avoid sending e-mail to everyone who already has subscribed :smile: