nushell/crates/nu-engine/src/scope.rs

750 lines
25 KiB
Rust
Raw Normal View History

use nu_protocol::{
ast::Expr,
2023-03-10 19:14:55 +01:00
engine::{Command, EngineState, Stack, Visibility},
2023-08-17 10:58:38 +02:00
ModuleId, Signature, Span, SyntaxShape, Type, Value,
};
use std::cmp::Ordering;
use std::collections::HashMap;
2022-12-30 16:44:37 +01:00
pub struct ScopeData<'e, 's> {
engine_state: &'e EngineState,
stack: &'s Stack,
vars_map: HashMap<&'e Vec<u8>, &'e usize>,
Remove broken compile-time overload system (#9677) # Description This PR removes the compile-time overload system. Unfortunately, this system never worked correctly because in a gradual type system where types can be `Any`, you don't have enough information to correctly resolve function calls with overloads. These resolutions must be done at runtime, if they're supported. That said, there's a bit of work that needs to go into resolving input/output types (here overloads do not execute separate commands, but the same command and each overload explains how each output type corresponds to input types). This PR also removes the type scope, which would give incorrect answers in cases where multiple subexpressions were used in a pipeline. # User-Facing Changes Finishes removing compile-time overloads. These were only used in a few places in the code base, but it's possible it may impact user code. I'll mark this as breaking change so we can review. # 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 -- -c "use std testing; testing run-tests --path crates/nu-std"` 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 > 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. -->
2023-07-13 21:05:03 +02:00
decls_map: HashMap<&'e Vec<u8>, &'e usize>,
modules_map: HashMap<&'e Vec<u8>, &'e usize>,
visibility: Visibility,
}
impl<'e, 's> ScopeData<'e, 's> {
pub fn new(engine_state: &'e EngineState, stack: &'s Stack) -> Self {
Self {
engine_state,
stack,
vars_map: HashMap::new(),
decls_map: HashMap::new(),
modules_map: HashMap::new(),
visibility: Visibility::new(),
}
}
2023-08-17 10:58:38 +02:00
pub fn populate_vars(&mut self) {
for overlay_frame in self.engine_state.active_overlays(&[]) {
self.vars_map.extend(&overlay_frame.vars);
2023-08-17 10:58:38 +02:00
}
}
// decls include all commands, i.e., normal commands, aliases, and externals
pub fn populate_decls(&mut self) {
for overlay_frame in self.engine_state.active_overlays(&[]) {
self.decls_map.extend(&overlay_frame.decls);
self.visibility.merge_with(overlay_frame.visibility.clone());
}
}
2022-12-30 16:44:37 +01:00
pub fn populate_modules(&mut self) {
for overlay_frame in self.engine_state.active_overlays(&[]) {
self.modules_map.extend(&overlay_frame.modules);
}
}
pub fn collect_vars(&self, span: Span) -> Vec<Value> {
let mut vars = vec![];
2023-08-17 10:58:38 +02:00
for (var_name, var_id) in &self.vars_map {
let var_name = Value::string(String::from_utf8_lossy(var_name).to_string(), span);
let var = self.engine_state.get_var(**var_id);
let var_type = Value::string(var.ty.to_string(), span);
let is_const = Value::bool(var.const_val.is_some(), span);
2023-08-17 10:58:38 +02:00
let var_value = if let Ok(val) = self.stack.get_var(**var_id, span) {
val
} else {
Value::nothing(span)
};
2023-08-17 10:58:38 +02:00
let var_id_val = Value::int(**var_id as i64, span);
vars.push(Value::Record {
2023-08-17 10:58:38 +02:00
cols: vec![
"name".to_string(),
"type".to_string(),
"value".to_string(),
"is_const".to_string(),
2023-08-17 10:58:38 +02:00
"var_id".to_string(),
],
vals: vec![var_name, var_type, var_value, is_const, var_id_val],
span,
})
}
sort_rows(&mut vars);
vars
}
2022-12-30 16:44:37 +01:00
pub fn collect_commands(&self, span: Span) -> Vec<Value> {
let mut commands = vec![];
2023-08-17 10:58:38 +02:00
Remove broken compile-time overload system (#9677) # Description This PR removes the compile-time overload system. Unfortunately, this system never worked correctly because in a gradual type system where types can be `Any`, you don't have enough information to correctly resolve function calls with overloads. These resolutions must be done at runtime, if they're supported. That said, there's a bit of work that needs to go into resolving input/output types (here overloads do not execute separate commands, but the same command and each overload explains how each output type corresponds to input types). This PR also removes the type scope, which would give incorrect answers in cases where multiple subexpressions were used in a pipeline. # User-Facing Changes Finishes removing compile-time overloads. These were only used in a few places in the code base, but it's possible it may impact user code. I'll mark this as breaking change so we can review. # 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 -- -c "use std testing; testing run-tests --path crates/nu-std"` 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 > 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. -->
2023-07-13 21:05:03 +02:00
for (command_name, decl_id) in &self.decls_map {
if self.visibility.is_decl_id_visible(decl_id)
&& !self.engine_state.get_decl(**decl_id).is_alias()
{
let mut cols = vec![];
let mut vals = vec![];
cols.push("name".into());
vals.push(Value::String {
val: String::from_utf8_lossy(command_name).to_string(),
span,
});
let decl = self.engine_state.get_decl(**decl_id);
let signature = decl.signature();
cols.push("category".to_string());
vals.push(Value::String {
val: signature.category.to_string(),
span,
});
cols.push("signatures".to_string());
vals.push(self.collect_signatures(&signature, span));
cols.push("usage".to_string());
vals.push(Value::String {
val: decl.usage().into(),
span,
});
cols.push("examples".to_string());
vals.push(Value::List {
vals: decl
.examples()
.into_iter()
.map(|x| Value::Record {
FEATURE: add the example results to the scope (#8319) Related to #8189. Should close #8302. Important to: - have a complete `$nu` structure with all available information - generate an accurate website, because the `make_docs.nu` script of `nushell.github.io` uses `$nu.scope.command` to generate the pages of https://nushell.sh/commands/ > **Note** > i was looking for "scope" in the source of `nushell` to augment `$nu.scope` and i found `crates/nu-engine/src/scope.rs` that defines `nu_engine::scope::create_scope` which lead me to `nu_engine::scope::ScopeData.collect_commands`. > i hope this is the right file :relieved: # Description this PR slightly modifies `nu_engine::scope::ScopeData.collect_commands`: - add the "result" column to `$nu.scope.commands.examples` - put the result of the example when a valid `Option(Value)` - put a `Value::Nothing` when the result is set to `None` in the source of the command # User-Facing Changes users can now access the results of all examples in ```bash $nu.scope.commands | where name == <command> | get examples.0.result ``` ## example... ### ...with a command that defines examples: `merge` ```bash >_ $nu.scope.commands | where name == merge | get examples.0 | reject description | table --expand ╭───┬────────────────────────────────────────────────────────┬───────────────────────────╮ │ # │ example │ result │ ├───┼────────────────────────────────────────────────────────┼───────────────────────────┤ │ 0 │ [a b c] | wrap name | merge ( [1 2 3] | wrap index ) │ ╭───┬──────╮ │ │ │ │ │ # │ name │ │ │ │ │ ├───┼──────┤ │ │ │ │ │ 1 │ a │ │ │ │ │ │ 2 │ b │ │ │ │ │ │ 3 │ c │ │ │ │ │ ╰───┴──────╯ │ │ 1 │ {a: 1, b: 2} | merge {c: 3} │ ╭───┬───╮ │ │ │ │ │ a │ 1 │ │ │ │ │ │ b │ 2 │ │ │ │ │ │ c │ 3 │ │ │ │ │ ╰───┴───╯ │ │ 2 │ [{columnA: A0 columnB: B0}] | merge [{columnA: 'A0*'}] │ ╭───┬─────────┬─────────╮ │ │ │ │ │ # │ columnA │ columnB │ │ │ │ │ ├───┼─────────┼─────────┤ │ │ │ │ │ 0 │ A0* │ B0 │ │ │ │ │ ╰───┴─────────┴─────────╯ │ ╰───┴────────────────────────────────────────────────────────┴───────────────────────────╯ ``` and we can check that these are "true" results and not just string, e.g. ```bash >_ $nu.scope.commands | where name == merge | get examples.0.result.0 | describe table<name: string, index: int> ``` ### ...with a command without any example: `open` ```bash >_ $nu.scope.commands | where name == open | get examples.0 | reject description | table --expand ╭───┬──────────────────────────────────────┬────────╮ │ # │ example │ result │ ├───┼──────────────────────────────────────┼────────┤ │ 0 │ open myfile.json │ │ │ 1 │ open myfile.json --raw │ │ │ 2 │ 'myfile.txt' | open │ │ │ 3 │ open myfile.txt --raw | decode utf-8 │ │ ╰───┴──────────────────────────────────────┴────────╯ ``` and same thing, we can check that there is `$nothing` in this last command ```bash >_ $nu.scope.commands | where name == open | get examples.0.result.0 | describe table<name: string, index: int> ``` # Tests + Formatting - :heavy_check_mark: `cargo fmt --all` - :heavy_check_mark: `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A clippy::needless_collect` - :heavy_check_mark: `cargo test --workspace` (~~currently running~~) # After Submitting the documentation would have to be regenerated!
2023-03-05 10:56:06 +01:00
cols: vec!["description".into(), "example".into(), "result".into()],
vals: vec![
Value::String {
val: x.description.to_string(),
span,
},
Value::String {
val: x.example.to_string(),
span,
},
FEATURE: add the example results to the scope (#8319) Related to #8189. Should close #8302. Important to: - have a complete `$nu` structure with all available information - generate an accurate website, because the `make_docs.nu` script of `nushell.github.io` uses `$nu.scope.command` to generate the pages of https://nushell.sh/commands/ > **Note** > i was looking for "scope" in the source of `nushell` to augment `$nu.scope` and i found `crates/nu-engine/src/scope.rs` that defines `nu_engine::scope::create_scope` which lead me to `nu_engine::scope::ScopeData.collect_commands`. > i hope this is the right file :relieved: # Description this PR slightly modifies `nu_engine::scope::ScopeData.collect_commands`: - add the "result" column to `$nu.scope.commands.examples` - put the result of the example when a valid `Option(Value)` - put a `Value::Nothing` when the result is set to `None` in the source of the command # User-Facing Changes users can now access the results of all examples in ```bash $nu.scope.commands | where name == <command> | get examples.0.result ``` ## example... ### ...with a command that defines examples: `merge` ```bash >_ $nu.scope.commands | where name == merge | get examples.0 | reject description | table --expand ╭───┬────────────────────────────────────────────────────────┬───────────────────────────╮ │ # │ example │ result │ ├───┼────────────────────────────────────────────────────────┼───────────────────────────┤ │ 0 │ [a b c] | wrap name | merge ( [1 2 3] | wrap index ) │ ╭───┬──────╮ │ │ │ │ │ # │ name │ │ │ │ │ ├───┼──────┤ │ │ │ │ │ 1 │ a │ │ │ │ │ │ 2 │ b │ │ │ │ │ │ 3 │ c │ │ │ │ │ ╰───┴──────╯ │ │ 1 │ {a: 1, b: 2} | merge {c: 3} │ ╭───┬───╮ │ │ │ │ │ a │ 1 │ │ │ │ │ │ b │ 2 │ │ │ │ │ │ c │ 3 │ │ │ │ │ ╰───┴───╯ │ │ 2 │ [{columnA: A0 columnB: B0}] | merge [{columnA: 'A0*'}] │ ╭───┬─────────┬─────────╮ │ │ │ │ │ # │ columnA │ columnB │ │ │ │ │ ├───┼─────────┼─────────┤ │ │ │ │ │ 0 │ A0* │ B0 │ │ │ │ │ ╰───┴─────────┴─────────╯ │ ╰───┴────────────────────────────────────────────────────────┴───────────────────────────╯ ``` and we can check that these are "true" results and not just string, e.g. ```bash >_ $nu.scope.commands | where name == merge | get examples.0.result.0 | describe table<name: string, index: int> ``` ### ...with a command without any example: `open` ```bash >_ $nu.scope.commands | where name == open | get examples.0 | reject description | table --expand ╭───┬──────────────────────────────────────┬────────╮ │ # │ example │ result │ ├───┼──────────────────────────────────────┼────────┤ │ 0 │ open myfile.json │ │ │ 1 │ open myfile.json --raw │ │ │ 2 │ 'myfile.txt' | open │ │ │ 3 │ open myfile.txt --raw | decode utf-8 │ │ ╰───┴──────────────────────────────────────┴────────╯ ``` and same thing, we can check that there is `$nothing` in this last command ```bash >_ $nu.scope.commands | where name == open | get examples.0.result.0 | describe table<name: string, index: int> ``` # Tests + Formatting - :heavy_check_mark: `cargo fmt --all` - :heavy_check_mark: `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A clippy::needless_collect` - :heavy_check_mark: `cargo test --workspace` (~~currently running~~) # After Submitting the documentation would have to be regenerated!
2023-03-05 10:56:06 +01:00
if let Some(result) = x.result {
result
} else {
Value::Nothing { span }
},
],
span,
})
.collect(),
span,
});
cols.push("is_builtin".to_string());
// we can only be a is_builtin or is_custom, not both
vals.push(Value::Bool {
val: !decl.is_custom_command(),
span,
});
cols.push("is_sub".to_string());
vals.push(Value::Bool {
val: decl.is_sub(),
span,
});
cols.push("is_plugin".to_string());
vals.push(Value::Bool {
val: decl.is_plugin().is_some(),
span,
});
cols.push("is_custom".to_string());
vals.push(Value::Bool {
val: decl.is_custom_command(),
span,
});
cols.push("is_keyword".into());
vals.push(Value::Bool {
val: decl.is_parser_keyword(),
span,
});
cols.push("is_extern".to_string());
vals.push(Value::Bool {
val: decl.is_known_external(),
span,
});
cols.push("creates_scope".to_string());
vals.push(Value::Bool {
val: signature.creates_scope,
span,
});
cols.push("extra_usage".to_string());
vals.push(Value::String {
val: decl.extra_usage().into(),
span,
});
let search_terms = decl.search_terms();
cols.push("search_terms".to_string());
vals.push(Value::String {
val: search_terms.join(", "),
span,
});
2023-08-17 10:58:38 +02:00
cols.push("decl_id".into());
vals.push(Value::int(**decl_id as i64, span));
commands.push(Value::Record { cols, vals, span })
}
}
sort_rows(&mut commands);
commands
}
fn collect_signatures(&self, signature: &Signature, span: Span) -> Value {
let mut sigs = signature
.input_output_types
.iter()
.map(|(input_type, output_type)| {
(
input_type.to_shape().to_string(),
Value::List {
vals: self.collect_signature_entries(
input_type,
output_type,
signature,
span,
),
span,
},
)
})
.collect::<Vec<(String, Value)>>();
allow custom commands to show up in `$nu.scope.commands` better (#8910) # Description This PR allows our custom commands to show up in `$nu.scope.commands` better. It still needs work because this PR hard code the input and output types as `Type::Any` but the reason they're being missed in the first place is that they are not assigned an input and output type. This allows things like this now. Note the `where is_custom == true` ![image](https://user-images.githubusercontent.com/343840/232523925-97eeef78-9722-4184-b60f-9d06f994c8e3.png) Another example. ![image](https://user-images.githubusercontent.com/343840/232525706-d4d088d8-6597-43ba-97c8-ab03c2c7408c.png) ![image](https://user-images.githubusercontent.com/343840/232525797-b7e9ded3-b299-489e-af33-7390f4291bfd.png) # User-Facing Changes <!-- List of all changes that impact the user experience here. This helps us keep track of breaking changes. --> # 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` 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 > 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. -->
2023-04-17 18:19:37 +02:00
// Until we allow custom commands to have input and output types, let's just
// make them Type::Any Type::Any so they can show up in our `scope commands`
allow custom commands to show up in `$nu.scope.commands` better (#8910) # Description This PR allows our custom commands to show up in `$nu.scope.commands` better. It still needs work because this PR hard code the input and output types as `Type::Any` but the reason they're being missed in the first place is that they are not assigned an input and output type. This allows things like this now. Note the `where is_custom == true` ![image](https://user-images.githubusercontent.com/343840/232523925-97eeef78-9722-4184-b60f-9d06f994c8e3.png) Another example. ![image](https://user-images.githubusercontent.com/343840/232525706-d4d088d8-6597-43ba-97c8-ab03c2c7408c.png) ![image](https://user-images.githubusercontent.com/343840/232525797-b7e9ded3-b299-489e-af33-7390f4291bfd.png) # User-Facing Changes <!-- List of all changes that impact the user experience here. This helps us keep track of breaking changes. --> # 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` 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 > 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. -->
2023-04-17 18:19:37 +02:00
// a little bit better. If sigs is empty, we're pretty sure that we're dealing
// with a custom command.
if sigs.is_empty() {
let any_type = &Type::Any;
sigs.push((
any_type.to_shape().to_string(),
Value::List {
vals: self.collect_signature_entries(any_type, any_type, signature, span),
span,
},
));
}
sigs.sort_unstable_by(|(k1, _), (k2, _)| k1.cmp(k2));
// For most commands, input types are not repeated in
// `input_output_types`, i.e. each input type has only one associated
// output type. Furthermore, we want this to always be true. However,
// there are currently some exceptions, such as `hash sha256` which
// takes in string but may output string or binary depending on the
// presence of the --binary flag. In such cases, the "special case"
// signature usually comes later in the input_output_types, so this will
// remove them from the record.
sigs.dedup_by(|(k1, _), (k2, _)| k1 == k2);
let (cols, vals) = sigs.into_iter().unzip();
Value::Record { cols, vals, span }
}
fn collect_signature_entries(
&self,
input_type: &Type,
output_type: &Type,
signature: &Signature,
span: Span,
) -> Vec<Value> {
let mut sig_records = vec![];
let sig_cols = vec![
"parameter_name".to_string(),
"parameter_type".to_string(),
"syntax_shape".to_string(),
"is_optional".to_string(),
"short_flag".to_string(),
"description".to_string(),
"custom_completion".to_string(),
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. -->
2023-05-11 20:59:56 +02:00
"parameter_default".to_string(),
];
// input
sig_records.push(Value::Record {
cols: sig_cols.clone(),
vals: vec![
Value::nothing(span),
Value::string("input", span),
Value::string(input_type.to_shape().to_string(), span),
Value::bool(false, span),
Value::nothing(span),
Value::nothing(span),
Value::nothing(span),
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. -->
2023-05-11 20:59:56 +02:00
Value::nothing(span),
],
span,
});
// required_positional
for req in &signature.required_positional {
let sig_vals = vec![
Value::string(&req.name, span),
Value::string("positional", span),
Value::string(req.shape.to_string(), span),
Value::bool(false, span),
Value::nothing(span),
Value::string(&req.desc, span),
Value::string(
extract_custom_completion_from_arg(self.engine_state, &req.shape),
span,
),
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. -->
2023-05-11 20:59:56 +02:00
Value::nothing(span),
];
sig_records.push(Value::Record {
cols: sig_cols.clone(),
vals: sig_vals,
span,
});
}
// optional_positional
for opt in &signature.optional_positional {
let sig_vals = vec![
Value::string(&opt.name, span),
Value::string("positional", span),
Value::string(opt.shape.to_string(), span),
Value::bool(true, span),
Value::nothing(span),
Value::string(&opt.desc, span),
Value::string(
extract_custom_completion_from_arg(self.engine_state, &opt.shape),
span,
),
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. -->
2023-05-11 20:59:56 +02:00
if let Some(val) = &opt.default_value {
val.clone()
} else {
Value::nothing(span)
},
];
sig_records.push(Value::Record {
cols: sig_cols.clone(),
vals: sig_vals,
span,
});
}
// rest_positional
if let Some(rest) = &signature.rest_positional {
let sig_vals = vec![
Value::string(if rest.name == "rest" { "" } else { &rest.name }, span),
Value::string("rest", span),
Value::string(rest.shape.to_string(), span),
Value::bool(true, span),
Value::nothing(span),
Value::string(&rest.desc, span),
Value::string(
extract_custom_completion_from_arg(self.engine_state, &rest.shape),
span,
),
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. -->
2023-05-11 20:59:56 +02:00
Value::nothing(span), // rest_positional does have default, but parser prohibits specifying it?!
];
sig_records.push(Value::Record {
cols: sig_cols.clone(),
vals: sig_vals,
span,
});
}
// named flags
for named in &signature.named {
let flag_type;
// Skip the help flag
if named.long == "help" {
continue;
}
let mut custom_completion_command_name: String = "".to_string();
let shape = if let Some(arg) = &named.arg {
flag_type = Value::string("named", span);
custom_completion_command_name =
extract_custom_completion_from_arg(self.engine_state, arg);
Value::string(arg.to_string(), span)
} else {
flag_type = Value::string("switch", span);
Value::nothing(span)
};
let short_flag = if let Some(c) = named.short {
Value::string(c, span)
} else {
Value::nothing(span)
};
let sig_vals = vec![
Value::string(&named.long, span),
flag_type,
shape,
Value::bool(!named.required, span),
short_flag,
Value::string(&named.desc, span),
Value::string(custom_completion_command_name, span),
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. -->
2023-05-11 20:59:56 +02:00
if let Some(val) = &named.default_value {
val.clone()
} else {
Value::nothing(span)
},
];
sig_records.push(Value::Record {
cols: sig_cols.clone(),
vals: sig_vals,
span,
});
}
// output
sig_records.push(Value::Record {
cols: sig_cols,
vals: vec![
Value::nothing(span),
Value::string("output", span),
Value::string(output_type.to_shape().to_string(), span),
Value::bool(false, span),
Value::nothing(span),
Value::nothing(span),
Value::nothing(span),
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. -->
2023-05-11 20:59:56 +02:00
Value::nothing(span),
],
span,
});
sig_records
}
Added `help externs` command (#8403) # Description `help externs` - command, which list external commands Closes https://github.com/nushell/nushell/issues/8301 # User-Facing Changes ```nu $ help externs ╭───┬──────────────┬─────────────┬───────────────────────────────────────────────────╮ │ # │ name │ module_name │ usage │ ├───┼──────────────┼─────────────┼───────────────────────────────────────────────────┤ │ 0 │ git push │ completions │ Push changes │ │ │ │ │ │ │ 1 │ git fetch │ completions │ Download objects and refs from another repository │ │ │ │ │ │ │ 2 │ git checkout │ completions │ Check out git branches and files │ │ │ │ │ │ ╰───┴──────────────┴─────────────┴───────────────────────────────────────────────────╯ ``` # 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` to check that you're using the standard code style - `cargo test --workspace` to check that all tests pass # 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.
2023-03-15 18:40:27 +01:00
pub fn collect_externs(&self, span: Span) -> Vec<Value> {
let mut externals = vec![];
2023-08-17 10:58:38 +02:00
Remove broken compile-time overload system (#9677) # Description This PR removes the compile-time overload system. Unfortunately, this system never worked correctly because in a gradual type system where types can be `Any`, you don't have enough information to correctly resolve function calls with overloads. These resolutions must be done at runtime, if they're supported. That said, there's a bit of work that needs to go into resolving input/output types (here overloads do not execute separate commands, but the same command and each overload explains how each output type corresponds to input types). This PR also removes the type scope, which would give incorrect answers in cases where multiple subexpressions were used in a pipeline. # User-Facing Changes Finishes removing compile-time overloads. These were only used in a few places in the code base, but it's possible it may impact user code. I'll mark this as breaking change so we can review. # 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 -- -c "use std testing; testing run-tests --path crates/nu-std"` 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 > 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. -->
2023-07-13 21:05:03 +02:00
for (command_name, decl_id) in &self.decls_map {
Added `help externs` command (#8403) # Description `help externs` - command, which list external commands Closes https://github.com/nushell/nushell/issues/8301 # User-Facing Changes ```nu $ help externs ╭───┬──────────────┬─────────────┬───────────────────────────────────────────────────╮ │ # │ name │ module_name │ usage │ ├───┼──────────────┼─────────────┼───────────────────────────────────────────────────┤ │ 0 │ git push │ completions │ Push changes │ │ │ │ │ │ │ 1 │ git fetch │ completions │ Download objects and refs from another repository │ │ │ │ │ │ │ 2 │ git checkout │ completions │ Check out git branches and files │ │ │ │ │ │ ╰───┴──────────────┴─────────────┴───────────────────────────────────────────────────╯ ``` # 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` to check that you're using the standard code style - `cargo test --workspace` to check that all tests pass # 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.
2023-03-15 18:40:27 +01:00
let decl = self.engine_state.get_decl(**decl_id);
if decl.is_known_external() {
let mut cols = vec![];
let mut vals = vec![];
cols.push("name".into());
vals.push(Value::String {
val: String::from_utf8_lossy(command_name).to_string(),
span,
});
cols.push("usage".to_string());
vals.push(Value::String {
val: decl.usage().into(),
span,
});
2023-08-17 10:58:38 +02:00
cols.push("decl_id".into());
vals.push(Value::int(**decl_id as i64, span));
Added `help externs` command (#8403) # Description `help externs` - command, which list external commands Closes https://github.com/nushell/nushell/issues/8301 # User-Facing Changes ```nu $ help externs ╭───┬──────────────┬─────────────┬───────────────────────────────────────────────────╮ │ # │ name │ module_name │ usage │ ├───┼──────────────┼─────────────┼───────────────────────────────────────────────────┤ │ 0 │ git push │ completions │ Push changes │ │ │ │ │ │ │ 1 │ git fetch │ completions │ Download objects and refs from another repository │ │ │ │ │ │ │ 2 │ git checkout │ completions │ Check out git branches and files │ │ │ │ │ │ ╰───┴──────────────┴─────────────┴───────────────────────────────────────────────────╯ ``` # 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` to check that you're using the standard code style - `cargo test --workspace` to check that all tests pass # 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.
2023-03-15 18:40:27 +01:00
externals.push(Value::Record { cols, vals, span })
}
}
sort_rows(&mut externals);
Added `help externs` command (#8403) # Description `help externs` - command, which list external commands Closes https://github.com/nushell/nushell/issues/8301 # User-Facing Changes ```nu $ help externs ╭───┬──────────────┬─────────────┬───────────────────────────────────────────────────╮ │ # │ name │ module_name │ usage │ ├───┼──────────────┼─────────────┼───────────────────────────────────────────────────┤ │ 0 │ git push │ completions │ Push changes │ │ │ │ │ │ │ 1 │ git fetch │ completions │ Download objects and refs from another repository │ │ │ │ │ │ │ 2 │ git checkout │ completions │ Check out git branches and files │ │ │ │ │ │ ╰───┴──────────────┴─────────────┴───────────────────────────────────────────────────╯ ``` # 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` to check that you're using the standard code style - `cargo test --workspace` to check that all tests pass # 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.
2023-03-15 18:40:27 +01:00
externals
}
2022-12-30 16:44:37 +01:00
pub fn collect_aliases(&self, span: Span) -> Vec<Value> {
let mut aliases = vec![];
2023-08-17 10:58:38 +02:00
for (decl_name, decl_id) in self.engine_state.get_decls_sorted(false) {
2023-03-10 19:14:55 +01:00
if self.visibility.is_decl_id_visible(&decl_id) {
let decl = self.engine_state.get_decl(decl_id);
if let Some(alias) = decl.as_alias() {
let aliased_decl_id = if let Expr::Call(wrapped_call) = &alias.wrapped_call.expr
{
Value::int(wrapped_call.decl_id as i64, span)
} else {
Value::nothing(span)
};
2023-03-10 19:14:55 +01:00
aliases.push(Value::Record {
2023-08-17 10:58:38 +02:00
cols: vec![
"name".into(),
"expansion".into(),
"usage".into(),
"decl_id".into(),
"aliased_decl_id".into(),
2023-08-17 10:58:38 +02:00
],
2023-03-10 19:14:55 +01:00
vals: vec![
2023-08-17 10:58:38 +02:00
Value::String {
val: String::from_utf8_lossy(&decl_name).to_string(),
span,
},
2023-03-10 19:14:55 +01:00
Value::String {
val: String::from_utf8_lossy(
self.engine_state.get_span_contents(alias.wrapped_call.span),
2023-03-10 19:14:55 +01:00
)
.to_string(),
span,
},
Value::String {
2023-08-17 10:58:38 +02:00
val: alias.usage().to_string(),
span,
},
Value::Int {
val: decl_id as i64,
2023-03-10 19:14:55 +01:00
span,
},
aliased_decl_id,
2023-03-10 19:14:55 +01:00
],
span,
});
}
}
}
sort_rows(&mut aliases);
// aliases.sort_by(|a, b| a.partial_cmp(b).unwrap_or(Ordering::Equal));
aliases
}
2023-08-17 10:58:38 +02:00
fn collect_module(&self, module_name: &[u8], module_id: &ModuleId, span: Span) -> Value {
let module = self.engine_state.get_module(*module_id);
2023-08-17 10:58:38 +02:00
let all_decls = module.decls();
2022-12-30 16:44:37 +01:00
let mut export_commands: Vec<Value> = all_decls
2023-08-17 10:58:38 +02:00
.iter()
.filter_map(|(name_bytes, decl_id)| {
let decl = self.engine_state.get_decl(*decl_id);
if !decl.is_alias() && !decl.is_known_external() {
Some(Value::record(
vec!["name".into(), "decl_id".into()],
vec![
Value::string(String::from_utf8_lossy(name_bytes), span),
Value::int(*decl_id as i64, span),
],
span,
))
} else {
None
}
})
.collect();
2022-12-30 16:44:37 +01:00
let mut export_aliases: Vec<Value> = all_decls
2023-08-17 10:58:38 +02:00
.iter()
.filter_map(|(name_bytes, decl_id)| {
let decl = self.engine_state.get_decl(*decl_id);
if decl.is_alias() {
Some(Value::record(
vec!["name".into(), "decl_id".into()],
vec![
Value::string(String::from_utf8_lossy(name_bytes), span),
Value::int(*decl_id as i64, span),
],
2022-12-30 16:44:37 +01:00
span,
2023-08-17 10:58:38 +02:00
))
} else {
None
}
})
.collect();
let mut export_externs: Vec<Value> = all_decls
2023-08-17 10:58:38 +02:00
.iter()
.filter_map(|(name_bytes, decl_id)| {
let decl = self.engine_state.get_decl(*decl_id);
if decl.is_known_external() {
Some(Value::record(
vec!["name".into(), "decl_id".into()],
vec![
Value::string(String::from_utf8_lossy(name_bytes), span),
Value::int(*decl_id as i64, span),
],
2022-12-30 16:44:37 +01:00
span,
2023-08-17 10:58:38 +02:00
))
} else {
None
}
})
.collect();
let mut export_submodules: Vec<Value> = module
2023-08-17 10:58:38 +02:00
.submodules()
.iter()
.map(|(name_bytes, submodule_id)| self.collect_module(name_bytes, submodule_id, span))
.collect();
let mut export_consts: Vec<Value> = module
Recursively export constants from modules (#10049) <!-- if this PR closes one or more issues, you can automatically link the PR with them by using one of the [*linking keywords*](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword), e.g. - this PR should close #xxxx - fixes #xxxx you can also mention related issues, PRs or discussions! --> # 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. --> https://github.com/nushell/nushell/pull/9773 introduced constants to modules and allowed to export them, but only within one level. This PR: * allows recursive exporting of constants from all submodules * fixes submodule imports in a list import pattern * makes sure exported constants are actual constants Should unblock https://github.com/nushell/nushell/pull/9678 ### Example: ```nushell module spam { export module eggs { export module bacon { export const viking = 'eats' } } } use spam print $spam.eggs.bacon.viking # prints 'eats' use spam [eggs] print $eggs.bacon.viking # prints 'eats' use spam eggs bacon viking print $viking # prints 'eats' ``` ### Limitation 1: Considering the above `spam` module, attempting to get `eggs bacon` from `spam` module doesn't work directly: ```nushell use spam [ eggs bacon ] # attempts to load `eggs`, then `bacon` use spam [ "eggs bacon" ] # obviously wrong name for a constant, but doesn't work also for commands ``` Workaround (for example): ```nushell use spam eggs use eggs [ bacon ] print $bacon.viking # prints 'eats' ``` I'm thinking I'll just leave it in, as you can easily work around this. It is also a limitation of the import pattern in general, not just constants. ### Limitation 2: `overlay use` successfully imports the constants, but `overlay hide` does not hide them, even though it seems to hide normal variables successfully. This needs more investigation. # User-Facing Changes <!-- List of all changes that impact the user experience here. This helps us keep track of breaking changes. --> Allows recursive constant exports from submodules. # 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 -- -c "use std testing; testing run-tests --path crates/nu-std"` 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 > 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. -->
2023-08-20 14:51:35 +02:00
.consts()
2023-08-17 10:58:38 +02:00
.iter()
.map(|(name_bytes, var_id)| {
Value::record(
vec!["name".into(), "type".into(), "var_id".into()],
vec![
Value::string(String::from_utf8_lossy(name_bytes), span),
Value::string(self.engine_state.get_var(*var_id).ty.to_string(), span),
Value::int(*var_id as i64, span),
],
span,
)
})
.collect();
sort_rows(&mut export_commands);
sort_rows(&mut export_aliases);
sort_rows(&mut export_externs);
sort_rows(&mut export_submodules);
sort_rows(&mut export_consts);
2023-08-17 10:58:38 +02:00
let export_env_block = module.env_block.map_or_else(
|| Value::nothing(span),
|block_id| Value::Block {
val: block_id,
span,
2023-08-17 10:58:38 +02:00
},
);
let module_usage = self
.engine_state
.build_module_usage(*module_id)
.map(|(usage, _)| usage)
.unwrap_or_default();
Value::Record {
cols: vec![
"name".into(),
"commands".into(),
"aliases".into(),
"externs".into(),
"submodules".into(),
"constants".into(),
"env_block".into(),
"usage".into(),
"module_id".into(),
],
vals: vec![
Value::string(String::from_utf8_lossy(module_name), span),
Value::List {
vals: export_commands,
span,
},
Value::List {
vals: export_aliases,
span,
},
Value::List {
vals: export_externs,
span,
},
Value::List {
vals: export_submodules,
span,
},
Value::List {
vals: export_consts,
span,
},
export_env_block,
Value::string(module_usage, span),
Value::int(*module_id as i64, span),
],
span,
}
}
pub fn collect_modules(&self, span: Span) -> Vec<Value> {
let mut modules = vec![];
for (module_name, module_id) in &self.modules_map {
modules.push(self.collect_module(module_name, module_id, span));
}
2023-08-17 10:58:38 +02:00
modules.sort_by(|a, b| a.partial_cmp(b).unwrap_or(Ordering::Equal));
modules
}
2022-12-30 16:44:37 +01:00
pub fn collect_engine_state(&self, span: Span) -> Value {
let engine_state_cols = vec![
"source_bytes".to_string(),
"num_vars".to_string(),
"num_decls".to_string(),
"num_blocks".to_string(),
"num_modules".to_string(),
"num_env_vars".to_string(),
];
let engine_state_vals = vec![
Value::int(self.engine_state.next_span_start() as i64, span),
Value::int(self.engine_state.num_vars() as i64, span),
Value::int(self.engine_state.num_decls() as i64, span),
Value::int(self.engine_state.num_blocks() as i64, span),
Value::int(self.engine_state.num_modules() as i64, span),
Value::int(
self.engine_state
.env_vars
.values()
.map(|overlay| overlay.len() as i64)
.sum(),
span,
),
];
2023-08-17 10:58:38 +02:00
Value::Record {
cols: engine_state_cols,
vals: engine_state_vals,
span,
}
}
}
fn extract_custom_completion_from_arg(engine_state: &EngineState, shape: &SyntaxShape) -> String {
return match shape {
SyntaxShape::Custom(_, custom_completion_decl_id) => {
let custom_completion_command = engine_state.get_decl(*custom_completion_decl_id);
let custom_completion_command_name: &str = custom_completion_command.name();
custom_completion_command_name.to_string()
}
_ => "".to_string(),
};
}
fn sort_rows(decls: &mut [Value]) {
decls.sort_by(|a, b| match (a, b) {
(Value::Record { vals: rec_a, .. }, Value::Record { vals: rec_b, .. }) => {
// Comparing the first value from the record
// It is expected that the first value is the name of the entry (command, module, alias, etc.)
match (rec_a.get(0), rec_b.get(0)) {
(Some(val_a), Some(val_b)) => match (val_a, val_b) {
(Value::String { val: str_a, .. }, Value::String { val: str_b, .. }) => {
str_a.cmp(str_b)
}
_ => Ordering::Equal,
},
_ => Ordering::Equal,
}
}
_ => Ordering::Equal,
});
}