Skip to content

Commit efa47ad

Browse files
authored
Respect NO_COLOR and always show the command as a header when paging uv help output (#16908)
## Summary Fix #16879 and address an additional issue where the pager prompt would be bold regardless of NO_COLOR. <img width="1437" height="483" alt="image" src="https://github.com/user-attachments/assets/7234129a-364b-40c6-834a-57ac34212925" /> ## Test Plan Ran the test suite and manually verified against `less` 679 and `busybox` v1.34.1. Checked with and without `NO_COLOR` on both "normal" `less`, `busybox` `less`, and `more`.
1 parent 05814f9 commit efa47ad

File tree

1 file changed

+22
-22
lines changed

1 file changed

+22
-22
lines changed

crates/uv/src/commands/help.rs

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::{fmt::Display, fmt::Write};
66
use anstream::{ColorChoice, stream::IsTerminal};
77
use anyhow::{Result, anyhow};
88
use clap::CommandFactory;
9-
use itertools::{Either, Itertools};
9+
use itertools::Itertools;
1010
use owo_colors::OwoColorize;
1111
use which::which;
1212

@@ -70,32 +70,29 @@ pub(crate) fn help(query: &[String], printer: Printer, no_pager: bool) -> Result
7070
.render_long_help()
7171
};
7272

73-
let help_ansi = match anstream::Stdout::choice(&std::io::stdout()) {
74-
ColorChoice::Always | ColorChoice::AlwaysAnsi => Either::Left(help.ansi()),
75-
ColorChoice::Never => Either::Right(help.clone()),
73+
let want_color = match anstream::Stdout::choice(&std::io::stdout()) {
74+
ColorChoice::Always | ColorChoice::AlwaysAnsi => true,
75+
ColorChoice::Never => false,
7676
// We just asked anstream for a choice, that can't be auto
7777
ColorChoice::Auto => unreachable!(),
7878
};
7979

8080
let is_terminal = std::io::stdout().is_terminal();
8181
let should_page = !no_pager && !is_root && is_terminal;
8282

83-
if should_page {
84-
if let Some(pager) = Pager::try_from_env() {
85-
let content = if pager.supports_colors() {
86-
help_ansi
87-
} else {
88-
Either::Right(help.clone())
89-
};
90-
pager.spawn(
91-
format!("{}: {}", "uv help".bold(), query.join(" ")),
92-
&content,
93-
)?;
83+
if should_page && let Some(pager) = Pager::try_from_env() {
84+
let query = query.join(" ");
85+
if want_color && pager.supports_colors() {
86+
pager.spawn(format!("{}: {query}", "uv help".bold()), help.ansi())?;
9487
} else {
95-
writeln!(printer.stdout(), "{help_ansi}")?;
88+
pager.spawn(format!("uv help: {query}"), help)?;
9689
}
9790
} else {
98-
writeln!(printer.stdout(), "{help_ansi}")?;
91+
if want_color {
92+
writeln!(printer.stdout(), "{}", help.ansi())?;
93+
} else {
94+
writeln!(printer.stdout(), "{help}")?;
95+
}
9996
}
10097

10198
Ok(ExitStatus::Success)
@@ -131,9 +128,9 @@ struct Pager {
131128
}
132129

133130
impl PagerKind {
134-
fn default_args(&self, prompt: String) -> Vec<String> {
131+
fn default_args(&self) -> Vec<String> {
135132
match self {
136-
Self::Less => vec!["-R".to_string(), "-P".to_string(), prompt],
133+
Self::Less => vec!["-R".to_string()],
137134
Self::More => vec![],
138135
Self::Other(_) => vec![],
139136
}
@@ -183,7 +180,7 @@ impl FromStr for Pager {
183180

184181
impl Pager {
185182
/// Display `contents` using the pager.
186-
fn spawn(self, prompt: String, contents: impl Display) -> Result<()> {
183+
fn spawn(self, heading: String, contents: impl Display) -> Result<()> {
187184
use std::io::Write;
188185

189186
let command = self
@@ -193,7 +190,7 @@ impl Pager {
193190
.unwrap_or(OsString::from(self.kind.to_string()));
194191

195192
let args = if self.args.is_empty() {
196-
self.kind.default_args(prompt)
193+
self.kind.default_args()
197194
} else {
198195
self.args
199196
};
@@ -209,7 +206,10 @@ impl Pager {
209206
.ok_or_else(|| anyhow!("Failed to take child process stdin"))?;
210207

211208
let contents = contents.to_string();
212-
let writer = std::thread::spawn(move || stdin.write_all(contents.as_bytes()));
209+
let writer = std::thread::spawn(move || {
210+
let _ = write!(stdin, "{heading}\n\n");
211+
let _ = stdin.write_all(contents.as_bytes());
212+
});
213213

214214
drop(child.wait());
215215
drop(writer.join());

0 commit comments

Comments
 (0)