From 12a2a451b4de8a4129f9b79ea6ae1da105f06c0b Mon Sep 17 00:00:00 2001 From: einfachIrgendwer0815 <85333734+einfachIrgendwer0815@users.noreply.github.com> Date: Wed, 26 Mar 2025 14:59:41 +0100 Subject: [PATCH] Add paging to `--list-themes` --- examples/buffer.rs | 9 +++++++-- src/bin/bat/app.rs | 5 ++++- src/bin/bat/main.rs | 21 +++++++++++++-------- src/controller.rs | 19 ++++++++----------- src/lib.rs | 2 +- src/output.rs | 15 +++++++++++++++ src/pretty_printer.rs | 6 +++++- src/printer.rs | 17 +---------------- 8 files changed, 54 insertions(+), 40 deletions(-) diff --git a/examples/buffer.rs b/examples/buffer.rs index 839689d4..eefdb249 100644 --- a/examples/buffer.rs +++ b/examples/buffer.rs @@ -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() { let mut buffer = String::new(); @@ -10,7 +12,10 @@ fn main() { let controller = Controller::new(&config, &assets); let input = Input::from_file(file!()); controller - .run(vec![input.into()], Some(&mut buffer)) + .run( + vec![input.into()], + Some(OutputHandle::FmtWrite(&mut buffer)), + ) .unwrap(); println!("{buffer}"); diff --git a/src/bin/bat/app.rs b/src/bin/bat/app.rs index d339ba94..946ce5b1 100644 --- a/src/bin/bat/app.rs +++ b/src/bin/bat/app.rs @@ -124,7 +124,10 @@ impl App { // 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") { 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 // interactive terminal and if we do not *read* from an interactive // terminal. diff --git a/src/bin/bat/main.rs b/src/bin/bat/main.rs index 70443b2f..4496032b 100644 --- a/src/bin/bat/main.rs +++ b/src/bin/bat/main.rs @@ -16,6 +16,7 @@ use std::io::{BufReader, Write}; use std::path::Path; use std::process; +use bat::output::{OutputHandle, OutputType}; use bat::theme::DetectColorScheme; use nu_ansi_term::Color::Green; use nu_ansi_term::Style; @@ -205,8 +206,9 @@ pub fn list_themes( config.language = Some("Rust"); config.style_components = StyleComponents(style); - let stdout = io::stdout(); - let mut stdout = stdout.lock(); + let mut output_type = + 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()); for theme in assets.themes() { @@ -221,26 +223,29 @@ pub fn list_themes( }; if config.colored_output { writeln!( - stdout, + writer, "Theme: {}{}\n", Style::new().bold().paint(theme.to_string()), default_theme_info )?; config.theme = theme.to_string(); Controller::new(&config, &assets) - .run(vec![theme_preview_file()], None) + .run( + vec![theme_preview_file()], + Some(OutputHandle::IoWrite(&mut writer)), + ) .ok(); - writeln!(stdout)?; + writeln!(writer)?; } else if config.loop_through { - writeln!(stdout, "{theme}")?; + writeln!(writer, "{theme}")?; } else { - writeln!(stdout, "{theme}{default_theme_info}")?; + writeln!(writer, "{theme}{default_theme_info}")?; } } if config.colored_output { writeln!( - stdout, + writer, "Further themes can be installed to '{}', \ and are added to the cache with `bat cache --build`. \ For more information, see:\n\n \ diff --git a/src/controller.rs b/src/controller.rs index 422b381e..c8961b91 100644 --- a/src/controller.rs +++ b/src/controller.rs @@ -11,10 +11,10 @@ use crate::lessopen::LessOpenPreprocessor; #[cfg(feature = "git")] use crate::line_range::LineRange; use crate::line_range::{LineRanges, RangeCheckResult}; -use crate::output::OutputType; +use crate::output::{OutputHandle, OutputType}; #[cfg(feature = "paging")] use crate::paging::PagingMode; -use crate::printer::{InteractivePrinter, OutputHandle, Printer, SimplePrinter}; +use crate::printer::{InteractivePrinter, Printer, SimplePrinter}; use clircle::{Clircle, Identifier}; @@ -35,18 +35,14 @@ impl Controller<'_> { } } - pub fn run( - &self, - inputs: Vec, - output_buffer: Option<&mut dyn std::fmt::Write>, - ) -> Result { - self.run_with_error_handler(inputs, output_buffer, default_error_handler) + pub fn run(&self, inputs: Vec, output_handle: Option>) -> Result { + self.run_with_error_handler(inputs, output_handle, default_error_handler) } pub fn run_with_error_handler( &self, inputs: Vec, - output_buffer: Option<&mut dyn std::fmt::Write>, + output_handle: Option>, mut handle_error: impl FnMut(&Error, &mut dyn Write), ) -> Result { let mut output_type; @@ -88,8 +84,9 @@ impl Controller<'_> { clircle::Identifier::stdout() }; - let mut writer = match output_buffer { - Some(buf) => OutputHandle::FmtWrite(buf), + let mut writer = match output_handle { + Some(OutputHandle::FmtWrite(w)) => OutputHandle::FmtWrite(w), + Some(OutputHandle::IoWrite(w)) => OutputHandle::IoWrite(w), None => OutputHandle::IoWrite(output_type.handle()?), }; let mut no_errors: bool = true; diff --git a/src/lib.rs b/src/lib.rs index 502427a7..4c60f10e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -38,7 +38,7 @@ mod less; mod lessopen; pub mod line_range; pub(crate) mod nonprintable_notation; -mod output; +pub mod output; #[cfg(feature = "paging")] mod pager; #[cfg(feature = "paging")] diff --git a/src/output.rs b/src/output.rs index dc75d6e7..bb9a45d5 100644 --- a/src/output.rs +++ b/src/output.rs @@ -1,3 +1,4 @@ +use std::fmt; use std::io::{self, Write}; #[cfg(feature = "paging")] 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), + } + } +} diff --git a/src/pretty_printer.rs b/src/pretty_printer.rs index a70ac021..4979bab5 100644 --- a/src/pretty_printer.rs +++ b/src/pretty_printer.rs @@ -10,6 +10,7 @@ use crate::{ error::Result, input, line_range::{HighlightedLineRanges, LineRange, LineRanges}, + output::OutputHandle, style::StyleComponent, StripAnsiMode, SyntaxMapping, WrappingMode, }; @@ -325,7 +326,10 @@ impl<'a> PrettyPrinter<'a> { // If writer is provided, pass it to the controller, otherwise pass None 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 { controller.run(inputs.into_iter().map(|i| i.into()).collect(), None) } diff --git a/src/printer.rs b/src/printer.rs index 2c364bd7..c62be3f6 100644 --- a/src/printer.rs +++ b/src/printer.rs @@ -1,5 +1,3 @@ -use std::fmt; -use std::io; use std::vec::Vec; use nu_ansi_term::Color::{Fixed, Green, Red, Yellow}; @@ -29,6 +27,7 @@ use crate::diff::LineChanges; use crate::error::*; use crate::input::OpenedInput; use crate::line_range::RangeCheckResult; +use crate::output::OutputHandle; use crate::preprocessor::strip_ansi; use crate::preprocessor::{expand_tabs, replace_nonprintable}; use crate::style::StyleComponent; @@ -68,20 +67,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 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 { fn print_header( &mut self,