wez / wezterm

A GPU-accelerated cross-platform terminal emulator and multiplexer written by @wez and implemented in Rust
https://wezfurlong.org/wezterm/
Other
17.7k stars 790 forks source link

termwiz: default SGR 8 bit color encoding doesn't work in PowerShell #2723

Open muirdm opened 1 year ago

muirdm commented 1 year ago

What Operating System(s) are you seeing this problem on?

Windows

Which Wayland compositor or X11 Window manager(s) are you using?

No response

WezTerm version

NA

Did you try the latest nightly build to see if the issue is better (or worse!) than your current version?

No, and I'll explain why below

Describe the bug

Termwiz ANSI SGR 8 bit color encoding changed to use ":" as a separator instead of ";" in e1f7edaeb349dd00332fc7f100094242719c7879. PowerShell doesn't seem to like the ":" separator and doesn't render the colors.

To Reproduce

No response

Configuration

no config

Expected Behavior

No response

Logs

No response

Anything else?

Note that when using the Terminal object directly, the 8-bit colors work fine on Windows. Perhaps this is due to apply_builtin_terminfo?

xavierd commented 1 year ago

Not sure if this matters, but Muir and I were discussing about this. I'm seeing this issue with Windows Terminal running PowerShell.

muirdm commented 1 year ago

Here is a reproducer. It tries to print a 3-bit color and a 8-bit color. I expect both to be colored, but only the 3-bit color works on Windows.

The output of this program is:

^[[94mhello-16^[[39m
^[[38:5:123mhello-256^[[39m

If I replace the colons with semicolons, the color shows up.

use termwiz::caps::Capabilities;
use termwiz::cell::{AttributeChange, CellAttributes};
use termwiz::color::{AnsiColor, ColorAttribute};
use termwiz::render::terminfo::TerminfoRenderer;
use termwiz::render::RenderTty;
use termwiz::surface::Change;

struct DumbTty {}

impl RenderTty for DumbTty {
    fn get_size_in_cells(&mut self) -> termwiz::Result<(usize, usize)> {
        Ok((80, 26))
    }
}

impl std::io::Write for DumbTty {
    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
        std::io::stdout().write(buf)
    }

    fn flush(&mut self) -> std::io::Result<()> {
        std::io::stdout().flush()
    }
}

fn main() {
    let caps = Capabilities::new_from_env().unwrap();
    let mut renderer = TerminfoRenderer::new(caps);

    renderer
        .render_to(
            &[
                Change::Attribute(AttributeChange::Foreground(AnsiColor::Blue.into())),
                Change::Text("hello-16".to_string()),
                Change::AllAttributes(CellAttributes::blank()),
                Change::Text("\n".to_string()),
                Change::Attribute(AttributeChange::Foreground(ColorAttribute::PaletteIndex(
                    123,
                ))),
                Change::Text("hello-256".to_string()),
                Change::AllAttributes(CellAttributes::blank()),
            ],
            &mut DumbTty {},
        )
        .unwrap();

    println!("\n");
}
wez commented 1 year ago

Note that when using the Terminal object directly, the 8-bit colors work fine on Windows. Perhaps this is due to apply_builtin_terminfo?

Can you expand on this? Perhaps by showing the program that does work on Windows?

I think your proposed PR is probably sort of OK (just bothers my OCD a bit with the asymmetry!) but that comment about it working has me wondering if there's a different way to resolve this.

muirdm commented 1 year ago

Below is an example that works w/ the Terminal object:

use termwiz::caps::Capabilities;
use termwiz::cell::{AttributeChange, CellAttributes};
use termwiz::color::{AnsiColor, ColorAttribute};
use termwiz::surface::Change;
use termwiz::terminal::{SystemTerminal, Terminal};

fn main() {
    let mut term = SystemTerminal::new(Capabilities::new_from_env().unwrap()).unwrap();

    term.render(&[
        Change::Attribute(AttributeChange::Foreground(AnsiColor::Blue.into())),
        Change::Text("hello-16".to_string()),
        Change::AllAttributes(CellAttributes::blank()),
        Change::Text("\n".to_string()),
        Change::Attribute(AttributeChange::Foreground(ColorAttribute::PaletteIndex(
            123,
        ))),
        Change::Text("hello-256".to_string()),
        Change::AllAttributes(CellAttributes::blank()),
    ])
    .unwrap();
}