Formatter colors are not correctly resetted
Lasering opened this issue · comments
Example: when using Formatter.enhanced on Scala JS the Chrome dev tools (in dark mode) shows:
Notice the date and the thread name are correctly in white. However any text coming after any color change is set to black. Any color formatted text should have a reset ansi code at the end. For example:
import scala.io.AnsiColor.*
s"${RED}text to format${RESET}"
@Lasering good catch. Any chance you'd be up to submitting a PR for this? I'm currently traveling right now, so it might be a while before I can get to this. However, if you can submit a PR, I'll make sure to get a new release out. Thanks.
I can look into it.
It seems the error is coming from this reset function:
https://github.com/outr/scribe/blob/master/core/shared/src/main/scala/scribe/output/format/ANSIOutputFormat.scala#L23-L31
The ANSI reset code is being sent but then any previous format is being reapplied which contradicts the reset. The fix would be to only send the reset code, but for this code to exist there must exist something I'm not grasping.
Ah, I see what you're doing. You're using the ANSI directly instead of through the expected mechanism. How about trying something like this:
import scribe.output._
scribe.info(out(
"Custom colors ",
blue("are supported "),
bgRed("with backgrounds "),
bgCyan(
"even ",
green("layered "),
red(
"styles ",
italic("are supported")
)
)
))
I'm using the predefined Formatter.enhanced. The example code I gave was just showing how to properly apply the reset.
To make things more explicit:
import scribe.Logger
import scribe.format.Formatter
import scribe.output.*
Logger.root.clearHandlers().withHandler(formatter = Formatter.simple).replace()
scribe.info(out("Custom colors ", blue("are supported "), "are supported"))
On Chrome dev tools in dark mode produces:
Where as with the correct reset:
import scala.io.AnsiColor.RESET
scribe.info(out("Custom colors ", blue("are supported "), s"${RESET}are supported"))
Notice the reset must be in the text following the color, if the reset was instead blue("are supported $RESET")
then the output would be the same as the first case (without the reset at all)
Sorry about that. Thanks for the clarification. Looks like in the JavaScript console it's not representing the "default" foreground color properly.
From where comes the need of saving the previous format?
That's a valid point. Previously, there was the risk of a race condition with certain terminals (like the one in IntelliJ) that could cause things to get confused, but I believe that was fixed. I might try just changing the reset to actually clear everything.
Looking at the code, the setting of the values after a reset shouldn't be a problem unless something else is setting the foreground to black. The code should only set the foreground if there was a previous value, which shouldn't be the case here. I'll play around with this more and see if I can narrow down the problem.
Ah, it's been so long since I wrote this section of code I forgot that it doesn't actually use ANSI at all. It uses RichBrowserOutputFormat
instead which uses CSS properties as arguments to the console.
For the moment, you can switch to ANSI in the browser by doing this:
Logger.root.clearHandlers().withHandler(
outputFormat = ANSIOutputFormat
).replace()
I'll keep looking into the RichBrowserOutputFormat
to see if I can figure out what's up there.
Just released 3.10.3
with this fix.
I don't know how I've missed the RichBrowserOutputFormat
. Thanks for the very fast turnaround.