mirror of
https://github.com/sharkdp/bat
synced 2026-06-09 10:03:18 +00:00
Merge pull request #3640 from eyupcanakman/fix/binary-as-text-width-3631
Fix line wrapping for files with control characters
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
- Add `--fallback-syntax`/`--fallback-language` to apply syntax highlighting only when auto-detection fails, see #1341 (@Xavrir)
|
||||
|
||||
## Bugfixes
|
||||
- Fix incorrect text width computation when using `--binary=as-text` with non-printable characters in caret notation, see #3640 and #3631 (@eyupcanakman)
|
||||
- Fix `BAT_CONFIG_DIR` pointing at system config directory causing duplicate flag errors. Closes #3589, see #3620 (@Xavrir)
|
||||
- Fix syntax highlighting for symlinked files when the symlink name has no extension but the target does. Closes #1001, see #3621 (@Xavrir)
|
||||
- Report error when pager is missing instead of silently falling back, see #3588 (@IMaloney)
|
||||
|
||||
+13
-5
@@ -37,6 +37,16 @@ use crate::wrapping::WrappingMode;
|
||||
use crate::BinaryBehavior;
|
||||
use crate::StripAnsiMode;
|
||||
|
||||
// Return the displayed width of a character.
|
||||
//
|
||||
// Control characters (0x00..=0x1F and 0x7F) are rendered by the terminal
|
||||
// in caret notation (e.g. ^@, ^A, ..., ^?), which occupies two columns.
|
||||
// UnicodeWidthChar::width() returns None for these, so we map them to 2
|
||||
// here instead of the previous default of 0.
|
||||
fn char_width(c: char) -> usize {
|
||||
c.width().unwrap_or(if c.is_control() { 2 } else { 0 })
|
||||
}
|
||||
|
||||
const ANSI_UNDERLINE_ENABLE: EscapeSequence = EscapeSequence::CSI {
|
||||
raw_sequence: "\x1B[4m",
|
||||
parameters: "4",
|
||||
@@ -793,7 +803,7 @@ impl Printer for InteractivePrinter<'_> {
|
||||
|
||||
for c in text.chars() {
|
||||
// calculate the displayed width for next character
|
||||
let cw = c.width().unwrap_or(0);
|
||||
let cw = char_width(c);
|
||||
current_width += cw;
|
||||
|
||||
// Track whitespace positions for word wrapping.
|
||||
@@ -868,10 +878,8 @@ impl Printer for InteractivePrinter<'_> {
|
||||
if let Some(rs) = rest_start {
|
||||
// Word wrap: carry remainder to next line.
|
||||
let remainder = line_buf[rs..].to_string();
|
||||
let rem_width: usize = remainder
|
||||
.chars()
|
||||
.map(|ch| ch.width().unwrap_or(0))
|
||||
.sum();
|
||||
let rem_width: usize =
|
||||
remainder.chars().map(char_width).sum();
|
||||
line_buf.clear();
|
||||
line_buf.push_str(&remainder);
|
||||
current_width = rem_width + cw;
|
||||
|
||||
BIN
Binary file not shown.
@@ -2681,6 +2681,25 @@ fn binary_as_text() {
|
||||
.stderr("");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn binary_as_text_control_char_width() {
|
||||
// Control characters are displayed as caret notation (e.g. ^@) by the
|
||||
// terminal, occupying 2 columns each. With 20 NUL bytes (40 columns) +
|
||||
// "END" (3 columns) = 43 columns, wrapping at terminal width 40 must
|
||||
// produce 2 lines, not 1. See #3631.
|
||||
bat()
|
||||
.arg("--binary=as-text")
|
||||
.arg("--wrap=character")
|
||||
.arg("--terminal-width=40")
|
||||
.arg("--decorations=always")
|
||||
.arg("--style=plain")
|
||||
.arg("--color=never")
|
||||
.arg("regression_tests/issue_3631.txt")
|
||||
.assert()
|
||||
.success()
|
||||
.stdout(predicate::function(|s: &str| s.lines().count() == 2));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_strip_overstrike_for_plain_text() {
|
||||
// Overstrike is preserved for plain text files (no syntax highlighting)
|
||||
|
||||
Reference in New Issue
Block a user