cmd2
cmd2 copied to clipboard
async_alert Doesn't Support Color Reset Ansi Sequences on Windows
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:
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:
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.
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.
I would prefer we wait and see if pyreadline3 accepts your PR instead of patching their code in cmd2.
As a temporary workaround, does appending cmd2.TextStyle.RESET_ALL to your styled text fix the issue?
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.
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.