-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improved ANSI passthrough. #1596
Conversation
Nice work! 🎆
Do we not have any tests that cover the non-wrapping behavior? Otherwise I'd expect to see some failures due to some differences in our highlighted test files for example. |
I don't think we have any tests specifically covering input with ANSI sequences. I definitely would've broken snapshots tests with this fix, but everything passed without an issue. |
Awesome! Excited to get this integrated soon. It might take me a few more days until I find the time to review it though. It would be great to see actual (before and after) benchmark results. Maybe with some of the "highlighted" files in tests/syntax-tests (which doesn't seem to work currently)? |
I unfortunately don't have a machine that's reliable enough to accurately benchmark That being said... I can still quantify the difference in how many bytes Using the pre-highlighted Rust syntax test:
And in more extreme cases such as the output from the command in #1481:
As far as the changes in 5aa94e8 are concerned though, they will have negative impact on unhighlighted text with
They do work with A smarter implementation would likey be for |
I wrote
Concerning the last point (thermal throttling): On Linux, there is a way to temporarily disable any frequency scaling, which can help with benchmarking. |
@sharkdp That worked really well, even on my Mac. Okay, so... as expected, this pull request does introduce some cost at runtime. In the worst case (e.g. #1481), it takes 27% longer when not printing to a terminal: And in the best case (no ANSI), it doesn't really change anything: Now when it actually prints something to the screen... let's just say that the old one couldn't be benchmarked.
The fixed version worked a lot better: |
Updated this PR to be merge-able into master. |
I was wondering why color was getting stripped when piping to bat, I was considering opening an issue but I found this PR. I really hope this gets merged soon. |
@ImportTaste Does passing |
I merged the code with origin/master and fixed some lints. I have confirmed that the added integration test fails on master. In other words, it tests that the fix in this PR is necessary and works. Which is a great test to have. I do think the code could use some de-duplication, but that was the case even before this PR, so I don't think we need to do that as part of this PR. Unless I'm mistaken, I think that #1976 allows us to do comprehensive benchmarking of this PR. Here are the results on my low-end desktop:
IMHO we should go ahead and merge this PR now, because it is an overall improvement. And we can always keep working on the code. Here is the full benchmark comparison if you want to look. Left is git master e250da8. Right is the latest commit in this PR namely |
Thank you for looking into this. I haven't had the time to fully review it. From a high-level view, it looks like the |
I haven't done a full review review either in the sense that I understand how the code works. But it looks like completely reasonable code, and I'm confident enough in the code to believe it's going to be easy to understand how it works when the need arises. I'm confident enough of that to set Approved on the code at least, and be willing to merge it. All the evidence so far points that it is an improvement over what we have at master right now, without any regressions. And we can always keep working on the code even if we merge it. Since you too are OK with merging it, I will merge it now. |
Closed #1481 |
This pull request overhauls how
bat
interprets and re-emits ANSI escape sequences.Prior to these changes,
bat
used a naiive heuristic that re-emits every encountered sequence on a new line. The encountered sequences are only cleared whenever the exact literal\x1B[0m
is encountered.In 60aad68, I added a simple ANSI sequence parser that only tracks the most recently-encountered ANSI SGR (color, style, etc.) sequence for each attribute. I haven't benchmarked the difference in CPU usage, but it significantly increases the performance of the pager (the cause of #1481).
Memory usage: (Top: before, Bottom: after)
In 5aa94e8, I fixed ANSI passthrough support when wrapping is disabled. The non-wrapping branch didn't have code to handle ANSI, which led to inconsistencies across lines.
Example:
printf '\x1B[33mYellow\nShould be yellow.\x1B[m' | bat --wrap=never
I did my best to manually check for any regressions, but I may have missed some. If anyone finds any issues with how ANSI is handled now, please let me know.
Additionally, if/when console-rs/console#95 is merged, we should update it. Without the fix, strings such as
\x1B(0lqk
will be incorrectly interpreted as [\x1B(0l
,qk
] instead of [\x1B(0
,lqk
].Edit by @Enselic: We included the fix in bat a month ago in #1934 🎉