1
0
mirror of https://github.com/sharkdp/bat.git synced 2025-04-15 07:10:43 +01:00

Merge branch 'master' into fix/multibyte-chars

This commit is contained in:
Keith Hall 2025-04-12 11:20:48 +03:00 committed by GitHub
commit 44a6e29da7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 59 additions and 42 deletions

View File

@ -173,7 +173,6 @@ jobs:
- { target: i686-unknown-linux-musl , os: ubuntu-20.04, dpkg_arch: musl-linux-i686, use-cross: true } - { target: i686-unknown-linux-musl , os: ubuntu-20.04, dpkg_arch: musl-linux-i686, use-cross: true }
- { target: x86_64-apple-darwin , os: macos-13, } - { target: x86_64-apple-darwin , os: macos-13, }
- { target: aarch64-apple-darwin , os: macos-14, } - { target: aarch64-apple-darwin , os: macos-14, }
- { target: x86_64-pc-windows-gnu , os: windows-2019, }
- { target: x86_64-pc-windows-msvc , os: windows-2019, } - { target: x86_64-pc-windows-msvc , os: windows-2019, }
- { target: x86_64-unknown-linux-gnu , os: ubuntu-20.04, dpkg_arch: amd64, use-cross: true } - { target: x86_64-unknown-linux-gnu , os: ubuntu-20.04, dpkg_arch: amd64, use-cross: true }
- { target: x86_64-unknown-linux-musl , os: ubuntu-20.04, dpkg_arch: musl-linux-amd64, use-cross: true } - { target: x86_64-unknown-linux-musl , os: ubuntu-20.04, dpkg_arch: musl-linux-amd64, use-cross: true }

View File

@ -30,4 +30,4 @@ jobs:
echo "Added lines in CHANGELOG.md:" echo "Added lines in CHANGELOG.md:"
echo "$ADDED" echo "$ADDED"
echo "Grepping for PR info (see CONTRIBUTING.md):" echo "Grepping for PR info (see CONTRIBUTING.md):"
grep "#${PR_NUMBER}\\b.*@${PR_SUBMITTER}\\b" <<< "$ADDED" grep "#${PR_NUMBER}\\b.*${PR_SUBMITTER}\\b" <<< "$ADDED"

View File

@ -2,6 +2,8 @@
## Features ## Features
- Add paging to `--list-themes`, see PR #3239 (@einfachIrgendwer0815)
## Bugfixes ## Bugfixes
- Fix `BAT_THEME_DARK` and `BAT_THEME_LIGHT` being ignored, see issue #3171 and PR #3168 (@bash) - Fix `BAT_THEME_DARK` and `BAT_THEME_LIGHT` being ignored, see issue #3171 and PR #3168 (@bash)
@ -13,6 +15,7 @@
## Other ## Other
- Work around build failures when building `bat` from vendored sources #3179 (@dtolnay) - Work around build failures when building `bat` from vendored sources #3179 (@dtolnay)
- CICD: Stop building for x86_64-pc-windows-gnu which fails #3261 (Enselic)
## Syntaxes ## Syntaxes

View File

@ -10,6 +10,7 @@ version = "0.25.0"
exclude = ["assets/syntaxes/*", "assets/themes/*"] exclude = ["assets/syntaxes/*", "assets/themes/*"]
build = "build/main.rs" build = "build/main.rs"
edition = '2021' edition = '2021'
# You are free to bump MSRV as soon as a reason for bumping emerges.
rust-version = "1.74" rust-version = "1.74"
[features] [features]

View File

@ -1,4 +1,6 @@
use bat::{assets::HighlightingAssets, config::Config, controller::Controller, Input}; use bat::{
assets::HighlightingAssets, config::Config, controller::Controller, output::OutputHandle, Input,
};
fn main() { fn main() {
let mut buffer = String::new(); let mut buffer = String::new();
@ -10,7 +12,10 @@ fn main() {
let controller = Controller::new(&config, &assets); let controller = Controller::new(&config, &assets);
let input = Input::from_file(file!()); let input = Input::from_file(file!());
controller controller
.run(vec![input.into()], Some(&mut buffer)) .run(
vec![input.into()],
Some(OutputHandle::FmtWrite(&mut buffer)),
)
.unwrap(); .unwrap();
println!("{buffer}"); println!("{buffer}");

View File

@ -124,7 +124,10 @@ impl App {
// If we have -pp as an option when in auto mode, the pager should be disabled. // If we have -pp as an option when in auto mode, the pager should be disabled.
if extra_plain || self.matches.get_flag("no-paging") { if extra_plain || self.matches.get_flag("no-paging") {
PagingMode::Never PagingMode::Never
} else if inputs.iter().any(Input::is_stdin) { } else if inputs.iter().any(Input::is_stdin)
// ignore stdin when --list-themes is used because in that case no input will be read anyways
&& !self.matches.get_flag("list-themes")
{
// If we are reading from stdin, only enable paging if we write to an // If we are reading from stdin, only enable paging if we write to an
// interactive terminal and if we do not *read* from an interactive // interactive terminal and if we do not *read* from an interactive
// terminal. // terminal.

View File

@ -16,6 +16,7 @@ use std::io::{BufReader, Write};
use std::path::Path; use std::path::Path;
use std::process; use std::process;
use bat::output::{OutputHandle, OutputType};
use bat::theme::DetectColorScheme; use bat::theme::DetectColorScheme;
use nu_ansi_term::Color::Green; use nu_ansi_term::Color::Green;
use nu_ansi_term::Style; use nu_ansi_term::Style;
@ -205,8 +206,9 @@ pub fn list_themes(
config.language = Some("Rust"); config.language = Some("Rust");
config.style_components = StyleComponents(style); config.style_components = StyleComponents(style);
let stdout = io::stdout(); let mut output_type =
let mut stdout = stdout.lock(); OutputType::from_mode(config.paging_mode, config.wrapping_mode, config.pager)?;
let mut writer = output_type.handle()?;
let default_theme_name = default_theme(color_scheme(detect_color_scheme).unwrap_or_default()); let default_theme_name = default_theme(color_scheme(detect_color_scheme).unwrap_or_default());
for theme in assets.themes() { for theme in assets.themes() {
@ -221,26 +223,29 @@ pub fn list_themes(
}; };
if config.colored_output { if config.colored_output {
writeln!( writeln!(
stdout, writer,
"Theme: {}{}\n", "Theme: {}{}\n",
Style::new().bold().paint(theme.to_string()), Style::new().bold().paint(theme.to_string()),
default_theme_info default_theme_info
)?; )?;
config.theme = theme.to_string(); config.theme = theme.to_string();
Controller::new(&config, &assets) Controller::new(&config, &assets)
.run(vec![theme_preview_file()], None) .run(
vec![theme_preview_file()],
Some(OutputHandle::IoWrite(&mut writer)),
)
.ok(); .ok();
writeln!(stdout)?; writeln!(writer)?;
} else if config.loop_through { } else if config.loop_through {
writeln!(stdout, "{theme}")?; writeln!(writer, "{theme}")?;
} else { } else {
writeln!(stdout, "{theme}{default_theme_info}")?; writeln!(writer, "{theme}{default_theme_info}")?;
} }
} }
if config.colored_output { if config.colored_output {
writeln!( writeln!(
stdout, writer,
"Further themes can be installed to '{}', \ "Further themes can be installed to '{}', \
and are added to the cache with `bat cache --build`. \ and are added to the cache with `bat cache --build`. \
For more information, see:\n\n \ For more information, see:\n\n \

View File

@ -11,10 +11,10 @@ use crate::lessopen::LessOpenPreprocessor;
#[cfg(feature = "git")] #[cfg(feature = "git")]
use crate::line_range::LineRange; use crate::line_range::LineRange;
use crate::line_range::{LineRanges, RangeCheckResult}; use crate::line_range::{LineRanges, RangeCheckResult};
use crate::output::OutputType; use crate::output::{OutputHandle, OutputType};
#[cfg(feature = "paging")] #[cfg(feature = "paging")]
use crate::paging::PagingMode; use crate::paging::PagingMode;
use crate::printer::{InteractivePrinter, OutputHandle, Printer, SimplePrinter}; use crate::printer::{InteractivePrinter, Printer, SimplePrinter};
use clircle::{Clircle, Identifier}; use clircle::{Clircle, Identifier};
@ -35,18 +35,14 @@ impl Controller<'_> {
} }
} }
pub fn run( pub fn run(&self, inputs: Vec<Input>, output_handle: Option<OutputHandle<'_>>) -> Result<bool> {
&self, self.run_with_error_handler(inputs, output_handle, default_error_handler)
inputs: Vec<Input>,
output_buffer: Option<&mut dyn std::fmt::Write>,
) -> Result<bool> {
self.run_with_error_handler(inputs, output_buffer, default_error_handler)
} }
pub fn run_with_error_handler( pub fn run_with_error_handler(
&self, &self,
inputs: Vec<Input>, inputs: Vec<Input>,
output_buffer: Option<&mut dyn std::fmt::Write>, output_handle: Option<OutputHandle<'_>>,
mut handle_error: impl FnMut(&Error, &mut dyn Write), mut handle_error: impl FnMut(&Error, &mut dyn Write),
) -> Result<bool> { ) -> Result<bool> {
let mut output_type; let mut output_type;
@ -88,8 +84,9 @@ impl Controller<'_> {
clircle::Identifier::stdout() clircle::Identifier::stdout()
}; };
let mut writer = match output_buffer { let mut writer = match output_handle {
Some(buf) => OutputHandle::FmtWrite(buf), Some(OutputHandle::FmtWrite(w)) => OutputHandle::FmtWrite(w),
Some(OutputHandle::IoWrite(w)) => OutputHandle::IoWrite(w),
None => OutputHandle::IoWrite(output_type.handle()?), None => OutputHandle::IoWrite(output_type.handle()?),
}; };
let mut no_errors: bool = true; let mut no_errors: bool = true;

View File

@ -38,7 +38,7 @@ mod less;
mod lessopen; mod lessopen;
pub mod line_range; pub mod line_range;
pub(crate) mod nonprintable_notation; pub(crate) mod nonprintable_notation;
mod output; pub mod output;
#[cfg(feature = "paging")] #[cfg(feature = "paging")]
mod pager; mod pager;
#[cfg(feature = "paging")] #[cfg(feature = "paging")]

View File

@ -1,3 +1,4 @@
use std::fmt;
use std::io::{self, Write}; use std::io::{self, Write};
#[cfg(feature = "paging")] #[cfg(feature = "paging")]
use std::process::Child; use std::process::Child;
@ -162,3 +163,17 @@ impl Drop for OutputType {
} }
} }
} }
pub enum OutputHandle<'a> {
IoWrite(&'a mut dyn io::Write),
FmtWrite(&'a mut dyn fmt::Write),
}
impl OutputHandle<'_> {
pub 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),
}
}
}

View File

@ -10,6 +10,7 @@ use crate::{
error::Result, error::Result,
input, input,
line_range::{HighlightedLineRanges, LineRange, LineRanges}, line_range::{HighlightedLineRanges, LineRange, LineRanges},
output::OutputHandle,
style::StyleComponent, style::StyleComponent,
StripAnsiMode, SyntaxMapping, WrappingMode, StripAnsiMode, SyntaxMapping, WrappingMode,
}; };
@ -325,7 +326,10 @@ impl<'a> PrettyPrinter<'a> {
// If writer is provided, pass it to the controller, otherwise pass None // If writer is provided, pass it to the controller, otherwise pass None
if let Some(mut w) = writer { if let Some(mut w) = writer {
controller.run(inputs.into_iter().map(|i| i.into()).collect(), Some(&mut w)) controller.run(
inputs.into_iter().map(|i| i.into()).collect(),
Some(OutputHandle::FmtWrite(&mut w)),
)
} else { } else {
controller.run(inputs.into_iter().map(|i| i.into()).collect(), None) controller.run(inputs.into_iter().map(|i| i.into()).collect(), None)
} }

View File

@ -1,5 +1,3 @@
use std::fmt;
use std::io;
use std::vec::Vec; use std::vec::Vec;
use nu_ansi_term::Color::{Fixed, Green, Red, Yellow}; use nu_ansi_term::Color::{Fixed, Green, Red, Yellow};
@ -30,6 +28,7 @@ use crate::diff::LineChanges;
use crate::error::*; use crate::error::*;
use crate::input::OpenedInput; use crate::input::OpenedInput;
use crate::line_range::RangeCheckResult; use crate::line_range::RangeCheckResult;
use crate::output::OutputHandle;
use crate::preprocessor::strip_ansi; use crate::preprocessor::strip_ansi;
use crate::preprocessor::{expand_tabs, replace_nonprintable}; use crate::preprocessor::{expand_tabs, replace_nonprintable};
use crate::style::StyleComponent; use crate::style::StyleComponent;
@ -69,20 +68,6 @@ const EMPTY_SYNTECT_STYLE: syntect::highlighting::Style = syntect::highlighting:
font_style: FontStyle::empty(), font_style: FontStyle::empty(),
}; };
pub enum OutputHandle<'a> {
IoWrite(&'a mut dyn io::Write),
FmtWrite(&'a mut dyn fmt::Write),
}
impl OutputHandle<'_> {
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 { pub(crate) trait Printer {
fn print_header( fn print_header(
&mut self, &mut self,