mirror of
https://github.com/nushell/nushell.git
synced 2025-08-09 02:55:07 +02:00
Parameter defaults to $nu.scope.commands (#9152)
(*third* try at posting this PR, #9104, like #9084, got polluted with unrelated commits. I'm never going to pull from the github feature branch again!) # Description <!-- Thank you for improving Nushell. Please, check our [contributing guide](../CONTRIBUTING.md) and talk to the core team before making major changes. Description of your pull request goes here. **Provide examples and/or screenshots** if your changes affect the user experience. --> Show parameter defaults in scope command signature, where they're available for display by help. per https://github.com/nushell/nushell/issues/8928. I found unexpected ramifications in one completer (NuHelpCompleter) and plugins, which both use the flag-formatting routine from builtin help. For the moment I made the minimum necessary changes to get the mainline scenario to pass tests and run. But we should circle back on what to do with plugins and help completer.. # User-Facing Changes <!-- List of all changes that impact the user experience here. This helps us keep track of breaking changes. --> 1. New `parameter_default` column to `signatures` table in `$nu.scope.commands` It is populated with whatever parameters can be defaulted: currently positional args and named flags. 2. Built in help (both `help <command>` and `<command> --help` will display the defaults 3. Help completer will display defaults for flags, but not for positionals. Example: A custom command with some default parameters: ``` 〉cat ~/work/dflts.nu # sample function to show defaults in help export def main [ arg1: string # mandatory positional arg2:string=abc # optional positional --switch # no default here --named:int # named flag, no default --other:string=def # flag --hard:record<foo:int bar:string, bas:bool> # default can be compound type = {foo:22, bar:"other worlds", bas:false} ] { {arg1: $arg1, arg2: $arg2, switch: $switch, named: $named, other: $other, hard: $hard, } } 〉use ~/work/dflts.nu 〉$nu.scope.commands | where name == 'dflts' | get signatures.0.any | reject short_flag description custom_completion ╭───┬────────────────┬────────────────┬──────────────────────────────────────────┬─────────────┬───────────────────────────╮ │ # │ parameter_name │ parameter_type │ syntax_shape │ is_optional │ parameter_default │ ├───┼────────────────┼────────────────┼──────────────────────────────────────────┼─────────────┼───────────────────────────┤ │ 0 │ │ input │ any │ false │ │ │ 1 │ arg1 │ positional │ string │ false │ │ │ 2 │ arg2 │ positional │ string │ true │ abc │ │ 3 │ switch │ switch │ │ true │ │ │ 4 │ named │ named │ int │ true │ │ │ 5 │ other │ named │ string │ true │ def │ │ 6 │ hard │ named │ record<foo: int, bar: string, bas: bool> │ true │ ╭───────┬───────────────╮ │ │ │ │ │ │ │ │ foo │ 22 │ │ │ │ │ │ │ │ │ bar │ other worlds │ │ │ │ │ │ │ │ │ bas │ false │ │ │ │ │ │ │ │ ╰───────┴───────────────╯ │ │ 7 │ │ output │ any │ false │ │ ╰───┴────────────────┴────────────────┴──────────────────────────────────────────┴─────────────┴───────────────────────────╯ 〉help dflts sample function to show defaults in help Usage: > dflts {flags} <arg1> (arg2) Flags: --switch - switch -- no default here --named <Int> - named flag, typed, but no default --other <String> - flag with default (default: 'def') --hard <Record([("foo", Int), ("bar", String), ("bas", Boolean)])> - default can be compound type (default: {foo: 22, bar: 'other worlds', bas: false}) -h, --help - Display the help message for this command Parameters: arg1 <string>: mandatory positional arg2 <string>: optional positional (optional, default: 'abc') ``` Compared to (relevant bits of) help output previously: ``` Flags: -h, --help - Display the help message for this command -, --switch - no default here -, --named <int> - named flag, no default -, --other <string> - flag -, --hard <record<foo: int, bar: string, bas: bool>> - default can be compound type Signatures: <any> | dflts <string> <string> -> <any> Parameters: arg1 <string>: mandatory positional (optional) arg2 <string>: optional positional ``` # Tests + Formatting <!-- Don't forget to add tests that cover your changes. Make sure you've run and fixed any issues with these commands: - `cargo fmt --all -- --check` to check standard code formatting (`cargo fmt --all` applies these changes) - `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A clippy::needless_collect -A clippy::result_large_err` to check that you're using the standard code style - `cargo test --workspace` to check that all tests pass - `cargo run -- crates/nu-std/tests/run.nu` to run the tests for the standard library > **Note** > from `nushell` you can also use the `toolkit` as follows > ```bash > use toolkit.nu # or use an `env_change` hook to activate it automatically > [x] toolkit check pr > ``` --> # After Submitting <!-- If your PR had any user-facing changes, update [the documentation](https://github.com/nushell/nushell.github.io) after the PR is merged, if necessary. This will help us keep the docs up to date. -->
This commit is contained in:
@ -7,6 +7,7 @@ mod test_converters;
|
||||
mod test_custom_commands;
|
||||
mod test_engine;
|
||||
mod test_env;
|
||||
mod test_help;
|
||||
mod test_hiding;
|
||||
mod test_ide;
|
||||
mod test_iteration;
|
||||
|
@ -1,4 +1,5 @@
|
||||
use crate::tests::{fail_test, run_test, TestResult};
|
||||
use rstest::rstest;
|
||||
|
||||
#[test]
|
||||
fn concrete_variable_assignment() -> TestResult {
|
||||
@ -63,6 +64,22 @@ fn scope_variable() -> TestResult {
|
||||
"int",
|
||||
)
|
||||
}
|
||||
#[rstest]
|
||||
#[case("a", "<> nothing")]
|
||||
#[case("b", "<1.23> float")]
|
||||
#[case("flag1", "<> nothing")]
|
||||
#[case("flag2", "<4.56> float")]
|
||||
|
||||
fn scope_command_defaults(#[case] var: &str, #[case] exp_result: &str) -> TestResult {
|
||||
run_test(
|
||||
&format!(
|
||||
r#"def t1 [a:int b?:float=1.23 --flag1:string --flag2:float=4.56] {{ true }};
|
||||
let rslt = ($nu.scope.commands | where name == 't1' | get signatures.0.any | where parameter_name == '{var}' | get parameter_default.0);
|
||||
$"<($rslt)> ($rslt | describe)""#
|
||||
),
|
||||
&format!("{exp_result}"),
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn earlier_errors() -> TestResult {
|
||||
|
27
src/tests/test_help.rs
Normal file
27
src/tests/test_help.rs
Normal file
@ -0,0 +1,27 @@
|
||||
use crate::tests::{run_test, TestResult};
|
||||
use rstest::rstest;
|
||||
|
||||
#[rstest]
|
||||
// avoid feeding strings containing parens to regex. Does not end well.
|
||||
#[case(": arga help")]
|
||||
#[case("argb help")]
|
||||
#[case("optional, default: 20")]
|
||||
#[case("- f1 switch")]
|
||||
#[case("- f2 named no default")]
|
||||
#[case("- f3 named default 3")]
|
||||
#[case("default: 33")]
|
||||
#[case("--help - Display the help message")]
|
||||
fn can_get_help(#[case] exp_result: &str) -> TestResult {
|
||||
run_test(
|
||||
&format!(
|
||||
r#"def t [a:string, # arga help
|
||||
b:int=20, # argb help
|
||||
--f1, # f1 switch help
|
||||
--f2:string, # f2 named no default
|
||||
--f3:int=33 # f3 named default 3
|
||||
] {{ true }};
|
||||
help t | ansi strip | find `{exp_result}` | get 0 | str replace -a '^(.*({exp_result}).*)$' '$2'"#,
|
||||
),
|
||||
exp_result,
|
||||
)
|
||||
}
|
Reference in New Issue
Block a user