diff --git a/Cargo.lock b/Cargo.lock index b1bde31..748d8e0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -39,37 +39,60 @@ dependencies = [ [[package]] name = "anstyle" -version = "0.2.5" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58bb0ec944fe041c41e32dcd60b49327fcb7ff761433838878cc97ddecf16db7" +checksum = "80c697cc33851b02ab0c26b2e8a211684fbe627ff1cc506131f35026dd7686dd" [[package]] -name = "anstyle-syntect" -version = "0.1.2" +name = "anstyle-parse" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7d1bb534e9efed14f3e5f44e7dd1a4f709384023a4165199a4241e18dff0116" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-stream" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a54d4b3ea7f3899dc1f0cfbff7f9dbceff209b799bd1e6c235f901e3c5b86efc" +checksum = "1383966ba5bad155fe30bb239f7ca9eb149990674414aee2f8aef35a0a2dc9d0" dependencies = [ "anstyle", - "syntect", + "anstyle-parse", + "anstyle-wincon", + "concolor-override", + "concolor-query", + "is-terminal", + "utf8parse", ] [[package]] -name = "anyhow" -version = "1.0.68" +name = "anstyle-syntect" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61" +checksum = "2cdd9c7dee67c16f269c1a545a9bc992947ceba236ba703eb8d5fff3409ed027" +dependencies = [ + "anstyle", + "syntect", +] [[package]] -name = "atty" -version = "0.2.14" +name = "anstyle-wincon" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +checksum = "c3127af6145b149f3287bb9a0d10ad9c5692dba8c53ad48285e5bec4063834fa" dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", + "anstyle", + "windows-sys 0.45.0", ] +[[package]] +name = "anyhow" +version = "1.0.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61" + [[package]] name = "backtrace" version = "0.3.66" @@ -191,30 +214,40 @@ dependencies = [ [[package]] name = "concolor" -version = "0.0.11" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "318d6c16e73b3a900eb212ad6a82fc7d298c5ab8184c7a9998646455bc474a16" +checksum = "0b946244a988c390a94667ae0e3958411fa40cc46ea496a929b263d883f5f9c3" dependencies = [ "bitflags", + "concolor-override", "concolor-query", "is-terminal", ] [[package]] name = "concolor-clap" -version = "0.0.13" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a9572308414bfdbda25e41cdd4a15a90e68d93f2d5a66e3ff6e1cdc856f923" +checksum = "435ff0007a3bb04099fe1beedc6b76e7dd5340c90b168008ac0d7e87441de1bf" dependencies = [ "clap", "concolor", ] +[[package]] +name = "concolor-override" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a855d4a1978dc52fb0536a04d384c2c0c1aa273597f08b77c8c4d3b2eec6037f" + [[package]] name = "concolor-query" -version = "0.1.0" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82a90734b3d5dcf656e7624cca6bce9c3a90ee11f900e80141a7427ccfb3d317" +checksum = "88d11d52c3d7ca2e6d0040212be9e4dbbcd78b6447f535b6b561f449427944cf" +dependencies = [ + "windows-sys 0.45.0", +] [[package]] name = "content_inspector" @@ -402,9 +435,9 @@ name = "git-dive" version = "0.0.1" dependencies = [ "anstyle", + "anstyle-stream", "anstyle-syntect", "anyhow", - "atty", "bincode", "bugreport", "clap", @@ -418,6 +451,7 @@ dependencies = [ "git-config-env", "git2", "human-panic", + "is-terminal", "log", "once_cell", "proc-exit", @@ -426,7 +460,6 @@ dependencies = [ "syntect", "terminal_size", "textwrap", - "yansi", ] [[package]] @@ -481,21 +514,9 @@ checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" [[package]] name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "hermit-abi" -version = "0.2.6" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" -dependencies = [ - "libc", -] +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" [[package]] name = "human-panic" @@ -529,19 +550,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46112a93252b123d31a119a8d1a1ac19deac4fac6e0e8b0df58f0d4e5870e63c" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] name = "is-terminal" -version = "0.4.1" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927609f78c2913a6f6ac3c27a4fe87f43e2a35367c0c4b0f8265e8f49a104330" +checksum = "21b6b32576413a8e69b90e952e4a026476040d81017b80445deda5f2d3921857" dependencies = [ - "hermit-abi 0.2.6", + "hermit-abi", "io-lifetimes", "rustix", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -789,7 +810,7 @@ dependencies = [ "io-lifetimes", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -920,7 +941,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb20089a8ba2b69debd491f8d2d023761cbf196e999218c591fa1e7e15a21907" dependencies = [ "rustix", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -1026,6 +1047,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + [[package]] name = "uuid" version = "0.8.2" @@ -1110,50 +1137,68 @@ dependencies = [ "windows_x86_64_msvc", ] +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.0" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" [[package]] name = "windows_aarch64_msvc" -version = "0.42.0" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_i686_gnu" -version = "0.42.0" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_msvc" -version = "0.42.0" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_x86_64_gnu" -version = "0.42.0" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.0" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" [[package]] name = "windows_x86_64_msvc" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" - -[[package]] -name = "yansi" -version = "0.5.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" diff --git a/Cargo.toml b/Cargo.toml index adee77f..28c40e9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,22 +33,22 @@ clap = { version = "4.1.4", features = ["derive", "wrap_help"] } clap-verbosity-flag = "2.0" log = "0.4" env_logger = { version = "0.10", default-features = false, features = ["color"] } -yansi = "0.5.1" -concolor = "0.0.11" -concolor-clap = { version = "0.0.13", features = ["api_unstable"] } +concolor = "0.1.1" +concolor-clap = { version = "0.1.0", features = ["api"] } proc-exit = "2" human-panic = "1" anyhow = "1.0.68" syntect = { version = "5.0.0", default-features = false, features = ["parsing", "regex-fancy"] } terminal_size = "0.2.3" textwrap = "0.16.0" -anstyle = "0.2.5" +anstyle = "0.3.1" +anstyle-stream = "0.2.2" +is-terminal = "0.4.4" content_inspector = "0.2.4" encoding = "0.2.33" git-config-env = "0.1.2" shlex = "1.1.0" -atty = "0.2.14" -anstyle-syntect = "0.1.2" +anstyle-syntect = "0.2.0" bincode = "1.3.3" serde = { version = "1.0.152", features = ["derive"] } flate2 = "1.0.25" diff --git a/src/assets/mod.rs b/src/assets/mod.rs index 0b73ff0..5a4d0fe 100644 --- a/src/assets/mod.rs +++ b/src/assets/mod.rs @@ -40,7 +40,7 @@ pub fn to_anstyle_color(color: syntect::highlighting::Color) -> Option anstyle::XTermColor(n).into(), + n => anstyle::Ansi256Color(n).into(), }) } else if color.a == 1 { // Themes can specify the terminal's default foreground/background color diff --git a/src/blame.rs b/src/blame.rs index f01c40e..d3994e5 100644 --- a/src/blame.rs +++ b/src/blame.rs @@ -11,9 +11,9 @@ pub fn blame( file_path: &std::path::Path, config: &mut Config, args: &crate::args::Args, - colored_stdout: bool, - _colored_stderr: bool, ) -> proc_exit::ExitResult { + let colored_stdout = anstyle_stream::AutoStream::choice(&std::io::stdout()) + != anstyle_stream::ColorChoice::Never; let total_width = terminal_size::terminal_size() .map(|(w, _h)| w.0) .or_else(|| std::env::var_os("COLUMNS").and_then(|s| s.to_str()?.parse::().ok())) @@ -470,7 +470,7 @@ fn gutter_style(theme: &syntect::highlighting::Theme) -> anstyle::Style { .settings .gutter_foreground .map(crate::assets::to_anstyle_color) - .unwrap_or_else(|| Some(anstyle::XTermColor(DEFAULT_GUTTER_COLOR).into())); + .unwrap_or_else(|| Some(anstyle::Ansi256Color(DEFAULT_GUTTER_COLOR).into())); anstyle::Style::new().fg_color(fg_color) } diff --git a/src/config.rs b/src/config.rs index 431f07c..320275b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -16,7 +16,7 @@ pub fn dump_config(output_path: &std::path::Path, config: &mut Config) -> proc_e if output_path == std::path::Path::new("-") { use std::io::Write; - std::io::stdout() + anstyle_stream::stdout() .write_all(output.as_bytes()) .with_code(proc_exit::Code::FAILURE)?; } else { diff --git a/src/git_pager.rs b/src/git_pager.rs index 7a3c1fc..f45ea9d 100644 --- a/src/git_pager.rs +++ b/src/git_pager.rs @@ -7,18 +7,21 @@ pub struct Pager { impl Pager { pub fn stdout(args: &str) -> Self { - let cmd = atty::is(atty::Stream::Stdout) + let cmd = anstyle_stream::stdout() + .is_terminal() .then(|| parse(args)) .flatten(); Self { cmd } } pub fn start(&mut self) -> ActivePager { - let stdout = std::io::stdout().lock(); + let stdout = anstyle_stream::stdout().lock(); if let Some(cmd) = &mut self.cmd { // should use pager instead of stderr if let Ok(p) = cmd.spawn() { - let stderr = atty::is(atty::Stream::Stderr).then(|| std::io::stderr().lock()); + let stderr = anstyle_stream::stderr() + .is_terminal() + .then(|| anstyle_stream::stderr().lock()); ActivePager { primary: stdout, _secondary: stderr, @@ -42,8 +45,8 @@ impl Pager { } pub struct ActivePager { - primary: std::io::StdoutLock<'static>, - _secondary: Option>, + primary: anstyle_stream::AutoStream>, + _secondary: Option>>, pager: Option, } diff --git a/src/logger.rs b/src/logger.rs index faa47e2..4e863b2 100644 --- a/src/logger.rs +++ b/src/logger.rs @@ -24,31 +24,19 @@ pub fn init_logging( builder.format_timestamp_secs(); } else { builder.format(move |f, record| match record.level() { - log::Level::Error => writeln!( - f, - "{}: {}", - palette.error.paint(record.level()), - record.args() - ), - log::Level::Warn => writeln!( - f, - "{}: {}", - palette.warn.paint(record.level()), - record.args() - ), + log::Level::Error => { + writeln!(f, "{}: {}", palette.error(record.level()), record.args()) + } + log::Level::Warn => { + writeln!(f, "{}: {}", palette.warn(record.level()), record.args()) + } log::Level::Info => writeln!(f, "{}", record.args()), - log::Level::Debug => writeln!( - f, - "{}: {}", - palette.debug.paint(record.level()), - record.args() - ), - log::Level::Trace => writeln!( - f, - "{}: {}", - palette.trace.paint(record.level()), - record.args() - ), + log::Level::Debug => { + writeln!(f, "{}: {}", palette.debug(record.level()), record.args()) + } + log::Level::Trace => { + writeln!(f, "{}: {}", palette.trace(record.level()), record.args()) + } }); } @@ -56,30 +44,67 @@ pub fn init_logging( } } -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Default, Debug)] struct Palette { - error: yansi::Style, - warn: yansi::Style, - debug: yansi::Style, - trace: yansi::Style, + error: anstyle::Style, + warn: anstyle::Style, + debug: anstyle::Style, + trace: anstyle::Style, } impl Palette { pub fn colored() -> Self { Self { - error: yansi::Style::new(yansi::Color::Red).bold(), - warn: yansi::Style::new(yansi::Color::Yellow), - debug: yansi::Style::new(yansi::Color::Blue), - trace: yansi::Style::new(yansi::Color::Cyan), + error: anstyle::AnsiColor::Red | anstyle::Effects::BOLD, + warn: anstyle::AnsiColor::Yellow.into(), + debug: anstyle::AnsiColor::Blue.into(), + trace: anstyle::AnsiColor::Cyan.into(), } } pub fn plain() -> Self { - Self { - error: yansi::Style::default(), - warn: yansi::Style::default(), - debug: yansi::Style::default(), - trace: yansi::Style::default(), + Self::default() + } + + pub(crate) fn error(self, display: D) -> Styled { + Styled::new(display, self.error) + } + + pub(crate) fn warn(self, display: D) -> Styled { + Styled::new(display, self.warn) + } + + pub(crate) fn debug(self, display: D) -> Styled { + Styled::new(display, self.debug) + } + + pub(crate) fn trace(self, display: D) -> Styled { + Styled::new(display, self.trace) + } +} + +#[derive(Debug)] +pub(crate) struct Styled { + display: D, + style: anstyle::Style, +} + +impl Styled { + pub(crate) fn new(display: D, style: anstyle::Style) -> Self { + Self { display, style } + } +} + +impl std::fmt::Display for Styled { + #[inline] + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if f.alternate() { + write!(f, "{}", self.style.render())?; + self.display.fmt(f)?; + write!(f, "{}", self.style.render_reset())?; + Ok(()) + } else { + self.display.fmt(f) } } } diff --git a/src/main.rs b/src/main.rs index 7b3c870..d98d3d5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -34,7 +34,6 @@ fn run() -> proc_exit::ExitResult { let args = args::Args::parse(); args.color.apply(); - let colored_stdout = concolor::get(concolor::Stream::Stdout).ansi_color(); let colored_stderr = concolor::get(concolor::Stream::Stderr).ansi_color(); logger::init_logging(args.verbose.clone(), colored_stderr); @@ -52,12 +51,16 @@ fn run() -> proc_exit::ExitResult { if let Some(output_path) = args.dump_config.as_deref() { config::dump_config(output_path, &mut config)?; } else if args.list_languages { - list_languages(&mut config, colored_stdout)?; + list_languages(&mut config)?; } else if args.list_themes { - list_themes(&mut config, colored_stdout)?; + list_themes(&mut config)?; } else if args.acknowledgements { use std::io::Write; - let _ = writeln!(std::io::stdout(), "{}", assets::get_acknowledgements()); + let _ = writeln!( + anstyle_stream::stdout(), + "{}", + assets::get_acknowledgements() + ); } else if args.diagnostic { use bugreport::{bugreport, collector::*, format::Markdown}; @@ -85,13 +88,7 @@ fn run() -> proc_exit::ExitResult { report.print::(); } else if let Some(file_path) = args.file.as_deref() { - blame::blame( - file_path, - &mut config, - &args, - colored_stdout, - colored_stderr, - )?; + blame::blame(file_path, &mut config, &args)?; } else { unreachable!("clap ensured a mode exists"); } @@ -99,7 +96,7 @@ fn run() -> proc_exit::ExitResult { Ok(()) } -fn list_languages(config: &mut Config, colored_stdout: bool) -> proc_exit::ExitResult { +fn list_languages(config: &mut Config) -> proc_exit::ExitResult { let total_width = terminal_size::terminal_size() .map(|(w, _h)| w.0) .or_else(|| std::env::var_os("COLUMNS").and_then(|s| s.to_str()?.parse::().ok())) @@ -133,20 +130,18 @@ fn list_languages(config: &mut Config, colored_stdout: bool) -> proc_exit::ExitR "".to_owned() }; let mut ext_line = ext_line.into_owned(); - if colored_stdout { - name = format!( - "{}{}{}", - anstyle::Effects::BOLD.render(), - name, - anstyle::Reset.render() - ); - ext_line = format!( - "{}{}{}", - anstyle::AnsiColor::Green.render_fg(), - ext_line, - anstyle::Reset.render() - ); - } + name = format!( + "{}{}{}", + anstyle::Effects::BOLD.render(), + name, + anstyle::Reset.render() + ); + ext_line = format!( + "{}{}{}", + anstyle::AnsiColor::Green.render_fg(), + ext_line, + anstyle::Reset.render() + ); let _ = writeln!(pager, "{name: proc_exit::ExitR Ok(()) } -fn list_themes(config: &mut Config, colored_stdout: bool) -> proc_exit::ExitResult { +fn list_themes(config: &mut Config) -> proc_exit::ExitResult { + let colored_stdout = anstyle_stream::AutoStream::choice(&std::io::stdout()) + != anstyle_stream::ColorChoice::Never; let pager = config.get(&crate::git2_config::PAGER); let mut pager = Pager::stdout(&pager); let mut pager = pager.start();