diff --git a/crates/nu-command/src/filters/default.rs b/crates/nu-command/src/filters/default.rs index c9a1506d4b..f0dc641d5f 100644 --- a/crates/nu-command/src/filters/default.rs +++ b/crates/nu-command/src/filters/default.rs @@ -1,4 +1,5 @@ use nu_engine::command_prelude::*; +use nu_protocol::{ListStream, Signals}; #[derive(Clone)] pub struct Default; @@ -146,6 +147,20 @@ fn default( && matches!(input, PipelineData::Value(ref value, _) if value.is_empty())) { Ok(value.into_pipeline_data()) + } else if default_when_empty && matches!(input, PipelineData::ListStream(..)) { + let PipelineData::ListStream(ls, metadata) = input else { + unreachable!() + }; + let span = ls.span(); + let mut stream = ls.into_inner().peekable(); + if stream.peek().is_none() { + return Ok(value.into_pipeline_data()); + } + + // stream's internal state already preserves the original signals config, so if this + // Signals::empty list stream gets interrupted it will be caught by the underlying iterator + let ls = ListStream::new(stream, span, Signals::empty()); + Ok(PipelineData::ListStream(ls, metadata)) } else { Ok(input) } diff --git a/crates/nu-command/tests/commands/default.rs b/crates/nu-command/tests/commands/default.rs index 1669aea4d1..b17e334b12 100644 --- a/crates/nu-command/tests/commands/default.rs +++ b/crates/nu-command/tests/commands/default.rs @@ -1,4 +1,4 @@ -use nu_test_support::{nu, pipeline}; +use nu_test_support::{fs::Stub::EmptyFile, nu, pipeline, playground::Playground}; #[test] fn adds_row_data_if_column_missing() { @@ -112,3 +112,41 @@ fn do_not_replace_empty_record() { let actual = nu!(r#"{} | default {a:5} | columns | length"#); assert_eq!(actual.out, "0"); } + +#[test] +fn replace_empty_list_stream() { + // This is specific for testing ListStreams when empty behave like other empty values + Playground::setup("glob_empty_list", |dirs, sandbox| { + sandbox.with_files(&[ + EmptyFile("yehuda.txt"), + EmptyFile("jttxt"), + EmptyFile("andres.txt"), + ]); + + let actual = nu!( + cwd: dirs.test(), + "glob ? | default -e void", + ); + + assert_eq!(actual.out, "void"); + }) +} + +#[test] +fn do_not_replace_non_empty_list_stream() { + // This is specific for testing ListStreams when empty behave like other empty values + Playground::setup("glob_non_empty_list", |dirs, sandbox| { + sandbox.with_files(&[ + EmptyFile("yehuda.txt"), + EmptyFile("jt.rs"), + EmptyFile("andres.txt"), + ]); + + let actual = nu!( + cwd: dirs.test(), + "glob '*.txt' | default -e void | length", + ); + + assert_eq!(actual.out, "2"); + }) +}