microsoft / terminal

The new Windows Terminal and the original Windows console host, all in the same place!

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support fonts and fonts attributes through inline escape sequences like mintty and vte52

csdvrx opened this issue · comments

Escape sequences to set fonts and their attributes are ignored, instead they are displayed as raw

Terminals support escape sequences to alter the fonts. Windows Terminal at the moment only support basic colors and reverse colors

This is linked to #109 #2916 #5461 #5462 #6703 and #6205 as currently most of the VTE52 font attributes are not supported.

Full support can be tested with:
https://github.com/csdvrx/sixel-testsuite/ansi-vte52.sh

Expected output:
https://github.com/csdvrx/sixel-testsuite/blob/master/test-passed-part1.jpg

It would be desirable to support all mintty font attributes, including support for alternative fonts, using ECMA-48 SGR codes. This would be linked to #1163 for usecases like CJK.

Mintty patch implementing this is on mintty/mintty@1250829

This allows sequences like:

echo "\e[12mVery thin font\e[0m"

image

I'm personally not in favour of many of these attribute, without some evidence of their being widely used, because otherwise we're just wasting buffer space on a feature that most people will never need.

For example, last I checked alternate fonts were supported by nobody other than Mintty, so it seems highly unlikely that there are many apps making use of that functionality. It also never seemed like a particularly practical feature to me. In what situation would an app choose to set a particular font number without knowing what that font was? Your "Very thin font" could just as easily be a very bold font, or a gothic font, or even just wingdings. An app has no way of knowing.

ECMA-48 defines FONT SELECTION (FNT), for selecting which ten fonts can be referenced with SELECT GRAPHIC RENDITION (SGR). However, it seems inconvenient:

  • The Ps2 parameter is a font number "according to a register which is to be established." I wonder if this register exists at all.
  • Instead of using the Ps2 parameter, it would be possible to embed a font name in a private parameter string (ECMA-48 §5.4.1). However, the font name would have to be awkwardly encoded using only bytes 0x30 to 0x3F. The private parameter string would also have to cover the Ps1 parameter of FNT, so a terminal that does not support the private parameter string would not even know whether the control sequence is intended to affect the primary font or one of the alternative fonts.

For those reasons, I think OSC or DCS is more suitable for specifying a font name than FNT. Xterm uses OSC 5 0 ; Pt ST but does not support alternative fonts in SGR. I imagine OSC 5 0 : Ps ; Pt ST might be a reasonable encoding, but I don't know if some terminals assign a different meaning to this encoding or define a different way to set alternative fonts.

ITU-T Rec. T.416 §8.2 (Font selection) uses SGR but not FNT.

OSC 50 is problematic, because it's one of those sequences that has a bunch of different interpretations. Other than the XTerm font selection, iTerm2 uses it for clipboard operations, and Konsole uses it for setting profile options (one of those options is the font, actually, but obviously not in a way that's compatible with the XTerm usage).

they are displayed as raw

What do you mean? As far as I can tell, Windows Terminal removes unsupported SGR control sequences from the output.

Full support can be tested with:
https://github.com/csdvrx/sixel-testsuite/ansi-vte52.sh

Dead link. https://github.com/csdvrx/sixel-testsuite/blob/31596c68ff960fd45457a6f0d8d86fa5614bc502/ansi-vte52.sh works better.

I was not interested in this feature, until now.

GitHub released the monaspace font family. They proposes to change the font based on semantics, such as having a different font for completion suggestions (GitHub Copilot, …), and they include fonts which plays nicely with each-others. This idea would also be useful in Windows Terminal, for example to have a different font for shell commands completion suggestions, but would need support for alternative fonts using ECMA-48 SGR codes (edit: or using other codes ?).

I was not interested in this feature, until now. GitHub released the monaspace font family.

Yeah, I had the same thought when I first read about that monaspace font. But I still come back to my initial objection above: I don't see any applications using something like this without a way to control (or at least query) the font/style associated with each SGR number.

It's also worth noting that DEC used SGR 10, 11, and 12 for something more akin to character set selection (see VT510 SGR), and I think there are a few modern terminals that follow that behavior too. So if we do ever decide to support SGR font selection, it may be best to limit it to SGR 13 and above.

Yeah, I had the same thought when I first read about that monaspace font. But I still come back to my initial objection above: I don't see any applications using something like this without a way to control (or at least query) the font/style associated with each SGR number.

I find syntax coloring to be very distracting, so I make heavy use of styles and fonts and I would really appreciate if WT terminal could support this feature:

  • even if only 10 fonts could be selected (though a mapping from within WT)
  • even if the applications couldn't introspect which is which, and could only knows the font number
  • even if I had to do some blind mapping by trial and error

This is because there is a very simple workaround: after the manual mapping process has been done within WT (ex: Font 1 is XX, Font 2 is YY...), then editors like vim (or shells) could show the "current result" to the user, to check if it matches the user expectations.

If it doesn't, the editors could offer suggestions to redo the mapping. like a guide process.

As for actual uses within the editor 2 examples:

  • for vim: 'select as font 1 the font that will be considered the thinnest as it will be used for inline C++ style code comments starting with //',
  • for eza: 'select as font 2 the font which will contain unicodes providing icons used for file types'

Only Microsoft can decide how features should be prioritized, and this is just a simple example with vim and eza, but I can see many text applications benefitting from having different usable fonts in the terminal (IRC: different font per channel or friend group, etc)

The user could also directly benefit from being able to introduce esc sequences for software with configuration files.

OSC 50 is problematic, because it's one of those sequences that has a bunch of different interpretations. Other than the XTerm font selection, iTerm2 uses it for clipboard operations, and Konsole uses it for setting profile options (one of those options is the font, actually, but obviously not in a way that's compatible with the XTerm usage).

There might be some different syntax for specifying fonts, but basic usage of OSC 50 for fonts has been defined in the ECMA-48 standard since 1991. Even if the syntax is a little different, it is far better for application developers (me) to be able to support slight changes than major ones.

Additionally, the OSC 50 ; ? query allows applications to pull the current font exactly as if it was defined, which gives a huge leg up for parsing the syntax and being able to return the terminal to a previous state.

Incidentally, iTerm has long since changed their clipboard control code to 1337.

basic usage of OSC 50 for fonts has been defined in the ECMA-48 standard since 1991

Where exactly? 8.3.89 OSC - OPERATING SYSTEM COMMAND does not mention fonts. I don't see anything relevant when searching for 50 or 03/05 03/00, either.

basic usage of OSC 50 for fonts has been defined in the ECMA-48 standard since 1991

Where exactly? 8.3.89 OSC - OPERATING SYSTEM COMMAND does not mention fonts. I don't see anything relevant when searching for 50 or 03/05 03/00, either.

The FNT command is for fonts. And in the XTerm documentation it is under 5 0 with a space.

The FNT command is for fonts. And in the XTerm documentation it is under 5 0 with a space.

@acook I think there may be some confusion here. FNT is a CSI sequence defined in the ECMA-48 standard to control the SGR font mappings. OSC 50 is a proprietary OSC sequence that XTerm defined to control their active font. The only thing they have in common is that they both work with fonts in some way. They're not the same thing.

Incidentally, iTerm has long since changed their clipboard control code to 1337.

Not exactly. iTerm still interprets OSC 50 as an alias for OSC 1337, so although they recommend using OSC 1337, it hasn't entirely replaced the original OSC 50 implementation as far as I know - both should still work.

The FNT command is for fonts. And in the XTerm documentation it is under 5 0 with a space.

@acook I think there may be some confusion here. FNT is a CSI sequence defined in the ECMA-48 standard to control the SGR font mappings. OSC 50 is a proprietary OSC sequence that XTerm defined to control their active font. The only thing they have in common is that they both work with fonts in some way. They're not the same thing.

It seems to me that XTerm's font implementation is certainly based on the ECMA-48's FNT, even if they chose 50. I put the two documents next to each other and they are suspiciously similar. So I wouldn't say they're entirely different.

This is not to justify XTerm dictating the design of all other terminals, but this pattern is useful for library and application developers like me that want to use advanced font features when they're available.

This sequence is supported by at least 5 other terminals today outside of XTerm.

If we want to have a different standard, then developers beyond the XTerm team need to work together to define it. Entirely bespoke or unreliable workarounds are not realistic to maintain, so we as terminal application and library developers will have to pick and choose what ones to support.

I'm happy to help however I can to facilitate this.

Incidentally, iTerm has long since changed their clipboard control code to 1337.

Not exactly. iTerm still interprets OSC 50 as an alias for OSC 1337, so although they recommend using OSC 1337, it hasn't entirely replaced the original OSC 50 implementation as far as I know - both should still work.

Their documentation says that "50 used to be ... so it is now 1337".

But I just tested the latest release of iTerm from December and you are correct. Not an ideal situation. Thank you for the additional information!