ok/jj
1
0
Fork 0
forked from mirrors/jj

cli: attach stderr stream of external diff command to pager

It's messy if pager and child output are interleaved as the pager controls
the tty.

Windows code is untested. I think the underlying I/O behavior is similar, but
I don't have expertise.
This commit is contained in:
Yuya Nishihara 2023-08-11 08:59:03 +09:00
parent 4c9c923258
commit 0cbee40aec
2 changed files with 21 additions and 0 deletions

View file

@ -447,6 +447,7 @@ pub fn generate_diff(
let mut child = cmd
.stdin(Stdio::null())
.stdout(Stdio::piped())
.stderr(ui.stderr_for_child().map_err(ExternalToolError::Io)?)
.spawn()
.map_err(|source| ExternalToolError::FailedToExecute {
tool_binary: tool.program.clone(),

View file

@ -186,6 +186,14 @@ impl Ui {
}
}
/// Stderr stream to be attached to a child process.
pub fn stderr_for_child(&self) -> io::Result<Stdio> {
match &self.output {
UiOutput::Terminal { .. } => Ok(Stdio::inherit()),
UiOutput::Paged { child_stdin, .. } => Ok(duplicate_child_stdin(child_stdin)?.into()),
}
}
/// Whether continuous feedback should be displayed for long-running
/// operations
pub fn use_progress_indicator(&self) -> bool {
@ -358,6 +366,18 @@ impl Drop for OutputGuard {
}
}
#[cfg(unix)]
fn duplicate_child_stdin(stdin: &ChildStdin) -> io::Result<std::os::fd::OwnedFd> {
use std::os::fd::AsFd as _;
stdin.as_fd().try_clone_to_owned()
}
#[cfg(windows)]
fn duplicate_child_stdin(stdin: &ChildStdin) -> io::Result<std::os::windows::io::OwnedHandle> {
use std::os::windows::io::AsHandle as _;
stdin.as_handle().try_clone_to_owned()
}
fn term_width() -> Option<u16> {
if let Some(cols) = env::var("COLUMNS").ok().and_then(|s| s.parse().ok()) {
Some(cols)