cmd2 icon indicating copy to clipboard operation
cmd2 copied to clipboard

async_alert Doesn't Support Color Reset Ansi Sequences on Windows

Open Chris3606 opened this issue 1 year ago • 4 comments

Steps to Reproduce

Color reset sequences (reset foreground, reset background), etc. do not work on Windows when using async_alert.

Given the following (baseline) code:

from cmd2 import Cmd, Fg, style


class App(Cmd):
    def do_print(self, _):
        self.poutput(style("Hello ", fg=Fg.BLUE) + style("World"))

app = App()
app.cmdloop()

We can generate sensible colored output: image

However, if we take the async printing example and change the first item in the ALERTS array to: style("Hello ", fg=Fg.BLUE) + style("World") (the same text we used in the original example, it fails rather spectacularly:

image

Notes

I believe this is due to a limitation and/or bug in pyreadline3. Its printing function does not support the color escape sequences at all (only 0, the global reset).

Adding support for the escape sequences is fairly trivial (I plan to ensure a PR is submitted to pyreadline for it).

Given that cmd2 is already extending pyreadline3, however, I wanted to submit for consideration that it may be possible to support this via additions to rl_utils. I plan to investigate this further.

Chris3606 avatar Jul 02 '24 21:07 Chris3606

Actually, this is slightly more extensive than just not having color reset sequences. According to the tests I've ran, pyreadline3 does not properly support background colors (at all), doesn't support background or foreground reset sequences, and doesn't support intensity reset sequences either.

I have put in an issue and corresponding PR to fix it in the pyreadline3 repository, however I'm not sure if it's still maintained or not.

I did test and in my own application was able to "patch" pyreadline3 by creating a class that inherits from AnsiWriter, fixing the function modified in the PR I linked, then creating an instance of that class and assigning it to the readline.rl.console.ansiwriter property; though obviously such a patch might have side effects that you don't want if, for instance, a user is using cmd2 and pyreadline3 directly (though this is unlikely).

If you're interested, I'd be happy to submit a PR to patch it, but it seems a bit of a hacky solution.

Chris3606 avatar Jul 03 '24 04:07 Chris3606

I would prefer we wait and see if pyreadline3 accepts your PR instead of patching their code in cmd2.

kmvanbrunt avatar Jul 03 '24 14:07 kmvanbrunt

As a temporary workaround, does appending cmd2.TextStyle.RESET_ALL to your styled text fix the issue?

kmvanbrunt avatar Jul 03 '24 15:07 kmvanbrunt

Yes, this works at least for the use case above. Obviously it will reset all elements, so it might not work for nested styles or some such, but I currently have none of those in my code.

Chris3606 avatar Jul 04 '24 03:07 Chris3606

It looks like pyreadline3 accepted your PR and it's now fixed as of pyreadline3 version 3.4.2. I just tested using 3.4.3 in both Windows Command Prompt and Windows Powershell and the async_alert() color issue you experienced is working correctly.

Nice job fixing this.

kmvanbrunt avatar Sep 12 '24 16:09 kmvanbrunt