Psreadline: Stop setting the background color when erasing

Created on 11 Dec 2018  ·  4Comments  ·  Source: PowerShell/PSReadLine

As of Windows 10 build 18298, the new “Terminal” settings allow setting _default_ ForegroundColor and BackgroundColor values which are _separate_ from the 16 color "ConsoleColor" palette.

PSReadLine doesn't use the ANSI/VT escape sequence for _default_ when erasing text, but instead overwrites the line with $Host.UI.RawUI.BackgroundColor (e.g. when pressing backspace, or when using the arrow keys to navigate through the history buffer with commands of different lengths -- worse when some have multiple lines).

PSReadLine needs to start using the "default" color, instead of specifying a color.

Most helpful comment

This is going to become critically important for a future Terminal update (1.2, 1.3).

Since it launched, Terminal has been operating in a compatibility mode where the backing console acts as though the terminal setting @Jaykul mentioned is turned _off_.

This has been the cause of a great number of issues, chief among them our inability to distinguish \e[40m from \e[49m and \e[37m from \e[39m. For a representative sample, look at duplicates of microsoft/terminal#293 and microsoft/terminal#2661.

We're finally getting that fixed.

We can differentiate colors set through the Win32 console API, by VT with the 0-8 color set (±brightness), and by VT with the 0-256 color set.

old behavior

color type|stored as|translated as
-|-|-
vt 0-8 (±brightness)|indexed 0-16|_mangled_
vt 0-256|rgb|_mangled_
vt rgb|rgb|_mangled_
vt defaults (39, 49)|"default" flag|_mangled_
win32 1-6, 8-16|indexed 0-16|_mangled_
win32 0, 7|indexed 0-16|_mangled_, but into vt 39, 49

(I marked every translation as "mangled" here because we would first resolve the index to an rgb color known to the conhost in the middle of the transaction, _then resolve the rgb color back to an index_, and if that RGB color matched the defaults turn it into 39/49, and if it didn't match an index turn it into a \e[38;2;x;y;zm RGB sequence)

new behavior

color type|stored as|translated as|notes
-|-|-|-
vt 0-8 (±brightness)|indexed 0-16|_passed through unchanged_|totally normal VT color
vt 0-256|indexed 0-256|_passed through unchanged_|cannot be brightened with SGR 1 (!)
vt defaults (39, 49)|"default" flag|_passed through unchanged_|
win32 0-16|indexed 0-256|vt 0-256|cannot be brightened with SGR 1 (!)
win32 index matching console properties sheet default for bg/fg|"default" flag|_vt defaults (39, 49)_|_this to stop all legacy console applications from forcing a black background_

Problem is, though, that due to the line @lzybkr pointed out PSReadline _takes a ConsoleColor and maps it to a VT color_. This means that we're reading out the foreground and background from win32 format (bottom of the table) and transforming it to vt (top of the table).

Joel's assertion about black backgrounds unfortunately _doesn't hold_ for our userbase. People love background images and acrylic, though I cannot quite determine why.

The result looks like this (with my transparency exaggerated for effect):

image

All 4 comments

Interesting, nobody has complained about this on Linux or Mac where this should also be a problem.

Have you tried removing this line? That might be all it takes.

Yeah, that's weird. I'm tempted to suggest that most people probably set their background = black(ish) and foreground = white(ish) (or vice-versa) and don't use an extra color ...

However, there are certainly a _lot_ of, say iTerm color schemes, where the default background is not one of the base16 colors. E.g. BirdsOfParadise, Borland, Chalk, Desert ...

I tried a couple of those in the new build last night but (as we've discussed elsewhere) I can't find a way to programmatically set the new color values yet.

This is going to become critically important for a future Terminal update (1.2, 1.3).

Since it launched, Terminal has been operating in a compatibility mode where the backing console acts as though the terminal setting @Jaykul mentioned is turned _off_.

This has been the cause of a great number of issues, chief among them our inability to distinguish \e[40m from \e[49m and \e[37m from \e[39m. For a representative sample, look at duplicates of microsoft/terminal#293 and microsoft/terminal#2661.

We're finally getting that fixed.

We can differentiate colors set through the Win32 console API, by VT with the 0-8 color set (±brightness), and by VT with the 0-256 color set.

old behavior

color type|stored as|translated as
-|-|-
vt 0-8 (±brightness)|indexed 0-16|_mangled_
vt 0-256|rgb|_mangled_
vt rgb|rgb|_mangled_
vt defaults (39, 49)|"default" flag|_mangled_
win32 1-6, 8-16|indexed 0-16|_mangled_
win32 0, 7|indexed 0-16|_mangled_, but into vt 39, 49

(I marked every translation as "mangled" here because we would first resolve the index to an rgb color known to the conhost in the middle of the transaction, _then resolve the rgb color back to an index_, and if that RGB color matched the defaults turn it into 39/49, and if it didn't match an index turn it into a \e[38;2;x;y;zm RGB sequence)

new behavior

color type|stored as|translated as|notes
-|-|-|-
vt 0-8 (±brightness)|indexed 0-16|_passed through unchanged_|totally normal VT color
vt 0-256|indexed 0-256|_passed through unchanged_|cannot be brightened with SGR 1 (!)
vt defaults (39, 49)|"default" flag|_passed through unchanged_|
win32 0-16|indexed 0-256|vt 0-256|cannot be brightened with SGR 1 (!)
win32 index matching console properties sheet default for bg/fg|"default" flag|_vt defaults (39, 49)_|_this to stop all legacy console applications from forcing a black background_

Problem is, though, that due to the line @lzybkr pointed out PSReadline _takes a ConsoleColor and maps it to a VT color_. This means that we're reading out the foreground and background from win32 format (bottom of the table) and transforming it to vt (top of the table).

Joel's assertion about black backgrounds unfortunately _doesn't hold_ for our userbase. People love background images and acrylic, though I cannot quite determine why.

The result looks like this (with my transparency exaggerated for effect):

image

And just to confirm, removing that line works great:

image

:smile:

Was this page helpful?
0 / 5 - 0 ratings