2022-11-11 23:20:28 +01:00
|
|
|
use nu_protocol::{
|
2023-08-18 19:47:38 +02:00
|
|
|
ast::Expr,
|
2023-03-10 19:14:55 +01:00
|
|
|
engine::{Command, EngineState, Stack, Visibility},
|
2024-02-18 13:20:22 +01:00
|
|
|
record, ModuleId, Signature, Span, SyntaxShape, Type, Value,
|
2022-11-11 23:20:28 +01:00
|
|
|
};
|
Add `command_prelude` module (#12291)
# Description
When implementing a `Command`, one must also import all the types
present in the function signatures for `Command`. This makes it so that
we often import the same set of types in each command implementation
file. E.g., something like this:
```rust
use nu_protocol::ast::Call;
use nu_protocol::engine::{Command, EngineState, Stack};
use nu_protocol::{
record, Category, Example, IntoInterruptiblePipelineData, IntoPipelineData, PipelineData,
ShellError, Signature, Span, Type, Value,
};
```
This PR adds the `nu_engine::command_prelude` module which contains the
necessary and commonly used types to implement a `Command`:
```rust
// command_prelude.rs
pub use crate::CallExt;
pub use nu_protocol::{
ast::{Call, CellPath},
engine::{Command, EngineState, Stack},
record, Category, Example, IntoInterruptiblePipelineData, IntoPipelineData, IntoSpanned,
PipelineData, Record, ShellError, Signature, Span, Spanned, SyntaxShape, Type, Value,
};
```
This should reduce the boilerplate needed to implement a command and
also gives us a place to track the breadth of the `Command` API. I tried
to be conservative with what went into the prelude modules, since it
might be hard/annoying to remove items from the prelude in the future.
Let me know if something should be included or excluded.
2024-03-26 22:17:30 +01:00
|
|
|
use std::{cmp::Ordering, collections::HashMap};
|
2022-11-11 23:20:28 +01:00
|
|
|
|
2022-12-30 16:44:37 +01:00
|
|
|
pub struct ScopeData<'e, 's> {
|
2022-11-11 23:20:28 +01:00
|
|
|
engine_state: &'e EngineState,
|
|
|
|
stack: &'s Stack,
|
|
|
|
vars_map: HashMap<&'e Vec<u8>, &'e usize>,
|
2023-07-13 21:05:03 +02:00
|
|
|
decls_map: HashMap<&'e Vec<u8>, &'e usize>,
|
2022-11-11 23:20:28 +01:00
|
|
|
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(),
|
2023-04-07 20:09:38 +02:00
|
|
|
decls_map: HashMap::new(),
|
2022-11-11 23:20:28 +01:00
|
|
|
modules_map: HashMap::new(),
|
|
|
|
visibility: Visibility::new(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-17 10:58:38 +02:00
|
|
|
pub fn populate_vars(&mut self) {
|
2022-11-11 23:20:28 +01:00
|
|
|
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(&[]) {
|
2023-04-07 20:09:38 +02:00
|
|
|
self.decls_map.extend(&overlay_frame.decls);
|
2022-11-11 23:20:28 +01:00
|
|
|
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> {
|
2022-11-11 23:20:28 +01:00
|
|
|
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);
|
2022-11-11 23:20:28 +01:00
|
|
|
|
2023-08-18 19:47:38 +02:00
|
|
|
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) {
|
2022-11-11 23:20:28 +01:00
|
|
|
val
|
|
|
|
} else {
|
|
|
|
Value::nothing(span)
|
|
|
|
};
|
|
|
|
|
2023-08-17 10:58:38 +02:00
|
|
|
let var_id_val = Value::int(**var_id as i64, span);
|
|
|
|
|
Create `Record` type (#10103)
# Description
This PR creates a new `Record` type to reduce duplicate code and
possibly bugs as well. (This is an edited version of #9648.)
- `Record` implements `FromIterator` and `IntoIterator` and so can be
iterated over or collected into. For example, this helps with
conversions to and from (hash)maps. (Also, no more
`cols.iter().zip(vals)`!)
- `Record` has a `push(col, val)` function to help insure that the
number of columns is equal to the number of values. I caught a few
potential bugs thanks to this (e.g. in the `ls` command).
- Finally, this PR also adds a `record!` macro that helps simplify
record creation. It is used like so:
```rust
record! {
"key1" => some_value,
"key2" => Value::string("text", span),
"key3" => Value::int(optional_int.unwrap_or(0), span),
"key4" => Value::bool(config.setting, span),
}
```
Since macros hinder formatting, etc., the right hand side values should
be relatively short and sweet like the examples above.
Where possible, prefer `record!` or `.collect()` on an iterator instead
of multiple `Record::push`s, since the first two automatically set the
record capacity and do less work overall.
# User-Facing Changes
Besides the changes in `nu-protocol` the only other breaking changes are
to `nu-table::{ExpandedTable::build_map, JustTable::kv_table}`.
2023-08-24 21:50:29 +02:00
|
|
|
vars.push(Value::record(
|
|
|
|
record! {
|
|
|
|
"name" => var_name,
|
|
|
|
"type" => var_type,
|
|
|
|
"value" => var_value,
|
|
|
|
"is_const" => is_const,
|
|
|
|
"var_id" => var_id_val,
|
|
|
|
},
|
2022-11-11 23:20:28 +01:00
|
|
|
span,
|
Create `Record` type (#10103)
# Description
This PR creates a new `Record` type to reduce duplicate code and
possibly bugs as well. (This is an edited version of #9648.)
- `Record` implements `FromIterator` and `IntoIterator` and so can be
iterated over or collected into. For example, this helps with
conversions to and from (hash)maps. (Also, no more
`cols.iter().zip(vals)`!)
- `Record` has a `push(col, val)` function to help insure that the
number of columns is equal to the number of values. I caught a few
potential bugs thanks to this (e.g. in the `ls` command).
- Finally, this PR also adds a `record!` macro that helps simplify
record creation. It is used like so:
```rust
record! {
"key1" => some_value,
"key2" => Value::string("text", span),
"key3" => Value::int(optional_int.unwrap_or(0), span),
"key4" => Value::bool(config.setting, span),
}
```
Since macros hinder formatting, etc., the right hand side values should
be relatively short and sweet like the examples above.
Where possible, prefer `record!` or `.collect()` on an iterator instead
of multiple `Record::push`s, since the first two automatically set the
record capacity and do less work overall.
# User-Facing Changes
Besides the changes in `nu-protocol` the only other breaking changes are
to `nu-table::{ExpandedTable::build_map, JustTable::kv_table}`.
2023-08-24 21:50:29 +02:00
|
|
|
));
|
2022-11-11 23:20:28 +01:00
|
|
|
}
|
2023-08-17 16:37:01 +02:00
|
|
|
|
|
|
|
sort_rows(&mut vars);
|
2022-11-11 23:20:28 +01:00
|
|
|
vars
|
|
|
|
}
|
|
|
|
|
2022-12-30 16:44:37 +01:00
|
|
|
pub fn collect_commands(&self, span: Span) -> Vec<Value> {
|
2022-11-11 23:20:28 +01:00
|
|
|
let mut commands = vec![];
|
2023-08-17 10:58:38 +02:00
|
|
|
|
2023-07-13 21:05:03 +02:00
|
|
|
for (command_name, decl_id) in &self.decls_map {
|
2023-04-07 20:09:38 +02:00
|
|
|
if self.visibility.is_decl_id_visible(decl_id)
|
|
|
|
&& !self.engine_state.get_decl(**decl_id).is_alias()
|
|
|
|
{
|
2022-11-11 23:20:28 +01:00
|
|
|
let decl = self.engine_state.get_decl(**decl_id);
|
|
|
|
let signature = decl.signature();
|
|
|
|
|
Create `Record` type (#10103)
# Description
This PR creates a new `Record` type to reduce duplicate code and
possibly bugs as well. (This is an edited version of #9648.)
- `Record` implements `FromIterator` and `IntoIterator` and so can be
iterated over or collected into. For example, this helps with
conversions to and from (hash)maps. (Also, no more
`cols.iter().zip(vals)`!)
- `Record` has a `push(col, val)` function to help insure that the
number of columns is equal to the number of values. I caught a few
potential bugs thanks to this (e.g. in the `ls` command).
- Finally, this PR also adds a `record!` macro that helps simplify
record creation. It is used like so:
```rust
record! {
"key1" => some_value,
"key2" => Value::string("text", span),
"key3" => Value::int(optional_int.unwrap_or(0), span),
"key4" => Value::bool(config.setting, span),
}
```
Since macros hinder formatting, etc., the right hand side values should
be relatively short and sweet like the examples above.
Where possible, prefer `record!` or `.collect()` on an iterator instead
of multiple `Record::push`s, since the first two automatically set the
record capacity and do less work overall.
# User-Facing Changes
Besides the changes in `nu-protocol` the only other breaking changes are
to `nu-table::{ExpandedTable::build_map, JustTable::kv_table}`.
2023-08-24 21:50:29 +02:00
|
|
|
let examples = decl
|
|
|
|
.examples()
|
|
|
|
.into_iter()
|
|
|
|
.map(|x| {
|
|
|
|
Value::record(
|
|
|
|
record! {
|
|
|
|
"description" => Value::string(x.description, span),
|
|
|
|
"example" => Value::string(x.example, span),
|
|
|
|
"result" => x.result.unwrap_or(Value::nothing(span)),
|
|
|
|
},
|
2022-11-11 23:20:28 +01:00
|
|
|
span,
|
Create `Record` type (#10103)
# Description
This PR creates a new `Record` type to reduce duplicate code and
possibly bugs as well. (This is an edited version of #9648.)
- `Record` implements `FromIterator` and `IntoIterator` and so can be
iterated over or collected into. For example, this helps with
conversions to and from (hash)maps. (Also, no more
`cols.iter().zip(vals)`!)
- `Record` has a `push(col, val)` function to help insure that the
number of columns is equal to the number of values. I caught a few
potential bugs thanks to this (e.g. in the `ls` command).
- Finally, this PR also adds a `record!` macro that helps simplify
record creation. It is used like so:
```rust
record! {
"key1" => some_value,
"key2" => Value::string("text", span),
"key3" => Value::int(optional_int.unwrap_or(0), span),
"key4" => Value::bool(config.setting, span),
}
```
Since macros hinder formatting, etc., the right hand side values should
be relatively short and sweet like the examples above.
Where possible, prefer `record!` or `.collect()` on an iterator instead
of multiple `Record::push`s, since the first two automatically set the
record capacity and do less work overall.
# User-Facing Changes
Besides the changes in `nu-protocol` the only other breaking changes are
to `nu-table::{ExpandedTable::build_map, JustTable::kv_table}`.
2023-08-24 21:50:29 +02:00
|
|
|
)
|
|
|
|
})
|
|
|
|
.collect();
|
|
|
|
|
|
|
|
let record = record! {
|
|
|
|
"name" => Value::string(String::from_utf8_lossy(command_name), span),
|
|
|
|
"category" => Value::string(signature.category.to_string(), span),
|
|
|
|
"signatures" => self.collect_signatures(&signature, span),
|
|
|
|
"usage" => Value::string(decl.usage(), span),
|
|
|
|
"examples" => Value::list(examples, span),
|
|
|
|
// we can only be a is_builtin or is_custom, not both
|
|
|
|
"is_builtin" => Value::bool(!decl.is_custom_command(), span),
|
|
|
|
"is_sub" => Value::bool(decl.is_sub(), span),
|
Keep plugins persistently running in the background (#12064)
# Description
This PR uses the new plugin protocol to intelligently keep plugin
processes running in the background for further plugin calls.
Running plugins can be seen by running the new `plugin list` command,
and stopped by running the new `plugin stop` command.
This is an enhancement for the performance of plugins, as starting new
plugin processes has overhead, especially for plugins in languages that
take a significant amount of time on startup. It also enables plugins
that have persistent state between commands, making the migration of
features like dataframes and `stor` to plugins possible.
Plugins are automatically stopped by the new plugin garbage collector,
configurable with `$env.config.plugin_gc`:
```nushell
$env.config.plugin_gc = {
# Configuration for plugin garbage collection
default: {
enabled: true # true to enable stopping of inactive plugins
stop_after: 10sec # how long to wait after a plugin is inactive to stop it
}
plugins: {
# alternate configuration for specific plugins, by name, for example:
#
# gstat: {
# enabled: false
# }
}
}
```
If garbage collection is enabled, plugins will be stopped after
`stop_after` passes after they were last active. Plugins are counted as
inactive if they have no running plugin calls. Reading the stream from
the response of a plugin call is still considered to be activity, but if
a plugin holds on to a stream but the call ends without an active
streaming response, it is not counted as active even if it is reading
it. Plugins can explicitly disable the GC as appropriate with
`engine.set_gc_disabled(true)`.
The `version` command now lists plugin names rather than plugin
commands. The list of plugin commands is accessible via `plugin list`.
Recommend doing this together with #12029, because it will likely force
plugin developers to do the right thing with mutability and lead to less
unexpected behavior when running plugins nested / in parallel.
# User-Facing Changes
- new command: `plugin list`
- new command: `plugin stop`
- changed command: `version` (now lists plugin names, rather than
commands)
- new config: `$env.config.plugin_gc`
- Plugins will keep running and be reused, at least for the configured
GC period
- Plugins that used mutable state in weird ways like `inc` did might
misbehave until fixed
- Plugins can disable GC if they need to
- Had to change plugin signature to accept `&EngineInterface` so that
the GC disable feature works. #12029 does this anyway, and I'm expecting
(resolvable) conflicts with that
# Tests + Formatting
- :green_circle: `toolkit fmt`
- :green_circle: `toolkit clippy`
- :green_circle: `toolkit test`
- :green_circle: `toolkit test stdlib`
Because there is some specific OS behavior required for plugins to not
respond to Ctrl-C directly, I've developed against and tested on both
Linux and Windows to ensure that works properly.
# After Submitting
I think this probably needs to be in the book somewhere
2024-03-10 00:10:22 +01:00
|
|
|
"is_plugin" => Value::bool(decl.is_plugin(), span),
|
Create `Record` type (#10103)
# Description
This PR creates a new `Record` type to reduce duplicate code and
possibly bugs as well. (This is an edited version of #9648.)
- `Record` implements `FromIterator` and `IntoIterator` and so can be
iterated over or collected into. For example, this helps with
conversions to and from (hash)maps. (Also, no more
`cols.iter().zip(vals)`!)
- `Record` has a `push(col, val)` function to help insure that the
number of columns is equal to the number of values. I caught a few
potential bugs thanks to this (e.g. in the `ls` command).
- Finally, this PR also adds a `record!` macro that helps simplify
record creation. It is used like so:
```rust
record! {
"key1" => some_value,
"key2" => Value::string("text", span),
"key3" => Value::int(optional_int.unwrap_or(0), span),
"key4" => Value::bool(config.setting, span),
}
```
Since macros hinder formatting, etc., the right hand side values should
be relatively short and sweet like the examples above.
Where possible, prefer `record!` or `.collect()` on an iterator instead
of multiple `Record::push`s, since the first two automatically set the
record capacity and do less work overall.
# User-Facing Changes
Besides the changes in `nu-protocol` the only other breaking changes are
to `nu-table::{ExpandedTable::build_map, JustTable::kv_table}`.
2023-08-24 21:50:29 +02:00
|
|
|
"is_custom" => Value::bool(decl.is_custom_command(), span),
|
|
|
|
"is_keyword" => Value::bool(decl.is_parser_keyword(), span),
|
|
|
|
"is_extern" => Value::bool(decl.is_known_external(), span),
|
|
|
|
"creates_scope" => Value::bool(signature.creates_scope, span),
|
|
|
|
"extra_usage" => Value::string(decl.extra_usage(), span),
|
|
|
|
"search_terms" => Value::string(decl.search_terms().join(", "), span),
|
|
|
|
"decl_id" => Value::int(**decl_id as i64, span),
|
|
|
|
};
|
|
|
|
|
|
|
|
commands.push(Value::record(record, span))
|
2022-11-11 23:20:28 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-17 16:37:01 +02:00
|
|
|
sort_rows(&mut commands);
|
|
|
|
|
2022-11-11 23:20:28 +01:00
|
|
|
commands
|
|
|
|
}
|
|
|
|
|
2022-11-12 23:26:20 +01:00
|
|
|
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(),
|
2023-09-03 16:27:29 +02:00
|
|
|
Value::list(
|
|
|
|
self.collect_signature_entries(input_type, output_type, signature, span),
|
2022-11-12 23:26:20 +01:00
|
|
|
span,
|
2023-09-03 16:27:29 +02:00
|
|
|
),
|
2022-11-12 23:26:20 +01:00
|
|
|
)
|
|
|
|
})
|
|
|
|
.collect::<Vec<(String, Value)>>();
|
2023-04-17 18:19:37 +02:00
|
|
|
|
|
|
|
// Until we allow custom commands to have input and output types, let's just
|
2023-06-20 23:33:01 +02:00
|
|
|
// make them Type::Any Type::Any so they can show up in our `scope commands`
|
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(),
|
2023-09-03 16:27:29 +02:00
|
|
|
Value::list(
|
|
|
|
self.collect_signature_entries(any_type, any_type, signature, span),
|
2023-04-17 18:19:37 +02:00
|
|
|
span,
|
2023-09-03 16:27:29 +02:00
|
|
|
),
|
2023-04-17 18:19:37 +02:00
|
|
|
));
|
|
|
|
}
|
2022-11-12 23:26:20 +01:00
|
|
|
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);
|
Create `Record` type (#10103)
# Description
This PR creates a new `Record` type to reduce duplicate code and
possibly bugs as well. (This is an edited version of #9648.)
- `Record` implements `FromIterator` and `IntoIterator` and so can be
iterated over or collected into. For example, this helps with
conversions to and from (hash)maps. (Also, no more
`cols.iter().zip(vals)`!)
- `Record` has a `push(col, val)` function to help insure that the
number of columns is equal to the number of values. I caught a few
potential bugs thanks to this (e.g. in the `ls` command).
- Finally, this PR also adds a `record!` macro that helps simplify
record creation. It is used like so:
```rust
record! {
"key1" => some_value,
"key2" => Value::string("text", span),
"key3" => Value::int(optional_int.unwrap_or(0), span),
"key4" => Value::bool(config.setting, span),
}
```
Since macros hinder formatting, etc., the right hand side values should
be relatively short and sweet like the examples above.
Where possible, prefer `record!` or `.collect()` on an iterator instead
of multiple `Record::push`s, since the first two automatically set the
record capacity and do less work overall.
# User-Facing Changes
Besides the changes in `nu-protocol` the only other breaking changes are
to `nu-table::{ExpandedTable::build_map, JustTable::kv_table}`.
2023-08-24 21:50:29 +02:00
|
|
|
Value::record(sigs.into_iter().collect(), span)
|
2022-11-12 23:26:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
fn collect_signature_entries(
|
|
|
|
&self,
|
|
|
|
input_type: &Type,
|
|
|
|
output_type: &Type,
|
|
|
|
signature: &Signature,
|
|
|
|
span: Span,
|
|
|
|
) -> Vec<Value> {
|
2022-11-11 23:20:28 +01:00
|
|
|
let mut sig_records = vec![];
|
|
|
|
|
2022-11-12 23:26:20 +01:00
|
|
|
// input
|
Create `Record` type (#10103)
# Description
This PR creates a new `Record` type to reduce duplicate code and
possibly bugs as well. (This is an edited version of #9648.)
- `Record` implements `FromIterator` and `IntoIterator` and so can be
iterated over or collected into. For example, this helps with
conversions to and from (hash)maps. (Also, no more
`cols.iter().zip(vals)`!)
- `Record` has a `push(col, val)` function to help insure that the
number of columns is equal to the number of values. I caught a few
potential bugs thanks to this (e.g. in the `ls` command).
- Finally, this PR also adds a `record!` macro that helps simplify
record creation. It is used like so:
```rust
record! {
"key1" => some_value,
"key2" => Value::string("text", span),
"key3" => Value::int(optional_int.unwrap_or(0), span),
"key4" => Value::bool(config.setting, span),
}
```
Since macros hinder formatting, etc., the right hand side values should
be relatively short and sweet like the examples above.
Where possible, prefer `record!` or `.collect()` on an iterator instead
of multiple `Record::push`s, since the first two automatically set the
record capacity and do less work overall.
# User-Facing Changes
Besides the changes in `nu-protocol` the only other breaking changes are
to `nu-table::{ExpandedTable::build_map, JustTable::kv_table}`.
2023-08-24 21:50:29 +02:00
|
|
|
sig_records.push(Value::record(
|
2024-02-18 13:20:22 +01:00
|
|
|
record! {
|
|
|
|
"parameter_name" => Value::nothing(span),
|
|
|
|
"parameter_type" => Value::string("input", span),
|
|
|
|
"syntax_shape" => Value::string(input_type.to_shape().to_string(), span),
|
|
|
|
"is_optional" => Value::bool(false, span),
|
|
|
|
"short_flag" => Value::nothing(span),
|
|
|
|
"description" => Value::nothing(span),
|
|
|
|
"custom_completion" => Value::nothing(span),
|
|
|
|
"parameter_default" => Value::nothing(span),
|
|
|
|
},
|
2022-11-12 23:26:20 +01:00
|
|
|
span,
|
Create `Record` type (#10103)
# Description
This PR creates a new `Record` type to reduce duplicate code and
possibly bugs as well. (This is an edited version of #9648.)
- `Record` implements `FromIterator` and `IntoIterator` and so can be
iterated over or collected into. For example, this helps with
conversions to and from (hash)maps. (Also, no more
`cols.iter().zip(vals)`!)
- `Record` has a `push(col, val)` function to help insure that the
number of columns is equal to the number of values. I caught a few
potential bugs thanks to this (e.g. in the `ls` command).
- Finally, this PR also adds a `record!` macro that helps simplify
record creation. It is used like so:
```rust
record! {
"key1" => some_value,
"key2" => Value::string("text", span),
"key3" => Value::int(optional_int.unwrap_or(0), span),
"key4" => Value::bool(config.setting, span),
}
```
Since macros hinder formatting, etc., the right hand side values should
be relatively short and sweet like the examples above.
Where possible, prefer `record!` or `.collect()` on an iterator instead
of multiple `Record::push`s, since the first two automatically set the
record capacity and do less work overall.
# User-Facing Changes
Besides the changes in `nu-protocol` the only other breaking changes are
to `nu-table::{ExpandedTable::build_map, JustTable::kv_table}`.
2023-08-24 21:50:29 +02:00
|
|
|
));
|
2022-11-12 23:26:20 +01:00
|
|
|
|
2022-11-11 23:20:28 +01:00
|
|
|
// required_positional
|
|
|
|
for req in &signature.required_positional {
|
2024-02-18 13:20:22 +01:00
|
|
|
let custom = extract_custom_completion_from_arg(self.engine_state, &req.shape);
|
2022-11-11 23:20:28 +01:00
|
|
|
|
Create `Record` type (#10103)
# Description
This PR creates a new `Record` type to reduce duplicate code and
possibly bugs as well. (This is an edited version of #9648.)
- `Record` implements `FromIterator` and `IntoIterator` and so can be
iterated over or collected into. For example, this helps with
conversions to and from (hash)maps. (Also, no more
`cols.iter().zip(vals)`!)
- `Record` has a `push(col, val)` function to help insure that the
number of columns is equal to the number of values. I caught a few
potential bugs thanks to this (e.g. in the `ls` command).
- Finally, this PR also adds a `record!` macro that helps simplify
record creation. It is used like so:
```rust
record! {
"key1" => some_value,
"key2" => Value::string("text", span),
"key3" => Value::int(optional_int.unwrap_or(0), span),
"key4" => Value::bool(config.setting, span),
}
```
Since macros hinder formatting, etc., the right hand side values should
be relatively short and sweet like the examples above.
Where possible, prefer `record!` or `.collect()` on an iterator instead
of multiple `Record::push`s, since the first two automatically set the
record capacity and do less work overall.
# User-Facing Changes
Besides the changes in `nu-protocol` the only other breaking changes are
to `nu-table::{ExpandedTable::build_map, JustTable::kv_table}`.
2023-08-24 21:50:29 +02:00
|
|
|
sig_records.push(Value::record(
|
2024-02-18 13:20:22 +01:00
|
|
|
record! {
|
|
|
|
"parameter_name" => Value::string(&req.name, span),
|
|
|
|
"parameter_type" => Value::string("positional", span),
|
|
|
|
"syntax_shape" => Value::string(req.shape.to_string(), span),
|
|
|
|
"is_optional" => Value::bool(false, span),
|
|
|
|
"short_flag" => Value::nothing(span),
|
|
|
|
"description" => Value::string(&req.desc, span),
|
|
|
|
"custom_completion" => Value::string(custom, span),
|
|
|
|
"parameter_default" => Value::nothing(span),
|
|
|
|
},
|
2022-11-11 23:20:28 +01:00
|
|
|
span,
|
Create `Record` type (#10103)
# Description
This PR creates a new `Record` type to reduce duplicate code and
possibly bugs as well. (This is an edited version of #9648.)
- `Record` implements `FromIterator` and `IntoIterator` and so can be
iterated over or collected into. For example, this helps with
conversions to and from (hash)maps. (Also, no more
`cols.iter().zip(vals)`!)
- `Record` has a `push(col, val)` function to help insure that the
number of columns is equal to the number of values. I caught a few
potential bugs thanks to this (e.g. in the `ls` command).
- Finally, this PR also adds a `record!` macro that helps simplify
record creation. It is used like so:
```rust
record! {
"key1" => some_value,
"key2" => Value::string("text", span),
"key3" => Value::int(optional_int.unwrap_or(0), span),
"key4" => Value::bool(config.setting, span),
}
```
Since macros hinder formatting, etc., the right hand side values should
be relatively short and sweet like the examples above.
Where possible, prefer `record!` or `.collect()` on an iterator instead
of multiple `Record::push`s, since the first two automatically set the
record capacity and do less work overall.
# User-Facing Changes
Besides the changes in `nu-protocol` the only other breaking changes are
to `nu-table::{ExpandedTable::build_map, JustTable::kv_table}`.
2023-08-24 21:50:29 +02:00
|
|
|
));
|
2022-11-11 23:20:28 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// optional_positional
|
|
|
|
for opt in &signature.optional_positional {
|
2024-02-18 13:20:22 +01:00
|
|
|
let custom = extract_custom_completion_from_arg(self.engine_state, &opt.shape);
|
|
|
|
let default = if let Some(val) = &opt.default_value {
|
|
|
|
val.clone()
|
|
|
|
} else {
|
|
|
|
Value::nothing(span)
|
|
|
|
};
|
2022-11-11 23:20:28 +01:00
|
|
|
|
Create `Record` type (#10103)
# Description
This PR creates a new `Record` type to reduce duplicate code and
possibly bugs as well. (This is an edited version of #9648.)
- `Record` implements `FromIterator` and `IntoIterator` and so can be
iterated over or collected into. For example, this helps with
conversions to and from (hash)maps. (Also, no more
`cols.iter().zip(vals)`!)
- `Record` has a `push(col, val)` function to help insure that the
number of columns is equal to the number of values. I caught a few
potential bugs thanks to this (e.g. in the `ls` command).
- Finally, this PR also adds a `record!` macro that helps simplify
record creation. It is used like so:
```rust
record! {
"key1" => some_value,
"key2" => Value::string("text", span),
"key3" => Value::int(optional_int.unwrap_or(0), span),
"key4" => Value::bool(config.setting, span),
}
```
Since macros hinder formatting, etc., the right hand side values should
be relatively short and sweet like the examples above.
Where possible, prefer `record!` or `.collect()` on an iterator instead
of multiple `Record::push`s, since the first two automatically set the
record capacity and do less work overall.
# User-Facing Changes
Besides the changes in `nu-protocol` the only other breaking changes are
to `nu-table::{ExpandedTable::build_map, JustTable::kv_table}`.
2023-08-24 21:50:29 +02:00
|
|
|
sig_records.push(Value::record(
|
2024-02-18 13:20:22 +01:00
|
|
|
record! {
|
|
|
|
"parameter_name" => Value::string(&opt.name, span),
|
|
|
|
"parameter_type" => Value::string("positional", span),
|
|
|
|
"syntax_shape" => Value::string(opt.shape.to_string(), span),
|
|
|
|
"is_optional" => Value::bool(true, span),
|
|
|
|
"short_flag" => Value::nothing(span),
|
|
|
|
"description" => Value::string(&opt.desc, span),
|
|
|
|
"custom_completion" => Value::string(custom, span),
|
|
|
|
"parameter_default" => default,
|
|
|
|
},
|
2022-11-11 23:20:28 +01:00
|
|
|
span,
|
Create `Record` type (#10103)
# Description
This PR creates a new `Record` type to reduce duplicate code and
possibly bugs as well. (This is an edited version of #9648.)
- `Record` implements `FromIterator` and `IntoIterator` and so can be
iterated over or collected into. For example, this helps with
conversions to and from (hash)maps. (Also, no more
`cols.iter().zip(vals)`!)
- `Record` has a `push(col, val)` function to help insure that the
number of columns is equal to the number of values. I caught a few
potential bugs thanks to this (e.g. in the `ls` command).
- Finally, this PR also adds a `record!` macro that helps simplify
record creation. It is used like so:
```rust
record! {
"key1" => some_value,
"key2" => Value::string("text", span),
"key3" => Value::int(optional_int.unwrap_or(0), span),
"key4" => Value::bool(config.setting, span),
}
```
Since macros hinder formatting, etc., the right hand side values should
be relatively short and sweet like the examples above.
Where possible, prefer `record!` or `.collect()` on an iterator instead
of multiple `Record::push`s, since the first two automatically set the
record capacity and do less work overall.
# User-Facing Changes
Besides the changes in `nu-protocol` the only other breaking changes are
to `nu-table::{ExpandedTable::build_map, JustTable::kv_table}`.
2023-08-24 21:50:29 +02:00
|
|
|
));
|
2022-11-11 23:20:28 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// rest_positional
|
|
|
|
if let Some(rest) = &signature.rest_positional {
|
2024-02-18 13:20:22 +01:00
|
|
|
let name = if rest.name == "rest" { "" } else { &rest.name };
|
|
|
|
let custom = extract_custom_completion_from_arg(self.engine_state, &rest.shape);
|
2022-11-11 23:20:28 +01:00
|
|
|
|
Create `Record` type (#10103)
# Description
This PR creates a new `Record` type to reduce duplicate code and
possibly bugs as well. (This is an edited version of #9648.)
- `Record` implements `FromIterator` and `IntoIterator` and so can be
iterated over or collected into. For example, this helps with
conversions to and from (hash)maps. (Also, no more
`cols.iter().zip(vals)`!)
- `Record` has a `push(col, val)` function to help insure that the
number of columns is equal to the number of values. I caught a few
potential bugs thanks to this (e.g. in the `ls` command).
- Finally, this PR also adds a `record!` macro that helps simplify
record creation. It is used like so:
```rust
record! {
"key1" => some_value,
"key2" => Value::string("text", span),
"key3" => Value::int(optional_int.unwrap_or(0), span),
"key4" => Value::bool(config.setting, span),
}
```
Since macros hinder formatting, etc., the right hand side values should
be relatively short and sweet like the examples above.
Where possible, prefer `record!` or `.collect()` on an iterator instead
of multiple `Record::push`s, since the first two automatically set the
record capacity and do less work overall.
# User-Facing Changes
Besides the changes in `nu-protocol` the only other breaking changes are
to `nu-table::{ExpandedTable::build_map, JustTable::kv_table}`.
2023-08-24 21:50:29 +02:00
|
|
|
sig_records.push(Value::record(
|
2024-02-18 13:20:22 +01:00
|
|
|
record! {
|
|
|
|
"parameter_name" => Value::string(name, span),
|
|
|
|
"parameter_type" => Value::string("rest", span),
|
|
|
|
"syntax_shape" => Value::string(rest.shape.to_string(), span),
|
|
|
|
"is_optional" => Value::bool(true, span),
|
|
|
|
"short_flag" => Value::nothing(span),
|
|
|
|
"description" => Value::string(&rest.desc, span),
|
|
|
|
"custom_completion" => Value::string(custom, span),
|
|
|
|
// rest_positional does have default, but parser prohibits specifying it?!
|
|
|
|
"parameter_default" => Value::nothing(span),
|
|
|
|
},
|
2022-11-11 23:20:28 +01:00
|
|
|
span,
|
Create `Record` type (#10103)
# Description
This PR creates a new `Record` type to reduce duplicate code and
possibly bugs as well. (This is an edited version of #9648.)
- `Record` implements `FromIterator` and `IntoIterator` and so can be
iterated over or collected into. For example, this helps with
conversions to and from (hash)maps. (Also, no more
`cols.iter().zip(vals)`!)
- `Record` has a `push(col, val)` function to help insure that the
number of columns is equal to the number of values. I caught a few
potential bugs thanks to this (e.g. in the `ls` command).
- Finally, this PR also adds a `record!` macro that helps simplify
record creation. It is used like so:
```rust
record! {
"key1" => some_value,
"key2" => Value::string("text", span),
"key3" => Value::int(optional_int.unwrap_or(0), span),
"key4" => Value::bool(config.setting, span),
}
```
Since macros hinder formatting, etc., the right hand side values should
be relatively short and sweet like the examples above.
Where possible, prefer `record!` or `.collect()` on an iterator instead
of multiple `Record::push`s, since the first two automatically set the
record capacity and do less work overall.
# User-Facing Changes
Besides the changes in `nu-protocol` the only other breaking changes are
to `nu-table::{ExpandedTable::build_map, JustTable::kv_table}`.
2023-08-24 21:50:29 +02:00
|
|
|
));
|
2022-11-11 23:20:28 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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)
|
|
|
|
};
|
|
|
|
|
2024-02-18 13:20:22 +01:00
|
|
|
let default = if let Some(val) = &named.default_value {
|
|
|
|
val.clone()
|
|
|
|
} else {
|
|
|
|
Value::nothing(span)
|
|
|
|
};
|
2022-11-11 23:20:28 +01:00
|
|
|
|
Create `Record` type (#10103)
# Description
This PR creates a new `Record` type to reduce duplicate code and
possibly bugs as well. (This is an edited version of #9648.)
- `Record` implements `FromIterator` and `IntoIterator` and so can be
iterated over or collected into. For example, this helps with
conversions to and from (hash)maps. (Also, no more
`cols.iter().zip(vals)`!)
- `Record` has a `push(col, val)` function to help insure that the
number of columns is equal to the number of values. I caught a few
potential bugs thanks to this (e.g. in the `ls` command).
- Finally, this PR also adds a `record!` macro that helps simplify
record creation. It is used like so:
```rust
record! {
"key1" => some_value,
"key2" => Value::string("text", span),
"key3" => Value::int(optional_int.unwrap_or(0), span),
"key4" => Value::bool(config.setting, span),
}
```
Since macros hinder formatting, etc., the right hand side values should
be relatively short and sweet like the examples above.
Where possible, prefer `record!` or `.collect()` on an iterator instead
of multiple `Record::push`s, since the first two automatically set the
record capacity and do less work overall.
# User-Facing Changes
Besides the changes in `nu-protocol` the only other breaking changes are
to `nu-table::{ExpandedTable::build_map, JustTable::kv_table}`.
2023-08-24 21:50:29 +02:00
|
|
|
sig_records.push(Value::record(
|
2024-02-18 13:20:22 +01:00
|
|
|
record! {
|
|
|
|
"parameter_name" => Value::string(&named.long, span),
|
|
|
|
"parameter_type" => flag_type,
|
|
|
|
"syntax_shape" => shape,
|
|
|
|
"is_optional" => Value::bool(!named.required, span),
|
|
|
|
"short_flag" => short_flag,
|
|
|
|
"description" => Value::string(&named.desc, span),
|
|
|
|
"custom_completion" => Value::string(custom_completion_command_name, span),
|
|
|
|
"parameter_default" => default,
|
|
|
|
},
|
2022-11-11 23:20:28 +01:00
|
|
|
span,
|
Create `Record` type (#10103)
# Description
This PR creates a new `Record` type to reduce duplicate code and
possibly bugs as well. (This is an edited version of #9648.)
- `Record` implements `FromIterator` and `IntoIterator` and so can be
iterated over or collected into. For example, this helps with
conversions to and from (hash)maps. (Also, no more
`cols.iter().zip(vals)`!)
- `Record` has a `push(col, val)` function to help insure that the
number of columns is equal to the number of values. I caught a few
potential bugs thanks to this (e.g. in the `ls` command).
- Finally, this PR also adds a `record!` macro that helps simplify
record creation. It is used like so:
```rust
record! {
"key1" => some_value,
"key2" => Value::string("text", span),
"key3" => Value::int(optional_int.unwrap_or(0), span),
"key4" => Value::bool(config.setting, span),
}
```
Since macros hinder formatting, etc., the right hand side values should
be relatively short and sweet like the examples above.
Where possible, prefer `record!` or `.collect()` on an iterator instead
of multiple `Record::push`s, since the first two automatically set the
record capacity and do less work overall.
# User-Facing Changes
Besides the changes in `nu-protocol` the only other breaking changes are
to `nu-table::{ExpandedTable::build_map, JustTable::kv_table}`.
2023-08-24 21:50:29 +02:00
|
|
|
));
|
2022-11-11 23:20:28 +01:00
|
|
|
}
|
2022-11-12 23:26:20 +01:00
|
|
|
|
|
|
|
// output
|
Create `Record` type (#10103)
# Description
This PR creates a new `Record` type to reduce duplicate code and
possibly bugs as well. (This is an edited version of #9648.)
- `Record` implements `FromIterator` and `IntoIterator` and so can be
iterated over or collected into. For example, this helps with
conversions to and from (hash)maps. (Also, no more
`cols.iter().zip(vals)`!)
- `Record` has a `push(col, val)` function to help insure that the
number of columns is equal to the number of values. I caught a few
potential bugs thanks to this (e.g. in the `ls` command).
- Finally, this PR also adds a `record!` macro that helps simplify
record creation. It is used like so:
```rust
record! {
"key1" => some_value,
"key2" => Value::string("text", span),
"key3" => Value::int(optional_int.unwrap_or(0), span),
"key4" => Value::bool(config.setting, span),
}
```
Since macros hinder formatting, etc., the right hand side values should
be relatively short and sweet like the examples above.
Where possible, prefer `record!` or `.collect()` on an iterator instead
of multiple `Record::push`s, since the first two automatically set the
record capacity and do less work overall.
# User-Facing Changes
Besides the changes in `nu-protocol` the only other breaking changes are
to `nu-table::{ExpandedTable::build_map, JustTable::kv_table}`.
2023-08-24 21:50:29 +02:00
|
|
|
sig_records.push(Value::record(
|
2024-02-18 13:20:22 +01:00
|
|
|
record! {
|
|
|
|
"parameter_name" => Value::nothing(span),
|
|
|
|
"parameter_type" => Value::string("output", span),
|
|
|
|
"syntax_shape" => Value::string(output_type.to_shape().to_string(), span),
|
|
|
|
"is_optional" => Value::bool(false, span),
|
|
|
|
"short_flag" => Value::nothing(span),
|
|
|
|
"description" => Value::nothing(span),
|
|
|
|
"custom_completion" => Value::nothing(span),
|
|
|
|
"parameter_default" => Value::nothing(span),
|
|
|
|
},
|
2022-11-12 23:26:20 +01:00
|
|
|
span,
|
Create `Record` type (#10103)
# Description
This PR creates a new `Record` type to reduce duplicate code and
possibly bugs as well. (This is an edited version of #9648.)
- `Record` implements `FromIterator` and `IntoIterator` and so can be
iterated over or collected into. For example, this helps with
conversions to and from (hash)maps. (Also, no more
`cols.iter().zip(vals)`!)
- `Record` has a `push(col, val)` function to help insure that the
number of columns is equal to the number of values. I caught a few
potential bugs thanks to this (e.g. in the `ls` command).
- Finally, this PR also adds a `record!` macro that helps simplify
record creation. It is used like so:
```rust
record! {
"key1" => some_value,
"key2" => Value::string("text", span),
"key3" => Value::int(optional_int.unwrap_or(0), span),
"key4" => Value::bool(config.setting, span),
}
```
Since macros hinder formatting, etc., the right hand side values should
be relatively short and sweet like the examples above.
Where possible, prefer `record!` or `.collect()` on an iterator instead
of multiple `Record::push`s, since the first two automatically set the
record capacity and do less work overall.
# User-Facing Changes
Besides the changes in `nu-protocol` the only other breaking changes are
to `nu-table::{ExpandedTable::build_map, JustTable::kv_table}`.
2023-08-24 21:50:29 +02:00
|
|
|
));
|
2022-11-12 23:26:20 +01:00
|
|
|
|
2022-11-11 23:20:28 +01:00
|
|
|
sig_records
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
2023-07-13 21:05:03 +02:00
|
|
|
for (command_name, decl_id) in &self.decls_map {
|
2023-03-15 18:40:27 +01:00
|
|
|
let decl = self.engine_state.get_decl(**decl_id);
|
|
|
|
|
|
|
|
if decl.is_known_external() {
|
Create `Record` type (#10103)
# Description
This PR creates a new `Record` type to reduce duplicate code and
possibly bugs as well. (This is an edited version of #9648.)
- `Record` implements `FromIterator` and `IntoIterator` and so can be
iterated over or collected into. For example, this helps with
conversions to and from (hash)maps. (Also, no more
`cols.iter().zip(vals)`!)
- `Record` has a `push(col, val)` function to help insure that the
number of columns is equal to the number of values. I caught a few
potential bugs thanks to this (e.g. in the `ls` command).
- Finally, this PR also adds a `record!` macro that helps simplify
record creation. It is used like so:
```rust
record! {
"key1" => some_value,
"key2" => Value::string("text", span),
"key3" => Value::int(optional_int.unwrap_or(0), span),
"key4" => Value::bool(config.setting, span),
}
```
Since macros hinder formatting, etc., the right hand side values should
be relatively short and sweet like the examples above.
Where possible, prefer `record!` or `.collect()` on an iterator instead
of multiple `Record::push`s, since the first two automatically set the
record capacity and do less work overall.
# User-Facing Changes
Besides the changes in `nu-protocol` the only other breaking changes are
to `nu-table::{ExpandedTable::build_map, JustTable::kv_table}`.
2023-08-24 21:50:29 +02:00
|
|
|
let record = record! {
|
|
|
|
"name" => Value::string(String::from_utf8_lossy(command_name), span),
|
|
|
|
"usage" => Value::string(decl.usage(), span),
|
|
|
|
"decl_id" => Value::int(**decl_id as i64, span),
|
|
|
|
};
|
2023-08-17 10:58:38 +02:00
|
|
|
|
Create `Record` type (#10103)
# Description
This PR creates a new `Record` type to reduce duplicate code and
possibly bugs as well. (This is an edited version of #9648.)
- `Record` implements `FromIterator` and `IntoIterator` and so can be
iterated over or collected into. For example, this helps with
conversions to and from (hash)maps. (Also, no more
`cols.iter().zip(vals)`!)
- `Record` has a `push(col, val)` function to help insure that the
number of columns is equal to the number of values. I caught a few
potential bugs thanks to this (e.g. in the `ls` command).
- Finally, this PR also adds a `record!` macro that helps simplify
record creation. It is used like so:
```rust
record! {
"key1" => some_value,
"key2" => Value::string("text", span),
"key3" => Value::int(optional_int.unwrap_or(0), span),
"key4" => Value::bool(config.setting, span),
}
```
Since macros hinder formatting, etc., the right hand side values should
be relatively short and sweet like the examples above.
Where possible, prefer `record!` or `.collect()` on an iterator instead
of multiple `Record::push`s, since the first two automatically set the
record capacity and do less work overall.
# User-Facing Changes
Besides the changes in `nu-protocol` the only other breaking changes are
to `nu-table::{ExpandedTable::build_map, JustTable::kv_table}`.
2023-08-24 21:50:29 +02:00
|
|
|
externals.push(Value::record(record, span))
|
2023-03-15 18:40:27 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-17 16:37:01 +02:00
|
|
|
sort_rows(&mut externals);
|
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> {
|
2022-11-11 23:20:28 +01:00
|
|
|
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() {
|
2023-08-18 19:47:38 +02:00
|
|
|
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)
|
|
|
|
};
|
|
|
|
|
Create `Record` type (#10103)
# Description
This PR creates a new `Record` type to reduce duplicate code and
possibly bugs as well. (This is an edited version of #9648.)
- `Record` implements `FromIterator` and `IntoIterator` and so can be
iterated over or collected into. For example, this helps with
conversions to and from (hash)maps. (Also, no more
`cols.iter().zip(vals)`!)
- `Record` has a `push(col, val)` function to help insure that the
number of columns is equal to the number of values. I caught a few
potential bugs thanks to this (e.g. in the `ls` command).
- Finally, this PR also adds a `record!` macro that helps simplify
record creation. It is used like so:
```rust
record! {
"key1" => some_value,
"key2" => Value::string("text", span),
"key3" => Value::int(optional_int.unwrap_or(0), span),
"key4" => Value::bool(config.setting, span),
}
```
Since macros hinder formatting, etc., the right hand side values should
be relatively short and sweet like the examples above.
Where possible, prefer `record!` or `.collect()` on an iterator instead
of multiple `Record::push`s, since the first two automatically set the
record capacity and do less work overall.
# User-Facing Changes
Besides the changes in `nu-protocol` the only other breaking changes are
to `nu-table::{ExpandedTable::build_map, JustTable::kv_table}`.
2023-08-24 21:50:29 +02:00
|
|
|
let expansion = String::from_utf8_lossy(
|
|
|
|
self.engine_state.get_span_contents(alias.wrapped_call.span),
|
|
|
|
);
|
|
|
|
|
|
|
|
aliases.push(Value::record(
|
|
|
|
record! {
|
|
|
|
"name" => Value::string(String::from_utf8_lossy(&decl_name), span),
|
|
|
|
"expansion" => Value::string(expansion, span),
|
|
|
|
"usage" => Value::string(alias.usage(), span),
|
|
|
|
"decl_id" => Value::int(decl_id as i64, span),
|
|
|
|
"aliased_decl_id" => aliased_decl_id,
|
|
|
|
},
|
2023-03-10 19:14:55 +01:00
|
|
|
span,
|
Create `Record` type (#10103)
# Description
This PR creates a new `Record` type to reduce duplicate code and
possibly bugs as well. (This is an edited version of #9648.)
- `Record` implements `FromIterator` and `IntoIterator` and so can be
iterated over or collected into. For example, this helps with
conversions to and from (hash)maps. (Also, no more
`cols.iter().zip(vals)`!)
- `Record` has a `push(col, val)` function to help insure that the
number of columns is equal to the number of values. I caught a few
potential bugs thanks to this (e.g. in the `ls` command).
- Finally, this PR also adds a `record!` macro that helps simplify
record creation. It is used like so:
```rust
record! {
"key1" => some_value,
"key2" => Value::string("text", span),
"key3" => Value::int(optional_int.unwrap_or(0), span),
"key4" => Value::bool(config.setting, span),
}
```
Since macros hinder formatting, etc., the right hand side values should
be relatively short and sweet like the examples above.
Where possible, prefer `record!` or `.collect()` on an iterator instead
of multiple `Record::push`s, since the first two automatically set the
record capacity and do less work overall.
# User-Facing Changes
Besides the changes in `nu-protocol` the only other breaking changes are
to `nu-table::{ExpandedTable::build_map, JustTable::kv_table}`.
2023-08-24 21:50:29 +02:00
|
|
|
));
|
2023-03-10 19:14:55 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-11-11 23:20:28 +01:00
|
|
|
|
2023-08-17 16:37:01 +02:00
|
|
|
sort_rows(&mut aliases);
|
|
|
|
// aliases.sort_by(|a, b| a.partial_cmp(b).unwrap_or(Ordering::Equal));
|
2022-11-11 23:20:28 +01:00
|
|
|
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);
|
2022-11-11 23:20:28 +01:00
|
|
|
|
2023-08-17 10:58:38 +02:00
|
|
|
let all_decls = module.decls();
|
2022-12-30 16:44:37 +01:00
|
|
|
|
2023-08-17 16:37:01 +02: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(
|
Create `Record` type (#10103)
# Description
This PR creates a new `Record` type to reduce duplicate code and
possibly bugs as well. (This is an edited version of #9648.)
- `Record` implements `FromIterator` and `IntoIterator` and so can be
iterated over or collected into. For example, this helps with
conversions to and from (hash)maps. (Also, no more
`cols.iter().zip(vals)`!)
- `Record` has a `push(col, val)` function to help insure that the
number of columns is equal to the number of values. I caught a few
potential bugs thanks to this (e.g. in the `ls` command).
- Finally, this PR also adds a `record!` macro that helps simplify
record creation. It is used like so:
```rust
record! {
"key1" => some_value,
"key2" => Value::string("text", span),
"key3" => Value::int(optional_int.unwrap_or(0), span),
"key4" => Value::bool(config.setting, span),
}
```
Since macros hinder formatting, etc., the right hand side values should
be relatively short and sweet like the examples above.
Where possible, prefer `record!` or `.collect()` on an iterator instead
of multiple `Record::push`s, since the first two automatically set the
record capacity and do less work overall.
# User-Facing Changes
Besides the changes in `nu-protocol` the only other breaking changes are
to `nu-table::{ExpandedTable::build_map, JustTable::kv_table}`.
2023-08-24 21:50:29 +02:00
|
|
|
record! {
|
|
|
|
"name" => Value::string(String::from_utf8_lossy(name_bytes), span),
|
|
|
|
"decl_id" => Value::int(*decl_id as i64, span),
|
|
|
|
},
|
2023-08-17 10:58:38 +02:00
|
|
|
span,
|
|
|
|
))
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.collect();
|
2022-12-30 16:44:37 +01:00
|
|
|
|
2023-08-17 16:37:01 +02: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(
|
Create `Record` type (#10103)
# Description
This PR creates a new `Record` type to reduce duplicate code and
possibly bugs as well. (This is an edited version of #9648.)
- `Record` implements `FromIterator` and `IntoIterator` and so can be
iterated over or collected into. For example, this helps with
conversions to and from (hash)maps. (Also, no more
`cols.iter().zip(vals)`!)
- `Record` has a `push(col, val)` function to help insure that the
number of columns is equal to the number of values. I caught a few
potential bugs thanks to this (e.g. in the `ls` command).
- Finally, this PR also adds a `record!` macro that helps simplify
record creation. It is used like so:
```rust
record! {
"key1" => some_value,
"key2" => Value::string("text", span),
"key3" => Value::int(optional_int.unwrap_or(0), span),
"key4" => Value::bool(config.setting, span),
}
```
Since macros hinder formatting, etc., the right hand side values should
be relatively short and sweet like the examples above.
Where possible, prefer `record!` or `.collect()` on an iterator instead
of multiple `Record::push`s, since the first two automatically set the
record capacity and do less work overall.
# User-Facing Changes
Besides the changes in `nu-protocol` the only other breaking changes are
to `nu-table::{ExpandedTable::build_map, JustTable::kv_table}`.
2023-08-24 21:50:29 +02:00
|
|
|
record! {
|
|
|
|
"name" => Value::string(String::from_utf8_lossy(name_bytes), span),
|
|
|
|
"decl_id" => 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();
|
|
|
|
|
2023-08-17 16:37:01 +02:00
|
|
|
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(
|
Create `Record` type (#10103)
# Description
This PR creates a new `Record` type to reduce duplicate code and
possibly bugs as well. (This is an edited version of #9648.)
- `Record` implements `FromIterator` and `IntoIterator` and so can be
iterated over or collected into. For example, this helps with
conversions to and from (hash)maps. (Also, no more
`cols.iter().zip(vals)`!)
- `Record` has a `push(col, val)` function to help insure that the
number of columns is equal to the number of values. I caught a few
potential bugs thanks to this (e.g. in the `ls` command).
- Finally, this PR also adds a `record!` macro that helps simplify
record creation. It is used like so:
```rust
record! {
"key1" => some_value,
"key2" => Value::string("text", span),
"key3" => Value::int(optional_int.unwrap_or(0), span),
"key4" => Value::bool(config.setting, span),
}
```
Since macros hinder formatting, etc., the right hand side values should
be relatively short and sweet like the examples above.
Where possible, prefer `record!` or `.collect()` on an iterator instead
of multiple `Record::push`s, since the first two automatically set the
record capacity and do less work overall.
# User-Facing Changes
Besides the changes in `nu-protocol` the only other breaking changes are
to `nu-table::{ExpandedTable::build_map, JustTable::kv_table}`.
2023-08-24 21:50:29 +02:00
|
|
|
record! {
|
|
|
|
"name" => Value::string(String::from_utf8_lossy(name_bytes), span),
|
|
|
|
"decl_id" => 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();
|
|
|
|
|
2023-08-17 16:37:01 +02:00
|
|
|
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();
|
|
|
|
|
2023-08-17 16:37:01 +02:00
|
|
|
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(
|
Create `Record` type (#10103)
# Description
This PR creates a new `Record` type to reduce duplicate code and
possibly bugs as well. (This is an edited version of #9648.)
- `Record` implements `FromIterator` and `IntoIterator` and so can be
iterated over or collected into. For example, this helps with
conversions to and from (hash)maps. (Also, no more
`cols.iter().zip(vals)`!)
- `Record` has a `push(col, val)` function to help insure that the
number of columns is equal to the number of values. I caught a few
potential bugs thanks to this (e.g. in the `ls` command).
- Finally, this PR also adds a `record!` macro that helps simplify
record creation. It is used like so:
```rust
record! {
"key1" => some_value,
"key2" => Value::string("text", span),
"key3" => Value::int(optional_int.unwrap_or(0), span),
"key4" => Value::bool(config.setting, span),
}
```
Since macros hinder formatting, etc., the right hand side values should
be relatively short and sweet like the examples above.
Where possible, prefer `record!` or `.collect()` on an iterator instead
of multiple `Record::push`s, since the first two automatically set the
record capacity and do less work overall.
# User-Facing Changes
Besides the changes in `nu-protocol` the only other breaking changes are
to `nu-table::{ExpandedTable::build_map, JustTable::kv_table}`.
2023-08-24 21:50:29 +02:00
|
|
|
record! {
|
|
|
|
"name" => Value::string(String::from_utf8_lossy(name_bytes), span),
|
|
|
|
"type" => Value::string(self.engine_state.get_var(*var_id).ty.to_string(), span),
|
|
|
|
"var_id" => Value::int(*var_id as i64, span),
|
|
|
|
},
|
2023-08-17 10:58:38 +02:00
|
|
|
span,
|
|
|
|
)
|
|
|
|
})
|
|
|
|
.collect();
|
|
|
|
|
2023-08-17 16:37:01 +02:00
|
|
|
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),
|
2023-09-03 16:27:29 +02:00
|
|
|
|block_id| Value::block(block_id, span),
|
2023-08-17 10:58:38 +02:00
|
|
|
);
|
|
|
|
|
2024-01-27 16:49:21 +01:00
|
|
|
let (module_usage, module_extra_usage) = self
|
2023-08-17 10:58:38 +02:00
|
|
|
.engine_state
|
|
|
|
.build_module_usage(*module_id)
|
|
|
|
.unwrap_or_default();
|
|
|
|
|
Create `Record` type (#10103)
# Description
This PR creates a new `Record` type to reduce duplicate code and
possibly bugs as well. (This is an edited version of #9648.)
- `Record` implements `FromIterator` and `IntoIterator` and so can be
iterated over or collected into. For example, this helps with
conversions to and from (hash)maps. (Also, no more
`cols.iter().zip(vals)`!)
- `Record` has a `push(col, val)` function to help insure that the
number of columns is equal to the number of values. I caught a few
potential bugs thanks to this (e.g. in the `ls` command).
- Finally, this PR also adds a `record!` macro that helps simplify
record creation. It is used like so:
```rust
record! {
"key1" => some_value,
"key2" => Value::string("text", span),
"key3" => Value::int(optional_int.unwrap_or(0), span),
"key4" => Value::bool(config.setting, span),
}
```
Since macros hinder formatting, etc., the right hand side values should
be relatively short and sweet like the examples above.
Where possible, prefer `record!` or `.collect()` on an iterator instead
of multiple `Record::push`s, since the first two automatically set the
record capacity and do less work overall.
# User-Facing Changes
Besides the changes in `nu-protocol` the only other breaking changes are
to `nu-table::{ExpandedTable::build_map, JustTable::kv_table}`.
2023-08-24 21:50:29 +02:00
|
|
|
Value::record(
|
|
|
|
record! {
|
|
|
|
"name" => Value::string(String::from_utf8_lossy(module_name), span),
|
|
|
|
"commands" => Value::list(export_commands, span),
|
|
|
|
"aliases" => Value::list(export_aliases, span),
|
|
|
|
"externs" => Value::list(export_externs, span),
|
|
|
|
"submodules" => Value::list(export_submodules, span),
|
|
|
|
"constants" => Value::list(export_consts, span),
|
|
|
|
"env_block" => export_env_block,
|
|
|
|
"usage" => Value::string(module_usage, span),
|
2024-01-27 16:49:21 +01:00
|
|
|
"extra_usage" => Value::string(module_extra_usage, span),
|
Create `Record` type (#10103)
# Description
This PR creates a new `Record` type to reduce duplicate code and
possibly bugs as well. (This is an edited version of #9648.)
- `Record` implements `FromIterator` and `IntoIterator` and so can be
iterated over or collected into. For example, this helps with
conversions to and from (hash)maps. (Also, no more
`cols.iter().zip(vals)`!)
- `Record` has a `push(col, val)` function to help insure that the
number of columns is equal to the number of values. I caught a few
potential bugs thanks to this (e.g. in the `ls` command).
- Finally, this PR also adds a `record!` macro that helps simplify
record creation. It is used like so:
```rust
record! {
"key1" => some_value,
"key2" => Value::string("text", span),
"key3" => Value::int(optional_int.unwrap_or(0), span),
"key4" => Value::bool(config.setting, span),
}
```
Since macros hinder formatting, etc., the right hand side values should
be relatively short and sweet like the examples above.
Where possible, prefer `record!` or `.collect()` on an iterator instead
of multiple `Record::push`s, since the first two automatically set the
record capacity and do less work overall.
# User-Facing Changes
Besides the changes in `nu-protocol` the only other breaking changes are
to `nu-table::{ExpandedTable::build_map, JustTable::kv_table}`.
2023-08-24 21:50:29 +02:00
|
|
|
"module_id" => Value::int(*module_id as i64, span),
|
|
|
|
},
|
2023-08-17 10:58:38 +02:00
|
|
|
span,
|
Create `Record` type (#10103)
# Description
This PR creates a new `Record` type to reduce duplicate code and
possibly bugs as well. (This is an edited version of #9648.)
- `Record` implements `FromIterator` and `IntoIterator` and so can be
iterated over or collected into. For example, this helps with
conversions to and from (hash)maps. (Also, no more
`cols.iter().zip(vals)`!)
- `Record` has a `push(col, val)` function to help insure that the
number of columns is equal to the number of values. I caught a few
potential bugs thanks to this (e.g. in the `ls` command).
- Finally, this PR also adds a `record!` macro that helps simplify
record creation. It is used like so:
```rust
record! {
"key1" => some_value,
"key2" => Value::string("text", span),
"key3" => Value::int(optional_int.unwrap_or(0), span),
"key4" => Value::bool(config.setting, span),
}
```
Since macros hinder formatting, etc., the right hand side values should
be relatively short and sweet like the examples above.
Where possible, prefer `record!` or `.collect()` on an iterator instead
of multiple `Record::push`s, since the first two automatically set the
record capacity and do less work overall.
# User-Facing Changes
Besides the changes in `nu-protocol` the only other breaking changes are
to `nu-table::{ExpandedTable::build_map, JustTable::kv_table}`.
2023-08-24 21:50:29 +02:00
|
|
|
)
|
2023-08-17 10:58:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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));
|
2022-11-11 23:20:28 +01:00
|
|
|
}
|
2023-08-17 10:58:38 +02:00
|
|
|
|
2022-11-11 23:20:28 +01: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 {
|
Create `Record` type (#10103)
# Description
This PR creates a new `Record` type to reduce duplicate code and
possibly bugs as well. (This is an edited version of #9648.)
- `Record` implements `FromIterator` and `IntoIterator` and so can be
iterated over or collected into. For example, this helps with
conversions to and from (hash)maps. (Also, no more
`cols.iter().zip(vals)`!)
- `Record` has a `push(col, val)` function to help insure that the
number of columns is equal to the number of values. I caught a few
potential bugs thanks to this (e.g. in the `ls` command).
- Finally, this PR also adds a `record!` macro that helps simplify
record creation. It is used like so:
```rust
record! {
"key1" => some_value,
"key2" => Value::string("text", span),
"key3" => Value::int(optional_int.unwrap_or(0), span),
"key4" => Value::bool(config.setting, span),
}
```
Since macros hinder formatting, etc., the right hand side values should
be relatively short and sweet like the examples above.
Where possible, prefer `record!` or `.collect()` on an iterator instead
of multiple `Record::push`s, since the first two automatically set the
record capacity and do less work overall.
# User-Facing Changes
Besides the changes in `nu-protocol` the only other breaking changes are
to `nu-table::{ExpandedTable::build_map, JustTable::kv_table}`.
2023-08-24 21:50:29 +02:00
|
|
|
let num_env_vars = self
|
|
|
|
.engine_state
|
|
|
|
.env_vars
|
|
|
|
.values()
|
|
|
|
.map(|overlay| overlay.len() as i64)
|
|
|
|
.sum();
|
|
|
|
|
|
|
|
Value::record(
|
|
|
|
record! {
|
|
|
|
"source_bytes" => Value::int(self.engine_state.next_span_start() as i64, span),
|
|
|
|
"num_vars" => Value::int(self.engine_state.num_vars() as i64, span),
|
|
|
|
"num_decls" => Value::int(self.engine_state.num_decls() as i64, span),
|
|
|
|
"num_blocks" => Value::int(self.engine_state.num_blocks() as i64, span),
|
|
|
|
"num_modules" => Value::int(self.engine_state.num_modules() as i64, span),
|
|
|
|
"num_env_vars" => Value::int(num_env_vars, span),
|
|
|
|
},
|
2022-11-11 23:20:28 +01:00
|
|
|
span,
|
Create `Record` type (#10103)
# Description
This PR creates a new `Record` type to reduce duplicate code and
possibly bugs as well. (This is an edited version of #9648.)
- `Record` implements `FromIterator` and `IntoIterator` and so can be
iterated over or collected into. For example, this helps with
conversions to and from (hash)maps. (Also, no more
`cols.iter().zip(vals)`!)
- `Record` has a `push(col, val)` function to help insure that the
number of columns is equal to the number of values. I caught a few
potential bugs thanks to this (e.g. in the `ls` command).
- Finally, this PR also adds a `record!` macro that helps simplify
record creation. It is used like so:
```rust
record! {
"key1" => some_value,
"key2" => Value::string("text", span),
"key3" => Value::int(optional_int.unwrap_or(0), span),
"key4" => Value::bool(config.setting, span),
}
```
Since macros hinder formatting, etc., the right hand side values should
be relatively short and sweet like the examples above.
Where possible, prefer `record!` or `.collect()` on an iterator instead
of multiple `Record::push`s, since the first two automatically set the
record capacity and do less work overall.
# User-Facing Changes
Besides the changes in `nu-protocol` the only other breaking changes are
to `nu-table::{ExpandedTable::build_map, JustTable::kv_table}`.
2023-08-24 21:50:29 +02:00
|
|
|
)
|
2022-11-11 23:20:28 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn extract_custom_completion_from_arg(engine_state: &EngineState, shape: &SyntaxShape) -> String {
|
|
|
|
return match shape {
|
2023-09-29 19:22:58 +02:00
|
|
|
SyntaxShape::CompleterWrapper(_, custom_completion_decl_id) => {
|
2022-11-11 23:20:28 +01:00
|
|
|
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(),
|
|
|
|
};
|
|
|
|
}
|
2023-08-17 16:37:01 +02:00
|
|
|
|
|
|
|
fn sort_rows(decls: &mut [Value]) {
|
|
|
|
decls.sort_by(|a, b| match (a, b) {
|
Create `Record` type (#10103)
# Description
This PR creates a new `Record` type to reduce duplicate code and
possibly bugs as well. (This is an edited version of #9648.)
- `Record` implements `FromIterator` and `IntoIterator` and so can be
iterated over or collected into. For example, this helps with
conversions to and from (hash)maps. (Also, no more
`cols.iter().zip(vals)`!)
- `Record` has a `push(col, val)` function to help insure that the
number of columns is equal to the number of values. I caught a few
potential bugs thanks to this (e.g. in the `ls` command).
- Finally, this PR also adds a `record!` macro that helps simplify
record creation. It is used like so:
```rust
record! {
"key1" => some_value,
"key2" => Value::string("text", span),
"key3" => Value::int(optional_int.unwrap_or(0), span),
"key4" => Value::bool(config.setting, span),
}
```
Since macros hinder formatting, etc., the right hand side values should
be relatively short and sweet like the examples above.
Where possible, prefer `record!` or `.collect()` on an iterator instead
of multiple `Record::push`s, since the first two automatically set the
record capacity and do less work overall.
# User-Facing Changes
Besides the changes in `nu-protocol` the only other breaking changes are
to `nu-table::{ExpandedTable::build_map, JustTable::kv_table}`.
2023-08-24 21:50:29 +02:00
|
|
|
(Value::Record { val: rec_a, .. }, Value::Record { val: rec_b, .. }) => {
|
2023-08-17 16:37:01 +02:00
|
|
|
// Comparing the first value from the record
|
|
|
|
// It is expected that the first value is the name of the entry (command, module, alias, etc.)
|
2023-11-01 23:19:58 +01:00
|
|
|
match (rec_a.values().next(), rec_b.values().next()) {
|
2023-08-17 16:37:01 +02:00
|
|
|
(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,
|
|
|
|
});
|
|
|
|
}
|