mirror of
https://github.com/sharkdp/bat
synced 2024-11-16 21:25:56 +00:00
Fix wrapping method to support unicode text
Related issues: - #787 - #811
This commit is contained in:
parent
22ded00824
commit
944866affd
117
src/printer.rs
117
src/printer.rs
@ -17,6 +17,8 @@ use content_inspector::ContentType;
|
|||||||
use encoding::all::{UTF_16BE, UTF_16LE};
|
use encoding::all::{UTF_16BE, UTF_16LE};
|
||||||
use encoding::{DecoderTrap, Encoding};
|
use encoding::{DecoderTrap, Encoding};
|
||||||
|
|
||||||
|
use unicode_width::UnicodeWidthChar;
|
||||||
|
|
||||||
use crate::assets::HighlightingAssets;
|
use crate::assets::HighlightingAssets;
|
||||||
use crate::decorations::{
|
use crate::decorations::{
|
||||||
Decoration, GridBorderDecoration, LineChangesDecoration, LineNumberDecoration,
|
Decoration, GridBorderDecoration, LineChangesDecoration, LineNumberDecoration,
|
||||||
@ -469,76 +471,85 @@ impl<'a> Printer for InteractivePrinter<'a> {
|
|||||||
&mut cursor_total,
|
&mut cursor_total,
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut chars = text.chars();
|
let max_width = cursor_max - cursor;
|
||||||
let mut remaining = text.chars().count();
|
|
||||||
|
|
||||||
while remaining > 0 {
|
// line buffer (avoid calling write! for every character)
|
||||||
let available = cursor_max - cursor;
|
let mut line_buf = String::with_capacity(max_width * 4);
|
||||||
|
|
||||||
// It fits.
|
// Displayed width of line_buf
|
||||||
if remaining <= available {
|
let mut current_width = 0;
|
||||||
let text = chars.by_ref().take(remaining).collect::<String>();
|
|
||||||
cursor += remaining;
|
|
||||||
|
|
||||||
|
for c in text.chars() {
|
||||||
|
// calculate the displayed width for next character
|
||||||
|
let cw = c.width().unwrap_or(0);
|
||||||
|
current_width += cw;
|
||||||
|
|
||||||
|
// if next character cannot be printed on this line,
|
||||||
|
// flush the buffer.
|
||||||
|
if current_width > max_width {
|
||||||
|
// Generate wrap padding if not already generated.
|
||||||
|
if panel_wrap.is_none() {
|
||||||
|
panel_wrap = if self.panel_width > 0 {
|
||||||
|
Some(format!(
|
||||||
|
"{} ",
|
||||||
|
self.decorations
|
||||||
|
.iter()
|
||||||
|
.map(|ref d| d
|
||||||
|
.generate(line_number, true, self)
|
||||||
|
.text)
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join(" ")
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
Some("".to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor = 0;
|
||||||
|
|
||||||
|
// It wraps.
|
||||||
write!(
|
write!(
|
||||||
handle,
|
handle,
|
||||||
"{}",
|
"{}\n{}",
|
||||||
as_terminal_escaped(
|
as_terminal_escaped(
|
||||||
style,
|
style,
|
||||||
&*format!(
|
&*format!(
|
||||||
"{}{}{}",
|
"{}{}{}",
|
||||||
self.ansi_prefix_sgr, ansi_prefix, text
|
self.ansi_prefix_sgr, ansi_prefix, line_buf
|
||||||
),
|
),
|
||||||
self.config.true_color,
|
self.config.true_color,
|
||||||
self.config.colored_output,
|
self.config.colored_output,
|
||||||
self.config.use_italic_text,
|
self.config.use_italic_text,
|
||||||
background_color
|
background_color
|
||||||
)
|
|
||||||
)?;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate wrap padding if not already generated.
|
|
||||||
if panel_wrap.is_none() {
|
|
||||||
panel_wrap = if self.panel_width > 0 {
|
|
||||||
Some(format!(
|
|
||||||
"{} ",
|
|
||||||
self.decorations
|
|
||||||
.iter()
|
|
||||||
.map(|ref d| d
|
|
||||||
.generate(line_number, true, self)
|
|
||||||
.text)
|
|
||||||
.collect::<Vec<String>>()
|
|
||||||
.join(" ")
|
|
||||||
))
|
|
||||||
} else {
|
|
||||||
Some("".to_string())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// It wraps.
|
|
||||||
let text = chars.by_ref().take(available).collect::<String>();
|
|
||||||
cursor = 0;
|
|
||||||
remaining -= available;
|
|
||||||
|
|
||||||
write!(
|
|
||||||
handle,
|
|
||||||
"{}\n{}",
|
|
||||||
as_terminal_escaped(
|
|
||||||
style,
|
|
||||||
&*format!(
|
|
||||||
"{}{}{}",
|
|
||||||
self.ansi_prefix_sgr, ansi_prefix, text
|
|
||||||
),
|
),
|
||||||
self.config.true_color,
|
panel_wrap.clone().unwrap()
|
||||||
self.config.colored_output,
|
)?;
|
||||||
self.config.use_italic_text,
|
|
||||||
background_color
|
line_buf.clear();
|
||||||
),
|
current_width = cw;
|
||||||
panel_wrap.clone().unwrap()
|
}
|
||||||
)?;
|
|
||||||
|
line_buf.push(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// flush the buffer
|
||||||
|
cursor += current_width;
|
||||||
|
write!(
|
||||||
|
handle,
|
||||||
|
"{}",
|
||||||
|
as_terminal_escaped(
|
||||||
|
style,
|
||||||
|
&*format!(
|
||||||
|
"{}{}{}",
|
||||||
|
self.ansi_prefix_sgr, ansi_prefix, line_buf
|
||||||
|
),
|
||||||
|
self.config.true_color,
|
||||||
|
self.config.colored_output,
|
||||||
|
self.config.use_italic_text,
|
||||||
|
background_color
|
||||||
|
)
|
||||||
|
)?;
|
||||||
|
|
||||||
// Clear the ANSI prefix buffer.
|
// Clear the ANSI prefix buffer.
|
||||||
ansi_prefix.clear();
|
ansi_prefix.clear();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user