mirror of
https://github.com/sharkdp/bat.git
synced 2025-09-08 22:32:26 +01:00
Merge branch 'master' into read-from-tail
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
use std::fmt;
|
||||
use std::io;
|
||||
use std::vec::Vec;
|
||||
|
||||
use nu_ansi_term::Color::{Fixed, Green, Red, Yellow};
|
||||
@@ -17,6 +15,7 @@ use content_inspector::ContentType;
|
||||
|
||||
use encoding_rs::{UTF_16BE, UTF_16LE};
|
||||
|
||||
use unicode_segmentation::UnicodeSegmentation;
|
||||
use unicode_width::UnicodeWidthChar;
|
||||
|
||||
use crate::assets::{HighlightingAssets, SyntaxReferenceInSet};
|
||||
@@ -29,12 +28,14 @@ use crate::diff::LineChanges;
|
||||
use crate::error::*;
|
||||
use crate::input::OpenedInput;
|
||||
use crate::line_range::{MaxBufferedLineNumber, RangeCheckResult};
|
||||
use crate::output::OutputHandle;
|
||||
use crate::preprocessor::strip_ansi;
|
||||
use crate::preprocessor::{expand_tabs, replace_nonprintable};
|
||||
use crate::style::StyleComponent;
|
||||
use crate::terminal::{as_terminal_escaped, to_ansi_color};
|
||||
use crate::vscreen::{AnsiStyle, EscapeSequence, EscapeSequenceIterator};
|
||||
use crate::wrapping::WrappingMode;
|
||||
use crate::BinaryBehavior;
|
||||
use crate::StripAnsiMode;
|
||||
|
||||
const ANSI_UNDERLINE_ENABLE: EscapeSequence = EscapeSequence::CSI {
|
||||
@@ -67,20 +68,6 @@ const EMPTY_SYNTECT_STYLE: syntect::highlighting::Style = syntect::highlighting:
|
||||
font_style: FontStyle::empty(),
|
||||
};
|
||||
|
||||
pub enum OutputHandle<'a> {
|
||||
IoWrite(&'a mut dyn io::Write),
|
||||
FmtWrite(&'a mut dyn fmt::Write),
|
||||
}
|
||||
|
||||
impl<'a> OutputHandle<'a> {
|
||||
fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> Result<()> {
|
||||
match self {
|
||||
Self::IoWrite(handle) => handle.write_fmt(args).map_err(Into::into),
|
||||
Self::FmtWrite(handle) => handle.write_fmt(args).map_err(Into::into),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) trait Printer {
|
||||
fn print_header(
|
||||
&mut self,
|
||||
@@ -116,7 +103,7 @@ impl<'a> SimplePrinter<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Printer for SimplePrinter<'a> {
|
||||
impl Printer for SimplePrinter<'_> {
|
||||
fn print_header(
|
||||
&mut self,
|
||||
_handle: &mut OutputHandle,
|
||||
@@ -145,7 +132,7 @@ impl<'a> Printer for SimplePrinter<'a> {
|
||||
// Skip squeezed lines.
|
||||
if let Some(squeeze_limit) = self.config.squeeze_lines {
|
||||
if String::from_utf8_lossy(line_buffer)
|
||||
.trim_end_matches(|c| c == '\r' || c == '\n')
|
||||
.trim_end_matches(['\r', '\n'])
|
||||
.is_empty()
|
||||
{
|
||||
self.consecutive_empty_lines += 1;
|
||||
@@ -268,9 +255,10 @@ impl<'a> InteractivePrinter<'a> {
|
||||
let is_printing_binary = input
|
||||
.reader
|
||||
.content_type
|
||||
.map_or(false, |c| c.is_binary() && !config.show_nonprintable);
|
||||
.is_some_and(|c| c.is_binary() && !config.show_nonprintable);
|
||||
|
||||
let needs_to_match_syntax = !is_printing_binary
|
||||
let needs_to_match_syntax = (!is_printing_binary
|
||||
|| matches!(config.binary, BinaryBehavior::AsText))
|
||||
&& (config.colored_output || config.strip_ansi == StripAnsiMode::Auto);
|
||||
|
||||
let (is_plain_text, highlighter_from_set) = if needs_to_match_syntax {
|
||||
@@ -403,14 +391,18 @@ impl<'a> InteractivePrinter<'a> {
|
||||
handle: &mut OutputHandle,
|
||||
content: &str,
|
||||
) -> Result<()> {
|
||||
let mut content = content;
|
||||
let content_width = self.config.term_width - self.get_header_component_indent_length();
|
||||
while content.len() > content_width {
|
||||
let (content_line, remaining) = content.split_at(content_width);
|
||||
self.print_header_component_with_indent(handle, content_line)?;
|
||||
content = remaining;
|
||||
if content.chars().count() <= content_width {
|
||||
return self.print_header_component_with_indent(handle, content);
|
||||
}
|
||||
self.print_header_component_with_indent(handle, content)
|
||||
|
||||
let mut content_graphemes: Vec<&str> = content.graphemes(true).collect();
|
||||
while content_graphemes.len() > content_width {
|
||||
let (content_line, remaining) = content_graphemes.split_at(content_width);
|
||||
self.print_header_component_with_indent(handle, content_line.join("").as_str())?;
|
||||
content_graphemes = remaining.iter().cloned().collect();
|
||||
}
|
||||
self.print_header_component_with_indent(handle, content_graphemes.join("").as_str())
|
||||
}
|
||||
|
||||
fn highlight_regions_for_line<'b>(
|
||||
@@ -432,7 +424,7 @@ impl<'a> InteractivePrinter<'a> {
|
||||
.highlight_line(for_highlighting, highlighter_from_set.syntax_set)?;
|
||||
|
||||
if too_long {
|
||||
highlighted_line[0].1 = &line;
|
||||
highlighted_line[0].1 = line;
|
||||
}
|
||||
|
||||
Ok(highlighted_line)
|
||||
@@ -448,7 +440,7 @@ impl<'a> InteractivePrinter<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Printer for InteractivePrinter<'a> {
|
||||
impl Printer for InteractivePrinter<'_> {
|
||||
fn print_header(
|
||||
&mut self,
|
||||
handle: &mut OutputHandle,
|
||||
@@ -460,7 +452,10 @@ impl<'a> Printer for InteractivePrinter<'a> {
|
||||
}
|
||||
|
||||
if !self.config.style_components.header() {
|
||||
if Some(ContentType::BINARY) == self.content_type && !self.config.show_nonprintable {
|
||||
if Some(ContentType::BINARY) == self.content_type
|
||||
&& !self.config.show_nonprintable
|
||||
&& !matches!(self.config.binary, BinaryBehavior::AsText)
|
||||
{
|
||||
writeln!(
|
||||
handle,
|
||||
"{}: Binary content from {} will not be printed to the terminal \
|
||||
@@ -541,7 +536,10 @@ impl<'a> Printer for InteractivePrinter<'a> {
|
||||
})?;
|
||||
|
||||
if self.config.style_components.grid() {
|
||||
if self.content_type.map_or(false, |c| c.is_text()) || self.config.show_nonprintable {
|
||||
if self.content_type.is_some_and(|c| c.is_text())
|
||||
|| self.config.show_nonprintable
|
||||
|| matches!(self.config.binary, BinaryBehavior::AsText)
|
||||
{
|
||||
self.print_horizontal_line(handle, '┼')?;
|
||||
} else {
|
||||
self.print_horizontal_line(handle, '┴')?;
|
||||
@@ -553,7 +551,9 @@ impl<'a> Printer for InteractivePrinter<'a> {
|
||||
|
||||
fn print_footer(&mut self, handle: &mut OutputHandle, _input: &OpenedInput) -> Result<()> {
|
||||
if self.config.style_components.grid()
|
||||
&& (self.content_type.map_or(false, |c| c.is_text()) || self.config.show_nonprintable)
|
||||
&& (self.content_type.is_some_and(|c| c.is_text())
|
||||
|| self.config.show_nonprintable
|
||||
|| matches!(self.config.binary, BinaryBehavior::AsText))
|
||||
{
|
||||
self.print_horizontal_line(handle, '┴')
|
||||
} else {
|
||||
@@ -602,7 +602,9 @@ impl<'a> Printer for InteractivePrinter<'a> {
|
||||
.into()
|
||||
} else {
|
||||
let mut line = match self.content_type {
|
||||
Some(ContentType::BINARY) | None => {
|
||||
Some(ContentType::BINARY) | None
|
||||
if !matches!(self.config.binary, BinaryBehavior::AsText) =>
|
||||
{
|
||||
return Ok(());
|
||||
}
|
||||
Some(ContentType::UTF_16LE) => UTF_16LE.decode_with_bom_removal(line_buffer).0,
|
||||
@@ -635,7 +637,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
|
||||
|
||||
// Skip squeezed lines.
|
||||
if let Some(squeeze_limit) = self.config.squeeze_lines {
|
||||
if line.trim_end_matches(|c| c == '\r' || c == '\n').is_empty() {
|
||||
if line.trim_end_matches(['\r', '\n']).is_empty() {
|
||||
self.consecutive_empty_lines += 1;
|
||||
if self.consecutive_empty_lines > squeeze_limit {
|
||||
return Ok(());
|
||||
@@ -692,7 +694,7 @@ impl<'a> Printer for InteractivePrinter<'a> {
|
||||
// Regular text.
|
||||
EscapeSequence::Text(text) => {
|
||||
let text = self.preprocess(text, &mut cursor_total);
|
||||
let text_trimmed = text.trim_end_matches(|c| c == '\r' || c == '\n');
|
||||
let text_trimmed = text.trim_end_matches(['\r', '\n']);
|
||||
|
||||
write!(
|
||||
handle,
|
||||
@@ -746,10 +748,8 @@ impl<'a> Printer for InteractivePrinter<'a> {
|
||||
match chunk {
|
||||
// Regular text.
|
||||
EscapeSequence::Text(text) => {
|
||||
let text = self.preprocess(
|
||||
text.trim_end_matches(|c| c == '\r' || c == '\n'),
|
||||
&mut cursor_total,
|
||||
);
|
||||
let text = self
|
||||
.preprocess(text.trim_end_matches(['\r', '\n']), &mut cursor_total);
|
||||
|
||||
let mut max_width = cursor_max - cursor;
|
||||
|
||||
|
Reference in New Issue
Block a user