From 2a8a628b728ee2810af69dc354be8f373d261bb8 Mon Sep 17 00:00:00 2001
From: Darren Schroeder <343840+fdncred@users.noreply.github.com>
Date: Sun, 27 Nov 2022 02:03:17 -0600
Subject: [PATCH] add `help operators` command (#7254)
# Description
This PR adds a new command called `help operators`. The intention is to
make nushell's operators more discoverable.
Operations are evaluated in the precedence order (from highest to
lowest).
# User-Facing 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
# 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.
---
.../src/core_commands/help_operators.rs | 288 ++++++++++++++++++
crates/nu-command/src/core_commands/mod.rs | 2 +
crates/nu-command/src/default_context.rs | 1 +
3 files changed, 291 insertions(+)
create mode 100644 crates/nu-command/src/core_commands/help_operators.rs
diff --git a/crates/nu-command/src/core_commands/help_operators.rs b/crates/nu-command/src/core_commands/help_operators.rs
new file mode 100644
index 000000000..ef21ad63b
--- /dev/null
+++ b/crates/nu-command/src/core_commands/help_operators.rs
@@ -0,0 +1,288 @@
+use nu_protocol::{
+ ast::Call,
+ engine::{Command, EngineState, Stack},
+ Category, IntoInterruptiblePipelineData, PipelineData, ShellError, Signature, Value,
+};
+
+#[derive(Clone)]
+pub struct HelpOperators;
+
+impl Command for HelpOperators {
+ fn name(&self) -> &str {
+ "help operators"
+ }
+
+ fn usage(&self) -> &str {
+ "Show help on nushell operators."
+ }
+
+ fn signature(&self) -> Signature {
+ Signature::build("help operators").category(Category::Core)
+ }
+
+ fn run(
+ &self,
+ engine_state: &EngineState,
+ _stack: &mut Stack,
+ call: &Call,
+ _input: PipelineData,
+ ) -> Result {
+ let head = call.head;
+ let op_info = generate_operator_info();
+ let mut recs = vec![];
+
+ for op in op_info {
+ let mut cols = vec![];
+ let mut vals = vec![];
+ cols.push("type".into());
+ vals.push(Value::string(op.op_type, head));
+ cols.push("operator".into());
+ vals.push(Value::string(op.operator, head));
+ cols.push("name".into());
+ vals.push(Value::string(op.name, head));
+ cols.push("precedence".into());
+ vals.push(Value::int(op.precedence, head));
+ recs.push(Value::Record {
+ cols,
+ vals,
+ span: head,
+ })
+ }
+
+ Ok(recs
+ .into_iter()
+ .into_pipeline_data(engine_state.ctrlc.clone()))
+ }
+}
+
+struct OperatorInfo {
+ op_type: String,
+ operator: String,
+ name: String,
+ precedence: i64,
+}
+
+fn generate_operator_info() -> Vec {
+ vec![
+ OperatorInfo {
+ op_type: "Assignment".into(),
+ operator: "=".into(),
+ name: "Assign".into(),
+ precedence: 10,
+ },
+ OperatorInfo {
+ op_type: "Assignment".into(),
+ operator: "+=".into(),
+ name: "PlusAssign".into(),
+ precedence: 10,
+ },
+ OperatorInfo {
+ op_type: "Assignment".into(),
+ operator: "-=".into(),
+ name: "MinusAssign".into(),
+ precedence: 10,
+ },
+ OperatorInfo {
+ op_type: "Assignment".into(),
+ operator: "*=".into(),
+ name: "MultiplyAssign".into(),
+ precedence: 10,
+ },
+ OperatorInfo {
+ op_type: "Assignment".into(),
+ operator: "/=".into(),
+ name: "DivideAssign".into(),
+ precedence: 10,
+ },
+ OperatorInfo {
+ op_type: "Comparison".into(),
+ operator: "==".into(),
+ name: "Equal".into(),
+ precedence: 80,
+ },
+ OperatorInfo {
+ op_type: "Comparison".into(),
+ operator: "!=".into(),
+ name: "NotEqual".into(),
+ precedence: 80,
+ },
+ OperatorInfo {
+ op_type: "Comparison".into(),
+ operator: "<".into(),
+ name: "LessThan".into(),
+ precedence: 80,
+ },
+ OperatorInfo {
+ op_type: "Comparison".into(),
+ operator: "<=".into(),
+ name: "LessThanOrEqual".into(),
+ precedence: 80,
+ },
+ OperatorInfo {
+ op_type: "Comparison".into(),
+ operator: ">".into(),
+ name: "GreaterThan".into(),
+ precedence: 80,
+ },
+ OperatorInfo {
+ op_type: "Comparison".into(),
+ operator: ">=".into(),
+ name: "GreaterThanOrEqual".into(),
+ precedence: 80,
+ },
+ OperatorInfo {
+ op_type: "Comparison".into(),
+ operator: "=~".into(),
+ name: "RegexMatch".into(),
+ precedence: 80,
+ },
+ OperatorInfo {
+ op_type: "Comparison".into(),
+ operator: "!~".into(),
+ name: "NotRegexMatch".into(),
+ precedence: 80,
+ },
+ OperatorInfo {
+ op_type: "Comparison".into(),
+ operator: "in".into(),
+ name: "In".into(),
+ precedence: 80,
+ },
+ OperatorInfo {
+ op_type: "Comparison".into(),
+ operator: "not-in".into(),
+ name: "NotIn".into(),
+ precedence: 80,
+ },
+ OperatorInfo {
+ op_type: "Comparison".into(),
+ operator: "starts-with".into(),
+ name: "StartsWith".into(),
+ precedence: 80,
+ },
+ OperatorInfo {
+ op_type: "Comparison".into(),
+ operator: "ends-with".into(),
+ name: "EndsWith".into(),
+ precedence: 80,
+ },
+ OperatorInfo {
+ op_type: "Math".into(),
+ operator: "+".into(),
+ name: "Plus".into(),
+ precedence: 90,
+ },
+ OperatorInfo {
+ op_type: "Math".into(),
+ operator: "++".into(),
+ name: "Append".into(),
+ precedence: 80,
+ },
+ OperatorInfo {
+ op_type: "Math".into(),
+ operator: "-".into(),
+ name: "Minus".into(),
+ precedence: 90,
+ },
+ OperatorInfo {
+ op_type: "Math".into(),
+ operator: "*".into(),
+ name: "Multiply".into(),
+ precedence: 95,
+ },
+ OperatorInfo {
+ op_type: "Math".into(),
+ operator: "/".into(),
+ name: "Divide".into(),
+ precedence: 95,
+ },
+ OperatorInfo {
+ op_type: "Math".into(),
+ operator: "//".into(),
+ name: "FloorDivision".into(),
+ precedence: 95,
+ },
+ OperatorInfo {
+ op_type: "Math".into(),
+ operator: "mod".into(),
+ name: "Modulo".into(),
+ precedence: 95,
+ },
+ OperatorInfo {
+ op_type: "Math".into(),
+ operator: "**".into(),
+ name: "Pow ".into(),
+ precedence: 100,
+ },
+ OperatorInfo {
+ op_type: "Bitwise".into(),
+ operator: "bit-or".into(),
+ name: "BitOr".into(),
+ precedence: 60,
+ },
+ OperatorInfo {
+ op_type: "Bitwise".into(),
+ operator: "bit-xor".into(),
+ name: "BitXor".into(),
+ precedence: 70,
+ },
+ OperatorInfo {
+ op_type: "Bitwise".into(),
+ operator: "bit-and".into(),
+ name: "BitAnd".into(),
+ precedence: 75,
+ },
+ OperatorInfo {
+ op_type: "Bitwise".into(),
+ operator: "bit-shl".into(),
+ name: "ShiftLeft".into(),
+ precedence: 85,
+ },
+ OperatorInfo {
+ op_type: "Bitwise".into(),
+ operator: "bit-shr".into(),
+ name: "ShiftRight".into(),
+ precedence: 85,
+ },
+ OperatorInfo {
+ op_type: "Boolean".into(),
+ operator: "&&".into(),
+ name: "And".into(),
+ precedence: 50,
+ },
+ OperatorInfo {
+ op_type: "Boolean".into(),
+ operator: "and".into(),
+ name: "And".into(),
+ precedence: 50,
+ },
+ OperatorInfo {
+ op_type: "Boolean".into(),
+ operator: "||".into(),
+ name: "Or".into(),
+ precedence: 40,
+ },
+ OperatorInfo {
+ op_type: "Boolean".into(),
+ operator: "or".into(),
+ name: "Or".into(),
+ precedence: 40,
+ },
+ OperatorInfo {
+ op_type: "Boolean".into(),
+ operator: "xor".into(),
+ name: "Xor".into(),
+ precedence: 45,
+ },
+ ]
+}
+
+#[cfg(test)]
+mod test {
+ #[test]
+ fn test_examples() {
+ use super::HelpOperators;
+ use crate::test_examples;
+ test_examples(HelpOperators {})
+ }
+}
diff --git a/crates/nu-command/src/core_commands/mod.rs b/crates/nu-command/src/core_commands/mod.rs
index 139b159a2..8cde57223 100644
--- a/crates/nu-command/src/core_commands/mod.rs
+++ b/crates/nu-command/src/core_commands/mod.rs
@@ -19,6 +19,7 @@ mod export_use;
mod extern_;
mod for_;
pub mod help;
+mod help_operators;
mod hide;
mod hide_env;
mod if_;
@@ -56,6 +57,7 @@ pub use export_use::ExportUse;
pub use extern_::Extern;
pub use for_::For;
pub use help::Help;
+pub use help_operators::HelpOperators;
pub use hide::Hide;
pub use hide_env::HideEnv;
pub use if_::If;
diff --git a/crates/nu-command/src/default_context.rs b/crates/nu-command/src/default_context.rs
index f7acf9dce..e1f66863b 100644
--- a/crates/nu-command/src/default_context.rs
+++ b/crates/nu-command/src/default_context.rs
@@ -49,6 +49,7 @@ pub fn create_default_context() -> EngineState {
Extern,
For,
Help,
+ HelpOperators,
Hide,
HideEnv,
If,