Stefan Holderbach 95b78eee25
Change the usage misnomer to "description" (#13598)
# Description
    
The meaning of the word usage is specific to describing how a command
function is *used* and not a synonym for general description. Usage can
be used to describe the SYNOPSIS or EXAMPLES sections of a man page
where the permitted argument combinations are shown or example *uses*
are given.
Let's not confuse people and call it what it is a description.

Our `help` command already creates its own *Usage* section based on the
available arguments and doesn't refer to the description with usage.

# User-Facing Changes

`help commands` and `scope commands` will now use `description` or
`extra_description`
`usage`-> `description`
`extra_usage` -> `extra_description`

Breaking change in the plugin protocol:

In the signature record communicated with the engine.
`usage`-> `description`
`extra_usage` -> `extra_description`

The same rename also takes place for the methods on
`SimplePluginCommand` and `PluginCommand`

# Tests + Formatting
- Updated plugin protocol specific changes
# After Submitting
- [ ] update plugin protocol doc
2024-08-22 12:02:08 +02:00

130 lines
4.0 KiB
Rust

use nu_engine::{command_prelude::*, get_eval_block, redirect_env};
use nu_protocol::{engine::Closure, DataSource, PipelineMetadata};
#[derive(Clone)]
pub struct Collect;
impl Command for Collect {
fn name(&self) -> &str {
"collect"
}
fn signature(&self) -> Signature {
Signature::build("collect")
.input_output_types(vec![(Type::Any, Type::Any)])
.optional(
"closure",
SyntaxShape::Closure(Some(vec![SyntaxShape::Any])),
"The closure to run once the stream is collected.",
)
.switch(
"keep-env",
"let the closure affect environment variables",
None,
)
.category(Category::Filters)
}
fn description(&self) -> &str {
"Collect a stream into a value."
}
fn extra_description(&self) -> &str {
r#"If provided, run a closure with the collected value as input.
The entire stream will be collected into one value in memory, so if the stream
is particularly large, this can cause high memory usage."#
}
fn run(
&self,
engine_state: &EngineState,
stack: &mut Stack,
call: &Call,
input: PipelineData,
) -> Result<PipelineData, ShellError> {
let closure: Option<Closure> = call.opt(engine_state, stack, 0)?;
let metadata = match input.metadata() {
// Remove the `FilePath` metadata, because after `collect` it's no longer necessary to
// check where some input came from.
Some(PipelineMetadata {
data_source: DataSource::FilePath(_),
content_type: None,
}) => None,
other => other,
};
let input = input.into_value(call.head)?;
let result;
if let Some(closure) = closure {
let block = engine_state.get_block(closure.block_id);
let mut stack_captures =
stack.captures_to_stack_preserve_out_dest(closure.captures.clone());
let mut saved_positional = None;
if let Some(var) = block.signature.get_positional(0) {
if let Some(var_id) = &var.var_id {
stack_captures.add_var(*var_id, input.clone());
saved_positional = Some(*var_id);
}
}
let eval_block = get_eval_block(engine_state);
result = eval_block(
engine_state,
&mut stack_captures,
block,
input.into_pipeline_data_with_metadata(metadata),
);
if call.has_flag(engine_state, stack, "keep-env")? {
redirect_env(engine_state, stack, &stack_captures);
// for when we support `data | let x = $in;`
// remove the variables added earlier
for (var_id, _) in closure.captures {
stack_captures.remove_var(var_id);
}
if let Some(u) = saved_positional {
stack_captures.remove_var(u);
}
// add any new variables to the stack
stack.vars.extend(stack_captures.vars);
}
} else {
result = Ok(input.into_pipeline_data_with_metadata(metadata));
}
result
}
fn examples(&self) -> Vec<Example> {
vec![
Example {
description: "Use the second value in the stream",
example: "[1 2 3] | collect { |x| $x.1 }",
result: Some(Value::test_int(2)),
},
Example {
description: "Read and write to the same file",
example: "open file.txt | collect | save -f file.txt",
result: None,
},
]
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_examples() {
use crate::test_examples;
test_examples(Collect {})
}
}