mirror of
https://github.com/nushell/nushell.git
synced 2025-06-30 14:40:06 +02:00
Change PluginCommand API to be more like Command (#12279)
# Description
This is something that was discussed in the core team meeting last
Wednesday. @ayax79 is building `nu-plugin-polars` with all of the
dataframe commands into a plugin, and there are a lot of them, so it
would help to make the API more similar. At the same time, I think the
`Command` API is just better anyway. I don't think the difference is
justified, and the types for core commands have the benefit of requiring
less `.into()` because they often don't own their data
- Broke `signature()` up into `name()`, `usage()`, `extra_usage()`,
`search_terms()`, `examples()`
- `signature()` returns `nu_protocol::Signature`
- `examples()` returns `Vec<nu_protocol::Example>`
- `PluginSignature` and `PluginExample` no longer need to be used by
plugin developers
# User-Facing Changes
Breaking API for plugins yet again 😄
This commit is contained in:
@ -1,35 +1,48 @@
|
||||
use nu_plugin::{EngineInterface, EvaluatedCall, PluginCommand};
|
||||
use nu_protocol::{
|
||||
Category, LabeledError, PipelineData, PluginExample, PluginSignature, RawStream, Type, Value,
|
||||
Category, Example, LabeledError, PipelineData, RawStream, Signature, Type, Value,
|
||||
};
|
||||
|
||||
use crate::Example;
|
||||
use crate::ExamplePlugin;
|
||||
|
||||
/// `<list<string>> | example collect-external`
|
||||
pub struct CollectExternal;
|
||||
|
||||
impl PluginCommand for CollectExternal {
|
||||
type Plugin = Example;
|
||||
type Plugin = ExamplePlugin;
|
||||
|
||||
fn signature(&self) -> PluginSignature {
|
||||
PluginSignature::build("example collect-external")
|
||||
.usage("Example transformer to raw external stream")
|
||||
.search_terms(vec!["example".into()])
|
||||
fn name(&self) -> &str {
|
||||
"example collect-external"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Example transformer to raw external stream"
|
||||
}
|
||||
|
||||
fn search_terms(&self) -> Vec<&str> {
|
||||
vec!["example"]
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build(self.name())
|
||||
.input_output_types(vec![
|
||||
(Type::List(Type::String.into()), Type::String),
|
||||
(Type::List(Type::Binary.into()), Type::Binary),
|
||||
])
|
||||
.plugin_examples(vec![PluginExample {
|
||||
example: "[a b] | example collect-external".into(),
|
||||
description: "collect strings into one stream".into(),
|
||||
result: Some(Value::test_string("ab")),
|
||||
}])
|
||||
.category(Category::Experimental)
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
example: "[a b] | example collect-external",
|
||||
description: "collect strings into one stream",
|
||||
result: Some(Value::test_string("ab")),
|
||||
}]
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_plugin: &Example,
|
||||
_plugin: &ExamplePlugin,
|
||||
_engine: &EngineInterface,
|
||||
call: &EvaluatedCall,
|
||||
input: PipelineData,
|
||||
@ -55,5 +68,5 @@ impl PluginCommand for CollectExternal {
|
||||
#[test]
|
||||
fn test_examples() -> Result<(), nu_protocol::ShellError> {
|
||||
use nu_plugin_test_support::PluginTest;
|
||||
PluginTest::new("example", Example.into())?.test_command_examples(&CollectExternal)
|
||||
PluginTest::new("example", ExamplePlugin.into())?.test_command_examples(&CollectExternal)
|
||||
}
|
||||
|
@ -1,25 +1,38 @@
|
||||
use nu_plugin::{EngineInterface, EvaluatedCall, SimplePluginCommand};
|
||||
use nu_protocol::{Category, LabeledError, PluginSignature, Type, Value};
|
||||
use nu_protocol::{Category, LabeledError, Signature, Type, Value};
|
||||
|
||||
use crate::Example;
|
||||
use crate::ExamplePlugin;
|
||||
|
||||
pub struct Config;
|
||||
|
||||
impl SimplePluginCommand for Config {
|
||||
type Plugin = Example;
|
||||
type Plugin = ExamplePlugin;
|
||||
|
||||
fn signature(&self) -> PluginSignature {
|
||||
PluginSignature::build("example config")
|
||||
.usage("Show plugin configuration")
|
||||
.extra_usage("The configuration is set under $env.config.plugins.example")
|
||||
fn name(&self) -> &str {
|
||||
"example config"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Show plugin configuration"
|
||||
}
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
"The configuration is set under $env.config.plugins.example"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build(self.name())
|
||||
.category(Category::Experimental)
|
||||
.search_terms(vec!["example".into(), "configuration".into()])
|
||||
.input_output_type(Type::Nothing, Type::Table(vec![]))
|
||||
}
|
||||
|
||||
fn search_terms(&self) -> Vec<&str> {
|
||||
vec!["example", "configuration"]
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_plugin: &Example,
|
||||
_plugin: &ExamplePlugin,
|
||||
engine: &EngineInterface,
|
||||
call: &EvaluatedCall,
|
||||
_input: &Value,
|
||||
|
@ -1,18 +1,23 @@
|
||||
use nu_plugin::{EngineInterface, EvaluatedCall, SimplePluginCommand};
|
||||
use nu_protocol::{Category, LabeledError, PluginSignature, Value};
|
||||
use nu_protocol::{Category, LabeledError, Signature, Value};
|
||||
|
||||
use crate::Example;
|
||||
use crate::ExamplePlugin;
|
||||
|
||||
pub struct DisableGc;
|
||||
|
||||
impl SimplePluginCommand for DisableGc {
|
||||
type Plugin = Example;
|
||||
type Plugin = ExamplePlugin;
|
||||
|
||||
fn signature(&self) -> PluginSignature {
|
||||
PluginSignature::build("example disable-gc")
|
||||
.usage("Disable the plugin garbage collector for `example`")
|
||||
.extra_usage(
|
||||
"\
|
||||
fn name(&self) -> &str {
|
||||
"example disable-gc"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Disable the plugin garbage collector for `example`"
|
||||
}
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
"\
|
||||
Plugins are garbage collected by default after a period of inactivity. This
|
||||
behavior is configurable with `$env.config.plugin_gc.default`, or to change it
|
||||
specifically for the example plugin, use
|
||||
@ -20,21 +25,22 @@ specifically for the example plugin, use
|
||||
|
||||
This command demonstrates how plugins can control this behavior and disable GC
|
||||
temporarily if they need to. It is still possible to stop the plugin explicitly
|
||||
using `plugin stop example`.",
|
||||
)
|
||||
.search_terms(vec![
|
||||
"example".into(),
|
||||
"gc".into(),
|
||||
"plugin_gc".into(),
|
||||
"garbage".into(),
|
||||
])
|
||||
using `plugin stop example`."
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build(self.name())
|
||||
.switch("reset", "Turn the garbage collector back on", None)
|
||||
.category(Category::Experimental)
|
||||
}
|
||||
|
||||
fn search_terms(&self) -> Vec<&str> {
|
||||
vec!["example", "gc", "plugin_gc", "garbage"]
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_plugin: &Example,
|
||||
_plugin: &ExamplePlugin,
|
||||
engine: &EngineInterface,
|
||||
call: &EvaluatedCall,
|
||||
_input: &Value,
|
||||
|
@ -1,17 +1,27 @@
|
||||
use nu_plugin::{EngineInterface, EvaluatedCall, SimplePluginCommand};
|
||||
use nu_protocol::{Category, LabeledError, PluginSignature, SyntaxShape, Type, Value};
|
||||
use nu_protocol::{Category, LabeledError, Signature, SyntaxShape, Type, Value};
|
||||
|
||||
use crate::Example;
|
||||
use crate::ExamplePlugin;
|
||||
|
||||
pub struct Env;
|
||||
|
||||
impl SimplePluginCommand for Env {
|
||||
type Plugin = Example;
|
||||
type Plugin = ExamplePlugin;
|
||||
|
||||
fn signature(&self) -> PluginSignature {
|
||||
PluginSignature::build("example env")
|
||||
.usage("Get environment variable(s)")
|
||||
.extra_usage("Returns all environment variables if no name provided")
|
||||
fn name(&self) -> &str {
|
||||
"example env"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Get environment variable(s)"
|
||||
}
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
"Returns all environment variables if no name provided"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build(self.name())
|
||||
.category(Category::Experimental)
|
||||
.optional(
|
||||
"name",
|
||||
@ -25,13 +35,16 @@ impl SimplePluginCommand for Env {
|
||||
"Set an environment variable to the value",
|
||||
None,
|
||||
)
|
||||
.search_terms(vec!["example".into(), "env".into()])
|
||||
.input_output_type(Type::Nothing, Type::Any)
|
||||
}
|
||||
|
||||
fn search_terms(&self) -> Vec<&str> {
|
||||
vec!["example", "env"]
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_plugin: &Example,
|
||||
_plugin: &ExamplePlugin,
|
||||
engine: &EngineInterface,
|
||||
call: &EvaluatedCall,
|
||||
_input: &Value,
|
||||
|
@ -1,37 +1,48 @@
|
||||
use nu_plugin::{EngineInterface, EvaluatedCall, PluginCommand};
|
||||
use nu_protocol::{
|
||||
Category, LabeledError, PipelineData, PluginExample, PluginSignature, SyntaxShape, Type,
|
||||
};
|
||||
use nu_protocol::{Category, Example, LabeledError, PipelineData, Signature, SyntaxShape, Type};
|
||||
|
||||
use crate::Example;
|
||||
use crate::ExamplePlugin;
|
||||
|
||||
/// `<list> | example for-each { |value| ... }`
|
||||
pub struct ForEach;
|
||||
|
||||
impl PluginCommand for ForEach {
|
||||
type Plugin = Example;
|
||||
type Plugin = ExamplePlugin;
|
||||
|
||||
fn signature(&self) -> PluginSignature {
|
||||
PluginSignature::build("example for-each")
|
||||
.usage("Example execution of a closure with a stream")
|
||||
.extra_usage("Prints each value the closure returns to stderr")
|
||||
fn name(&self) -> &str {
|
||||
"example for-each"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Example execution of a closure with a stream"
|
||||
}
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
"Prints each value the closure returns to stderr"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build(self.name())
|
||||
.input_output_type(Type::ListStream, Type::Nothing)
|
||||
.required(
|
||||
"closure",
|
||||
SyntaxShape::Closure(Some(vec![SyntaxShape::Any])),
|
||||
"The closure to run for each input value",
|
||||
)
|
||||
.plugin_examples(vec![PluginExample {
|
||||
example: "ls | get name | example for-each { |f| ^file $f }".into(),
|
||||
description: "example with an external command".into(),
|
||||
result: None,
|
||||
}])
|
||||
.category(Category::Experimental)
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
example: "ls | get name | example for-each { |f| ^file $f }",
|
||||
description: "example with an external command",
|
||||
result: None,
|
||||
}]
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_plugin: &Example,
|
||||
_plugin: &ExamplePlugin,
|
||||
engine: &EngineInterface,
|
||||
call: &EvaluatedCall,
|
||||
input: PipelineData,
|
||||
@ -49,5 +60,5 @@ impl PluginCommand for ForEach {
|
||||
#[test]
|
||||
fn test_examples() -> Result<(), nu_protocol::ShellError> {
|
||||
use nu_plugin_test_support::PluginTest;
|
||||
PluginTest::new("example", Example.into())?.test_command_examples(&ForEach)
|
||||
PluginTest::new("example", ExamplePlugin.into())?.test_command_examples(&ForEach)
|
||||
}
|
||||
|
@ -1,21 +1,31 @@
|
||||
use nu_plugin::{EngineInterface, EvaluatedCall, PluginCommand};
|
||||
use nu_protocol::{
|
||||
Category, IntoInterruptiblePipelineData, LabeledError, PipelineData, PluginExample,
|
||||
PluginSignature, SyntaxShape, Type, Value,
|
||||
Category, Example, IntoInterruptiblePipelineData, LabeledError, PipelineData, Signature,
|
||||
SyntaxShape, Type, Value,
|
||||
};
|
||||
|
||||
use crate::Example;
|
||||
use crate::ExamplePlugin;
|
||||
|
||||
/// `example generate <initial> { |previous| {out: ..., next: ...} }`
|
||||
pub struct Generate;
|
||||
|
||||
impl PluginCommand for Generate {
|
||||
type Plugin = Example;
|
||||
type Plugin = ExamplePlugin;
|
||||
|
||||
fn signature(&self) -> PluginSignature {
|
||||
PluginSignature::build("example generate")
|
||||
.usage("Example execution of a closure to produce a stream")
|
||||
.extra_usage("See the builtin `generate` command")
|
||||
fn name(&self) -> &str {
|
||||
"example generate"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Example execution of a closure to produce a stream"
|
||||
}
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
"See the builtin `generate` command"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build(self.name())
|
||||
.input_output_type(Type::Nothing, Type::ListStream)
|
||||
.required(
|
||||
"initial",
|
||||
@ -27,23 +37,25 @@ impl PluginCommand for Generate {
|
||||
SyntaxShape::Closure(Some(vec![SyntaxShape::Any])),
|
||||
"The closure to run to generate values",
|
||||
)
|
||||
.plugin_examples(vec![PluginExample {
|
||||
example: "example generate 0 { |i| if $i <= 10 { {out: $i, next: ($i + 2)} } }"
|
||||
.into(),
|
||||
description: "Generate a sequence of numbers".into(),
|
||||
result: Some(Value::test_list(
|
||||
[0, 2, 4, 6, 8, 10]
|
||||
.into_iter()
|
||||
.map(Value::test_int)
|
||||
.collect(),
|
||||
)),
|
||||
}])
|
||||
.category(Category::Experimental)
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
example: "example generate 0 { |i| if $i <= 10 { {out: $i, next: ($i + 2)} } }",
|
||||
description: "Generate a sequence of numbers",
|
||||
result: Some(Value::test_list(
|
||||
[0, 2, 4, 6, 8, 10]
|
||||
.into_iter()
|
||||
.map(Value::test_int)
|
||||
.collect(),
|
||||
)),
|
||||
}]
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_plugin: &Example,
|
||||
_plugin: &ExamplePlugin,
|
||||
engine: &EngineInterface,
|
||||
call: &EvaluatedCall,
|
||||
_input: PipelineData,
|
||||
@ -81,7 +93,7 @@ impl PluginCommand for Generate {
|
||||
fn test_examples() -> Result<(), nu_protocol::ShellError> {
|
||||
use nu_cmd_lang::If;
|
||||
use nu_plugin_test_support::PluginTest;
|
||||
PluginTest::new("example", Example.into())?
|
||||
PluginTest::new("example", ExamplePlugin.into())?
|
||||
.add_decl(Box::new(If))?
|
||||
.test_command_examples(&Generate)
|
||||
}
|
||||
|
@ -1,28 +1,38 @@
|
||||
use nu_plugin::{EngineInterface, EvaluatedCall, SimplePluginCommand};
|
||||
use nu_protocol::{Category, LabeledError, PluginSignature, Value};
|
||||
use nu_protocol::{Category, LabeledError, Signature, Value};
|
||||
|
||||
use crate::Example;
|
||||
use crate::ExamplePlugin;
|
||||
|
||||
pub struct Main;
|
||||
|
||||
impl SimplePluginCommand for Main {
|
||||
type Plugin = Example;
|
||||
type Plugin = ExamplePlugin;
|
||||
|
||||
fn signature(&self) -> PluginSignature {
|
||||
PluginSignature::build("example")
|
||||
.usage("Example commands for Nushell plugins")
|
||||
.extra_usage(
|
||||
r#"
|
||||
fn name(&self) -> &str {
|
||||
"example"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Example commands for Nushell plugins"
|
||||
}
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
r#"
|
||||
The `example` plugin demonstrates usage of the Nushell plugin API.
|
||||
|
||||
Several commands provided to test and demonstrate different capabilities of
|
||||
plugins exposed through the API. None of these commands are intended to be
|
||||
particularly useful.
|
||||
"#
|
||||
.trim(),
|
||||
)
|
||||
.search_terms(vec!["example".into()])
|
||||
.category(Category::Experimental)
|
||||
.trim()
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build(self.name()).category(Category::Experimental)
|
||||
}
|
||||
|
||||
fn search_terms(&self) -> Vec<&str> {
|
||||
vec!["example"]
|
||||
}
|
||||
|
||||
fn run(
|
||||
|
@ -1,37 +1,53 @@
|
||||
use nu_plugin::{EngineInterface, EvaluatedCall, SimplePluginCommand};
|
||||
use nu_protocol::{Category, LabeledError, PluginExample, PluginSignature, SyntaxShape, Value};
|
||||
use nu_protocol::{Category, Example, LabeledError, Signature, SyntaxShape, Value};
|
||||
|
||||
use crate::Example;
|
||||
use crate::ExamplePlugin;
|
||||
|
||||
pub struct One;
|
||||
|
||||
impl SimplePluginCommand for One {
|
||||
type Plugin = Example;
|
||||
type Plugin = ExamplePlugin;
|
||||
|
||||
fn signature(&self) -> PluginSignature {
|
||||
fn name(&self) -> &str {
|
||||
"example one"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Plugin test example 1. Returns Value::Nothing"
|
||||
}
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
"Extra usage for example one"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
// The signature defines the usage of the command inside Nu, and also automatically
|
||||
// generates its help page.
|
||||
PluginSignature::build("example one")
|
||||
.usage("PluginSignature test 1 for plugin. Returns Value::Nothing")
|
||||
.extra_usage("Extra usage for example one")
|
||||
.search_terms(vec!["example".into()])
|
||||
Signature::build(self.name())
|
||||
.required("a", SyntaxShape::Int, "required integer value")
|
||||
.required("b", SyntaxShape::String, "required string value")
|
||||
.switch("flag", "a flag for the signature", Some('f'))
|
||||
.optional("opt", SyntaxShape::Int, "Optional number")
|
||||
.named("named", SyntaxShape::String, "named string", Some('n'))
|
||||
.rest("rest", SyntaxShape::String, "rest value string")
|
||||
.plugin_examples(vec![PluginExample {
|
||||
example: "example one 3 bb".into(),
|
||||
description: "running example with an int value and string value".into(),
|
||||
result: None,
|
||||
}])
|
||||
.category(Category::Experimental)
|
||||
}
|
||||
|
||||
fn search_terms(&self) -> Vec<&str> {
|
||||
vec!["example"]
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
example: "example one 3 bb",
|
||||
description: "running example with an int value and string value",
|
||||
result: None,
|
||||
}]
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
plugin: &Example,
|
||||
plugin: &ExamplePlugin,
|
||||
_engine: &EngineInterface,
|
||||
call: &EvaluatedCall,
|
||||
input: &Value,
|
||||
@ -45,5 +61,5 @@ impl SimplePluginCommand for One {
|
||||
#[test]
|
||||
fn test_examples() -> Result<(), nu_protocol::ShellError> {
|
||||
use nu_plugin_test_support::PluginTest;
|
||||
PluginTest::new("example", Example.into())?.test_command_examples(&One)
|
||||
PluginTest::new("example", ExamplePlugin.into())?.test_command_examples(&One)
|
||||
}
|
||||
|
@ -1,39 +1,51 @@
|
||||
use nu_plugin::{EngineInterface, EvaluatedCall, PluginCommand};
|
||||
use nu_protocol::{
|
||||
Category, LabeledError, ListStream, PipelineData, PluginExample, PluginSignature, SyntaxShape,
|
||||
Type, Value,
|
||||
Category, Example, LabeledError, ListStream, PipelineData, Signature, SyntaxShape, Type, Value,
|
||||
};
|
||||
|
||||
use crate::Example;
|
||||
use crate::ExamplePlugin;
|
||||
|
||||
/// `example seq <first> <last>`
|
||||
pub struct Seq;
|
||||
|
||||
impl PluginCommand for Seq {
|
||||
type Plugin = Example;
|
||||
type Plugin = ExamplePlugin;
|
||||
|
||||
fn signature(&self) -> PluginSignature {
|
||||
PluginSignature::build("example seq")
|
||||
.usage("Example stream generator for a list of values")
|
||||
.search_terms(vec!["example".into()])
|
||||
fn name(&self) -> &str {
|
||||
"example seq"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Example stream generator for a list of values"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build(self.name())
|
||||
.required("first", SyntaxShape::Int, "first number to generate")
|
||||
.required("last", SyntaxShape::Int, "last number to generate")
|
||||
.input_output_type(Type::Nothing, Type::List(Type::Int.into()))
|
||||
.plugin_examples(vec![PluginExample {
|
||||
example: "example seq 1 3".into(),
|
||||
description: "generate a sequence from 1 to 3".into(),
|
||||
result: Some(Value::test_list(vec![
|
||||
Value::test_int(1),
|
||||
Value::test_int(2),
|
||||
Value::test_int(3),
|
||||
])),
|
||||
}])
|
||||
.category(Category::Experimental)
|
||||
}
|
||||
|
||||
fn search_terms(&self) -> Vec<&str> {
|
||||
vec!["example"]
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
example: "example seq 1 3",
|
||||
description: "generate a sequence from 1 to 3",
|
||||
result: Some(Value::test_list(vec![
|
||||
Value::test_int(1),
|
||||
Value::test_int(2),
|
||||
Value::test_int(3),
|
||||
])),
|
||||
}]
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_plugin: &Example,
|
||||
_plugin: &ExamplePlugin,
|
||||
_engine: &EngineInterface,
|
||||
call: &EvaluatedCall,
|
||||
_input: PipelineData,
|
||||
@ -50,5 +62,5 @@ impl PluginCommand for Seq {
|
||||
#[test]
|
||||
fn test_examples() -> Result<(), nu_protocol::ShellError> {
|
||||
use nu_plugin_test_support::PluginTest;
|
||||
PluginTest::new("example", Example.into())?.test_command_examples(&Seq)
|
||||
PluginTest::new("example", ExamplePlugin.into())?.test_command_examples(&Seq)
|
||||
}
|
||||
|
@ -1,35 +1,46 @@
|
||||
use nu_plugin::{EngineInterface, EvaluatedCall, PluginCommand};
|
||||
use nu_protocol::{
|
||||
Category, LabeledError, PipelineData, PluginExample, PluginSignature, Span, Type, Value,
|
||||
};
|
||||
use nu_protocol::{Category, Example, LabeledError, PipelineData, Signature, Span, Type, Value};
|
||||
|
||||
use crate::Example;
|
||||
use crate::ExamplePlugin;
|
||||
|
||||
/// `<list> | example sum`
|
||||
pub struct Sum;
|
||||
|
||||
impl PluginCommand for Sum {
|
||||
type Plugin = Example;
|
||||
type Plugin = ExamplePlugin;
|
||||
|
||||
fn signature(&self) -> PluginSignature {
|
||||
PluginSignature::build("example sum")
|
||||
.usage("Example stream consumer for a list of values")
|
||||
.search_terms(vec!["example".into()])
|
||||
fn name(&self) -> &str {
|
||||
"example sum"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Example stream consumer for a list of values"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build(self.name())
|
||||
.input_output_types(vec![
|
||||
(Type::List(Type::Int.into()), Type::Int),
|
||||
(Type::List(Type::Float.into()), Type::Float),
|
||||
])
|
||||
.plugin_examples(vec![PluginExample {
|
||||
example: "example seq 1 5 | example sum".into(),
|
||||
description: "sum values from 1 to 5".into(),
|
||||
result: Some(Value::test_int(15)),
|
||||
}])
|
||||
.category(Category::Experimental)
|
||||
}
|
||||
|
||||
fn search_terms(&self) -> Vec<&str> {
|
||||
vec!["example"]
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
example: "example seq 1 5 | example sum",
|
||||
description: "sum values from 1 to 5",
|
||||
result: Some(Value::test_int(15)),
|
||||
}]
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_plugin: &Example,
|
||||
_plugin: &ExamplePlugin,
|
||||
_engine: &EngineInterface,
|
||||
call: &EvaluatedCall,
|
||||
input: PipelineData,
|
||||
@ -92,5 +103,5 @@ impl IntOrFloat {
|
||||
#[test]
|
||||
fn test_examples() -> Result<(), nu_protocol::ShellError> {
|
||||
use nu_plugin_test_support::PluginTest;
|
||||
PluginTest::new("example", Example.into())?.test_command_examples(&Sum)
|
||||
PluginTest::new("example", ExamplePlugin.into())?.test_command_examples(&Sum)
|
||||
}
|
||||
|
@ -1,18 +1,25 @@
|
||||
use nu_plugin::{EngineInterface, EvaluatedCall, SimplePluginCommand};
|
||||
use nu_protocol::{Category, LabeledError, PluginSignature, SyntaxShape, Value};
|
||||
use nu_protocol::{Category, LabeledError, Signature, SyntaxShape, Value};
|
||||
|
||||
use crate::Example;
|
||||
use crate::ExamplePlugin;
|
||||
|
||||
pub struct Three;
|
||||
|
||||
impl SimplePluginCommand for Three {
|
||||
type Plugin = Example;
|
||||
type Plugin = ExamplePlugin;
|
||||
|
||||
fn signature(&self) -> PluginSignature {
|
||||
fn name(&self) -> &str {
|
||||
"example three"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Plugin test example 3. Returns labeled error"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
// The signature defines the usage of the command inside Nu, and also automatically
|
||||
// generates its help page.
|
||||
PluginSignature::build("example three")
|
||||
.usage("PluginSignature test 3 for plugin. Returns labeled error")
|
||||
Signature::build(self.name())
|
||||
.required("a", SyntaxShape::Int, "required integer value")
|
||||
.required("b", SyntaxShape::String, "required string value")
|
||||
.switch("flag", "a flag for the signature", Some('f'))
|
||||
@ -24,7 +31,7 @@ impl SimplePluginCommand for Three {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
plugin: &Example,
|
||||
plugin: &ExamplePlugin,
|
||||
_engine: &EngineInterface,
|
||||
call: &EvaluatedCall,
|
||||
input: &Value,
|
||||
|
@ -1,18 +1,25 @@
|
||||
use nu_plugin::{EngineInterface, EvaluatedCall, SimplePluginCommand};
|
||||
use nu_protocol::{record, Category, LabeledError, PluginSignature, SyntaxShape, Value};
|
||||
use nu_protocol::{record, Category, LabeledError, Signature, SyntaxShape, Value};
|
||||
|
||||
use crate::Example;
|
||||
use crate::ExamplePlugin;
|
||||
|
||||
pub struct Two;
|
||||
|
||||
impl SimplePluginCommand for Two {
|
||||
type Plugin = Example;
|
||||
type Plugin = ExamplePlugin;
|
||||
|
||||
fn signature(&self) -> PluginSignature {
|
||||
fn name(&self) -> &str {
|
||||
"example two"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Plugin test example 2. Returns list of records"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
// The signature defines the usage of the command inside Nu, and also automatically
|
||||
// generates its help page.
|
||||
PluginSignature::build("example two")
|
||||
.usage("PluginSignature test 2 for plugin. Returns list of records")
|
||||
Signature::build(self.name())
|
||||
.required("a", SyntaxShape::Int, "required integer value")
|
||||
.required("b", SyntaxShape::String, "required string value")
|
||||
.switch("flag", "a flag for the signature", Some('f'))
|
||||
@ -24,7 +31,7 @@ impl SimplePluginCommand for Two {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
plugin: &Example,
|
||||
plugin: &ExamplePlugin,
|
||||
_engine: &EngineInterface,
|
||||
call: &EvaluatedCall,
|
||||
input: &Value,
|
||||
|
@ -1,9 +1,9 @@
|
||||
use nu_plugin::EvaluatedCall;
|
||||
use nu_protocol::{LabeledError, Value};
|
||||
|
||||
pub struct Example;
|
||||
pub struct ExamplePlugin;
|
||||
|
||||
impl Example {
|
||||
impl ExamplePlugin {
|
||||
pub fn print_values(
|
||||
&self,
|
||||
index: u32,
|
||||
|
@ -4,9 +4,9 @@ mod commands;
|
||||
mod example;
|
||||
|
||||
pub use commands::*;
|
||||
pub use example::Example;
|
||||
pub use example::ExamplePlugin;
|
||||
|
||||
impl Plugin for Example {
|
||||
impl Plugin for ExamplePlugin {
|
||||
fn commands(&self) -> Vec<Box<dyn PluginCommand<Plugin = Self>>> {
|
||||
// This is a list of all of the commands you would like Nu to register when your plugin is
|
||||
// loaded.
|
||||
|
@ -1,12 +1,12 @@
|
||||
use nu_plugin::{serve_plugin, MsgPackSerializer};
|
||||
use nu_plugin_example::Example;
|
||||
use nu_plugin_example::ExamplePlugin;
|
||||
|
||||
fn main() {
|
||||
// When defining your plugin, you can select the Serializer that could be
|
||||
// used to encode and decode the messages. The available options are
|
||||
// MsgPackSerializer and JsonSerializer. Both are defined in the serializer
|
||||
// folder in nu-plugin.
|
||||
serve_plugin(&Example {}, MsgPackSerializer {})
|
||||
serve_plugin(&ExamplePlugin {}, MsgPackSerializer {})
|
||||
|
||||
// Note
|
||||
// When creating plugins in other languages one needs to consider how a plugin
|
||||
|
Reference in New Issue
Block a user