macOS Terminal - still missing the mark Apple!

One of the more lauded features in macOS 26 is the updated Terminal.app.
As some of you may know, I'm the author of a very popular library for interacting with terminals and terminal emulators, at least within the Go ecosystem.
I was excited to hear about the new Terminal.app. Finally, we would get support for 24-bit color, years after everyone else has had it. (Even Microsoft beat Apple to the punch here, leading by something like half a decade.)
So yes, the good news is that macOS Terminal.app in does support 24-bit color.
But in nearly every other interesting case it is far inferior.
The rest of this is probably only interesting to terminal nerds, but for those of you who care about these things, the new Terminal.app is a major disappointment.
Identification Woes
The first and most egregious failing is that there is no good way to remotely identify the macOS terminal, or even what features it might support.
Normally we would like to be able to query and get useful feedback via one of the following mechanisms:
-
Primary Device Attributes (obtained via
CSI c): Terminal.app reports that it is a vanilla VT100 with no extra features, it does not claim to be a VT220 or similar. 2. Extended Device Attributes (obained via
CSI > q): Terminal.app reports nothing here. Most modern terminal emulators store their application name and version here. While I dislike hardcoding capabilities for a specific terminal emulator (so-called "quirks"), this isn't even an option because we can't know that this is Terminal.app.3.
DECRQM- DEC mode queries. This is supported officially starting with VT320 and up, but pretty much every other software emulator supports it. This can be used to query whether a given DEC mode (including things like mouse support and features, automatic margin wrap, etc.) are present and modifiable. It has been used for new things like synchronized output (to fix tearing during a resize) and to identify support for grapheme clusters (very important in a Unicode world). Terminal.app does not support these queries, but it even gets it wrong in a worse way. This is a CSI sequence, so the reasonable behavior would be to parse to the end of the sequence, and discard it if you don't support it. Terminal.app instead aborts the parsing early, emitting the final character of the sequence on the screen. So during early startup we see these mysterious "p" characters show up as Tcell tries to query for support.
Ok, this is just about identification. What about TERM? Well Terminal.app identifies as xterm-256color - although it clearly is not compatible with genuine xterm. What about $TERM_PROGRAM? Well, yes, we could use that. But note that this environment variable is not passed through ssh by default, which makes it useful only for locally running applications.
Unicode Woes
Modern applications and users expect to be able to use things like skin-tone modifiers for emoji, national flags, and similar "characters" (well graphemes technically, which is just another way of saying a user-perceived character). In Unicode, these graphemes are composed by combining multiple Unicode "characters" together.
This approach is also used with certain languages, such as Arabic, or even in Western languages where a character might be modified to include the diaeresis using two code points joined by a special character called the "zero-width-joiner". (For example, in Bengali, র্য (No, I do not read or speak Bengali.)
How does Terminal.app fare here? Well its mixed results. For some, such as 👨🚒 and the Bengali example, it works reasonably well. But for others, like the flag emoji 🇨🇭 it miscalculates the width. (In this case it calculates the width of the flag as just one cell, instead of two, even though it renders it using two cells!).
This behavior could be detected by an application emitting the composed sequence, then querying the resulting position using CSI 6 n.
It would be easier, and better if Apple would implement the DECRQM and advertise mode 2027. It could be hard coded to 3 (forced on) in this case, unless Apple were prepared to add the complexity to support both legacy and modern grapheme support.
Hashimoto also has something to say about Terminal.app and grapheme clustering:
(Apparently it miscalculated the width a joined sequence as 6, probably because it considered the ZWJ as occupying two cells.)🤡 Living in its own cursed little world
Broken State Machine
printf "\x1b]something\x1b\\"$TERM, it doesn't answer any of the standard queries to test for functionality, nor does it answer the extended attributes to help a user program identify that it should avoid any of the normal things it might expect to be able to do with a real implementation of xterm.APC, SOS and PM (which are generally unused by modern terminals)? They behave as DCS. The content goes straight to screen.DECRQM above? That is a valid CSI sequence:CSI ?Pm$ p
Modern Key Events
So What To Do?
What About Windows Users?
CSI > q identification, and better support for grapheme clusters, but for most applications it behaves quite well. One I specifically do not recommend is ConEmu, as it has many different ways in which it is broken. It also appears to be abandonware, in spite of its once great popularity.
Comments