microsoft / terminal

The new Windows Terminal and the original Windows console host, all in the same place!
MIT License
95.01k stars 8.22k forks source link

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

Open csdvrx opened 4 years ago

csdvrx commented 4 years ago

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 https://github.com/mintty/mintty/commit/1250829806d3da2f05b3207183b190747d2cc127

This allows sequences like:

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

image

j4james commented 4 years ago

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.

KalleOlaviNiemitalo commented 4 years ago

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

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.

j4james commented 4 years ago

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).

KalleOlaviNiemitalo commented 4 years ago

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.

gcollic commented 9 months ago

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 ?).

j4james commented 9 months ago

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.

csdvrx commented 9 months ago

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:

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:

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.

acook commented 6 months ago

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.

KalleOlaviNiemitalo commented 6 months ago

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.

acook commented 6 months ago

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.

j4james commented 6 months ago

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.

acook commented 6 months ago

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!