summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/nu-cli/src/completions/completer.rs2
-rw-r--r--crates/nu-cli/src/menus/menu_completions.rs2
-rw-r--r--crates/nu-cli/src/reedline_config.rs2
-rw-r--r--crates/nu-cmd-lang/src/core_commands/do_.rs5
-rw-r--r--crates/nu-cmd-lang/src/core_commands/let_.rs2
-rw-r--r--crates/nu-cmd-lang/src/core_commands/mut_.rs2
-rw-r--r--crates/nu-cmd-lang/src/example_support.rs4
-rw-r--r--crates/nu-command/src/filesystem/save.rs2
-rw-r--r--crates/nu-command/src/filters/tee.rs10
-rw-r--r--crates/nu-command/src/system/complete.rs2
-rw-r--r--crates/nu-command/src/system/run_external.rs4
-rw-r--r--crates/nu-command/tests/commands/try_.rs12
-rw-r--r--crates/nu-engine/src/compile/call.rs2
-rw-r--r--crates/nu-engine/src/compile/expression.rs22
-rw-r--r--crates/nu-engine/src/compile/keyword.rs16
-rw-r--r--crates/nu-engine/src/compile/operator.rs12
-rw-r--r--crates/nu-engine/src/compile/redirect.rs9
-rw-r--r--crates/nu-engine/src/documentation.rs6
-rw-r--r--crates/nu-engine/src/eval.rs8
-rw-r--r--crates/nu-engine/src/eval_ir.rs3
-rw-r--r--crates/nu-explore/src/nu_common/command.rs4
-rw-r--r--crates/nu-plugin-engine/src/context.rs8
-rw-r--r--crates/nu-plugin-engine/src/persistent.rs2
-rw-r--r--crates/nu-plugin-test-support/src/plugin_test.rs2
-rw-r--r--crates/nu-protocol/src/engine/stack.rs21
-rw-r--r--crates/nu-protocol/src/engine/stack_out_dest.rs14
-rw-r--r--crates/nu-protocol/src/ir/display.rs9
-rw-r--r--crates/nu-protocol/src/ir/mod.rs3
-rw-r--r--crates/nu-protocol/src/pipeline/byte_stream.rs8
-rw-r--r--crates/nu-protocol/src/pipeline/out_dest.rs10
-rw-r--r--crates/nu-protocol/src/pipeline/pipeline_data.rs15
-rw-r--r--src/test_bins.rs2
32 files changed, 127 insertions, 98 deletions
diff --git a/crates/nu-cli/src/completions/completer.rs b/crates/nu-cli/src/completions/completer.rs
index f4e3b1e81..079425e2a 100644
--- a/crates/nu-cli/src/completions/completer.rs
+++ b/crates/nu-cli/src/completions/completer.rs
@@ -25,7 +25,7 @@ impl NuCompleter {
pub fn new(engine_state: Arc<EngineState>, stack: Arc<Stack>) -> Self {
Self {
engine_state,
- stack: Stack::with_parent(stack).reset_out_dest().capture(),
+ stack: Stack::with_parent(stack).reset_out_dest().collect_value(),
}
}
diff --git a/crates/nu-cli/src/menus/menu_completions.rs b/crates/nu-cli/src/menus/menu_completions.rs
index af653843f..4c4c9f59e 100644
--- a/crates/nu-cli/src/menus/menu_completions.rs
+++ b/crates/nu-cli/src/menus/menu_completions.rs
@@ -28,7 +28,7 @@ impl NuMenuCompleter {
Self {
block_id,
span,
- stack: stack.reset_out_dest().capture(),
+ stack: stack.reset_out_dest().collect_value(),
engine_state,
only_buffer_difference,
}
diff --git a/crates/nu-cli/src/reedline_config.rs b/crates/nu-cli/src/reedline_config.rs
index 71fd9f32e..6c3d45761 100644
--- a/crates/nu-cli/src/reedline_config.rs
+++ b/crates/nu-cli/src/reedline_config.rs
@@ -122,7 +122,7 @@ pub(crate) fn add_menus(
engine_state.merge_delta(delta)?;
- let mut temp_stack = Stack::new().capture();
+ let mut temp_stack = Stack::new().collect_value();
let input = PipelineData::Empty;
menu_eval_results.push(eval_block::<WithoutDebug>(
&engine_state,
diff --git a/crates/nu-cmd-lang/src/core_commands/do_.rs b/crates/nu-cmd-lang/src/core_commands/do_.rs
index 742bc3d21..3a48c6674 100644
--- a/crates/nu-cmd-lang/src/core_commands/do_.rs
+++ b/crates/nu-cmd-lang/src/core_commands/do_.rs
@@ -166,7 +166,10 @@ impl Command for Do {
}
Ok(PipelineData::ByteStream(mut stream, metadata))
if ignore_program_errors
- && !matches!(caller_stack.stdout(), OutDest::Pipe | OutDest::Capture) =>
+ && !matches!(
+ caller_stack.stdout(),
+ OutDest::Pipe | OutDest::PipeSeparate | OutDest::Value
+ ) =>
{
if let ByteStreamSource::Child(child) = stream.source_mut() {
child.ignore_error();
diff --git a/crates/nu-cmd-lang/src/core_commands/let_.rs b/crates/nu-cmd-lang/src/core_commands/let_.rs
index 3e0b2f97e..b7deca5b8 100644
--- a/crates/nu-cmd-lang/src/core_commands/let_.rs
+++ b/crates/nu-cmd-lang/src/core_commands/let_.rs
@@ -63,7 +63,7 @@ impl Command for Let {
let block = engine_state.get_block(block_id);
let eval_block = get_eval_block(engine_state);
- let stack = &mut stack.start_capture();
+ let stack = &mut stack.start_collect_value();
let pipeline_data = eval_block(engine_state, stack, block, input)?;
let value = pipeline_data.into_value(call.head)?;
diff --git a/crates/nu-cmd-lang/src/core_commands/mut_.rs b/crates/nu-cmd-lang/src/core_commands/mut_.rs
index a72d8f484..785a47f94 100644
--- a/crates/nu-cmd-lang/src/core_commands/mut_.rs
+++ b/crates/nu-cmd-lang/src/core_commands/mut_.rs
@@ -63,7 +63,7 @@ impl Command for Mut {
let block = engine_state.get_block(block_id);
let eval_block = get_eval_block(engine_state);
- let stack = &mut stack.start_capture();
+ let stack = &mut stack.start_collect_value();
let pipeline_data = eval_block(engine_state, stack, block, input)?;
let value = pipeline_data.into_value(call.head)?;
diff --git a/crates/nu-cmd-lang/src/example_support.rs b/crates/nu-cmd-lang/src/example_support.rs
index 8df5a6c1e..e430c35c4 100644
--- a/crates/nu-cmd-lang/src/example_support.rs
+++ b/crates/nu-cmd-lang/src/example_support.rs
@@ -126,7 +126,7 @@ pub fn eval_block(
cwd: &std::path::Path,
engine_state: &EngineState,
) -> Value {
- let mut stack = Stack::new().capture();
+ let mut stack = Stack::new().collect_value();
stack.add_env_var("PWD".to_string(), Value::test_string(cwd.to_string_lossy()));
@@ -143,7 +143,7 @@ pub fn check_example_evaluates_to_expected_output(
cwd: &std::path::Path,
engine_state: &mut Box<EngineState>,
) {
- let mut stack = Stack::new().capture();
+ let mut stack = Stack::new().collect_value();
// Set up PWD
stack.add_env_var("PWD".to_string(), Value::test_string(cwd.to_string_lossy()));
diff --git a/crates/nu-command/src/filesystem/save.rs b/crates/nu-command/src/filesystem/save.rs
index 1b6ddd598..f14ed2547 100644
--- a/crates/nu-command/src/filesystem/save.rs
+++ b/crates/nu-command/src/filesystem/save.rs
@@ -270,7 +270,7 @@ impl Command for Save {
}
fn pipe_redirection(&self) -> (Option<OutDest>, Option<OutDest>) {
- (Some(OutDest::Capture), Some(OutDest::Capture))
+ (Some(OutDest::PipeSeparate), Some(OutDest::PipeSeparate))
}
}
diff --git a/crates/nu-command/src/filters/tee.rs b/crates/nu-command/src/filters/tee.rs
index 65c0aba54..02afdc527 100644
--- a/crates/nu-command/src/filters/tee.rs
+++ b/crates/nu-command/src/filters/tee.rs
@@ -158,7 +158,7 @@ use it in your pipeline."#
let tee_thread = spawn_tee(info.clone(), eval_block)?;
let tee = IoTee::new(stderr, tee_thread);
match stack.stderr() {
- OutDest::Pipe | OutDest::Capture => {
+ OutDest::Pipe | OutDest::PipeSeparate | OutDest::Value => {
child.stderr = Some(ChildPipe::Tee(Box::new(tee)));
Ok(None)
}
@@ -176,7 +176,7 @@ use it in your pipeline."#
if let Some(stdout) = child.stdout.take() {
match stack.stdout() {
- OutDest::Pipe | OutDest::Capture => {
+ OutDest::Pipe | OutDest::PipeSeparate | OutDest::Value => {
child.stdout = Some(stdout);
Ok(())
}
@@ -191,7 +191,7 @@ use it in your pipeline."#
let stderr_thread = if let Some(stderr) = child.stderr.take() {
let info = info.clone();
match stack.stderr() {
- OutDest::Pipe | OutDest::Capture => {
+ OutDest::Pipe | OutDest::PipeSeparate | OutDest::Value => {
child.stderr = Some(stderr);
Ok(None)
}
@@ -213,7 +213,7 @@ use it in your pipeline."#
let tee_thread = spawn_tee(info.clone(), eval_block)?;
let tee = IoTee::new(stdout, tee_thread);
match stack.stdout() {
- OutDest::Pipe | OutDest::Capture => {
+ OutDest::Pipe | OutDest::PipeSeparate | OutDest::Value => {
child.stdout = Some(ChildPipe::Tee(Box::new(tee)));
Ok(())
}
@@ -280,7 +280,7 @@ use it in your pipeline."#
}
fn pipe_redirection(&self) -> (Option<OutDest>, Option<OutDest>) {
- (Some(OutDest::Capture), Some(OutDest::Capture))
+ (Some(OutDest::PipeSeparate), Some(OutDest::PipeSeparate))
}
}
diff --git a/crates/nu-command/src/system/complete.rs b/crates/nu-command/src/system/complete.rs
index 948f8acec..21b33ac65 100644
--- a/crates/nu-command/src/system/complete.rs
+++ b/crates/nu-command/src/system/complete.rs
@@ -93,6 +93,6 @@ impl Command for Complete {
}
fn pipe_redirection(&self) -> (Option<OutDest>, Option<OutDest>) {
- (Some(OutDest::Capture), Some(OutDest::Capture))
+ (Some(OutDest::PipeSeparate), Some(OutDest::PipeSeparate))
}
}
diff --git a/crates/nu-command/src/system/run_external.rs b/crates/nu-command/src/system/run_external.rs
index 70a00bc81..80c1c94e2 100644
--- a/crates/nu-command/src/system/run_external.rs
+++ b/crates/nu-command/src/system/run_external.rs
@@ -340,7 +340,7 @@ fn write_pipeline_data(
} else if let PipelineData::Value(Value::Binary { val, .. }, ..) = data {
writer.write_all(&val)?;
} else {
- stack.start_capture();
+ stack.start_collect_value();
// Turn off color as we pass data through
Arc::make_mut(&mut engine_state.config).use_ansi_coloring = false;
@@ -367,7 +367,7 @@ pub fn command_not_found(
) -> ShellError {
// Run the `command_not_found` hook if there is one.
if let Some(hook) = &stack.get_config(engine_state).hooks.command_not_found {
- let mut stack = stack.start_capture();
+ let mut stack = stack.start_collect_value();
// Set a special environment variable to avoid infinite loops when the
// `command_not_found` hook triggers itself.
let canary = "ENTERED_COMMAND_NOT_FOUND";
diff --git a/crates/nu-command/tests/commands/try_.rs b/crates/nu-command/tests/commands/try_.rs
index 58d1c8f80..dc8c7ba5f 100644
--- a/crates/nu-command/tests/commands/try_.rs
+++ b/crates/nu-command/tests/commands/try_.rs
@@ -105,3 +105,15 @@ fn exit_code_available_in_catch() {
let actual = nu!("try { nu -c 'exit 42' } catch { |e| $e.exit_code }");
assert_eq!(actual.out, "42");
}
+
+#[test]
+fn try_catches_exit_code_in_assignment() {
+ let actual = nu!("let x = try { nu -c 'exit 42' } catch { |e| $e.exit_code }; $x");
+ assert_eq!(actual.out, "42");
+}
+
+#[test]
+fn try_catches_exit_code_in_expr() {
+ let actual = nu!("print (try { nu -c 'exit 42' } catch { |e| $e.exit_code })");
+ assert_eq!(actual.out, "42");
+}
diff --git a/crates/nu-engine/src/compile/call.rs b/crates/nu-engine/src/compile/call.rs
index d9f1b8e58..e928b6382 100644
--- a/crates/nu-engine/src/compile/call.rs
+++ b/crates/nu-engine/src/compile/call.rs
@@ -108,7 +108,7 @@ pub(crate) fn compile_call(
working_set,
builder,
expr,
- RedirectModes::capture_out(arg.span()),
+ RedirectModes::value(arg.span()),
None,
arg_reg,
)?;
diff --git a/crates/nu-engine/src/compile/expression.rs b/crates/nu-engine/src/compile/expression.rs
index 80fc4fb3f..0badb76b4 100644
--- a/crates/nu-engine/src/compile/expression.rs
+++ b/crates/nu-engine/src/compile/expression.rs
@@ -90,7 +90,7 @@ pub(crate) fn compile_expression(
working_set,
builder,
part_expr,
- RedirectModes::capture_out(part_expr.span),
+ RedirectModes::value(part_expr.span),
None,
reg,
)?;
@@ -148,7 +148,7 @@ pub(crate) fn compile_expression(
working_set,
builder,
subexpr,
- RedirectModes::capture_out(subexpr.span),
+ RedirectModes::value(subexpr.span),
None,
out_reg,
)?;
@@ -217,7 +217,7 @@ pub(crate) fn compile_expression(
working_set,
builder,
expr,
- RedirectModes::capture_out(expr.span),
+ RedirectModes::value(expr.span),
None,
reg,
)?;
@@ -265,7 +265,7 @@ pub(crate) fn compile_expression(
working_set,
builder,
column,
- RedirectModes::capture_out(column.span),
+ RedirectModes::value(column.span),
None,
reg,
)?;
@@ -290,7 +290,7 @@ pub(crate) fn compile_expression(
working_set,
builder,
item,
- RedirectModes::capture_out(item.span),
+ RedirectModes::value(item.span),
None,
item_reg,
)?;
@@ -337,7 +337,7 @@ pub(crate) fn compile_expression(
working_set,
builder,
key,
- RedirectModes::capture_out(key.span),
+ RedirectModes::value(key.span),
None,
key_reg,
)?;
@@ -345,7 +345,7 @@ pub(crate) fn compile_expression(
working_set,
builder,
val,
- RedirectModes::capture_out(val.span),
+ RedirectModes::value(val.span),
None,
val_reg,
)?;
@@ -365,7 +365,7 @@ pub(crate) fn compile_expression(
working_set,
builder,
expr,
- RedirectModes::capture_out(expr.span),
+ RedirectModes::value(expr.span),
None,
reg,
)?;
@@ -449,7 +449,7 @@ pub(crate) fn compile_expression(
// general, which shouldn't be captured any differently than they otherwise
// would be.
if !full_cell_path.tail.is_empty() {
- RedirectModes::capture_out(expr.span)
+ RedirectModes::value(expr.span)
} else {
redirect_modes
},
@@ -491,7 +491,7 @@ pub(crate) fn compile_expression(
working_set,
builder,
exprs_iter.next().expect("peek() was Some"),
- RedirectModes::capture_out(expr.span),
+ RedirectModes::value(expr.span),
None,
out_reg,
)?;
@@ -507,7 +507,7 @@ pub(crate) fn compile_expression(
working_set,
builder,
expr,
- RedirectModes::capture_out(expr.span),
+ RedirectModes::value(expr.span),
None,
scratch_reg,
)?;
diff --git a/crates/nu-engine/src/compile/keyword.rs b/crates/nu-engine/src/compile/keyword.rs
index f9a81ab6d..62c5b7108 100644
--- a/crates/nu-engine/src/compile/keyword.rs
+++ b/crates/nu-engine/src/compile/keyword.rs
@@ -47,7 +47,7 @@ pub(crate) fn compile_if(
working_set,
builder,
condition,
- RedirectModes::capture_out(condition.span),
+ RedirectModes::value(condition.span),
None,
condition_reg,
)?;
@@ -181,7 +181,7 @@ pub(crate) fn compile_match(
working_set,
builder,
match_expr,
- RedirectModes::capture_out(match_expr.span),
+ RedirectModes::value(match_expr.span),
None,
match_reg,
)?;
@@ -233,7 +233,7 @@ pub(crate) fn compile_match(
working_set,
builder,
guard,
- RedirectModes::capture_out(guard.span),
+ RedirectModes::value(guard.span),
None,
guard_reg,
)?;
@@ -319,7 +319,7 @@ pub(crate) fn compile_let(
working_set,
builder,
block,
- RedirectModes::capture_out(call.head),
+ RedirectModes::value(call.head),
Some(io_reg),
io_reg,
)?;
@@ -427,7 +427,7 @@ pub(crate) fn compile_try(
working_set,
builder,
catch_expr,
- RedirectModes::capture_out(catch_expr.span),
+ RedirectModes::value(catch_expr.span),
None,
closure_reg,
)?;
@@ -655,7 +655,7 @@ pub(crate) fn compile_while(
working_set,
builder,
cond_arg,
- RedirectModes::capture_out(call.head),
+ RedirectModes::value(call.head),
None,
io_reg,
)?;
@@ -739,7 +739,7 @@ pub(crate) fn compile_for(
working_set,
builder,
in_expr,
- RedirectModes::capture_out(in_expr.span),
+ RedirectModes::value(in_expr.span),
None,
stream_reg,
)?;
@@ -867,7 +867,7 @@ pub(crate) fn compile_return(
working_set,
builder,
arg_expr,
- RedirectModes::capture_out(arg_expr.span),
+ RedirectModes::value(arg_expr.span),
None,
io_reg,
)?;
diff --git a/crates/nu-engine/src/compile/operator.rs b/crates/nu-engine/src/compile/operator.rs
index a1ed3f66d..bad206358 100644
--- a/crates/nu-engine/src/compile/operator.rs
+++ b/crates/nu-engine/src/compile/operator.rs
@@ -35,7 +35,7 @@ pub(crate) fn compile_binary_op(
working_set,
builder,
rhs,
- RedirectModes::capture_out(rhs.span),
+ RedirectModes::value(rhs.span),
None,
out_reg,
)?;
@@ -53,7 +53,7 @@ pub(crate) fn compile_binary_op(
working_set,
builder,
lhs,
- RedirectModes::capture_out(lhs.span),
+ RedirectModes::value(lhs.span),
None,
lhs_reg,
)?;
@@ -73,7 +73,7 @@ pub(crate) fn compile_binary_op(
working_set,
builder,
rhs,
- RedirectModes::capture_out(rhs.span),
+ RedirectModes::value(rhs.span),
None,
lhs_reg,
)?;
@@ -96,7 +96,7 @@ pub(crate) fn compile_binary_op(
working_set,
builder,
rhs,
- RedirectModes::capture_out(rhs.span),
+ RedirectModes::value(rhs.span),
None,
lhs_reg,
)?;
@@ -118,7 +118,7 @@ pub(crate) fn compile_binary_op(
working_set,
builder,
rhs,
- RedirectModes::capture_out(rhs.span),
+ RedirectModes::value(rhs.span),
None,
rhs_reg,
)?;
@@ -277,7 +277,7 @@ pub(crate) fn compile_assignment(
working_set,
builder,
&path.head,
- RedirectModes::capture_out(path.head.span),
+ RedirectModes::value(path.head.span),
None,
head_reg,
)?;
diff --git a/crates/nu-engine/src/compile/redirect.rs b/crates/nu-engine/src/compile/redirect.rs
index 15af1a9f8..eaedd6521 100644
--- a/crates/nu-engine/src/compile/redirect.rs
+++ b/crates/nu-engine/src/compile/redirect.rs
@@ -14,9 +14,9 @@ pub(crate) struct RedirectModes {
}
impl RedirectModes {
- pub(crate) fn capture_out(span: Span) -> Self {
+ pub(crate) fn value(span: Span) -> Self {
RedirectModes {
- out: Some(RedirectMode::Capture.into_spanned(span)),
+ out: Some(RedirectMode::Value.into_spanned(span)),
err: None,
}
}
@@ -46,7 +46,7 @@ pub(crate) fn redirection_target_to_mode(
working_set,
builder,
expr,
- RedirectModes::capture_out(*redir_span),
+ RedirectModes::value(*redir_span),
None,
path_reg,
)?;
@@ -148,7 +148,8 @@ pub(crate) fn out_dest_to_redirect_mode(
out_dest
.map(|out_dest| match out_dest {
OutDest::Pipe => Ok(RedirectMode::Pipe),
- OutDest::Capture => Ok(RedirectMode::Capture),
+ OutDest::PipeSeparate => Ok(RedirectMode::PipeSeparate),
+ OutDest::Value => Ok(RedirectMode::Value),
OutDest::Null => Ok(RedirectMode::Null),
OutDest::Inherit => Ok(RedirectMode::Inherit),
OutDest::File(_) => Err(CompileError::InvalidRedirectMode { span }),
diff --git a/crates/nu-engine/src/documentation.rs b/crates/nu-engine/src/documentation.rs
index 9d7ea7f8f..92f2c3b92 100644
--- a/crates/nu-engine/src/documentation.rs
+++ b/crates/nu-engine/src/documentation.rs
@@ -23,7 +23,7 @@ pub fn get_full_help(
// internally call several commands (`table`, `ansi`, `nu-highlight`) and get their
// `PipelineData` using this `Stack`, any other output should not be redirected like the main
// execution.
- let stack = &mut stack.start_capture();
+ let stack = &mut stack.start_collect_value();
let signature = engine_state
.get_signature(command)
@@ -202,7 +202,7 @@ fn get_documentation(
));
}
- let caller_stack = &mut Stack::new().capture();
+ let caller_stack = &mut Stack::new().collect_value();
if let Ok(result) = eval_call::<WithoutDebug>(
engine_state,
caller_stack,
@@ -329,7 +329,7 @@ fn update_ansi_from_config(
theme_component: &str,
) {
if let Some(color) = &nu_config.color_config.get(theme_component) {
- let caller_stack = &mut Stack::new().capture();
+ let caller_stack = &mut Stack::new().collect_value();
let span = Span::unknown();
let span_id = UNKNOWN_SPAN_ID;
diff --git a/crates/nu-engine/src/eval.rs b/crates/nu-engine/src/eval.rs
index ccb494e68..f0effb9a3 100644
--- a/crates/nu-engine/src/eval.rs
+++ b/crates/nu-engine/src/eval.rs
@@ -235,7 +235,7 @@ pub fn eval_expression<D: DebugContext>(
stack: &mut Stack,
expr: &Expression,
) -> Result<Value, ShellError> {
- let stack = &mut stack.start_capture();
+ let stack = &mut stack.start_collect_value();
<EvalRuntime as Eval>::eval::<D>(engine_state, stack, expr)
}
@@ -278,7 +278,7 @@ pub fn eval_expression_with_input<D: DebugContext>(
let block = engine_state.get_block(*block_id);
if !full_cell_path.tail.is_empty() {
- let stack = &mut stack.start_capture();
+ let stack = &mut stack.start_collect_value();
// FIXME: protect this collect with ctrl-c
input = eval_subexpression::<D>(engine_state, stack, block, input)?
.into_value(*span)?
@@ -325,7 +325,7 @@ fn eval_redirection<D: DebugContext>(
}
RedirectionTarget::Pipe { .. } => {
let dest = match next_out {
- None | Some(OutDest::Capture) => OutDest::Pipe,
+ None | Some(OutDest::PipeSeparate) => OutDest::Pipe,
Some(next) => next,
};
Ok(Redirection::Pipe(dest))
@@ -357,7 +357,7 @@ fn eval_element_redirection<D: DebugContext>(
let stderr = eval_redirection::<D>(engine_state, stack, target, None)?;
if matches!(stderr, Redirection::Pipe(OutDest::Pipe)) {
let dest = match next_out {
- None | Some(OutDest::Capture) => OutDest::Pipe,
+ None | Some(OutDest::PipeSeparate) => OutDest::Pipe,
Some(next) => next,
};
// e>| redirection, don't override current stack `stdout`
diff --git a/crates/nu-engine/src/eval_ir.rs b/crates/nu-engine/src/eval_ir.rs
index 7cc4e0267..790016cb1 100644
--- a/crates/nu-engine/src/eval_ir.rs
+++ b/crates/nu-engine/src/eval_ir.rs
@@ -1414,7 +1414,8 @@ fn eval_redirection(
) -> Result<Option<Redirection>, ShellError> {
match mode {
RedirectMode::Pipe => Ok(Some(Redirection::Pipe(OutDest::Pipe))),
- RedirectMode::Capture => Ok(Some(Redirection::Pipe(OutDest::Capture))),
+ RedirectMode::PipeSeparate => Ok(Some(Redirection::Pipe(OutDest::PipeSeparate))),
+ RedirectMode::Value => Ok(Some(Redirection::Pipe(OutDest::Value))),
RedirectMode::Null => Ok(Some(Redirection::Pipe(OutDest::Null))),
RedirectMode::Inherit => Ok(Some(Redirection::Pipe(OutDest::Inherit))),
RedirectMode::File { file_num } => {
diff --git a/crates/nu-explore/src/nu_common/command.rs b/crates/nu-explore/src/nu_common/command.rs
index 269382d1f..ef0157ac6 100644
--- a/crates/nu-explore/src/nu_common/command.rs
+++ b/crates/nu-explore/src/nu_common/command.rs
@@ -96,8 +96,8 @@ fn eval_source2(
}
let stack = &mut stack.push_redirection(
- Some(Redirection::Pipe(OutDest::Capture)),
- Some(Redirection::Pipe(OutDest::Capture)),
+ Some(Redirection::Pipe(OutDest::PipeSeparate)),
+ Some(Redirection::Pipe(OutDest::PipeSeparate)),
);
eval_block::<WithoutDebug>(engine_state, stack, &block, input)
}
diff --git a/crates/nu-plugin-engine/src/context.rs b/crates/nu-plugin-engine/src/context.rs
index 160ce802b..6b6b1a15f 100644
--- a/crates/nu-plugin-engine/src/context.rs
+++ b/crates/nu-plugin-engine/src/context.rs
@@ -190,8 +190,8 @@ impl<'a> PluginExecutionContext for PluginExecutionCommandContext<'a> {
.reset_pipes();
let stack = &mut stack.push_redirection(
- redirect_stdout.then_some(Redirection::Pipe(OutDest::Capture)),
- redirect_stderr.then_some(Redirection::Pipe(OutDest::Capture)),
+ redirect_stdout.then_some(Redirection::Pipe(OutDest::PipeSeparate)),
+ redirect_stderr.then_some(Redirection::Pipe(OutDest::PipeSeparate)),
);
// Set up the positional arguments
@@ -239,8 +239,8 @@ impl<'a> PluginExecutionContext for PluginExecutionCommandContext<'a> {
let decl = self.engine_state.get_decl(decl_id);
let stack = &mut self.stack.push_redirection(
- redirect_stdout.then_some(Redirection::Pipe(OutDest::Capture)),
- redirect_stderr.then_some(Redirection::Pipe(OutDest::Capture)),
+ redirect_stdout.then_some(Redirection::Pipe(OutDest::PipeSeparate)),
+ redirect_stderr.then_some(Redirection::Pipe(OutDest::PipeSeparate)),
);
let mut call_builder = ir::Call::build(decl_id, call.head);
diff --git a/crates/nu-plugin-engine/src/persistent.rs b/crates/nu-plugin-engine/src/persistent.rs
index f9dcc5143..e664b37f8 100644
--- a/crates/nu-plugin-engine/src/persistent.rs
+++ b/crates/nu-plugin-engine/src/persistent.rs
@@ -353,7 +353,7 @@ impl GetPlugin for PersistentPlugin {
// We need the current environment variables for `python` based plugins. Or
// we'll likely have a problem when a plugin is implemented in a virtual Python
// environment.
- let stack = &mut stack.start_capture();
+ let stack = &mut stack.start_collect_value();
nu_engine::env::env_to_strings(engine_state, stack)
})
.transpose()?;
diff --git a/crates/nu-plugin-test-support/src/plugin_test.rs b/crates/nu-plugin-test-support/src/plugin_test.rs
index d414887e8..1d6667482 100644
--- a/crates/nu-plugin-test-support/src/plugin_test.rs
+++ b/crates/nu-plugin-test-support/src/plugin_test.rs
@@ -156,7 +156,7 @@ impl PluginTest {
};
// Eval the block with the input
- let mut stack = Stack::new().capture();
+ let mut stack = Stack::new().collect_value();
let data = eval_block::<WithoutDebug>(&self.engine_state, &mut stack, &block, input)?;
if matches!(data, PipelineData::ByteStream(..)) {
Ok(data)
diff --git a/crates/nu-protocol/src/engine/stack.rs b/crates/nu-protocol/src/engine/stack.rs
index 854b338c1..843315871 100644
--- a/crates/nu-protocol/src/engine/stack.rs
+++ b/crates/nu-protocol/src/engine/stack.rs
@@ -1,7 +1,7 @@
use crate::{
engine::{
ArgumentStack, EngineState, ErrorHandlerStack, Redirection, StackCallArgGuard,
- StackCaptureGuard, StackIoGuard, StackOutDest, DEFAULT_OVERLAY_NAME,
+ StackCollectValueGuard, StackIoGuard, StackOutDest, DEFAULT_OVERLAY_NAME,
},
Config, OutDest, ShellError, Span, Value, VarId, ENV_VARIABLE_ID, NU_VARIABLE_ID,
};
@@ -68,7 +68,7 @@ impl Stack {
/// stdout and stderr will be set to [`OutDest::Inherit`]. So, if the last command is an external command,
/// then its output will be forwarded to the terminal/stdio streams.
///
- /// Use [`Stack::capture`] afterwards if you need to evaluate an expression to a [`Value`]
+ /// Use [`Stack::collect_value`] afterwards if you need to evaluate an expression to a [`Value`]
/// (as opposed to a [`PipelineData`](crate::PipelineData)).
pub fn new() -> Self {
Self {
@@ -299,7 +299,8 @@ impl Stack {
}
pub fn captures_to_stack(&self, captures: Vec<(VarId, Value)>) -> Stack {
- self.captures_to_stack_preserve_out_dest(captures).capture()
+ self.captures_to_stack_preserve_out_dest(captures)
+ .collect_value()
}
pub fn captures_to_stack_preserve_out_dest(&self, captures: Vec<(VarId, Value)>) -> Stack {
@@ -589,11 +590,11 @@ impl Stack {
self.out_dest.pipe_stderr.as_ref()
}
- /// Temporarily set the pipe stdout redirection to [`OutDest::Capture`].
+ /// Temporarily set the pipe stdout redirection to [`OutDest::Value`].
///
/// This is used before evaluating an expression into a `Value`.
- pub fn start_capture(&mut self) -> StackCaptureGuard {
- StackCaptureGuard::new(self)
+ pub fn start_collect_value(&mut self) -> StackCollectValueGuard {
+ StackCollectValueGuard::new(self)
}
/// Temporarily use the output redirections in the parent scope.
@@ -612,14 +613,14 @@ impl Stack {
StackIoGuard::new(self, stdout, stderr)
}
- /// Mark stdout for the last command as [`OutDest::Capture`].
+ /// Mark stdout for the last command as [`OutDest::Value`].
///
/// This will irreversibly alter the output redirections, and so it only makes sense to use this on an owned `Stack`
/// (which is why this function does not take `&mut self`).
///
- /// See [`Stack::start_capture`] which can temporarily set stdout as [`OutDest::Capture`] for a mutable `Stack` reference.
- pub fn capture(mut self) -> Self {
- self.out_dest.pipe_stdout = Some(OutDest::Capture);
+ /// See [`Stack::start_collect_value`] which can temporarily set stdout as [`OutDest::Value`] for a mutable `Stack` reference.
+ pub fn collect_value(mut self) -> Self {
+ self.out_dest.pipe_stdout = Some(OutDest::Value);
self.out_dest.pipe_stderr = None;
self
}
diff --git a/crates/nu-protocol/src/engine/stack_out_dest.rs b/crates/nu-protocol/src/engine/stack_out_dest.rs
index 7699d29ed..b11177ec3 100644
--- a/crates/nu-protocol/src/engine/stack_out_dest.rs
+++ b/crates/nu-protocol/src/engine/stack_out_dest.rs
@@ -184,15 +184,15 @@ impl Drop for StackIoGuard<'_> {
}
}
-pub struct StackCaptureGuard<'a> {
+pub struct StackCollectValueGuard<'a> {
stack: &'a mut Stack,
old_pipe_stdout: Option<OutDest>,
old_pipe_stderr: Option<OutDest>,
}
-impl<'a> StackCaptureGuard<'a> {
+impl<'a> StackCollectValueGuard<'a> {
pub(crate) fn new(stack: &'a mut Stack) -> Self {
- let old_pipe_stdout = mem::replace(&mut stack.out_dest.pipe_stdout, Some(OutDest::Capture));
+ let old_pipe_stdout = mem::replace(&mut stack.out_dest.pipe_stdout, Some(OutDest::Value));
let old_pipe_stderr = stack.out_dest.pipe_stderr.take();
Self {
stack,
@@ -202,7 +202,7 @@ impl<'a> StackCaptureGuard<'a> {
}
}
-impl<'a> Deref for StackCaptureGuard<'a> {
+impl<'a> Deref for StackCollectValueGuard<'a> {
type Target = Stack;
fn deref(&self) -> &Self::Target {
@@ -210,13 +210,13 @@ impl<'a> Deref for StackCaptureGuard<'a> {
}
}
-impl<'a> DerefMut for StackCaptureGuard<'a> {
+impl<'a> DerefMut for StackCollectValueGuard<'a> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.stack
}
}
-impl Drop for StackCaptureGuard<'_> {
+impl Drop for StackCollectValueGuard<'_> {
fn drop(&mut self) {
self.out_dest.pipe_stdout = self.old_pipe_stdout.take();
self.out_dest.pipe_stderr = self.old_pipe_stderr.take();
@@ -233,7 +233,7 @@ pub struct StackCallArgGuard<'a> {
impl<'a> StackCallArgGuard<'a> {
pub(crate) fn new(stack: &'a mut Stack) -> Self {
- let old_pipe_stdout = mem::replace(&mut stack.out_dest.pipe_stdout, Some(OutDest::Capture));
+ let old_pipe_stdout = mem::replace(&mut stack.out_dest.pipe_stdout, Some(OutDest::Value));
let old_pipe_stderr = stack.out_dest.pipe_stderr.take();
let old_stdout = stack
diff --git a/crates/nu-protocol/src/ir/display.rs b/crates/nu-protocol/src/ir/display.rs
index feac8f961..0168306f8 100644
--- a/crates/nu-protocol/src/ir/display.rs
+++ b/crates/nu-protocol/src/ir/display.rs
@@ -1,8 +1,6 @@
-use std::fmt;
-
-use crate::{ast::Pattern, engine::EngineState, DeclId, VarId};
-
use super::{DataSlice, Instruction, IrBlock, Literal, RedirectMode};
+use crate::{ast::Pattern, engine::EngineState, DeclId, VarId};
+use std::fmt::{self};
pub struct FmtIrBlock<'a> {
pub(super) engine_state: &'a EngineState,
@@ -310,7 +308,8 @@ impl fmt::Display for RedirectMode {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
RedirectMode::Pipe => write!(f, "pipe"),
- RedirectMode::Capture => write!(f, "capture"),
+ RedirectMode::PipeSeparate => write!(f, "pipe separate"),
+ RedirectMode::Value => write!(f, "value"),
RedirectMode::Null => write!(f, "null"),
RedirectMode::Inherit => write!(f, "inherit"),
RedirectMode::File { file_num } => write!(f, "file({file_num})"),
diff --git a/crates/nu-protocol/src/ir/mod.rs b/crates/nu-protocol/src/ir/mod.rs
index c2f51f514..8c1bb5224 100644
--- a/crates/nu-protocol/src/ir/mod.rs
+++ b/crates/nu-protocol/src/ir/mod.rs
@@ -446,7 +446,8 @@ pub enum Literal {
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub enum RedirectMode {
Pipe,
- Capture,
+ PipeSeparate,
+ Value,
Null,
Inherit,
/// Use the given numbered file.
diff --git a/crates/nu-protocol/src/pipeline/byte_stream.rs b/crates/nu-protocol/src/pipeline/byte_stream.rs
index 6811b7b89..0dc03b309 100644
--- a/crates/nu-protocol/src/pipeline/byte_stream.rs
+++ b/crates/nu-protocol/src/pipeline/byte_stream.rs
@@ -580,8 +580,8 @@ impl ByteStream {
copy_with_signals(file, dest, span, signals)?;
}
ByteStreamSource::Child(mut child) => {
- // All `OutDest`s except `OutDest::Capture` will cause `stderr` to be `None`.
- // Only `save`, `tee`, and `complete` set the stderr `OutDest` to `OutDest::Capture`,
+ // All `OutDest`s except `OutDest::PipeSeparate` will cause `stderr` to be `None`.
+ // Only `save`, `tee`, and `complete` set the stderr `OutDest` to `OutDest::PipeSeparate`,
// and those commands have proper simultaneous handling of stdout and stderr.
debug_assert!(child.stderr.is_none(), "stderr should not exist");
@@ -614,7 +614,7 @@ impl ByteStream {
write_to_out_dest(read, stdout, true, span, signals)?;
}
ByteStreamSource::File(file) => match stdout {
- OutDest::Pipe | OutDest::Capture | OutDest::Null => {}
+ OutDest::Pipe | OutDest::PipeSeparate | OutDest::Value | OutDest::Null => {}
OutDest::Inherit => {
copy_with_signals(file, io::stdout(), span, signals)?;
}
@@ -970,7 +970,7 @@ fn write_to_out_dest(
signals: &Signals,
) -> Result<(), ShellError> {
match stream {
- OutDest::Pipe | OutDest::Capture => return Ok(()),
+ OutDest::Pipe | OutDest::PipeSeparate | OutDest::Value => return Ok(()),
OutDest::Null => copy_with_signals(read, io::sink(), span, signals),
OutDest::Inherit if stdout => copy_with_signals(read, io::stdout(), span, signals),
OutDest::Inherit => copy_with_signals(read, io::stderr(), span, signals),
diff --git a/crates/nu-protocol/src/pipeline/out_dest.rs b/crates/nu-protocol/src/pipeline/out_dest.rs
index 69955e6b0..8ea839537 100644
--- a/crates/nu-protocol/src/pipeline/out_dest.rs
+++ b/crates/nu-protocol/src/pipeline/out_dest.rs
@@ -10,13 +10,17 @@ pub enum OutDest {
/// If stdout and stderr are both set to `Pipe`,
/// then they will combined into the `stdout` of [`ChildProcess`](crate::process::ChildProcess).
Pipe,
- /// Capture output to later be collected into a [`Value`](crate::Value), `Vec`, or used in some other way.
+ /// Redirect the stdout and/or stderr of one command as the input for the next command in the pipeline.
///
/// The output stream(s) will be available in the `stdout` or `stderr` of [`ChildProcess`](crate::process::ChildProcess).
///
/// This is similar to `Pipe` but will never combine stdout and stderr
/// or place an external command's stderr into `stdout` of [`ChildProcess`](crate::process::ChildProcess).
- Capture,
+ PipeSeparate,
+ /// Signifies the result of the pipeline will be immediately collected into a value after this command.
+ ///
+ /// So, it is fine to collect the stream ahead of time in the current command.
+ Value,
/// Ignore output.
///
/// This will forward output to the null device for the platform.
@@ -46,7 +50,7 @@ impl TryFrom<&OutDest> for Stdio {
fn try_from(out_dest: &OutDest) -> Result<Self, Self::Error> {
match out_dest {
- OutDest::Pipe | OutDest::Capture => Ok(Self::piped()),
+ OutDest::Pipe | OutDest::PipeSeparate | OutDest::Value => Ok(Self::piped()),
OutDest::Null => Ok(Self::null()),
OutDest::Inherit => Ok(Self::inherit()),
OutDest::File(file) => Ok(file.try_clone()?.into()),
diff --git a/crates/nu-protocol/src/pipeline/pipeline_data.rs b/crates/nu-protocol/src/pipeline/pipeline_data.rs
index da0fea321..45704e2cf 100644
--- a/crates/nu-protocol/src/pipeline/pipeline_data.rs
+++ b/crates/nu-protocol/src/pipeline/pipeline_data.rs
@@ -167,8 +167,8 @@ impl PipelineData {
/// Writes all values or redirects all output to the current [`OutDest`]s in `stack`.
///
- /// For [`OutDest::Pipe`] and [`OutDest::Capture`], this will return the `PipelineData` as is
- /// without consuming input and without writing anything.
+ /// For [`OutDest::Pipe`] and [`OutDest::PipeSeparate`], this will return the `PipelineData` as
+ /// is without consuming input and without writing anything.
///
/// For the other [`OutDest`]s, the given `PipelineData` will be completely consumed
/// and `PipelineData::Empty` will be returned (assuming no errors).
@@ -178,11 +178,18 @@ impl PipelineData {
stack: &mut Stack,
) -> Result<PipelineData, ShellError> {
match (self, stack.stdout()) {
- (data, OutDest::Pipe | OutDest::Capture) => return Ok(data),
+ (PipelineData::Empty, ..) => {}
+ (data, OutDest::Pipe | OutDest::PipeSeparate) => return Ok(data),
+ (data, OutDest::Value) => {
+ let metadata = data.metadata();
+ let span = data.span().unwrap_or(Span::unknown());
+ return data
+ .into_value(span)
+ .map(|val| PipelineData::Value(val, metadata));
+ }
(PipelineData::ByteStream(stream, ..), stdout) => {
stream.write_to_out_dests(stdout, stack.stderr())?;
}
- (PipelineData::Empty, ..) => {}
(PipelineData::Value(..), OutDest::Null) => {}
(PipelineData::ListStream(stream, ..), OutDest::Null) => {
// we need to drain the stream in case there are external commands in the pipeline
diff --git a/src/test_bins.rs b/src/test_bins.rs
index d5ae92ec6..efa7e9dd7 100644
--- a/src/test_bins.rs
+++ b/src/test_bins.rs
@@ -337,7 +337,7 @@ pub fn nu_repl() {
let config = engine_state.get_config();
{
- let stack = &mut stack.start_capture();
+ let stack = &mut stack.start_collect_value();
match eval_block::<WithoutDebug>(&engine_state, stack, &block, input) {
Ok(pipeline_data) => match pipeline_data.collect_string("", config) {
Ok(s) => last_output = s,