From 6b4e57703223f3d3289ee56ba7db7474f1835aab Mon Sep 17 00:00:00 2001 From: Fernando Herrera Date: Tue, 26 Jul 2022 14:47:54 +0100 Subject: [PATCH] plugin show signature (#6126) * plugin show signature * remove expect from macro * use fold to create string --- crates/nu-plugin/src/plugin/mod.rs | 76 +++++++++++++++++++ crates/nu-plugin/src/serializers/capnp/mod.rs | 4 + crates/nu-plugin/src/serializers/json.rs | 4 + 3 files changed, 84 insertions(+) diff --git a/crates/nu-plugin/src/plugin/mod.rs b/crates/nu-plugin/src/plugin/mod.rs index 9c43d98a06..53532725e3 100644 --- a/crates/nu-plugin/src/plugin/mod.rs +++ b/crates/nu-plugin/src/plugin/mod.rs @@ -1,8 +1,11 @@ mod declaration; pub use declaration::PluginDeclaration; +use nu_engine::documentation::get_flags_section; use crate::protocol::{CallInput, LabeledError, PluginCall, PluginData, PluginResponse}; use crate::EncodingType; +use std::env; +use std::fmt::Write; use std::io::BufReader; use std::path::{Path, PathBuf}; use std::process::{Child, Command as CommandSys, Stdio}; @@ -15,6 +18,8 @@ use super::EvaluatedCall; pub(crate) const OUTPUT_BUFFER_SIZE: usize = 8192; pub trait PluginEncoder: Clone { + fn name(&self) -> &str; + fn encode_call( &self, plugin_call: &PluginCall, @@ -183,6 +188,11 @@ pub trait Plugin { // That should be encoded correctly and sent to StdOut for nushell to decode and // and present its result pub fn serve_plugin(plugin: &mut impl Plugin, encoder: impl PluginEncoder) { + if env::args().any(|arg| (arg == "-h") || (arg == "--help")) { + print_help(plugin, encoder); + std::process::exit(0) + } + let mut stdin_buf = BufReader::with_capacity(OUTPUT_BUFFER_SIZE, std::io::stdin()); let plugin_call = encoder.decode_call(&mut stdin_buf); @@ -253,3 +263,69 @@ pub fn serve_plugin(plugin: &mut impl Plugin, encoder: impl PluginEncoder) { } } } + +fn print_help(plugin: &mut impl Plugin, encoder: impl PluginEncoder) { + println!("Nushell Plugin"); + println!("Encoder: {}", encoder.name()); + + let mut help = String::new(); + + plugin.signature().iter().for_each(|signature| { + let res = write!(help, "\nCommand: {}", signature.name) + .and_then(|_| writeln!(help, "\nUsage:\n > {}", signature.usage)) + .and_then(|_| { + if !signature.extra_usage.is_empty() { + writeln!(help, "\nExtra usage:\n > {}", signature.extra_usage) + } else { + Ok(()) + } + }) + .and_then(|_| { + let flags = get_flags_section(signature); + write!(help, "{}", flags) + }) + .and_then(|_| writeln!(help, "\nParameters:")) + .and_then(|_| { + signature + .required_positional + .iter() + .try_for_each(|positional| { + writeln!( + help, + " {} <{:?}>: {}", + positional.name, positional.shape, positional.desc + ) + }) + }) + .and_then(|_| { + signature + .optional_positional + .iter() + .try_for_each(|positional| { + writeln!( + help, + " (optional) {} <{:?}>: {}", + positional.name, positional.shape, positional.desc + ) + }) + }) + .and_then(|_| { + if let Some(rest_positional) = &signature.rest_positional { + writeln!( + help, + " ...{} <{:?}>: {}", + rest_positional.name, rest_positional.shape, rest_positional.desc + ) + } else { + Ok(()) + } + }) + .and_then(|_| writeln!(help, "======================")); + + if res.is_err() { + println!("{:?}", res) + } + }); + + println!("{}", help) +} diff --git a/crates/nu-plugin/src/serializers/capnp/mod.rs b/crates/nu-plugin/src/serializers/capnp/mod.rs index 96bd87ddf8..08e7d529f0 100644 --- a/crates/nu-plugin/src/serializers/capnp/mod.rs +++ b/crates/nu-plugin/src/serializers/capnp/mod.rs @@ -13,6 +13,10 @@ use crate::{plugin::PluginEncoder, protocol::PluginResponse}; pub struct CapnpSerializer; impl PluginEncoder for CapnpSerializer { + fn name(&self) -> &str { + "Capnp Serializer" + } + fn encode_call( &self, plugin_call: &crate::protocol::PluginCall, diff --git a/crates/nu-plugin/src/serializers/json.rs b/crates/nu-plugin/src/serializers/json.rs index 87a43d0506..be90100f15 100644 --- a/crates/nu-plugin/src/serializers/json.rs +++ b/crates/nu-plugin/src/serializers/json.rs @@ -6,6 +6,10 @@ use crate::{plugin::PluginEncoder, protocol::PluginResponse}; pub struct JsonSerializer; impl PluginEncoder for JsonSerializer { + fn name(&self) -> &str { + "Json Serializer" + } + fn encode_call( &self, plugin_call: &crate::protocol::PluginCall,