mirror of
https://github.com/sharkdp/bat.git
synced 2025-10-01 09:32:27 +01:00
Add a "builtin" pager using the Minus crate
This commit is contained in:
committed by
Academician
parent
929669728c
commit
a470cebf32
@@ -16,7 +16,7 @@ use std::io::{BufReader, Write};
|
||||
use std::path::Path;
|
||||
use std::process;
|
||||
|
||||
use bat::output::{OutputHandle, OutputType};
|
||||
use bat::output::OutputType;
|
||||
use bat::theme::DetectColorScheme;
|
||||
use nu_ansi_term::Color::Green;
|
||||
use nu_ansi_term::Style;
|
||||
@@ -229,10 +229,7 @@ pub fn list_themes(
|
||||
)?;
|
||||
config.theme = theme.to_string();
|
||||
Controller::new(&config, &assets)
|
||||
.run(
|
||||
vec![theme_preview_file()],
|
||||
Some(OutputHandle::IoWrite(&mut writer)),
|
||||
)
|
||||
.run(vec![theme_preview_file()], Some(&mut writer))
|
||||
.ok();
|
||||
writeln!(writer)?;
|
||||
} else if config.loop_through {
|
||||
|
@@ -36,14 +36,18 @@ impl Controller<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run(&self, inputs: Vec<Input>, output_handle: Option<OutputHandle<'_>>) -> Result<bool> {
|
||||
pub fn run(
|
||||
&self,
|
||||
inputs: Vec<Input>,
|
||||
output_handle: Option<&mut OutputHandle<'_>>,
|
||||
) -> Result<bool> {
|
||||
self.run_with_error_handler(inputs, output_handle, default_error_handler)
|
||||
}
|
||||
|
||||
pub fn run_with_error_handler(
|
||||
&self,
|
||||
inputs: Vec<Input>,
|
||||
output_handle: Option<OutputHandle<'_>>,
|
||||
output_handle: Option<&mut OutputHandle<'_>>,
|
||||
mut handle_error: impl FnMut(&Error, &mut dyn Write),
|
||||
) -> Result<bool> {
|
||||
let mut output_type;
|
||||
@@ -88,7 +92,7 @@ impl Controller<'_> {
|
||||
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()?),
|
||||
None => output_type.handle()?,
|
||||
};
|
||||
let mut no_errors: bool = true;
|
||||
let stderr = io::stderr();
|
||||
|
@@ -28,6 +28,9 @@ pub enum Error {
|
||||
InvalidPagerValueBat,
|
||||
#[error("{0}")]
|
||||
Msg(String),
|
||||
#[cfg(feature = "paging")]
|
||||
#[error(transparent)]
|
||||
MinusError(#[from] ::minus::MinusError),
|
||||
#[cfg(feature = "lessopen")]
|
||||
#[error(transparent)]
|
||||
VarError(#[from] ::std::env::VarError),
|
||||
|
@@ -1,7 +1,9 @@
|
||||
use std::fmt;
|
||||
use std::io::{self, Write};
|
||||
use std::io;
|
||||
#[cfg(feature = "paging")]
|
||||
use std::process::Child;
|
||||
#[cfg(feature = "paging")]
|
||||
use std::thread::{spawn, JoinHandle};
|
||||
|
||||
use crate::error::*;
|
||||
#[cfg(feature = "paging")]
|
||||
@@ -11,6 +13,36 @@ use crate::paging::PagingMode;
|
||||
#[cfg(feature = "paging")]
|
||||
use crate::wrapping::WrappingMode;
|
||||
|
||||
#[cfg(feature = "paging")]
|
||||
pub struct BuiltinPager {
|
||||
pager: minus::Pager,
|
||||
handle: Option<JoinHandle<Result<()>>>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "paging")]
|
||||
impl BuiltinPager {
|
||||
fn new() -> Self {
|
||||
let pager = minus::Pager::new();
|
||||
let handle = {
|
||||
let pager = pager.clone();
|
||||
Some(spawn(move || {
|
||||
minus::dynamic_paging(pager).map_err(Error::from)
|
||||
}))
|
||||
};
|
||||
Self { pager, handle }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "paging")]
|
||||
impl std::fmt::Debug for BuiltinPager {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("BuiltinPager")
|
||||
//.field("pager", &self.pager) /// minus::Pager doesn't implement fmt::Debug
|
||||
.field("handle", &self.handle)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "paging")]
|
||||
#[derive(Debug, PartialEq)]
|
||||
enum SingleScreenAction {
|
||||
@@ -22,6 +54,8 @@ enum SingleScreenAction {
|
||||
pub enum OutputType {
|
||||
#[cfg(feature = "paging")]
|
||||
Pager(Child),
|
||||
#[cfg(feature = "paging")]
|
||||
BuiltinPager(BuiltinPager),
|
||||
Stdout(io::Stdout),
|
||||
}
|
||||
|
||||
@@ -64,6 +98,10 @@ impl OutputType {
|
||||
return Err(Error::InvalidPagerValueBat);
|
||||
}
|
||||
|
||||
if pager.kind == PagerKind::Builtin {
|
||||
return Ok(OutputType::BuiltinPager(BuiltinPager::new()));
|
||||
}
|
||||
|
||||
let resolved_path = match grep_cli::resolve_binary(&pager.bin) {
|
||||
Ok(path) => path,
|
||||
Err(_) => {
|
||||
@@ -138,7 +176,7 @@ impl OutputType {
|
||||
|
||||
#[cfg(feature = "paging")]
|
||||
pub(crate) fn is_pager(&self) -> bool {
|
||||
matches!(self, OutputType::Pager(_))
|
||||
matches!(self, OutputType::Pager(_) | OutputType::BuiltinPager(_))
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "paging"))]
|
||||
@@ -146,14 +184,18 @@ impl OutputType {
|
||||
false
|
||||
}
|
||||
|
||||
pub fn handle(&mut self) -> Result<&mut dyn Write> {
|
||||
pub fn handle<'a>(&'a mut self) -> Result<OutputHandle<'a>> {
|
||||
Ok(match *self {
|
||||
#[cfg(feature = "paging")]
|
||||
OutputType::Pager(ref mut command) => command
|
||||
.stdin
|
||||
.as_mut()
|
||||
.ok_or("Could not open stdin for pager")?,
|
||||
OutputType::Stdout(ref mut handle) => handle,
|
||||
OutputType::Pager(ref mut command) => OutputHandle::IoWrite(
|
||||
command
|
||||
.stdin
|
||||
.as_mut()
|
||||
.ok_or("Could not open stdin for pager")?,
|
||||
),
|
||||
#[cfg(feature = "paging")]
|
||||
OutputType::BuiltinPager(ref mut pager) => OutputHandle::FmtWrite(&mut pager.pager),
|
||||
OutputType::Stdout(ref mut handle) => OutputHandle::IoWrite(handle),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -161,8 +203,16 @@ impl OutputType {
|
||||
#[cfg(feature = "paging")]
|
||||
impl Drop for OutputType {
|
||||
fn drop(&mut self) {
|
||||
if let OutputType::Pager(ref mut command) = *self {
|
||||
let _ = command.wait();
|
||||
match *self {
|
||||
OutputType::Pager(ref mut command) => {
|
||||
let _ = command.wait();
|
||||
}
|
||||
OutputType::BuiltinPager(ref mut pager) => {
|
||||
if pager.handle.is_some() {
|
||||
let _ = pager.handle.take().unwrap().join().unwrap();
|
||||
}
|
||||
}
|
||||
OutputType::Stdout(_) => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -32,6 +32,9 @@ pub(crate) enum PagerKind {
|
||||
/// most
|
||||
Most,
|
||||
|
||||
/// builtin
|
||||
Builtin,
|
||||
|
||||
/// A pager we don't know about
|
||||
Unknown,
|
||||
}
|
||||
@@ -40,6 +43,10 @@ impl PagerKind {
|
||||
fn from_bin(bin: &str) -> PagerKind {
|
||||
use std::path::Path;
|
||||
|
||||
if bin == "builtin" {
|
||||
return PagerKind::Builtin;
|
||||
}
|
||||
|
||||
// Set to `less` by default on most Linux distros.
|
||||
let pager_bin = Path::new(bin).file_stem();
|
||||
|
||||
|
@@ -328,7 +328,7 @@ impl<'a> PrettyPrinter<'a> {
|
||||
if let Some(mut w) = writer {
|
||||
controller.run(
|
||||
inputs.into_iter().map(|i| i.into()).collect(),
|
||||
Some(OutputHandle::FmtWrite(&mut w)),
|
||||
Some(&mut OutputHandle::FmtWrite(&mut w)),
|
||||
)
|
||||
} else {
|
||||
controller.run(inputs.into_iter().map(|i| i.into()).collect(), None)
|
||||
|
Reference in New Issue
Block a user