diff --git a/src/main.rs b/src/main.rs index e952a3bcb..3b0e621c0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -150,6 +150,8 @@ pub fn run_app( let pager_cfg = (&config).into(); let paging_mode = if capture_output.is_some() { PagingMode::Capture + } else if config.paging_mode != PagingMode::Always && !io::stdout().is_terminal() { + PagingMode::Never } else { config.paging_mode }; @@ -303,3 +305,4 @@ pub fn run_app( // `output_type` drop impl runs here } + diff --git a/tests/empty_stdin.rs b/tests/empty_stdin.rs new file mode 100644 index 000000000..548d8886f --- /dev/null +++ b/tests/empty_stdin.rs @@ -0,0 +1,67 @@ +use std::ffi::OsString; +use std::io::Write; +use std::path::PathBuf; +use std::process::{Command, Stdio}; + +fn delta_bin() -> OsString { + std::env::var_os("CARGO_BIN_EXE_delta").unwrap_or_else(|| { + // Fallback for when not run via cargo test + let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + path.push("target"); + path.push("debug"); + path.push(format!("delta{}", std::env::consts::EXE_SUFFIX)); + path.into_os_string() + }) +} + +#[test] +fn test_no_output_on_empty_stdin_when_stdout_piped() { + let mut child = Command::new(delta_bin()) + .args(["--no-gitconfig"]) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .spawn() + .expect("failed to spawn delta"); + + child.stdin.take().unwrap().write_all(b"").unwrap(); + let output = child.wait_with_output().unwrap(); + + assert!( + output.status.success(), + "delta exited with error on empty stdin: {}", + String::from_utf8_lossy(&output.stderr) + ); + assert_eq!( + output.stdout.len(), + 0, + "Expected 0 bytes on empty stdin piped to delta, got {} bytes: {:?}", + output.stdout.len(), + String::from_utf8_lossy(&output.stdout) + ); +} + +#[test] +fn test_empty_stdin_does_not_hang_with_paging_always() { + // Use a non-interactive pager that exists on all platforms. + // On Windows, `more` is available; on Unix, `cat` is available. + let pager = if cfg!(windows) { "more" } else { "cat" }; + + let mut child = Command::new(delta_bin()) + .args(["--no-gitconfig", "--paging=always", &format!("--pager={}", pager)]) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .spawn() + .expect("failed to spawn delta"); + + child.stdin.take().unwrap().write_all(b"").unwrap(); + let output = child.wait_with_output().unwrap(); + + // --paging=always still starts the pager even when stdout is piped. + assert!( + output.status.success(), + "delta --paging=always exited with error on empty stdin: {}", + String::from_utf8_lossy(&output.stderr) + ); +}