From 75ddfe9f5a84a7d25dde27cbe0576118423c3975 Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Tue, 2 Jul 2019 19:56:20 +1200 Subject: [PATCH 1/7] Add filter and sink plugins --- src/cli.rs | 4 +- src/commands/command.rs | 8 +++ src/commands/config.rs | 4 ++ src/commands/open.rs | 14 ++-- src/commands/plugin.rs | 74 ++++++++++++++++----- src/commands/skip_while.rs | 4 ++ src/commands/where_.rs | 4 ++ src/lib.rs | 3 + src/parser/registry.rs | 25 +++++--- src/plugin.rs | 101 +++++++++++++++++++++++++++++ src/plugins/inc.rs | 127 +++++++++++-------------------------- src/plugins/sum.rs | 94 +++++++-------------------- 12 files changed, 268 insertions(+), 194 deletions(-) create mode 100644 src/plugin.rs diff --git a/src/cli.rs b/src/cli.rs index 92dce34e7..a59aef321 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -80,8 +80,7 @@ pub async fn cli() -> Result<(), Box> { Arc::new(Config), Arc::new(SkipWhile), command("sort-by", sort_by::sort_by), - command("inc", |x| plugin::plugin("inc".into(), x)), - command("sum", |x| plugin::plugin("sum".into(), x)), + command("inc", |x| plugin::filter_plugin("inc".into(), x)), ]); context.add_sinks(vec![ @@ -91,6 +90,7 @@ pub async fn cli() -> Result<(), Box> { sink("table", table::table), sink("tree", tree::tree), sink("vtable", vtable::vtable), + sink("sum", |x| plugin::sink_plugin("sum".into(), x)), ]); } diff --git a/src/commands/command.rs b/src/commands/command.rs index 36e521de6..e9eac51b5 100644 --- a/src/commands/command.rs +++ b/src/commands/command.rs @@ -82,6 +82,10 @@ pub trait Command { optional_positional: vec![], rest_positional: true, named: indexmap::IndexMap::new(), + is_filter: true, + is_sink: false, + can_load: vec![], + can_save: vec![], } } } @@ -97,6 +101,10 @@ pub trait Sink { optional_positional: vec![], rest_positional: true, named: indexmap::IndexMap::new(), + is_filter: false, + is_sink: true, + can_load: vec![], + can_save: vec![], } } } diff --git a/src/commands/config.rs b/src/commands/config.rs index 3e8ec1992..d4c793e7c 100644 --- a/src/commands/config.rs +++ b/src/commands/config.rs @@ -33,6 +33,10 @@ impl Command for Config { optional_positional: vec![], rest_positional: false, named, + is_sink: true, + is_filter: false, + can_load: vec![], + can_save: vec![], } } } diff --git a/src/commands/open.rs b/src/commands/open.rs index 87d1d959e..a03086397 100644 --- a/src/commands/open.rs +++ b/src/commands/open.rs @@ -28,11 +28,19 @@ impl Command for Open { optional_positional: vec![], rest_positional: false, named, + is_filter: true, + is_sink: false, + can_load: vec![], + can_save: vec![], } } } -pub fn fetch(cwd: &PathBuf, location: &str, span: Span) -> Result<(Option, String), ShellError> { +pub fn fetch( + cwd: &PathBuf, + location: &str, + span: Span, +) -> Result<(Option, String), ShellError> { let mut cwd = cwd.clone(); if location.starts_with("http:") || location.starts_with("https:") { let response = reqwest::get(location); @@ -154,9 +162,7 @@ pub fn parse_as_value( name_span, ) }), - _ => { - Ok(Value::string(contents)) - } + _ => Ok(Value::string(contents)), } } diff --git a/src/commands/plugin.rs b/src/commands/plugin.rs index 8d7b2c5d8..60b972ad3 100644 --- a/src/commands/plugin.rs +++ b/src/commands/plugin.rs @@ -1,3 +1,4 @@ +use crate::commands::command::SinkCommandArgs; use crate::errors::ShellError; use crate::prelude::*; use serde::{self, Deserialize, Serialize}; @@ -26,21 +27,23 @@ impl JsonRpc { #[serde(tag = "method")] #[allow(non_camel_case_types)] pub enum NuResult { - response { params: VecDeque }, + response { + params: Result, ShellError>, + }, } -pub fn plugin(plugin_name: String, args: CommandArgs) -> Result { - let input = args.input; - let args = if let Some(ref positional) = args.args.positional { - positional.clone() - } else { - vec![] - }; - +pub fn filter_plugin(plugin_name: String, args: CommandArgs) -> Result { let mut path = std::path::PathBuf::from("."); path.push("target"); path.push("debug"); path.push(format!("nu_plugin_{}", plugin_name)); + + path = if path.exists() { + path + } else { + std::path::PathBuf::from(format!("nu_plugin_{}", plugin_name)) + }; + let mut child = std::process::Command::new(path) .stdin(std::process::Stdio::piped()) .stdout(std::process::Stdio::piped()) @@ -53,7 +56,7 @@ pub fn plugin(plugin_name: String, args: CommandArgs) -> Result Result { @@ -90,20 +94,30 @@ pub fn plugin(plugin_name: String, args: CommandArgs) -> Result { let response = serde_json::from_str::(&input); match response { - Ok(NuResult::response { params }) => params, - Err(_) => { + Ok(NuResult::response { params }) => match params { + Ok(params) => params, + Err(e) => { + let mut result = VecDeque::new(); + result.push_back(ReturnValue::Value(Value::Error(Box::new(e)))); + result + } + }, + Err(e) => { let mut result = VecDeque::new(); result.push_back(ReturnValue::Value(Value::Error(Box::new( - ShellError::string("Error while processing input"), + ShellError::string(format!( + "Error while processing input: {:?} {}", + e, input + )), )))); result } } } - Err(_) => { + Err(e) => { let mut result = VecDeque::new(); result.push_back(ReturnValue::Value(Value::Error(Box::new( - ShellError::string("Error while processing input"), + ShellError::string(format!("Error while processing input: {:?}", e)), )))); result } @@ -114,3 +128,31 @@ pub fn plugin(plugin_name: String, args: CommandArgs) -> Result Result<(), ShellError> { + let mut path = std::path::PathBuf::from("."); + path.push("target"); + path.push("debug"); + path.push(format!("nu_plugin_{}", plugin_name)); + + path = if path.exists() { + path + } else { + std::path::PathBuf::from(format!("nu_plugin_{}", plugin_name)) + }; + + let mut child = std::process::Command::new(path) + .stdin(std::process::Stdio::piped()) + .spawn() + .expect("Failed to spawn child process"); + + let stdin = child.stdin.as_mut().expect("Failed to open stdin"); + + let request = JsonRpc::new("sink", (args.args, args.input)); + let request_raw = serde_json::to_string(&request).unwrap(); + stdin.write(format!("{}\n", request_raw).as_bytes())?; + + let _ = child.wait(); + + Ok(()) +} diff --git a/src/commands/skip_while.rs b/src/commands/skip_while.rs index eb6a94882..466f8d956 100644 --- a/src/commands/skip_while.rs +++ b/src/commands/skip_while.rs @@ -20,6 +20,10 @@ impl Command for SkipWhile { optional_positional: vec![], rest_positional: false, named: indexmap::IndexMap::new(), + is_filter: true, + is_sink: false, + can_load: vec![], + can_save: vec![], } } } diff --git a/src/commands/where_.rs b/src/commands/where_.rs index e5c2279ad..afc0d901c 100644 --- a/src/commands/where_.rs +++ b/src/commands/where_.rs @@ -19,6 +19,10 @@ impl Command for Where { optional_positional: vec![], rest_positional: false, named: indexmap::IndexMap::new(), + is_filter: true, + is_sink: false, + can_load: vec![], + can_save: vec![], } } } diff --git a/src/lib.rs b/src/lib.rs index 1f801a435..c84390672 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,6 +15,7 @@ mod format; mod git; mod object; mod parser; +mod plugin; mod prelude; mod shell; mod stream; @@ -22,7 +23,9 @@ mod stream; pub use crate::commands::command::ReturnValue; pub use crate::parser::parse::span::SpannedItem; pub use crate::parser::Spanned; +pub use crate::plugin::{serve_plugin, Plugin}; pub use cli::cli; pub use errors::ShellError; pub use object::base::{Primitive, Value}; pub use parser::parse::text::Text; +pub use parser::registry::{Args, CommandConfig}; diff --git a/src/parser/registry.rs b/src/parser/registry.rs index c3ee5ebf0..52cc9f049 100644 --- a/src/parser/registry.rs +++ b/src/parser/registry.rs @@ -5,17 +5,18 @@ use derive_new::new; use getset::Getters; use indexmap::IndexMap; use log::trace; +use serde::{Deserialize, Serialize}; use std::fmt; #[allow(unused)] -#[derive(Debug)] +#[derive(Debug, Serialize, Deserialize)] pub enum NamedType { Switch, Mandatory(NamedValue), Optional(NamedValue), } -#[derive(Debug)] +#[derive(Debug, Serialize, Deserialize)] pub enum NamedValue { Single, @@ -33,7 +34,7 @@ impl NamedValue { } #[allow(unused)] -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub enum PositionalType { Value(String), Block(String), @@ -55,17 +56,21 @@ impl PositionalType { } } -#[derive(Debug, Getters)] +#[derive(Debug, Getters, Serialize, Deserialize)] #[get = "crate"] pub struct CommandConfig { - crate name: String, - crate mandatory_positional: Vec, - crate optional_positional: Vec, - crate rest_positional: bool, - crate named: IndexMap, + pub name: String, + pub mandatory_positional: Vec, + pub optional_positional: Vec, + pub rest_positional: bool, + pub named: IndexMap, + pub is_filter: bool, + pub is_sink: bool, + pub can_load: Vec, + pub can_save: Vec, } -#[derive(Debug, Default, new)] +#[derive(Debug, Default, new, Serialize, Deserialize)] pub struct Args { pub positional: Option>>, pub named: Option>>, diff --git a/src/plugin.rs b/src/plugin.rs new file mode 100644 index 000000000..412e5aa8a --- /dev/null +++ b/src/plugin.rs @@ -0,0 +1,101 @@ +use crate::{Args, CommandConfig, ReturnValue, ShellError, Value}; +use serde::{Deserialize, Serialize}; +use std::io; + +pub trait Plugin { + fn config(&mut self) -> Result { + Err(ShellError::string("`config` not implemented in plugin")) + } + #[allow(unused)] + fn begin_filter(&mut self, args: Args) -> Result<(), ShellError> { + Err(ShellError::string( + "`begin_filter` not implemented in plugin", + )) + } + #[allow(unused)] + fn filter(&mut self, input: Value) -> Result, ShellError> { + Err(ShellError::string("`filter` not implemented in plugin")) + } + #[allow(unused)] + fn sink(&mut self, args: Args, input: Vec) {} + + fn quit(&mut self) { + return; + } +} + +pub fn serve_plugin(plugin: &mut dyn Plugin) { + loop { + let mut input = String::new(); + match io::stdin().read_line(&mut input) { + Ok(_) => { + let command = serde_json::from_str::(&input); + match command { + Ok(NuCommand::config) => { + send_response(plugin.config()); + } + Ok(NuCommand::begin_filter { params }) => { + let _ = plugin.begin_filter(params); + } + Ok(NuCommand::filter { params }) => { + send_response(plugin.filter(params)); + } + Ok(NuCommand::sink { params }) => { + plugin.sink(params.0, params.1); + break; + } + Ok(NuCommand::quit) => { + plugin.quit(); + break; + } + e => { + send_response(ShellError::string(format!( + "Could not handle plugin message: {:?}", + e, + ))); + break; + } + } + } + e => { + send_response(ShellError::string(format!( + "Could not handle plugin message: {:?}", + e, + ))); + break; + } + } + } +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct JsonRpc { + jsonrpc: String, + pub method: String, + pub params: T, +} +impl JsonRpc { + pub fn new>(method: U, params: T) -> Self { + JsonRpc { + jsonrpc: "2.0".into(), + method: method.into(), + params, + } + } +} + +fn send_response(result: T) { + let response = JsonRpc::new("response", result); + let response_raw = serde_json::to_string(&response).unwrap(); + println!("{}", response_raw); +} +#[derive(Debug, Serialize, Deserialize)] +#[serde(tag = "method")] +#[allow(non_camel_case_types)] +pub enum NuCommand { + config, + begin_filter { params: Args }, + filter { params: Value }, + sink { params: (Args, Vec) }, + quit, +} diff --git a/src/plugins/inc.rs b/src/plugins/inc.rs index d6ac3d84b..afb0abeaf 100644 --- a/src/plugins/inc.rs +++ b/src/plugins/inc.rs @@ -1,102 +1,49 @@ -use nu::{Primitive, ReturnValue, ShellError, Spanned, Value}; -use serde::{Deserialize, Serialize}; -use std::io; +use nu::{serve_plugin, Args, Plugin, Primitive, ReturnValue, ShellError, Spanned, Value}; -/// A wrapper for proactive notifications to the IDE (eg. diagnostics). These must -/// follow the JSON 2.0 RPC spec - -#[derive(Debug, Serialize, Deserialize)] -pub struct JsonRpc { - jsonrpc: String, - pub method: String, - pub params: Vec, +struct Inc { + inc_by: i64, } -impl JsonRpc { - pub fn new>(method: U, params: Vec) -> Self { - JsonRpc { - jsonrpc: "2.0".into(), - method: method.into(), - params, - } +impl Inc { + fn new() -> Inc { + Inc { inc_by: 1 } } } -fn send_response(result: Vec) { - let response = JsonRpc::new("response", result); - let response_raw = serde_json::to_string(&response).unwrap(); - println!("{}", response_raw); -} -#[derive(Debug, Serialize, Deserialize)] -#[serde(tag = "method")] -#[allow(non_camel_case_types)] -pub enum NuCommand { - init { params: Vec> }, - filter { params: Value }, - quit, -} - -fn main() -> Result<(), Box> { - let mut inc_by = 1; - - loop { - let mut input = String::new(); - match io::stdin().read_line(&mut input) { - Ok(_) => { - let command = serde_json::from_str::(&input); - - match command { - Ok(NuCommand::init { params }) => { - for param in params { - match param { - Spanned { - item: Value::Primitive(Primitive::Int(i)), - .. - } => { - inc_by = i; - } - _ => { - send_response(vec![ReturnValue::Value(Value::Error( - Box::new(ShellError::string("Unrecognized type in params")), - ))]); - } - } - } - } - Ok(NuCommand::filter { params }) => match params { - Value::Primitive(Primitive::Int(i)) => { - send_response(vec![ReturnValue::Value(Value::int(i + inc_by))]); - } - Value::Primitive(Primitive::Bytes(b)) => { - send_response(vec![ReturnValue::Value(Value::bytes( - b + inc_by as u64, - ))]); - } - x => { - send_response(vec![ReturnValue::Value(Value::Error(Box::new( - ShellError::string(format!("Unrecognized type in stream: {:?}", x)), - )))]); - } - }, - Ok(NuCommand::quit) => { - break; - } - Err(e) => { - send_response(vec![ReturnValue::Value(Value::Error(Box::new( - ShellError::string(format!( - "Unrecognized type in stream: {} {:?}", - input, e - )), - )))]); +impl Plugin for Inc { + fn begin_filter(&mut self, args: Args) -> Result<(), ShellError> { + if let Some(args) = args.positional { + for arg in args { + match arg { + Spanned { + item: Value::Primitive(Primitive::Int(i)), + .. + } => { + self.inc_by = i; } + _ => return Err(ShellError::string("Unrecognized type in params")), } } - Err(_) => { - send_response(vec![ReturnValue::Value(Value::Error(Box::new( - ShellError::string(format!("Unrecognized type in stream: {}", input)), - )))]); - } } + + Ok(()) } - Ok(()) + fn filter(&mut self, input: Value) -> Result, ShellError> { + match input { + Value::Primitive(Primitive::Int(i)) => { + Ok(vec![ReturnValue::Value(Value::int(i + self.inc_by))]) + } + Value::Primitive(Primitive::Bytes(b)) => Ok(vec![ReturnValue::Value(Value::bytes( + b + self.inc_by as u64, + ))]), + x => Err(ShellError::string(format!( + "Unrecognized type in stream: {:?}", + x + ))), + } + } +} + +fn main() { + serve_plugin(&mut Inc::new()); } diff --git a/src/plugins/sum.rs b/src/plugins/sum.rs index 0bbfc6a5f..4576ad1d5 100644 --- a/src/plugins/sum.rs +++ b/src/plugins/sum.rs @@ -1,83 +1,33 @@ -use nu::{Primitive, ReturnValue, ShellError, Spanned, Value}; -use serde::{Deserialize, Serialize}; -use std::io; +use nu::{serve_plugin, Args, Plugin, Primitive, Value}; -/// A wrapper for proactive notifications to the IDE (eg. diagnostics). These must -/// follow the JSON 2.0 RPC spec +struct Sum; -#[derive(Debug, Serialize, Deserialize)] -pub struct JsonRpc { - jsonrpc: String, - pub method: String, - pub params: Vec, -} -impl JsonRpc { - pub fn new>(method: U, params: Vec) -> Self { - JsonRpc { - jsonrpc: "2.0".into(), - method: method.into(), - params, - } +impl Sum { + fn new() -> Sum { + Sum } } -fn send_response(result: Vec) { - let response = JsonRpc::new("response", result); - let response_raw = serde_json::to_string(&response).unwrap(); - println!("{}", response_raw); -} -#[derive(Debug, Serialize, Deserialize)] -#[serde(tag = "method")] -#[allow(non_camel_case_types)] -pub enum NuCommand { - init { params: Vec> }, - filter { params: Value }, - quit, -} +impl Plugin for Sum { + fn sink(&mut self, _args: Args, input: Vec) { + let mut total = 0i64; -fn main() -> Result<(), Box> { - let mut total = 0i64; - - loop { - let mut input = String::new(); - match io::stdin().read_line(&mut input) { - Ok(_) => { - let command = serde_json::from_str::(&input); - - match command { - Ok(NuCommand::init { .. }) => {} - Ok(NuCommand::filter { params }) => match params { - Value::Primitive(Primitive::Int(i)) => { - total += i as i64; - send_response(vec![ReturnValue::Value(Value::int(total))]); - } - Value::Primitive(Primitive::Bytes(b)) => { - total += b as i64; - send_response(vec![ReturnValue::Value(Value::bytes(total as u64))]); - } - _ => { - send_response(vec![ReturnValue::Value(Value::Error(Box::new( - ShellError::string("Unrecognized type in stream"), - )))]); - } - }, - Ok(NuCommand::quit) => { - break; - } - Err(_) => { - send_response(vec![ReturnValue::Value(Value::Error(Box::new( - ShellError::string("Unrecognized type in stream"), - )))]); - } + for v in input { + match v { + Value::Primitive(Primitive::Int(i)) => { + total += i; } - } - Err(_) => { - send_response(vec![ReturnValue::Value(Value::Error(Box::new( - ShellError::string("Unrecognized type in stream"), - )))]); + Value::Primitive(Primitive::Bytes(i)) => { + total += i as i64; + } + _ => {} } } - } - Ok(()) + println!("Result: {}", total); + } +} + +fn main() { + serve_plugin(&mut Sum::new()); } From 0180769971f6e24388434d5dd6b9c3107e2ae732 Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Thu, 4 Jul 2019 05:37:09 +1200 Subject: [PATCH 2/7] WIP now load plugins automatically --- Cargo.lock | 1 + Cargo.toml | 5 + src/cli.rs | 201 +++++++++++++++++++++++++++++--------- src/commands/command.rs | 11 ++- src/commands/from_ini.rs | 9 +- src/commands/from_json.rs | 7 +- src/commands/from_toml.rs | 7 +- src/commands/from_xml.rs | 7 +- src/commands/from_yaml.rs | 7 +- src/commands/plugin.rs | 40 ++++---- src/commands/to_json.rs | 2 +- src/commands/to_toml.rs | 2 +- src/format/entries.rs | 18 +--- src/format/table.rs | 12 +-- src/format/tree.rs | 4 +- src/format/vtable.rs | 8 +- src/lib.rs | 2 +- src/object.rs | 2 - src/object/base.rs | 41 ++++---- src/object/desc.rs | 134 ------------------------- src/object/dict.rs | 54 +++------- src/plugin.rs | 8 +- src/plugins/inc.rs | 19 +++- src/plugins/newskip.rs | 59 +++++++++++ src/plugins/sum.rs | 17 +++- 25 files changed, 348 insertions(+), 329 deletions(-) delete mode 100644 src/object/desc.rs create mode 100644 src/plugins/newskip.rs diff --git a/Cargo.lock b/Cargo.lock index a6feec745..8c4808fe7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1492,6 +1492,7 @@ dependencies = [ "toml 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "toml-query 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 2.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 18e2bf9d4..695cef75e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -63,6 +63,7 @@ serde_ini = "0.2.0" subprocess = "0.1.18" sys-info = "0.5.7" mime = "0.3.13" +walkdir = "2.2.8" [dev-dependencies] pretty_assertions = "0.6.1" @@ -79,6 +80,10 @@ path = "src/plugins/sum.rs" name = "nu_plugin_inc" path = "src/plugins/inc.rs" +[[bin]] +name = "nu_plugin_newskip" +path = "src/plugins/newskip.rs" + [[bin]] name = "nu" path = "src/main.rs" diff --git a/src/cli.rs b/src/cli.rs index a59aef321..b205ec3a7 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,30 +1,31 @@ use crate::commands::autoview; use crate::commands::classified::SinkCommand; -use crate::commands::command::sink; - -use crate::prelude::*; - use crate::commands::classified::{ ClassifiedCommand, ClassifiedInputStream, ClassifiedPipeline, ExternalCommand, InternalCommand, StreamNext, }; +use crate::commands::command::sink; +use crate::commands::plugin::{JsonRpc, NuResult}; use crate::context::Context; crate use crate::errors::ShellError; use crate::evaluate::Scope; -use crate::parser::parse::span::Spanned; -use crate::parser::registry; -use crate::parser::{Pipeline, PipelineElement, TokenNode}; - use crate::git::current_branch; use crate::object::Value; +use crate::parser::parse::span::Spanned; +use crate::parser::registry; +use crate::parser::registry::CommandConfig; +use crate::parser::{Pipeline, PipelineElement, TokenNode}; +use crate::prelude::*; use log::{debug, trace}; use rustyline::error::ReadlineError; use rustyline::{self, ColorMode, Config, Editor}; - +use std::env; use std::error::Error; +use std::io::{BufRead, BufReader, Write}; use std::iter::Iterator; use std::sync::atomic::{AtomicBool, Ordering}; +use walkdir::WalkDir; #[derive(Debug)] pub enum MaybeOwned<'a, T> { @@ -41,6 +42,112 @@ impl MaybeOwned<'a, T> { } } +fn load_plugin(fname: &str, context: &mut Context) -> Result<(), ShellError> { + use crate::commands::{command, plugin}; + + println!("fname: {}", fname); + let mut child = std::process::Command::new(fname) + .stdin(std::process::Stdio::piped()) + .stdout(std::process::Stdio::piped()) + .spawn() + .expect("Failed to spawn child process"); + + let stdin = child.stdin.as_mut().expect("Failed to open stdin"); + let stdout = child.stdout.as_mut().expect("Failed to open stdout"); + + let mut reader = BufReader::new(stdout); + + println!("Sending out config request"); + + let request = JsonRpc::new("config", Vec::::new()); + let request_raw = serde_json::to_string(&request).unwrap(); + stdin.write(format!("{}\n", request_raw).as_bytes())?; + + let mut input = String::new(); + match reader.read_line(&mut input) { + Ok(_) => { + println!("Got a response!: {}", input); + let response = + serde_json::from_str::>>(&input); + match response { + Ok(jrpc) => match jrpc.params { + Ok(params) => { + println!("Loaded: {}", params.name); + if params.is_filter { + let fname = fname.to_string(); + context.add_commands(vec![command( + ¶ms.name, + Box::new(move |x| plugin::filter_plugin(fname.clone(), x)), + )]); + Ok(()) + } else if params.is_sink { + let fname = fname.to_string(); + context.add_sinks(vec![sink( + ¶ms.name, + Box::new(move |x| plugin::sink_plugin(fname.clone(), x)), + )]); + Ok(()) + } else { + Ok(()) + } + } + Err(e) => Err(e), + }, + Err(e) => Err(ShellError::string(format!("Error: {:?}", e))), + } + } + Err(e) => Err(ShellError::string(format!("Error: {:?}", e))), + } +} + +fn load_plugins(context: &mut Context) -> Result<(), ShellError> { + match env::var_os("PATH") { + Some(paths) => { + //println!("{:?}", paths); + for path in env::split_paths(&paths) { + match std::fs::read_dir(path) { + Ok(path) => { + for entry in path { + let entry = entry.unwrap(); + let filename = entry.file_name(); + let f_name = filename.to_string_lossy(); + if f_name.starts_with("nu_plugin_") && !f_name.ends_with(".d") { + //println!("Found: {}", f_name); + load_plugin(&f_name, context)?; + } + } + } + _ => {} + } + } + } + None => println!("PATH is not defined in the environment."), + } + + // Also use our debug output for now + let mut path = std::path::PathBuf::from("."); + path.push("target"); + path.push("debug"); + + match std::fs::read_dir(path) { + Ok(path) => { + for entry in path { + let entry = entry.unwrap(); + let filename = entry.file_name(); + let f_name = filename.to_string_lossy(); + println!("looking at: {}", f_name); + if f_name.starts_with("nu_plugin_") && !f_name.ends_with(".d") { + println!("Found: {}", f_name); + load_plugin(&entry.path().to_string_lossy(), context)?; + } + } + } + _ => {} + } + + Ok(()) +} + pub async fn cli() -> Result<(), Box> { let mut context = Context::basic()?; @@ -48,51 +155,55 @@ pub async fn cli() -> Result<(), Box> { use crate::commands::*; context.add_commands(vec![ - command("ps", ps::ps), - command("ls", ls::ls), - command("sysinfo", sysinfo::sysinfo), - command("cd", cd::cd), - command("view", view::view), - command("skip", skip::skip), - command("first", first::first), - command("size", size::size), - command("from-ini", from_ini::from_ini), - command("from-json", from_json::from_json), - command("from-toml", from_toml::from_toml), - command("from-xml", from_xml::from_xml), - command("from-yaml", from_yaml::from_yaml), - command("get", get::get), - command("enter", enter::enter), - command("exit", exit::exit), - command("lines", lines::lines), - command("pick", pick::pick), - command("split-column", split_column::split_column), - command("split-row", split_row::split_row), - command("lines", lines::lines), - command("reject", reject::reject), - command("trim", trim::trim), - command("to-array", to_array::to_array), - command("to-json", to_json::to_json), - command("to-toml", to_toml::to_toml), - command("sort-by", sort_by::sort_by), + command("ps", Box::new(ps::ps)), + command("ls", Box::new(ls::ls)), + command("sysinfo", Box::new(sysinfo::sysinfo)), + command("cd", Box::new(cd::cd)), + command("view", Box::new(view::view)), + command("skip", Box::new(skip::skip)), + command("first", Box::new(first::first)), + command("size", Box::new(size::size)), + command("from-ini", Box::new(from_ini::from_ini)), + command("from-json", Box::new(from_json::from_json)), + command("from-toml", Box::new(from_toml::from_toml)), + command("from-xml", Box::new(from_xml::from_xml)), + command("from-yaml", Box::new(from_yaml::from_yaml)), + command("get", Box::new(get::get)), + command("enter", Box::new(enter::enter)), + command("exit", Box::new(exit::exit)), + command("lines", Box::new(lines::lines)), + command("pick", Box::new(pick::pick)), + command("split-column", Box::new(split_column::split_column)), + command("split-row", Box::new(split_row::split_row)), + command("lines", Box::new(lines::lines)), + command("reject", Box::new(reject::reject)), + command("trim", Box::new(trim::trim)), + command("to-array", Box::new(to_array::to_array)), + command("to-json", Box::new(to_json::to_json)), + command("to-toml", Box::new(to_toml::to_toml)), + command("sort-by", Box::new(sort_by::sort_by)), Arc::new(Open), Arc::new(Where), Arc::new(Config), Arc::new(SkipWhile), - command("sort-by", sort_by::sort_by), + command("sort-by", Box::new(sort_by::sort_by)), + /* command("inc", |x| plugin::filter_plugin("inc".into(), x)), + command("newskip", |x| plugin::filter_plugin("newskip".into(), x)), + */ ]); context.add_sinks(vec![ - sink("autoview", autoview::autoview), - sink("clip", clip::clip), - sink("save", save::save), - sink("table", table::table), - sink("tree", tree::tree), - sink("vtable", vtable::vtable), - sink("sum", |x| plugin::sink_plugin("sum".into(), x)), + sink("autoview", Box::new(autoview::autoview)), + sink("clip", Box::new(clip::clip)), + sink("save", Box::new(save::save)), + sink("table", Box::new(table::table)), + sink("tree", Box::new(tree::tree)), + sink("vtable", Box::new(vtable::vtable)), + //sink("sum", |x| plugin::sink_plugin("sum".into(), x)), ]); } + load_plugins(&mut context); let config = Config::builder().color_mode(ColorMode::Forced).build(); let h = crate::shell::Helper::new(context.clone_commands()); @@ -250,7 +361,7 @@ async fn process_line(readline: Result, ctx: &mut Context Some(ClassifiedCommand::Sink(_)) => {} Some(ClassifiedCommand::External(_)) => {} _ => pipeline.commands.push(ClassifiedCommand::Sink(SinkCommand { - command: sink("autoview", autoview::autoview), + command: sink("autoview", Box::new(autoview::autoview)), name_span: None, args: registry::Args { positional: None, diff --git a/src/commands/command.rs b/src/commands/command.rs index e9eac51b5..31d572328 100644 --- a/src/commands/command.rs +++ b/src/commands/command.rs @@ -111,7 +111,7 @@ pub trait Sink { pub struct FnCommand { name: String, - func: fn(CommandArgs) -> Result, + func: Box Result>, } impl Command for FnCommand { @@ -126,7 +126,7 @@ impl Command for FnCommand { pub fn command( name: &str, - func: fn(CommandArgs) -> Result, + func: Box Result>, ) -> Arc { Arc::new(FnCommand { name: name.to_string(), @@ -136,7 +136,7 @@ pub fn command( pub struct FnSink { name: String, - func: fn(SinkCommandArgs) -> Result<(), ShellError>, + func: Box Result<(), ShellError>>, } impl Sink for FnSink { @@ -149,7 +149,10 @@ impl Sink for FnSink { } } -pub fn sink(name: &str, func: fn(SinkCommandArgs) -> Result<(), ShellError>) -> Arc { +pub fn sink( + name: &str, + func: Box Result<(), ShellError>>, +) -> Arc { Arc::new(FnSink { name: name.to_string(), func, diff --git a/src/commands/from_ini.rs b/src/commands/from_ini.rs index fd1410136..4e8701d98 100644 --- a/src/commands/from_ini.rs +++ b/src/commands/from_ini.rs @@ -1,4 +1,4 @@ -use crate::object::{DataDescriptor, Dictionary, Primitive, Value}; +use crate::object::{Dictionary, Primitive, Value}; use crate::prelude::*; use indexmap::IndexMap; use std::collections::HashMap; @@ -7,7 +7,7 @@ fn convert_ini_second_to_nu_value(v: &HashMap) -> Value { let mut second = Dictionary::new(IndexMap::new()); for (key, value) in v.into_iter() { second.add( - DataDescriptor::from(key.as_str()), + key.clone(), Value::Primitive(Primitive::String(value.clone())), ); } @@ -16,10 +16,7 @@ fn convert_ini_second_to_nu_value(v: &HashMap) -> Value { fn convert_ini_top_to_nu_value(v: &HashMap>) -> Value { let mut top_level = Dictionary::new(IndexMap::new()); for (key, value) in v.iter() { - top_level.add( - DataDescriptor::from(key.as_str()), - convert_ini_second_to_nu_value(value), - ); + top_level.add(key.clone(), convert_ini_second_to_nu_value(value)); } Value::Object(top_level) } diff --git a/src/commands/from_json.rs b/src/commands/from_json.rs index 9f344c01f..e85d19d68 100644 --- a/src/commands/from_json.rs +++ b/src/commands/from_json.rs @@ -1,5 +1,5 @@ use crate::object::base::OF64; -use crate::object::{DataDescriptor, Dictionary, Primitive, Value}; +use crate::object::{Dictionary, Primitive, Value}; use crate::prelude::*; fn convert_json_value_to_nu_value(v: &serde_hjson::Value) -> Value { @@ -18,10 +18,7 @@ fn convert_json_value_to_nu_value(v: &serde_hjson::Value) -> Value { serde_hjson::Value::Object(o) => { let mut collected = Dictionary::default(); for (k, v) in o.iter() { - collected.add( - DataDescriptor::from(k.clone()), - convert_json_value_to_nu_value(v), - ); + collected.add(k.clone(), convert_json_value_to_nu_value(v)); } Value::Object(collected) } diff --git a/src/commands/from_toml.rs b/src/commands/from_toml.rs index 4d9f3b735..5d1bb9a0c 100644 --- a/src/commands/from_toml.rs +++ b/src/commands/from_toml.rs @@ -1,5 +1,5 @@ use crate::object::base::OF64; -use crate::object::{DataDescriptor, Dictionary, Primitive, Value}; +use crate::object::{Dictionary, Primitive, Value}; use crate::prelude::*; fn convert_toml_value_to_nu_value(v: &toml::Value) -> Value { @@ -17,10 +17,7 @@ fn convert_toml_value_to_nu_value(v: &toml::Value) -> Value { toml::Value::Table(t) => { let mut collected = Dictionary::default(); for (k, v) in t.iter() { - collected.add( - DataDescriptor::from(k.clone()), - convert_toml_value_to_nu_value(v), - ); + collected.add(k.clone(), convert_toml_value_to_nu_value(v)); } Value::Object(collected) } diff --git a/src/commands/from_xml.rs b/src/commands/from_xml.rs index 66b4adf28..d7c8091f8 100644 --- a/src/commands/from_xml.rs +++ b/src/commands/from_xml.rs @@ -1,4 +1,4 @@ -use crate::object::{DataDescriptor, Dictionary, Primitive, Value}; +use crate::object::{Dictionary, Primitive, Value}; use crate::prelude::*; fn from_node_to_value<'a, 'd>(n: &roxmltree::Node<'a, 'd>) -> Value { @@ -25,10 +25,7 @@ fn from_node_to_value<'a, 'd>(n: &roxmltree::Node<'a, 'd>) -> Value { .collect(); let mut collected = Dictionary::default(); - collected.add( - DataDescriptor::from(name.clone()), - Value::List(children_values), - ); + collected.add(name.clone(), Value::List(children_values)); Value::Object(collected) } else if n.is_comment() { diff --git a/src/commands/from_yaml.rs b/src/commands/from_yaml.rs index 6aa5ab0af..2a07d47d1 100644 --- a/src/commands/from_yaml.rs +++ b/src/commands/from_yaml.rs @@ -1,5 +1,5 @@ use crate::object::base::OF64; -use crate::object::{DataDescriptor, Dictionary, Primitive, Value}; +use crate::object::{Dictionary, Primitive, Value}; use crate::prelude::*; fn convert_yaml_value_to_nu_value(v: &serde_yaml::Value) -> Value { @@ -22,10 +22,7 @@ fn convert_yaml_value_to_nu_value(v: &serde_yaml::Value) -> Value { for (k, v) in t.iter() { match k { serde_yaml::Value::String(k) => { - collected.add( - DataDescriptor::from(k.clone()), - convert_yaml_value_to_nu_value(v), - ); + collected.add(k.clone(), convert_yaml_value_to_nu_value(v)); } _ => unimplemented!("Unknown key type"), } diff --git a/src/commands/plugin.rs b/src/commands/plugin.rs index 60b972ad3..dad845941 100644 --- a/src/commands/plugin.rs +++ b/src/commands/plugin.rs @@ -32,17 +32,17 @@ pub enum NuResult { }, } -pub fn filter_plugin(plugin_name: String, args: CommandArgs) -> Result { - let mut path = std::path::PathBuf::from("."); - path.push("target"); - path.push("debug"); - path.push(format!("nu_plugin_{}", plugin_name)); +pub fn filter_plugin(path: String, args: CommandArgs) -> Result { + //let mut path = std::path::PathBuf::from("."); + //path.push("target"); + //path.push("debug"); + //path.push(format!("nu_plugin_{}", plugin_name)); - path = if path.exists() { - path - } else { - std::path::PathBuf::from(format!("nu_plugin_{}", plugin_name)) - }; + // path = if path.exists() { + // path + // } else { + // std::path::PathBuf::from(format!("nu_plugin_{}", plugin_name)) + // }; let mut child = std::process::Command::new(path) .stdin(std::process::Stdio::piped()) @@ -129,17 +129,17 @@ pub fn filter_plugin(plugin_name: String, args: CommandArgs) -> Result Result<(), ShellError> { - let mut path = std::path::PathBuf::from("."); - path.push("target"); - path.push("debug"); - path.push(format!("nu_plugin_{}", plugin_name)); +pub fn sink_plugin(path: String, args: SinkCommandArgs) -> Result<(), ShellError> { + // let mut path = std::path::PathBuf::from("."); + // path.push("target"); + // path.push("debug"); + // path.push(format!("nu_plugin_{}", plugin_name)); - path = if path.exists() { - path - } else { - std::path::PathBuf::from(format!("nu_plugin_{}", plugin_name)) - }; + // path = if path.exists() { + // path + // } else { + // std::path::PathBuf::from(format!("nu_plugin_{}", plugin_name)) + // }; let mut child = std::process::Command::new(path) .stdin(std::process::Stdio::piped()) diff --git a/src/commands/to_json.rs b/src/commands/to_json.rs index 51dee4fd6..8d78ad9ac 100644 --- a/src/commands/to_json.rs +++ b/src/commands/to_json.rs @@ -27,7 +27,7 @@ pub fn value_to_json_value(v: &Value) -> serde_json::Value { Value::Object(o) => { let mut m = serde_json::Map::new(); for (k, v) in o.entries.iter() { - m.insert(k.name.display().to_string(), value_to_json_value(v)); + m.insert(k.clone(), value_to_json_value(v)); } serde_json::Value::Object(m) } diff --git a/src/commands/to_toml.rs b/src/commands/to_toml.rs index 4818ddd91..256dde52d 100644 --- a/src/commands/to_toml.rs +++ b/src/commands/to_toml.rs @@ -21,7 +21,7 @@ pub fn value_to_toml_value(v: &Value) -> toml::Value { Value::Object(o) => { let mut m = toml::map::Map::new(); for (k, v) in o.entries.iter() { - m.insert(k.name.display().to_string(), value_to_toml_value(v)); + m.insert(k.clone(), value_to_toml_value(v)); } toml::Value::Table(m) } diff --git a/src/format/entries.rs b/src/format/entries.rs index a39462caa..67855beed 100644 --- a/src/format/entries.rs +++ b/src/format/entries.rs @@ -10,7 +10,7 @@ use derive_new::new; // another_name : ... #[derive(new)] pub struct EntriesView { - entries: Vec<(crate::object::DescriptorName, String)>, + entries: Vec<(String, String)>, } impl EntriesView { @@ -23,7 +23,7 @@ impl EntriesView { let formatted_value = value.borrow().format_leaf(None); - entries.push((desc.name.clone(), formatted_value)) + entries.push((desc.clone(), formatted_value)) } EntriesView::new(entries) @@ -36,20 +36,10 @@ impl RenderView for EntriesView { return Ok(()); } - let max_name_size: usize = self - .entries - .iter() - .map(|(n, _)| n.display().len()) - .max() - .unwrap(); + let max_name_size: usize = self.entries.iter().map(|(n, _)| n.len()).max().unwrap(); for (name, value) in &self.entries { - println!( - "{:width$} : {}", - name.display(), - value, - width = max_name_size - ) + println!("{:width$} : {}", name, value, width = max_name_size) } Ok(()) diff --git a/src/format/table.rs b/src/format/table.rs index d3b585c7a..6b2205c3f 100644 --- a/src/format/table.rs +++ b/src/format/table.rs @@ -1,5 +1,5 @@ use crate::format::RenderView; -use crate::object::{DataDescriptor, Value}; +use crate::object::Value; use crate::prelude::*; use derive_new::new; use prettytable::format::{FormatBuilder, LinePosition, LineSeparator}; @@ -8,12 +8,12 @@ use prettytable::{color, Attr, Cell, Row, Table}; #[derive(new)] pub struct TableView { - headers: Vec, + headers: Vec, entries: Vec>, } impl TableView { - fn merge_descriptors(values: &[Value]) -> Vec { + fn merge_descriptors(values: &[Value]) -> Vec { let mut ret = vec![]; for value in values { for desc in value.data_descriptors() { @@ -30,10 +30,10 @@ impl TableView { return None; } - let headers = TableView::merge_descriptors(values); + let mut headers = TableView::merge_descriptors(values); if headers.len() == 0 { - return None; + headers.push("value".to_string()); } let mut entries = vec![]; @@ -74,7 +74,7 @@ impl RenderView for TableView { .headers .iter() .map(|h| { - Cell::new(h.display_header()) + Cell::new(h) .with_style(Attr::ForegroundColor(color::GREEN)) .with_style(Attr::Bold) }) diff --git a/src/format/tree.rs b/src/format/tree.rs index 6bf7206a9..e9a59e86a 100644 --- a/src/format/tree.rs +++ b/src/format/tree.rs @@ -26,7 +26,7 @@ impl TreeView { } Value::Object(o) => { for (k, v) in o.entries.iter() { - builder = builder.begin_child(k.name.display().to_string()); + builder = builder.begin_child(k.clone()); Self::from_value_helper(v, builder); builder = builder.end_child(); } @@ -49,7 +49,7 @@ impl TreeView { for desc in descs { let value = value.get_data(&desc); - builder = builder.begin_child(desc.name.display().to_string()); + builder = builder.begin_child(desc.clone()); Self::from_value_helper(value.borrow(), &mut builder); builder = builder.end_child(); //entries.push((desc.name.clone(), value.borrow().copy())) diff --git a/src/format/vtable.rs b/src/format/vtable.rs index 86ddd62df..9e658f5c8 100644 --- a/src/format/vtable.rs +++ b/src/format/vtable.rs @@ -1,5 +1,5 @@ use crate::format::RenderView; -use crate::object::{DescriptorName, Value}; +use crate::object::Value; use crate::prelude::*; use derive_new::new; use prettytable::format::{FormatBuilder, LinePosition, LineSeparator}; @@ -29,11 +29,7 @@ impl VTableView { for header in headers { let mut row = vec![]; - if let DescriptorName::String(s) = &header.name { - row.push(s.clone()); - } else { - row.push("value".to_string()); - } + row.push(header.clone()); for value in values { row.push(value.get_data(&header).borrow().format_leaf(Some(&header))); } diff --git a/src/lib.rs b/src/lib.rs index c84390672..49953b3c7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,4 +28,4 @@ pub use cli::cli; pub use errors::ShellError; pub use object::base::{Primitive, Value}; pub use parser::parse::text::Text; -pub use parser::registry::{Args, CommandConfig}; +pub use parser::registry::{Args, CommandConfig, NamedType, PositionalType}; diff --git a/src/object.rs b/src/object.rs index 3a54ea25c..7e8be20e0 100644 --- a/src/object.rs +++ b/src/object.rs @@ -1,12 +1,10 @@ crate mod base; crate mod config; -crate mod desc; crate mod dict; crate mod files; crate mod process; crate mod types; crate use base::{Primitive, Value}; -crate use desc::{DataDescriptor, DescriptorName}; crate use dict::Dictionary; crate use files::dir_entry_dict; diff --git a/src/object/base.rs b/src/object/base.rs index e61e612ed..d1dd7cfc4 100644 --- a/src/object/base.rs +++ b/src/object/base.rs @@ -1,6 +1,5 @@ use crate::errors::ShellError; use crate::evaluate::{evaluate_baseline_expr, Scope}; -use crate::object::DataDescriptor; use crate::parser::{hir, Operator, Span, Spanned}; use crate::prelude::*; use crate::Text; @@ -76,7 +75,7 @@ impl Primitive { } } - crate fn format(&self, field_name: Option<&DataDescriptor>) -> String { + crate fn format(&self, field_name: Option<&String>) -> String { match self { Primitive::Nothing => format!("{}", Color::Black.bold().paint("-")), Primitive::EndOfStream => format!("{}", Color::Black.bold().paint("-")), @@ -100,8 +99,8 @@ impl Primitive { Primitive::Boolean(b) => match (b, field_name) { (true, None) => format!("Yes"), (false, None) => format!("No"), - (true, Some(s)) if s.is_string_name() => format!("{}", s.display_header()), - (false, Some(s)) if s.is_string_name() => format!(""), + (true, Some(s)) if !s.is_empty() => format!("{}", s), + (false, Some(s)) if !s.is_empty() => format!(""), (true, Some(_)) => format!("Yes"), (false, Some(_)) => format!("No"), }, @@ -245,13 +244,18 @@ impl Value { ValueDebug { value: self } } - crate fn data_descriptors(&self) -> Vec { + crate fn data_descriptors(&self) -> Vec { match self { - Value::Primitive(_) => vec![DataDescriptor::value_of()], - Value::Object(o) => o.data_descriptors(), - Value::Block(_) => vec![DataDescriptor::value_of()], + Value::Primitive(_) => vec![], + Value::Object(o) => o + .entries + .keys() + .into_iter() + .map(|x| x.to_string()) + .collect(), + Value::Block(_) => vec![], Value::List(_) => vec![], - Value::Error(_) => vec![DataDescriptor::value_of()], + Value::Error(_) => vec![], Value::Filesystem => vec![], } } @@ -282,7 +286,7 @@ impl Value { } } - crate fn get_data(&'a self, desc: &DataDescriptor) -> MaybeOwned<'a, Value> { + crate fn get_data(&'a self, desc: &String) -> MaybeOwned<'a, Value> { match self { p @ Value::Primitive(_) => MaybeOwned::Borrowed(p), p @ Value::Filesystem => MaybeOwned::Borrowed(p), @@ -307,7 +311,7 @@ impl Value { } } - crate fn format_leaf(&self, desc: Option<&DataDescriptor>) -> String { + crate fn format_leaf(&self, desc: Option<&String>) -> String { match self { Value::Primitive(p) => p.format(desc), Value::Block(b) => itertools::join( @@ -471,9 +475,9 @@ crate fn select_fields(obj: &Value, fields: &[String]) -> crate::object::Diction let descs = obj.data_descriptors(); for field in fields { - match descs.iter().find(|d| d.name.is_string(field)) { - None => out.add(DataDescriptor::for_string_name(field), Value::nothing()), - Some(desc) => out.add(desc.copy(), obj.get_data(desc).borrow().copy()), + match descs.iter().find(|d| *d == field) { + None => out.add(field, Value::nothing()), + Some(desc) => out.add(desc.clone(), obj.get_data(desc).borrow().copy()), } } @@ -486,10 +490,9 @@ crate fn reject_fields(obj: &Value, fields: &[String]) -> crate::object::Diction let descs = obj.data_descriptors(); for desc in descs { - match desc.name.as_string() { - None => continue, - Some(s) if fields.iter().any(|field| field == s) => continue, - Some(_) => out.add(desc.copy(), obj.get_data(&desc).borrow().copy()), + match desc { + x if fields.iter().any(|field| *field == x) => continue, + _ => out.add(desc.clone(), obj.get_data(&desc).borrow().copy()), } } @@ -499,7 +502,7 @@ crate fn reject_fields(obj: &Value, fields: &[String]) -> crate::object::Diction #[allow(unused)] crate fn find(obj: &Value, field: &str, op: &Operator, rhs: &Value) -> bool { let descs = obj.data_descriptors(); - match descs.iter().find(|d| d.name.is_string(field)) { + match descs.iter().find(|d| *d == field) { None => false, Some(desc) => { let v = obj.get_data(desc).borrow().copy(); diff --git a/src/object/desc.rs b/src/object/desc.rs deleted file mode 100644 index a3d7784a6..000000000 --- a/src/object/desc.rs +++ /dev/null @@ -1,134 +0,0 @@ -use crate::object::types::Type; -use crate::Text; -use derive_new::new; -use serde::{Deserialize, Serialize, Serializer}; - -#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize, Hash)] -pub enum DescriptorName { - String(String), - ValueOf, -} - -impl DescriptorName { - crate fn display(&self) -> &str { - match self { - DescriptorName::String(s) => s, - DescriptorName::ValueOf => "value", - } - } - - crate fn debug(&self) -> &str { - match self { - DescriptorName::String(s) => s, - DescriptorName::ValueOf => "[[value]]", - } - } - - crate fn as_string(&self) -> Option<&str> { - match self { - DescriptorName::String(s) => Some(s), - DescriptorName::ValueOf => None, - } - } - - crate fn is_string(&self, string: &str) -> bool { - match self { - DescriptorName::String(s) => s == string, - DescriptorName::ValueOf => false, - } - } -} - -#[derive(Debug, Deserialize, Clone, Eq, PartialEq, Hash, Ord, PartialOrd, new)] -pub struct DataDescriptor { - crate name: DescriptorName, - crate readonly: bool, - crate ty: Type, -} - -impl DataDescriptor { - crate fn display_header(&self) -> &str { - self.name.display() - } - - crate fn is_string_name(&self) -> bool { - match self.name { - DescriptorName::String(_) => true, - DescriptorName::ValueOf => false, - } - } -} - -impl Serialize for DataDescriptor { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - match self.name { - DescriptorName::String(ref s) => serializer.serialize_str(s), - DescriptorName::ValueOf => serializer.serialize_str("value"), - } - } -} - -impl From<&str> for DataDescriptor { - fn from(input: &str) -> DataDescriptor { - DataDescriptor { - name: DescriptorName::String(input.to_string()), - readonly: true, - ty: Type::Any, - } - } -} - -impl From for DataDescriptor { - fn from(input: String) -> DataDescriptor { - DataDescriptor { - name: DescriptorName::String(input), - readonly: true, - ty: Type::Any, - } - } -} - -impl From for DataDescriptor { - fn from(input: Text) -> DataDescriptor { - DataDescriptor { - name: DescriptorName::String(input.to_string()), - readonly: true, - ty: Type::Any, - } - } -} - -impl DescriptorName { - crate fn for_string_name(name: impl AsRef) -> DescriptorName { - DescriptorName::String(name.as_ref().into()) - } -} - -impl DataDescriptor { - crate fn value_of() -> DataDescriptor { - DataDescriptor { - name: DescriptorName::ValueOf, - readonly: true, - ty: Type::Any, - } - } - - crate fn for_name(name: impl Into) -> DataDescriptor { - DataDescriptor { - name: name.into(), - readonly: true, - ty: Type::Any, - } - } - - crate fn for_string_name(name: impl AsRef) -> DataDescriptor { - DataDescriptor::for_name(DescriptorName::for_string_name(name)) - } - - crate fn copy(&self) -> DataDescriptor { - self.clone() - } -} diff --git a/src/object/dict.rs b/src/object/dict.rs index 146967c81..225de4fe9 100644 --- a/src/object/dict.rs +++ b/src/object/dict.rs @@ -1,23 +1,21 @@ use crate::prelude::*; -use crate::object::DataDescriptor; use crate::object::{Primitive, Value}; use derive_new::new; use indexmap::IndexMap; -use serde::ser::{Serialize, SerializeMap, Serializer}; -use serde_derive::Deserialize; +use serde::{Deserialize, Serialize}; use std::cmp::{Ordering, PartialOrd}; use std::fmt; -#[derive(Debug, Default, Eq, PartialEq, Deserialize, Clone, new)] +#[derive(Debug, Default, Eq, PartialEq, Serialize, Deserialize, Clone, new)] pub struct Dictionary { - pub entries: IndexMap, + pub entries: IndexMap, } impl PartialOrd for Dictionary { fn partial_cmp(&self, other: &Dictionary) -> Option { - let this: Vec<&DataDescriptor> = self.entries.keys().collect(); - let that: Vec<&DataDescriptor> = other.entries.keys().collect(); + let this: Vec<&String> = self.entries.keys().collect(); + let that: Vec<&String> = other.entries.keys().collect(); if this != that { return this.partial_cmp(&that); @@ -30,34 +28,12 @@ impl PartialOrd for Dictionary { } } -impl Serialize for Dictionary { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - let mut map = serializer.serialize_map(Some(self.entries.len()))?; - for (k, v) in self.entries.iter() { - match v { - Value::Object(_) => {} - _ => map.serialize_entry(k, v)?, - } - } - for (k, v) in self.entries.iter() { - match v { - Value::Object(_) => map.serialize_entry(k, v)?, - _ => {} - } - } - map.end() - } -} - impl From> for Dictionary { fn from(input: IndexMap) -> Dictionary { let mut out = IndexMap::default(); for (key, value) in input { - out.insert(DataDescriptor::for_string_name(key), value); + out.insert(key, value); } Dictionary::new(out) @@ -66,8 +42,8 @@ impl From> for Dictionary { impl Ord for Dictionary { fn cmp(&self, other: &Dictionary) -> Ordering { - let this: Vec<&DataDescriptor> = self.entries.keys().collect(); - let that: Vec<&DataDescriptor> = other.entries.keys().collect(); + let this: Vec<&String> = self.entries.keys().collect(); + let that: Vec<&String> = other.entries.keys().collect(); if this != that { return this.cmp(&that); @@ -96,7 +72,7 @@ impl PartialEq for Dictionary { } impl Dictionary { - crate fn add(&mut self, name: impl Into, value: Value) { + crate fn add(&mut self, name: impl Into, value: Value) { self.entries.insert(name.into(), value); } @@ -104,17 +80,13 @@ impl Dictionary { let mut out = Dictionary::default(); for (key, value) in self.entries.iter() { - out.add(key.copy(), value.copy()); + out.add(key.clone(), value.copy()); } out } - crate fn data_descriptors(&self) -> Vec { - self.entries.iter().map(|(name, _)| name.copy()).collect() - } - - crate fn get_data(&'a self, desc: &DataDescriptor) -> MaybeOwned<'a, Value> { + crate fn get_data(&'a self, desc: &String) -> MaybeOwned<'a, Value> { match self.entries.get(desc) { Some(v) => MaybeOwned::Borrowed(v), None => MaybeOwned::Owned(Value::Primitive(Primitive::Nothing)), @@ -125,7 +97,7 @@ impl Dictionary { match self .entries .iter() - .find(|(desc_name, _)| desc_name.name.is_string(name)) + .find(|(desc_name, _)| *desc_name == name) { Some((_, v)) => Some(v), None => None, @@ -136,7 +108,7 @@ impl Dictionary { let mut debug = f.debug_struct("Dictionary"); for (desc, value) in self.entries.iter() { - debug.field(desc.name.debug(), &value.debug()); + debug.field(desc, &value.debug()); } debug.finish() diff --git a/src/plugin.rs b/src/plugin.rs index 412e5aa8a..688b44831 100644 --- a/src/plugin.rs +++ b/src/plugin.rs @@ -3,9 +3,7 @@ use serde::{Deserialize, Serialize}; use std::io; pub trait Plugin { - fn config(&mut self) -> Result { - Err(ShellError::string("`config` not implemented in plugin")) - } + fn config(&mut self) -> Result; #[allow(unused)] fn begin_filter(&mut self, args: Args) -> Result<(), ShellError> { Err(ShellError::string( @@ -50,8 +48,8 @@ pub fn serve_plugin(plugin: &mut dyn Plugin) { } e => { send_response(ShellError::string(format!( - "Could not handle plugin message: {:?}", - e, + "Could not handle plugin message: {} {:?}", + input, e ))); break; } diff --git a/src/plugins/inc.rs b/src/plugins/inc.rs index afb0abeaf..a55c3d34f 100644 --- a/src/plugins/inc.rs +++ b/src/plugins/inc.rs @@ -1,4 +1,8 @@ -use nu::{serve_plugin, Args, Plugin, Primitive, ReturnValue, ShellError, Spanned, Value}; +use indexmap::IndexMap; +use nu::{ + serve_plugin, Args, CommandConfig, Plugin, PositionalType, Primitive, ReturnValue, ShellError, + Spanned, Value, +}; struct Inc { inc_by: i64, @@ -10,6 +14,19 @@ impl Inc { } impl Plugin for Inc { + fn config(&mut self) -> Result { + Ok(CommandConfig { + name: "inc".to_string(), + mandatory_positional: vec![], + optional_positional: vec![PositionalType::Value("Increment".into())], + can_load: vec![], + can_save: vec![], + is_filter: true, + is_sink: false, + named: IndexMap::new(), + rest_positional: true, + }) + } fn begin_filter(&mut self, args: Args) -> Result<(), ShellError> { if let Some(args) = args.positional { for arg in args { diff --git a/src/plugins/newskip.rs b/src/plugins/newskip.rs new file mode 100644 index 000000000..14e3a5dee --- /dev/null +++ b/src/plugins/newskip.rs @@ -0,0 +1,59 @@ +use indexmap::IndexMap; +use nu::{ + serve_plugin, Args, CommandConfig, Plugin, Primitive, ReturnValue, ShellError, Spanned, Value, +}; + +struct NewSkip { + skip_amount: i64, +} +impl NewSkip { + fn new() -> NewSkip { + NewSkip { skip_amount: 0 } + } +} + +impl Plugin for NewSkip { + fn config(&mut self) -> Result { + Ok(CommandConfig { + name: "skip".to_string(), + mandatory_positional: vec![], + optional_positional: vec![], + can_load: vec![], + can_save: vec![], + is_filter: true, + is_sink: false, + named: IndexMap::new(), + rest_positional: true, + }) + } + fn begin_filter(&mut self, args: Args) -> Result<(), ShellError> { + if let Some(args) = args.positional { + for arg in args { + match arg { + Spanned { + item: Value::Primitive(Primitive::Int(i)), + .. + } => { + self.skip_amount = i; + } + _ => return Err(ShellError::string("Unrecognized type in params")), + } + } + } + + Ok(()) + } + + fn filter(&mut self, input: Value) -> Result, ShellError> { + if self.skip_amount == 0 { + Ok(vec![ReturnValue::Value(input)]) + } else { + self.skip_amount -= 1; + Ok(vec![]) + } + } +} + +fn main() { + serve_plugin(&mut NewSkip::new()); +} diff --git a/src/plugins/sum.rs b/src/plugins/sum.rs index 4576ad1d5..f8ac4607a 100644 --- a/src/plugins/sum.rs +++ b/src/plugins/sum.rs @@ -1,4 +1,5 @@ -use nu::{serve_plugin, Args, Plugin, Primitive, Value}; +use indexmap::IndexMap; +use nu::{serve_plugin, Args, CommandConfig, Plugin, Primitive, ShellError, Value}; struct Sum; @@ -9,6 +10,20 @@ impl Sum { } impl Plugin for Sum { + fn config(&mut self) -> Result { + Ok(CommandConfig { + name: "sum".to_string(), + mandatory_positional: vec![], + optional_positional: vec![], + can_load: vec![], + can_save: vec![], + is_filter: false, + is_sink: true, + named: IndexMap::new(), + rest_positional: true, + }) + } + fn sink(&mut self, _args: Args, input: Vec) { let mut total = 0i64; From c653751d2c1bd85964ad8f175f9c480f38986732 Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Thu, 4 Jul 2019 15:06:43 +1200 Subject: [PATCH 3/7] Bump and cleanup plugin name match --- Cargo.lock | 84 +++++++++++++++++++++++++++++------------------------- Cargo.toml | 10 +++---- src/cli.rs | 76 ++++++++++++++++++++---------------------------- 3 files changed, 81 insertions(+), 89 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8c4808fe7..8a6626631 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -120,7 +120,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -194,7 +194,7 @@ dependencies = [ "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -276,9 +276,9 @@ dependencies = [ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "rust-ini 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)", "serde-hjson 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -332,8 +332,8 @@ dependencies = [ "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "publicsuffix 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "try_from 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -430,7 +430,7 @@ dependencies = [ "csv-core 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "ryu 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1053,7 +1053,7 @@ name = "indexmap" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1476,23 +1476,23 @@ dependencies = [ "prettyprint 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "prettytable-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "ptree 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.9.18 (registry+https://github.com/rust-lang/crates.io-index)", "roxmltree 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustyline 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)", "serde-hjson 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)", "serde_ini 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "serde_yaml 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)", "subprocess 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "sys-info 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)", "sysinfo 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "toml-query 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "toml-query 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "walkdir 2.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1624,7 +1624,7 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1770,7 +1770,7 @@ dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "line-wrap 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)", "xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1846,9 +1846,9 @@ dependencies = [ "directories 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "isatty 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)", "serde-value 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)", "tint 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2084,8 +2084,8 @@ dependencies = [ "mime 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", "mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2157,6 +2157,11 @@ name = "ryu" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "ryu" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "safemem" version = "0.3.0" @@ -2233,10 +2238,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.93" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde_derive 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2269,12 +2274,12 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ordered-float 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_derive" -version = "1.0.93" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2297,18 +2302,18 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "result 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_json" -version = "1.0.39" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "ryu 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", + "ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2326,7 +2331,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2337,7 +2342,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)", "yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2452,9 +2457,9 @@ dependencies = [ "onig 4.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "plist 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "regex-syntax 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2701,7 +2706,7 @@ name = "toml" version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2709,12 +2714,12 @@ name = "toml" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "toml-query" -version = "0.9.0" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3202,6 +3207,7 @@ dependencies = [ "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" "checksum rustyline 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "67e12e40e0240de07f0dab4f4dd01bdb15d74dc977026d4ba91666c41c679ade" "checksum ryu 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "b96a9549dc8d48f2c283938303c4b5a77aa29bfbc5b54b084fb1630408899a8f" +"checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997" "checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9" "checksum same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267" "checksum schannel 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f6abf258d99c3c1c5c2131d99d064e94b7b3dd5f416483057f308fea253339" @@ -3213,14 +3219,14 @@ dependencies = [ "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" "checksum serde 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)" = "9dad3f759919b92c3068c696c15c3d17238234498bbdcc80f2c469606f948ac8" -"checksum serde 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)" = "960e29cf7004b3b6e65fc5002981400eb3ccc017a08a2406940823e58e7179a9" +"checksum serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)" = "076a696fdea89c19d3baed462576b8f6d663064414b5c793642da8dfeb99475b" "checksum serde-hjson 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0b833c5ad67d52ced5f5938b2980f32a9c1c5ef047f0b4fb3127e7a423c76153" "checksum serde-hjson 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4640cf3168e40c00c874ff1ad436c0f18c37edec101d5d897a4396f617abce29" "checksum serde-value 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7a663f873dedc4eac1a559d4c6bc0d0b2c34dc5ac4702e105014b8281489e44f" -"checksum serde_derive 1.0.93 (registry+https://github.com/rust-lang/crates.io-index)" = "c4cce6663696bd38272e90bf34a0267e1226156c33f52d3f3915a2dd5d802085" +"checksum serde_derive 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)" = "ef45eb79d6463b22f5f9e16d283798b7c0175ba6050bc25c1a946c122727fe7b" "checksum serde_derive_internals 0.24.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8a80c6c0b1ebbcea4ec2c7e9e2e9fa197a425d17f1afec8ba79fcd1352b18ffb" "checksum serde_ini 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eb236687e2bb073a7521c021949be944641e671b8505a94069ca37b656c81139" -"checksum serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)" = "5a23aa71d4a4d43fdbfaac00eff68ba8a06a51759a89ac3304323e800c4dd40d" +"checksum serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "051c49229f282f7c6f3813f8286cc1e3323e8051823fce42c7ea80fe13521704" "checksum serde_test 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)" = "110b3dbdf8607ec493c22d5d947753282f3bae73c0f56d322af1e8c78e4c23d5" "checksum serde_urlencoded 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "642dd69105886af2efd227f75a520ec9b44a820d65bc133a9131f7d229fd165a" "checksum serde_yaml 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)" = "38b08a9a90e5260fe01c6480ec7c811606df6d3a660415808c3c3fa8ed95b582" @@ -3263,7 +3269,7 @@ dependencies = [ "checksum tokio-trace-core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9c8a256d6956f7cb5e2bdfe8b1e8022f1a09206c6c2b1ba00f3b746b260c613" "checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f" "checksum toml 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b8c96d7873fa7ef8bdeb3a9cda3ac48389b4154f32b9803b4bc26220b677b039" -"checksum toml-query 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a24369a1894ac8224efcfd567c3d141aea360292f49888e7ec7dcc316527aebb" +"checksum toml-query 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "654d5afba116c445bb5fb6812e7c3177d90d143427af73f12956f33e18a1cedb" "checksum toml-query_derive 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c99ca245ec273c7e75c8ee58f47b882d0146f3c2c8495158082c6671e8b5335" "checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" "checksum try_from 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "283d3b89e1368717881a9d51dad843cc435380d8109c9e47d38780a324698d8b" diff --git a/Cargo.toml b/Cargo.toml index 695cef75e..38a1f6817 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,18 +32,18 @@ term = "0.5.2" bytes = "0.4.12" log = "0.4.6" pretty_env_logger = "0.3.0" -serde = "1.0.93" -serde_json = "1.0.39" +serde = "1.0.94" +serde_json = "1.0.40" serde-hjson = "0.9.0" serde_yaml = "0.8" -serde_derive = "1.0.93" +serde_derive = "1.0.94" getset = "0.0.7" logos = "0.10.0-rc2" logos-derive = "0.10.0-rc2" language-reporting = "0.3.0" app_dirs = "1.2.1" toml = "0.5.1" -toml-query = "0.9.0" +toml-query = "0.9.2" clap = "2.33.0" enum_derive = "0.1.7" adhoc_derive = "0.1.2" @@ -63,7 +63,7 @@ serde_ini = "0.2.0" subprocess = "0.1.18" sys-info = "0.5.7" mime = "0.3.13" -walkdir = "2.2.8" +regex = "1.1.7" [dev-dependencies] pretty_assertions = "0.6.1" diff --git a/src/cli.rs b/src/cli.rs index b205ec3a7..b06e5089b 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -5,7 +5,7 @@ use crate::commands::classified::{ StreamNext, }; use crate::commands::command::sink; -use crate::commands::plugin::{JsonRpc, NuResult}; +use crate::commands::plugin::JsonRpc; use crate::context::Context; crate use crate::errors::ShellError; use crate::evaluate::Scope; @@ -18,6 +18,7 @@ use crate::parser::{Pipeline, PipelineElement, TokenNode}; use crate::prelude::*; use log::{debug, trace}; +use regex::Regex; use rustyline::error::ReadlineError; use rustyline::{self, ColorMode, Config, Editor}; use std::env; @@ -25,7 +26,6 @@ use std::error::Error; use std::io::{BufRead, BufReader, Write}; use std::iter::Iterator; use std::sync::atomic::{AtomicBool, Ordering}; -use walkdir::WalkDir; #[derive(Debug)] pub enum MaybeOwned<'a, T> { @@ -42,11 +42,10 @@ impl MaybeOwned<'a, T> { } } -fn load_plugin(fname: &str, context: &mut Context) -> Result<(), ShellError> { +fn load_plugin(path: &std::path::Path, context: &mut Context) -> Result<(), ShellError> { use crate::commands::{command, plugin}; - println!("fname: {}", fname); - let mut child = std::process::Command::new(fname) + let mut child = std::process::Command::new(path) .stdin(std::process::Stdio::piped()) .stdout(std::process::Stdio::piped()) .spawn() @@ -57,8 +56,6 @@ fn load_plugin(fname: &str, context: &mut Context) -> Result<(), ShellError> { let mut reader = BufReader::new(stdout); - println!("Sending out config request"); - let request = JsonRpc::new("config", Vec::::new()); let request_raw = serde_json::to_string(&request).unwrap(); stdin.write(format!("{}\n", request_raw).as_bytes())?; @@ -66,13 +63,13 @@ fn load_plugin(fname: &str, context: &mut Context) -> Result<(), ShellError> { let mut input = String::new(); match reader.read_line(&mut input) { Ok(_) => { - println!("Got a response!: {}", input); let response = serde_json::from_str::>>(&input); match response { Ok(jrpc) => match jrpc.params { Ok(params) => { - println!("Loaded: {}", params.name); + let fname = path.to_string_lossy(); + println!("Loaded: {} from {}", params.name, fname); if params.is_filter { let fname = fname.to_string(); context.add_commands(vec![command( @@ -100,25 +97,33 @@ fn load_plugin(fname: &str, context: &mut Context) -> Result<(), ShellError> { } } +fn load_plugins_in_dir(path: &std::path::PathBuf, context: &mut Context) -> Result<(), ShellError> { + let re_bin = Regex::new(r"^nu_plugin_[A-Za-z_]+$").unwrap(); + let re_exe = Regex::new(r"^nu_plugin_[A-Za-z_]+\.exe$").unwrap(); + + match std::fs::read_dir(path) { + Ok(p) => { + for entry in p { + let entry = entry.unwrap(); + let filename = entry.file_name(); + let f_name = filename.to_string_lossy(); + if re_bin.is_match(&f_name) || re_exe.is_match(&f_name) { + let mut load_path = path.clone(); + load_path.push(f_name.to_string()); + load_plugin(&load_path, context)?; + } + } + } + _ => {} + } + Ok(()) +} + fn load_plugins(context: &mut Context) -> Result<(), ShellError> { match env::var_os("PATH") { Some(paths) => { - //println!("{:?}", paths); for path in env::split_paths(&paths) { - match std::fs::read_dir(path) { - Ok(path) => { - for entry in path { - let entry = entry.unwrap(); - let filename = entry.file_name(); - let f_name = filename.to_string_lossy(); - if f_name.starts_with("nu_plugin_") && !f_name.ends_with(".d") { - //println!("Found: {}", f_name); - load_plugin(&f_name, context)?; - } - } - } - _ => {} - } + let _ = load_plugins_in_dir(&path, context); } } None => println!("PATH is not defined in the environment."), @@ -129,21 +134,7 @@ fn load_plugins(context: &mut Context) -> Result<(), ShellError> { path.push("target"); path.push("debug"); - match std::fs::read_dir(path) { - Ok(path) => { - for entry in path { - let entry = entry.unwrap(); - let filename = entry.file_name(); - let f_name = filename.to_string_lossy(); - println!("looking at: {}", f_name); - if f_name.starts_with("nu_plugin_") && !f_name.ends_with(".d") { - println!("Found: {}", f_name); - load_plugin(&entry.path().to_string_lossy(), context)?; - } - } - } - _ => {} - } + let _ = load_plugins_in_dir(&path, context); Ok(()) } @@ -187,10 +178,6 @@ pub async fn cli() -> Result<(), Box> { Arc::new(Config), Arc::new(SkipWhile), command("sort-by", Box::new(sort_by::sort_by)), - /* - command("inc", |x| plugin::filter_plugin("inc".into(), x)), - command("newskip", |x| plugin::filter_plugin("newskip".into(), x)), - */ ]); context.add_sinks(vec![ @@ -200,10 +187,9 @@ pub async fn cli() -> Result<(), Box> { sink("table", Box::new(table::table)), sink("tree", Box::new(tree::tree)), sink("vtable", Box::new(vtable::vtable)), - //sink("sum", |x| plugin::sink_plugin("sum".into(), x)), ]); } - load_plugins(&mut context); + let _ = load_plugins(&mut context); let config = Config::builder().color_mode(ColorMode::Forced).build(); let h = crate::shell::Helper::new(context.clone_commands()); From dc8545ce1088483bc50c6722a930f328c336af1f Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Thu, 4 Jul 2019 15:18:19 +1200 Subject: [PATCH 4/7] Add a test for the plugins --- src/cli.rs | 4 +++- src/commands/plugin.rs | 22 ---------------------- tests/inc_plugin.out | 1 + tests/inc_plugin.txt | 3 +++ tests/tests.rs | 5 +++++ 5 files changed, 12 insertions(+), 23 deletions(-) create mode 100644 tests/inc_plugin.out create mode 100644 tests/inc_plugin.txt diff --git a/src/cli.rs b/src/cli.rs index b06e5089b..b6bba4918 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -69,7 +69,7 @@ fn load_plugin(path: &std::path::Path, context: &mut Context) -> Result<(), Shel Ok(jrpc) => match jrpc.params { Ok(params) => { let fname = path.to_string_lossy(); - println!("Loaded: {} from {}", params.name, fname); + //println!("Loaded: {} from {}", params.name, fname); if params.is_filter { let fname = fname.to_string(); context.add_commands(vec![command( @@ -129,12 +129,14 @@ fn load_plugins(context: &mut Context) -> Result<(), ShellError> { None => println!("PATH is not defined in the environment."), } + /* // Also use our debug output for now let mut path = std::path::PathBuf::from("."); path.push("target"); path.push("debug"); let _ = load_plugins_in_dir(&path, context); + */ Ok(()) } diff --git a/src/commands/plugin.rs b/src/commands/plugin.rs index dad845941..9be9dad7a 100644 --- a/src/commands/plugin.rs +++ b/src/commands/plugin.rs @@ -33,17 +33,6 @@ pub enum NuResult { } pub fn filter_plugin(path: String, args: CommandArgs) -> Result { - //let mut path = std::path::PathBuf::from("."); - //path.push("target"); - //path.push("debug"); - //path.push(format!("nu_plugin_{}", plugin_name)); - - // path = if path.exists() { - // path - // } else { - // std::path::PathBuf::from(format!("nu_plugin_{}", plugin_name)) - // }; - let mut child = std::process::Command::new(path) .stdin(std::process::Stdio::piped()) .stdout(std::process::Stdio::piped()) @@ -130,17 +119,6 @@ pub fn filter_plugin(path: String, args: CommandArgs) -> Result Result<(), ShellError> { - // let mut path = std::path::PathBuf::from("."); - // path.push("target"); - // path.push("debug"); - // path.push(format!("nu_plugin_{}", plugin_name)); - - // path = if path.exists() { - // path - // } else { - // std::path::PathBuf::from(format!("nu_plugin_{}", plugin_name)) - // }; - let mut child = std::process::Command::new(path) .stdin(std::process::Stdio::piped()) .spawn() diff --git a/tests/inc_plugin.out b/tests/inc_plugin.out new file mode 100644 index 000000000..b4de39476 --- /dev/null +++ b/tests/inc_plugin.out @@ -0,0 +1 @@ +11 diff --git a/tests/inc_plugin.txt b/tests/inc_plugin.txt new file mode 100644 index 000000000..111eb6e42 --- /dev/null +++ b/tests/inc_plugin.txt @@ -0,0 +1,3 @@ +cd tests +open test.json | get glossary.GlossDiv.GlossList.GlossEntry.Height | inc | echo $it +exit \ No newline at end of file diff --git a/tests/tests.rs b/tests/tests.rs index 3974e2f80..011fdffb3 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -112,4 +112,9 @@ mod tests { fn unit() { test_helper("unit"); } + + #[test] + fn inc_plugin() { + test_helper("inc_plugin"); + } } From 65a0d27c8a007643b36feededf6a84df0629b7f5 Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Thu, 4 Jul 2019 17:11:56 +1200 Subject: [PATCH 5/7] Add binary type and tree sink --- Cargo.toml | 4 ++ src/cli.rs | 5 +- src/commands/autoview.rs | 9 ++-- src/commands/enter.rs | 15 ++++-- src/commands/open.rs | 30 ++++++----- src/commands/to_json.rs | 7 +++ src/commands/to_toml.rs | 3 ++ src/env/host.rs | 2 +- src/format/generic.rs | 5 ++ src/format/tree.rs | 8 +-- src/lib.rs | 1 + src/object/base.rs | 14 +++-- src/object/dict.rs | 2 +- src/plugins/treeview.rs | 114 +++++++++++++++++++++++++++++++++++++++ 14 files changed, 181 insertions(+), 38 deletions(-) create mode 100644 src/plugins/treeview.rs diff --git a/Cargo.toml b/Cargo.toml index 38a1f6817..57c430ca7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -84,6 +84,10 @@ path = "src/plugins/inc.rs" name = "nu_plugin_newskip" path = "src/plugins/newskip.rs" +[[bin]] +name = "nu_plugin_treeview" +path = "src/plugins/treeview.rs" + [[bin]] name = "nu" path = "src/main.rs" diff --git a/src/cli.rs b/src/cli.rs index b6bba4918..4b74979a6 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -34,7 +34,7 @@ pub enum MaybeOwned<'a, T> { } impl MaybeOwned<'a, T> { - crate fn borrow(&self) -> &T { + pub fn borrow(&self) -> &T { match self { MaybeOwned::Owned(v) => v, MaybeOwned::Borrowed(v) => v, @@ -59,6 +59,7 @@ fn load_plugin(path: &std::path::Path, context: &mut Context) -> Result<(), Shel let request = JsonRpc::new("config", Vec::::new()); let request_raw = serde_json::to_string(&request).unwrap(); stdin.write(format!("{}\n", request_raw).as_bytes())?; + let path = dunce::canonicalize(path).unwrap(); let mut input = String::new(); match reader.read_line(&mut input) { @@ -129,14 +130,12 @@ fn load_plugins(context: &mut Context) -> Result<(), ShellError> { None => println!("PATH is not defined in the environment."), } - /* // Also use our debug output for now let mut path = std::path::PathBuf::from("."); path.push("target"); path.push("debug"); let _ = load_plugins_in_dir(&path, context); - */ Ok(()) } diff --git a/src/commands/autoview.rs b/src/commands/autoview.rs index c38578324..6894b0559 100644 --- a/src/commands/autoview.rs +++ b/src/commands/autoview.rs @@ -5,11 +5,10 @@ use crate::prelude::*; pub fn autoview(args: SinkCommandArgs) -> Result<(), ShellError> { if args.input.len() > 0 { - if equal_shapes(&args.input) { - let mut host = args.ctx.host.lock().unwrap(); - let view = TableView::from_list(&args.input).unwrap(); - - handle_unexpected(&mut *host, |host| crate::format::print_view(&view, host)); + if let Value::Binary(_) = args.input[0] { + println!("Binary"); + } else if equal_shapes(&args.input) { + args.ctx.get_sink("table").run(args)?; } else { let mut host = args.ctx.host.lock().unwrap(); for i in args.input.iter() { diff --git a/src/commands/enter.rs b/src/commands/enter.rs index d699db5d0..d8eba93c9 100644 --- a/src/commands/enter.rs +++ b/src/commands/enter.rs @@ -67,11 +67,16 @@ pub fn enter(args: CommandArgs) -> Result { } }; - stream.push_back(ReturnValue::Action(CommandAction::Enter(parse_as_value( - file_extension, - contents, - span, - )?))); + match contents { + Value::Primitive(Primitive::String(x)) => { + stream.push_back(ReturnValue::Action(CommandAction::Enter(parse_as_value( + file_extension, + x, + span, + )?))); + } + x => stream.push_back(ReturnValue::Action(CommandAction::Enter(x))), + } Ok(stream.boxed()) } diff --git a/src/commands/open.rs b/src/commands/open.rs index a03086397..39227b066 100644 --- a/src/commands/open.rs +++ b/src/commands/open.rs @@ -40,7 +40,7 @@ pub fn fetch( cwd: &PathBuf, location: &str, span: Span, -) -> Result<(Option, String), ShellError> { +) -> Result<(Option, Value), ShellError> { let mut cwd = cwd.clone(); if location.starts_with("http:") || location.starts_with("https:") { let response = reqwest::get(location); @@ -71,7 +71,7 @@ pub fn fetch( None => path_extension, }; - Ok((extension, s)) + Ok((extension, Value::string(s))) } Err(_) => { return Err(ShellError::labeled_error( @@ -91,12 +91,15 @@ pub fn fetch( } } else { cwd.push(Path::new(location)); - match std::fs::read_to_string(&cwd) { - Ok(s) => Ok(( - cwd.extension() - .map(|name| name.to_string_lossy().to_string()), - s, - )), + match std::fs::read(&cwd) { + Ok(bytes) => match std::str::from_utf8(&bytes) { + Ok(s) => Ok(( + cwd.extension() + .map(|name| name.to_string_lossy().to_string()), + Value::string(s), + )), + Err(_) => Ok((None, Value::Binary(bytes))), + }, Err(_) => { return Err(ShellError::labeled_error( "File cound not be opened", @@ -227,11 +230,12 @@ fn open(args: CommandArgs) -> Result { } }; - stream.push_back(ReturnValue::Value(parse_as_value( - file_extension, - contents, - span, - )?)); + match contents { + Value::Primitive(Primitive::String(x)) => { + stream.push_back(ReturnValue::Value(parse_as_value(file_extension, x, span)?)); + } + x => stream.push_back(ReturnValue::Value(x)), + } Ok(stream.boxed()) } diff --git a/src/commands/to_json.rs b/src/commands/to_json.rs index 8d78ad9ac..497b0310c 100644 --- a/src/commands/to_json.rs +++ b/src/commands/to_json.rs @@ -24,6 +24,13 @@ pub fn value_to_json_value(v: &Value) -> serde_json::Value { } Value::Error(e) => serde_json::Value::String(e.to_string()), Value::Block(_) => serde_json::Value::Null, + Value::Binary(b) => serde_json::Value::Array( + b.iter() + .map(|x| { + serde_json::Value::Number(serde_json::Number::from_f64(*x as f64).unwrap()) + }) + .collect(), + ), Value::Object(o) => { let mut m = serde_json::Map::new(); for (k, v) in o.entries.iter() { diff --git a/src/commands/to_toml.rs b/src/commands/to_toml.rs index 256dde52d..2e90b99fa 100644 --- a/src/commands/to_toml.rs +++ b/src/commands/to_toml.rs @@ -18,6 +18,9 @@ pub fn value_to_toml_value(v: &Value) -> toml::Value { Value::List(l) => toml::Value::Array(l.iter().map(|x| value_to_toml_value(x)).collect()), Value::Error(e) => toml::Value::String(e.to_string()), Value::Block(_) => toml::Value::String("".to_string()), + Value::Binary(b) => { + toml::Value::Array(b.iter().map(|x| toml::Value::Integer(*x as i64)).collect()) + } Value::Object(o) => { let mut m = toml::map::Map::new(); for (k, v) in o.entries.iter() { diff --git a/src/env/host.rs b/src/env/host.rs index 787b72856..8033f86dd 100644 --- a/src/env/host.rs +++ b/src/env/host.rs @@ -40,7 +40,7 @@ impl Host for Box { } #[derive(Debug)] -crate struct BasicHost; +pub struct BasicHost; impl Host for BasicHost { fn out_terminal(&self) -> Box { diff --git a/src/format/generic.rs b/src/format/generic.rs index ba99123e8..f5fdf0772 100644 --- a/src/format/generic.rs +++ b/src/format/generic.rs @@ -41,6 +41,11 @@ impl RenderView for GenericView<'value> { Ok(()) } + Value::Binary(_) => { + host.stdout(""); + Ok(()) + } + Value::Filesystem => { host.stdout(""); Ok(()) diff --git a/src/format/tree.rs b/src/format/tree.rs index e9a59e86a..5492adf15 100644 --- a/src/format/tree.rs +++ b/src/format/tree.rs @@ -7,14 +7,8 @@ use ptree::print_config::PrintConfig; use ptree::style::{Color, Style}; use ptree::TreeBuilder; -// An entries list is printed like this: -// -// name : ... -// name2 : ... -// another_name : ... #[derive(new)] pub struct TreeView { - //entries: Vec<(crate::object::DescriptorName, Value)>, tree: StringItem, } @@ -39,6 +33,7 @@ impl TreeView { Value::Block(_) => {} Value::Error(_) => {} Value::Filesystem => {} + Value::Binary(_) => {} } } crate fn from_value(value: &Value) -> TreeView { @@ -73,7 +68,6 @@ impl RenderView for TreeView { bold: true, ..Style::default() }; - //config.characters = UTF_CHARS_BOLD.into(); config.indent = 4; config }; diff --git a/src/lib.rs b/src/lib.rs index 49953b3c7..fe30296c8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -21,6 +21,7 @@ mod shell; mod stream; pub use crate::commands::command::ReturnValue; +pub use crate::env::host::BasicHost; pub use crate::parser::parse::span::SpannedItem; pub use crate::parser::Spanned; pub use crate::plugin::{serve_plugin, Plugin}; diff --git a/src/object/base.rs b/src/object/base.rs index d1dd7cfc4..9e616049e 100644 --- a/src/object/base.rs +++ b/src/object/base.rs @@ -75,7 +75,7 @@ impl Primitive { } } - crate fn format(&self, field_name: Option<&String>) -> String { + pub fn format(&self, field_name: Option<&String>) -> String { match self { Primitive::Nothing => format!("{}", Color::Black.bold().paint("-")), Primitive::EndOfStream => format!("{}", Color::Black.bold().paint("-")), @@ -180,6 +180,8 @@ pub enum Value { Primitive(Primitive), Object(crate::object::Dictionary), List(Vec), + Binary(Vec), + #[allow(unused)] Block(Block), Filesystem, @@ -217,6 +219,7 @@ impl fmt::Debug for ValueDebug<'a> { Value::Block(_) => write!(f, "[[block]]"), Value::Error(err) => write!(f, "[[error :: {} ]]", err), Value::Filesystem => write!(f, "[[filesystem]]"), + Value::Binary(_) => write!(f, "[[binary]]"), } } } @@ -237,6 +240,7 @@ impl Value { Value::Block(_) => format!("block"), Value::Error(_) => format!("error"), Value::Filesystem => format!("filesystem"), + Value::Binary(_) => format!("binary"), } } @@ -244,7 +248,7 @@ impl Value { ValueDebug { value: self } } - crate fn data_descriptors(&self) -> Vec { + pub fn data_descriptors(&self) -> Vec { match self { Value::Primitive(_) => vec![], Value::Object(o) => o @@ -257,6 +261,7 @@ impl Value { Value::List(_) => vec![], Value::Error(_) => vec![], Value::Filesystem => vec![], + Value::Binary(_) => vec![], } } @@ -286,7 +291,7 @@ impl Value { } } - crate fn get_data(&'a self, desc: &String) -> MaybeOwned<'a, Value> { + pub fn get_data(&'a self, desc: &String) -> MaybeOwned<'a, Value> { match self { p @ Value::Primitive(_) => MaybeOwned::Borrowed(p), p @ Value::Filesystem => MaybeOwned::Borrowed(p), @@ -294,6 +299,7 @@ impl Value { Value::Block(_) => MaybeOwned::Owned(Value::nothing()), Value::List(_) => MaybeOwned::Owned(Value::nothing()), Value::Error(e) => MaybeOwned::Owned(Value::string(&format!("{:#?}", e))), + Value::Binary(_) => MaybeOwned::Owned(Value::nothing()), } } @@ -308,6 +314,7 @@ impl Value { } Value::Error(e) => Value::Error(Box::new(e.copy_error())), Value::Filesystem => Value::Filesystem, + Value::Binary(b) => Value::Binary(b.clone()), } } @@ -324,6 +331,7 @@ impl Value { Value::List(_) => format!("[list List]"), Value::Error(e) => format!("{}", e), Value::Filesystem => format!(""), + Value::Binary(_) => format!(""), } } diff --git a/src/object/dict.rs b/src/object/dict.rs index 225de4fe9..9c0e4ed34 100644 --- a/src/object/dict.rs +++ b/src/object/dict.rs @@ -86,7 +86,7 @@ impl Dictionary { out } - crate fn get_data(&'a self, desc: &String) -> MaybeOwned<'a, Value> { + pub fn get_data(&'a self, desc: &String) -> MaybeOwned<'a, Value> { match self.entries.get(desc) { Some(v) => MaybeOwned::Borrowed(v), None => MaybeOwned::Owned(Value::Primitive(Primitive::Nothing)), diff --git a/src/plugins/treeview.rs b/src/plugins/treeview.rs new file mode 100644 index 000000000..0ff78dc99 --- /dev/null +++ b/src/plugins/treeview.rs @@ -0,0 +1,114 @@ +use derive_new::new; +use indexmap::IndexMap; +use nu::{serve_plugin, Args, CommandConfig, Plugin, ShellError, Value}; +use ptree::item::StringItem; +use ptree::output::print_tree_with; +use ptree::print_config::PrintConfig; +use ptree::style::{Color, Style}; +use ptree::TreeBuilder; + +#[derive(new)] +pub struct TreeView { + tree: StringItem, +} + +impl TreeView { + fn from_value_helper(value: &Value, mut builder: &mut TreeBuilder) { + match value { + Value::Primitive(p) => { + let _ = builder.add_empty_child(p.format(None)); + } + Value::Object(o) => { + for (k, v) in o.entries.iter() { + builder = builder.begin_child(k.clone()); + Self::from_value_helper(v, builder); + builder = builder.end_child(); + } + } + Value::List(l) => { + for elem in l.iter() { + Self::from_value_helper(elem, builder); + } + } + Value::Block(_) => {} + Value::Error(_) => {} + Value::Filesystem => {} + Value::Binary(_) => {} + } + } + + fn from_value(value: &Value) -> TreeView { + let descs = value.data_descriptors(); + + let mut tree = TreeBuilder::new("".to_string()); + let mut builder = &mut tree; + + for desc in descs { + let value = value.get_data(&desc); + builder = builder.begin_child(desc.clone()); + Self::from_value_helper(value.borrow(), &mut builder); + builder = builder.end_child(); + //entries.push((desc.name.clone(), value.borrow().copy())) + } + + TreeView::new(builder.build()) + } + + fn render_view(&self) -> Result<(), ShellError> { + // Set up the print configuration + let config = { + let mut config = PrintConfig::from_env(); + config.branch = Style { + foreground: Some(Color::Green), + dimmed: true, + ..Style::default() + }; + config.leaf = Style { + bold: true, + ..Style::default() + }; + //config.characters = UTF_CHARS_BOLD.into(); + config.indent = 4; + config + }; + + // Print out the tree using custom formatting + print_tree_with(&self.tree, &config)?; + + Ok(()) + } +} + +struct TreeViewer; + +impl Plugin for TreeViewer { + fn config(&mut self) -> Result { + Ok(CommandConfig { + name: "treeview".to_string(), + mandatory_positional: vec![], + optional_positional: vec![], + can_load: vec![], + can_save: vec![], + is_filter: false, + is_sink: true, + named: IndexMap::new(), + rest_positional: true, + }) + } + + fn sink(&mut self, _args: Args, input: Vec) { + if input.len() > 0 { + for i in input.iter() { + let view = TreeView::from_value(&i); + let _ = view.render_view(); + //handle_unexpected(&mut *host, |host| crate::format::print_view(&view, host)); + } + } + + //Ok(()) + } +} + +fn main() { + serve_plugin(&mut TreeViewer); +} From 5e779d8b2bf37394d6e7277d12df9a0e3e7f0eb9 Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Thu, 4 Jul 2019 17:23:05 +1200 Subject: [PATCH 6/7] Add pretty binary viewing --- Cargo.lock | 7 ++++++ Cargo.toml | 5 +++++ src/commands/autoview.rs | 2 +- src/plugins/binaryview.rs | 46 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 src/plugins/binaryview.rs diff --git a/Cargo.lock b/Cargo.lock index 8a6626631..e9a0a85e1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1471,6 +1471,7 @@ dependencies = [ "nom 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "nom_locate 0.3.1 (git+https://github.com/wycats/nom_locate.git?branch=nom5)", "ordered-float 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "pretty-hex 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_env_logger 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "prettyprint 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1774,6 +1775,11 @@ dependencies = [ "xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "pretty-hex" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "pretty_assertions" version = "0.6.1" @@ -3169,6 +3175,7 @@ dependencies = [ "checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587" "checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" "checksum plist 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5f2a9f075f6394100e7c105ed1af73fb1859d6fd14e49d4290d578120beb167f" +"checksum pretty-hex 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "119929a2a3b731bb3d888f7a1b5dc3c1db28b6c134def5d99f7e16e2da16b8f7" "checksum pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3f81e1644e1b54f5a68959a29aa86cde704219254669da328ecfdf6a1f09d427" "checksum pretty_env_logger 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df8b3f4e0475def7d9c2e5de8e5a1306949849761e107b360d03e98eafaffd61" "checksum prettyprint 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f32f02328f651d5283173c7a9b2ef354b079fa535706547dde16d61ae23ecded" diff --git a/Cargo.toml b/Cargo.toml index 57c430ca7..8df4b8955 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -64,6 +64,7 @@ subprocess = "0.1.18" sys-info = "0.5.7" mime = "0.3.13" regex = "1.1.7" +pretty-hex = "0.1.0" [dev-dependencies] pretty_assertions = "0.6.1" @@ -88,6 +89,10 @@ path = "src/plugins/newskip.rs" name = "nu_plugin_treeview" path = "src/plugins/treeview.rs" +[[bin]] +name = "nu_plugin_binaryview" +path = "src/plugins/binaryview.rs" + [[bin]] name = "nu" path = "src/main.rs" diff --git a/src/commands/autoview.rs b/src/commands/autoview.rs index 6894b0559..4d8d85bd7 100644 --- a/src/commands/autoview.rs +++ b/src/commands/autoview.rs @@ -6,7 +6,7 @@ use crate::prelude::*; pub fn autoview(args: SinkCommandArgs) -> Result<(), ShellError> { if args.input.len() > 0 { if let Value::Binary(_) = args.input[0] { - println!("Binary"); + args.ctx.get_sink("binaryview").run(args)?; } else if equal_shapes(&args.input) { args.ctx.get_sink("table").run(args)?; } else { diff --git a/src/plugins/binaryview.rs b/src/plugins/binaryview.rs new file mode 100644 index 000000000..2a19a49eb --- /dev/null +++ b/src/plugins/binaryview.rs @@ -0,0 +1,46 @@ +use indexmap::IndexMap; +use nu::{serve_plugin, Args, CommandConfig, Plugin, Primitive, ShellError, Value}; + +struct BinaryView; + +impl BinaryView { + fn new() -> BinaryView { + BinaryView + } +} + +impl Plugin for BinaryView { + fn config(&mut self) -> Result { + Ok(CommandConfig { + name: "binaryview".to_string(), + mandatory_positional: vec![], + optional_positional: vec![], + can_load: vec![], + can_save: vec![], + is_filter: false, + is_sink: true, + named: IndexMap::new(), + rest_positional: true, + }) + } + + fn sink(&mut self, _args: Args, input: Vec) { + for v in input { + match v { + Value::Binary(b) => { + view_binary(&b); + } + _ => {} + } + } + } +} + +fn view_binary(b: &[u8]) { + use pretty_hex::*; + println!("{:?}", b.hex_dump()); +} + +fn main() { + serve_plugin(&mut BinaryView::new()); +} From 73d87e57ab2f3a26fd0a48fdebae703501774b19 Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Fri, 5 Jul 2019 10:17:18 +1200 Subject: [PATCH 7/7] Switch to rawkey reader. Add more binary reading --- Cargo.lock | 299 +++++++++++++++++++++++++++++++++++++- Cargo.toml | 5 + src/cli.rs | 7 + src/commands/autoview.rs | 2 +- src/commands/plugin.rs | 17 ++- src/plugin.rs | 106 +++++++++----- src/plugins/binaryview.rs | 180 ++++++++++++++++++++++- 7 files changed, 564 insertions(+), 52 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e9a0a85e1..91137970b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -147,6 +147,11 @@ name = "build_const" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "bumpalo" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "byte-unit" version = "2.1.0" @@ -176,6 +181,15 @@ dependencies = [ "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "c2-chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "cc" version = "1.0.37" @@ -422,6 +436,90 @@ dependencies = [ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "crossterm" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossterm_cursor 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "crossterm_input 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "crossterm_screen 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "crossterm_style 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "crossterm_terminal 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "crossterm_utils 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossterm_cursor" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossterm_utils 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "crossterm_winapi 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossterm_input" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossterm_screen 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "crossterm_utils 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "crossterm_winapi 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossterm_screen" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossterm_utils 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "crossterm_winapi 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossterm_style" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossterm_utils 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "crossterm_winapi 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossterm_terminal" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossterm_cursor 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "crossterm_utils 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "crossterm_winapi 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossterm_utils" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossterm_winapi 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossterm_winapi" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "csv" version = "1.0.7" @@ -917,6 +1015,15 @@ dependencies = [ "futures-preview 0.3.0-alpha.16 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "getrandom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "getset" version = "0.0.7" @@ -1132,6 +1239,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "lazy_static" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "lazycell" @@ -1375,7 +1485,20 @@ dependencies = [ "schannel 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tempfile 3.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "neso" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bincode 1.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.47 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1448,6 +1571,7 @@ dependencies = [ "chrono-tz 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "clipboard 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossterm 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)", "ctrlc 3.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "derive-new 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1468,6 +1592,7 @@ dependencies = [ "logos 0.10.0-rc2 (registry+https://github.com/rust-lang/crates.io-index)", "logos-derive 0.10.0-rc2 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "neso 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "nom 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "nom_locate 0.3.1 (git+https://github.com/wycats/nom_locate.git?branch=nom5)", "ordered-float 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1477,8 +1602,10 @@ dependencies = [ "prettyprint 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "prettytable-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "ptree 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rawkey 0.1.0 (git+https://github.com/jonathandturner/rawkey.git)", "regex 1.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.9.18 (registry+https://github.com/rust-lang/crates.io-index)", + "resize 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "roxmltree 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustyline 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1490,6 +1617,7 @@ dependencies = [ "subprocess 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "sys-info 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)", "sysinfo 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "toml-query 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1775,6 +1903,11 @@ dependencies = [ "xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ppv-lite86" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "pretty-hex" version = "0.1.0" @@ -1901,6 +2034,18 @@ dependencies = [ "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rand" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "getrandom 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_chacha 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand_chacha" version = "0.1.1" @@ -1910,6 +2055,16 @@ dependencies = [ "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rand_chacha" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand_core" version = "0.3.1" @@ -1923,6 +2078,14 @@ name = "rand_core" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "rand_core" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "getrandom 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand_hc" version = "0.1.0" @@ -1931,6 +2094,14 @@ dependencies = [ "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand_isaac" version = "0.1.1" @@ -1979,6 +2150,17 @@ dependencies = [ "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rawkey" +version = "0.1.0" +source = "git+https://github.com/jonathandturner/rawkey.git#f06456a6f662eff142ed019fb5583043e11b771c" +dependencies = [ + "readkey 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "x11 2.18.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rayon" version = "1.1.0" @@ -2009,6 +2191,11 @@ dependencies = [ "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "readkey" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "redox_syscall" version = "0.1.54" @@ -2103,6 +2290,11 @@ dependencies = [ "uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "resize" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "result" version = "1.0.0" @@ -2381,6 +2573,11 @@ name = "smallvec" version = "0.6.10" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "spin" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "stable_deref_trait" version = "1.1.1" @@ -2493,12 +2690,12 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.0.8" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", "remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2830,6 +3027,15 @@ dependencies = [ "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "user32-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "utf8-ranges" version = "1.0.3" @@ -2888,6 +3094,54 @@ dependencies = [ "try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "wasm-bindgen" +version = "0.2.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "wasm-bindgen-macro 0.2.47 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bumpalo 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.37 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-shared 0.2.47 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-macro-support 0.2.47 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.37 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-backend 0.2.47 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-shared 0.2.47 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.47" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "winapi" version = "0.2.8" @@ -2943,6 +3197,15 @@ dependencies = [ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "x11" +version = "2.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "x11-clipboard" version = "0.3.2" @@ -3002,10 +3265,12 @@ dependencies = [ "checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" "checksum block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" "checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39" +"checksum bumpalo 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2cd43d82f27d68911e6ee11ee791fb248f138f5d69424dc02e098d4f152b0b05" "checksum byte-unit 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6754bb4703aa167bed5381f0c6842f1cc31a9ecde3b9443f726dde3ad3afb841" "checksum bytecount 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f861d9ce359f56dbcb6e0c2a1cb84e52ad732cadb57b806adeb3c7668caccbd8" "checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" "checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" +"checksum c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7d64d04786e0f528460fc884753cf8dddcc466be308f6026f8e355c41a0e4101" "checksum cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "39f75544d7bbaf57560d2168f28fd649ff9c76153874db88bdbdfd839b1a7e7d" "checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33" "checksum chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "77d81f58b7301084de3b958691458a53c3f7e0b1d702f77e550b6a88e3a88abe" @@ -3032,6 +3297,14 @@ dependencies = [ "checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b" "checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015" "checksum crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f8306fcef4a7b563b76b7dd949ca48f52bc1141aa067d2ea09565f3e2652aa5c" +"checksum crossterm 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)" = "21ac79357981b3c35917a377e6138729b66316db7649f9f96fbb517bb02361e5" +"checksum crossterm_cursor 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4b8ddb43937bfafbe07d349ee9497754ceac818ee872116afccb076f2de28d3d" +"checksum crossterm_input 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a23a71b51ddc8f74e13e341179b1a26b20f0030d14ff8fbdd9da45fd0e342bc5" +"checksum crossterm_screen 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "90889b9f1d7867a583dede34deab1e32a10379e9eb70d920ca7895e144aa6d65" +"checksum crossterm_style 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "983596405fe738aac9645656b666073fe6e0a8bf088679b7e256916ee41b61f7" +"checksum crossterm_terminal 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "18792c97c5cdcc5fd3582df58188a793bf290af4a53d5fc8442c7d17e003b356" +"checksum crossterm_utils 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8321d40908d0ee77cb29335f591eae2b4f7225152f81b9dfa35a161ca3b077dc" +"checksum crossterm_winapi 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c061e4a1c47a53952ba0f2396c00a61cd7ab74482eba99b9c9cc77fdca71932" "checksum csv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9044e25afb0924b5a5fc5511689b0918629e85d68ea591e5e87fbf1e85ea1b3b" "checksum csv-core 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa5cdef62f37e6ffe7d1f07a381bc0db32b7a3ff1cac0de56cb0d81e71f53d65" "checksum ctor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3b4c17619643c1252b5f690084b82639dd7fac141c57c8e77a00e0148132092c" @@ -3089,6 +3362,7 @@ dependencies = [ "checksum futures-sink-preview 0.3.0-alpha.16 (registry+https://github.com/rust-lang/crates.io-index)" = "49dcfdacd6b5974ca0b9b78bc38ffd1071da0206179735c3df82e279f5b784e4" "checksum futures-util-preview 0.3.0-alpha.16 (registry+https://github.com/rust-lang/crates.io-index)" = "f7a0451b9c5047c2b9ab93425ffd0793165511e93c04b977cd45fbd41c6e34b2" "checksum futures_codec 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b60f48aa03e365df015d2fbf0b79f17b440350c268a5e20305da17b394adcc1e" +"checksum getrandom 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e65cce4e5084b14874c4e7097f38cab54f47ee554f9194673456ea379dcc4c55" "checksum getset 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "19fbde0fad0c1c1f9474694b1f5c9ba22b09f2f74f74e6d2bd19c43f6656e2cb" "checksum git2 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "924b2e7d2986e625dcad89e8a429a7b3adee3c3d71e585f4a66c4f7e78715e31" "checksum h2 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "69b2a5a3092cbebbc951fe55408402e696ee2ed09019137d1800fc2c411265d2" @@ -3137,6 +3411,7 @@ dependencies = [ "checksum mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)" = "83f51996a3ed004ef184e16818edc51fadffe8e7ca68be67f9dee67d84d0ff23" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e" +"checksum neso 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6b3c31defbcb081163db18437fd88c2a267cb3e26f7bd5e4b186e4b1b38fe8c8" "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" "checksum nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce" "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" @@ -3175,6 +3450,7 @@ dependencies = [ "checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587" "checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" "checksum plist 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5f2a9f075f6394100e7c105ed1af73fb1859d6fd14e49d4290d578120beb167f" +"checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b" "checksum pretty-hex 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "119929a2a3b731bb3d888f7a1b5dc3c1db28b6c134def5d99f7e16e2da16b8f7" "checksum pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3f81e1644e1b54f5a68959a29aa86cde704219254669da328ecfdf6a1f09d427" "checksum pretty_env_logger 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df8b3f4e0475def7d9c2e5de8e5a1306949849761e107b360d03e98eafaffd61" @@ -3186,18 +3462,24 @@ dependencies = [ "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" "checksum quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "faf4799c5d274f3868a4aae320a0a182cbd2baee377b378f080e16a23e9d80db" "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" +"checksum rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d47eab0e83d9693d40f825f86948aa16eff6750ead4bdffc4ab95b8b3a7f052c" "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" +"checksum rand_chacha 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e193067942ef6f485a349a113329140d0ab9e2168ce92274499bb0e9a4190d9d" "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" "checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" +"checksum rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "615e683324e75af5d43d8f7a39ffe3ee4a9dc42c5c701167a71dc59c3a493aca" "checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" +"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" "checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" "checksum rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" "checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" "checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" "checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" +"checksum rawkey 0.1.0 (git+https://github.com/jonathandturner/rawkey.git)" = "" "checksum rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a4b0186e22767d5b9738a05eab7c6ac90b15db17e5b5f9bd87976dd7d89a10a4" "checksum rayon-core 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbe0df8435ac0c397d467b6cad6d25543d06e8a019ef3f6af3c384597515bd2" "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +"checksum readkey 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d98db94bb4f3e926c8d8186547cd9366d958d753aff5801214d93d38214e8f0f" "checksum redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)" = "12229c14a0f65c4f1cb046a3b52047cdd9da1f4b30f8a39c5063c8bae515e252" "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" "checksum redox_users 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3fe5204c3a17e97dde73f285d49be585df59ed84b50a872baf416e73b62c3828" @@ -3206,6 +3488,7 @@ dependencies = [ "checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" "checksum render-tree 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "68ed587df09cfb7ce1bc6fe8f77e24db219f222c049326ccbfb948ec67e31664" "checksum reqwest 0.9.18 (registry+https://github.com/rust-lang/crates.io-index)" = "00eb63f212df0e358b427f0f40aa13aaea010b470be642ad422bcbca2feff2e4" +"checksum resize 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0ed16788c219e719ec11912d96f4e819641941578d1b02f00dab139b00789fb8" "checksum result 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "194d8e591e405d1eecf28819740abed6d719d1a2db87fc0bcdedee9a26d55560" "checksum roxmltree 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "330d8f80a274bc3cb608908ee345970e7e24b96907f1ad69615a498bec57871c" "checksum rust-ini 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e52c148ef37f8c375d49d5a73aa70713125b7f19095948a923f80afdeb22ec2" @@ -3242,6 +3525,7 @@ dependencies = [ "checksum siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" "checksum smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7" +"checksum spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44363f6f51401c34e7be73db0db371c04705d35efbe9f7d6082e03a921a32c55" "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" "checksum stackvector 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1c4725650978235083241fab0fdc8e694c3de37821524e7534a1a9061d1068af" "checksum static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c19be23126415861cb3a23e501d34a708f7f9b2183c5252d690941c2e69199d5" @@ -3254,7 +3538,7 @@ dependencies = [ "checksum syntect 3.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e80b8831c5a543192ffc3727f01cf0e57579c6ac15558e3048bfb5708892167b" "checksum sys-info 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)" = "76d6cf7b349b6a6daaf7a3797227e2f4108c8dd398e0aca7e29b9fb239948541" "checksum sysinfo 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c3e2cab189e59f72710e3dd5e1e0d5be0f6c5c999c326f2fdcdf3bf4483ec9fd" -"checksum tempfile 3.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7dc4738f2e68ed2855de5ac9cdbe05c9216773ecde4739b2f095002ab03a13ef" +"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" "checksum term 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "edd106a334b7657c10b7c540a0106114feadeb4dc314513e97df481d5d966f42" "checksum termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "96d6098003bde162e4277c70665bd87c326f5a0c3f3fbfb285787fa482d54e6e" "checksum termion 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a8fb22f7cde82c8220e5aeacb3258ed7ce996142c77cba193f203515e26c330" @@ -3290,6 +3574,7 @@ dependencies = [ "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" +"checksum user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ef4711d107b21b410a3a974b1204d9accc8b10dad75d8324b5d755de1617d47" "checksum utf8-ranges 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9d50aa7650df78abf942826607c62468ce18d9019673d4a2ebe1865dbb96ffde" "checksum utf8parse 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8772a4ccbb4e89959023bc5b7cb8623a795caa7092d99f3aa9501b9484d4557d" "checksum uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "90dbc611eb48397705a6b0f6e917da23ae517e4d127123d2cf7674206627d32a" @@ -3299,6 +3584,11 @@ dependencies = [ "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum walkdir 2.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c7904a7e2bb3cdf0cf5e783f44204a85a37a93151738fa349f06680f59a98b45" "checksum want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "797464475f30ddb8830cc529aaaae648d581f99e2036a928877dfde027ddf6b3" +"checksum wasm-bindgen 0.2.47 (registry+https://github.com/rust-lang/crates.io-index)" = "22029998cc650473cb05f10f19c06a1536b9e1f1572e4f5dacd45ab4d3f85877" +"checksum wasm-bindgen-backend 0.2.47 (registry+https://github.com/rust-lang/crates.io-index)" = "6f858ff3cb4196c702e8c24b75fba1d3ab46958de4f7c253627f0507aae1507c" +"checksum wasm-bindgen-macro 0.2.47 (registry+https://github.com/rust-lang/crates.io-index)" = "15c29f04eb117312931e7b02878453ee63d67a6f291797651890128bf5ee71db" +"checksum wasm-bindgen-macro-support 0.2.47 (registry+https://github.com/rust-lang/crates.io-index)" = "92b1356b623816248dfe0e2c4b7e113618d647808907ff6a3d9838ebee8e82ee" +"checksum wasm-bindgen-shared 0.2.47 (registry+https://github.com/rust-lang/crates.io-index)" = "15de16ddb30cfd424a87598b30021491bae1607d32e52056979865c98b7913b4" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" @@ -3307,6 +3597,7 @@ dependencies = [ "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "561ed901ae465d6185fa7864d63fbd5720d0ef718366c9a4dc83cf6170d7e9ba" "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" +"checksum x11 2.18.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39697e3123f715483d311b5826e254b6f3cfebdd83cf7ef3358f579c3d68e235" "checksum x11-clipboard 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3a77356335a1398267e15a7c1d5fa1c8d3fdb3e5ba2e381407d74482c29587d3" "checksum xcb 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5e917a3f24142e9ff8be2414e36c649d47d6cc2ba81f16201cdef96e533e02de" "checksum xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" diff --git a/Cargo.toml b/Cargo.toml index 8df4b8955..2806483ff 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -65,6 +65,11 @@ sys-info = "0.5.7" mime = "0.3.13" regex = "1.1.7" pretty-hex = "0.1.0" +neso = "0.5.0" +rawkey = { git = "https://github.com/jonathandturner/rawkey.git" } +resize = "0.3.0" +crossterm = "0.9.6" +tempfile = "3.1.0" [dev-dependencies] pretty_assertions = "0.6.1" diff --git a/src/cli.rs b/src/cli.rs index 4b74979a6..be9bb01fb 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -137,6 +137,13 @@ fn load_plugins(context: &mut Context) -> Result<(), ShellError> { let _ = load_plugins_in_dir(&path, context); + // Also use our release output for now + let mut path = std::path::PathBuf::from("."); + path.push("target"); + path.push("release"); + + let _ = load_plugins_in_dir(&path, context); + Ok(()) } diff --git a/src/commands/autoview.rs b/src/commands/autoview.rs index 4d8d85bd7..be49c25e0 100644 --- a/src/commands/autoview.rs +++ b/src/commands/autoview.rs @@ -1,6 +1,6 @@ use crate::commands::command::SinkCommandArgs; use crate::errors::ShellError; -use crate::format::{GenericView, TableView}; +use crate::format::GenericView; use crate::prelude::*; pub fn autoview(args: SinkCommandArgs) -> Result<(), ShellError> { diff --git a/src/commands/plugin.rs b/src/commands/plugin.rs index 9be9dad7a..d7fa3f92d 100644 --- a/src/commands/plugin.rs +++ b/src/commands/plugin.rs @@ -119,16 +119,17 @@ pub fn filter_plugin(path: String, args: CommandArgs) -> Result Result<(), ShellError> { - let mut child = std::process::Command::new(path) - .stdin(std::process::Stdio::piped()) - .spawn() - .expect("Failed to spawn child process"); - - let stdin = child.stdin.as_mut().expect("Failed to open stdin"); - + //use subprocess::Exec; let request = JsonRpc::new("sink", (args.args, args.input)); let request_raw = serde_json::to_string(&request).unwrap(); - stdin.write(format!("{}\n", request_raw).as_bytes())?; + let mut tmpfile = tempfile::NamedTempFile::new()?; + let _ = writeln!(tmpfile, "{}", request_raw); + let _ = tmpfile.flush(); + + let mut child = std::process::Command::new(path) + .arg(tmpfile.path()) + .spawn() + .expect("Failed to spawn child process"); let _ = child.wait(); diff --git a/src/plugin.rs b/src/plugin.rs index 688b44831..fcf0addde 100644 --- a/src/plugin.rs +++ b/src/plugin.rs @@ -23,44 +23,78 @@ pub trait Plugin { } pub fn serve_plugin(plugin: &mut dyn Plugin) { - loop { - let mut input = String::new(); - match io::stdin().read_line(&mut input) { - Ok(_) => { - let command = serde_json::from_str::(&input); - match command { - Ok(NuCommand::config) => { - send_response(plugin.config()); - } - Ok(NuCommand::begin_filter { params }) => { - let _ = plugin.begin_filter(params); - } - Ok(NuCommand::filter { params }) => { - send_response(plugin.filter(params)); - } - Ok(NuCommand::sink { params }) => { - plugin.sink(params.0, params.1); - break; - } - Ok(NuCommand::quit) => { - plugin.quit(); - break; - } - e => { - send_response(ShellError::string(format!( - "Could not handle plugin message: {} {:?}", - input, e - ))); - break; - } + let args = std::env::args(); + if args.len() > 1 { + let input = std::fs::read_to_string(args.skip(1).next().unwrap()); + if let Ok(input) = input { + let command = serde_json::from_str::(&input); + match command { + Ok(NuCommand::config) => { + send_response(plugin.config()); + } + Ok(NuCommand::begin_filter { params }) => { + let _ = plugin.begin_filter(params); + } + Ok(NuCommand::filter { params }) => { + send_response(plugin.filter(params)); + } + Ok(NuCommand::sink { params }) => { + plugin.sink(params.0, params.1); + return; + } + Ok(NuCommand::quit) => { + plugin.quit(); + return; + } + e => { + send_response(ShellError::string(format!( + "Could not handle plugin message: {} {:?}", + input, e + ))); + return; } } - e => { - send_response(ShellError::string(format!( - "Could not handle plugin message: {:?}", - e, - ))); - break; + } + } else { + loop { + let mut input = String::new(); + match io::stdin().read_line(&mut input) { + Ok(_) => { + let command = serde_json::from_str::(&input); + match command { + Ok(NuCommand::config) => { + send_response(plugin.config()); + } + Ok(NuCommand::begin_filter { params }) => { + let _ = plugin.begin_filter(params); + } + Ok(NuCommand::filter { params }) => { + send_response(plugin.filter(params)); + } + Ok(NuCommand::sink { params }) => { + plugin.sink(params.0, params.1); + break; + } + Ok(NuCommand::quit) => { + plugin.quit(); + break; + } + e => { + send_response(ShellError::string(format!( + "Could not handle plugin message: {} {:?}", + input, e + ))); + break; + } + } + } + e => { + send_response(ShellError::string(format!( + "Could not handle plugin message: {:?}", + e, + ))); + break; + } } } } diff --git a/src/plugins/binaryview.rs b/src/plugins/binaryview.rs index 2a19a49eb..56c4bee14 100644 --- a/src/plugins/binaryview.rs +++ b/src/plugins/binaryview.rs @@ -1,5 +1,6 @@ +use crossterm::{cursor, terminal, Attribute, Color, Colored, RawScreen}; use indexmap::IndexMap; -use nu::{serve_plugin, Args, CommandConfig, Plugin, Primitive, ShellError, Value}; +use nu::{serve_plugin, Args, CommandConfig, Plugin, ShellError, Value}; struct BinaryView; @@ -28,7 +29,7 @@ impl Plugin for BinaryView { for v in input { match v { Value::Binary(b) => { - view_binary(&b); + let _ = view_binary(&b); } _ => {} } @@ -36,9 +37,182 @@ impl Plugin for BinaryView { } } -fn view_binary(b: &[u8]) { +fn view_binary(b: &[u8]) -> Result<(), Box> { use pretty_hex::*; + if b.len() > 3 { + match (b[0], b[1], b[2]) { + (0x4e, 0x45, 0x53) => { + view_contents(b)?; + return Ok(()); + } + _ => {} + } + } println!("{:?}", b.hex_dump()); + Ok(()) +} + +#[derive(PartialEq, Debug)] +pub enum JoyButton { + A = 0, + B = 1, + Select = 2, + Start = 3, + Up = 4, + Down = 5, + Left = 6, + Right = 7, +} +pub struct Context { + pub width: usize, + pub height: usize, + pub frame_buffer: Vec<(char, (u8, u8, u8))>, + pub since_last_button: Vec, +} + +impl Context { + pub fn blank() -> Context { + Context { + width: 0, + height: 0, + frame_buffer: vec![], + since_last_button: vec![0; 8], + } + } + pub fn clear(&mut self) { + self.frame_buffer = vec![(' ', (0, 0, 0)); self.width * self.height as usize]; + } + pub fn flush(&self) -> Result<(), Box> { + let cursor = cursor(); + cursor.goto(0, 0)?; + + let mut prev_color = None; + + for pixel in &self.frame_buffer { + match prev_color { + Some(c) if c == pixel.1 => { + print!("{}", pixel.0); + } + _ => { + prev_color = Some(pixel.1); + print!( + "{}{}{}", + Colored::Fg(Color::Rgb { + r: (pixel.1).0, + g: (pixel.1).1, + b: (pixel.1).2 + }), + Colored::Bg(Color::Rgb { + r: 25, + g: 25, + b: 25 + }), + pixel.0 + ) + } + } + } + + println!("{}", Attribute::Reset); + + Ok(()) + } + pub fn update(&mut self) -> Result<(), Box> { + let terminal = terminal(); + let terminal_size = terminal.terminal_size(); + + if (self.width != terminal_size.0 as usize) || (self.height != terminal_size.1 as usize) { + let cursor = cursor(); + cursor.hide()?; + + self.width = terminal_size.0 as usize + 1; + self.height = terminal_size.1 as usize; + } + + Ok(()) + } +} + +pub fn view_contents(buffer: &[u8]) -> Result<(), Box> { + use rawkey::{KeyCode, RawKey}; + + let mut nes = neso::Nes::new(48000.0); + let rawkey = RawKey::new(); + nes.load_rom(&buffer); + + nes.reset(); + + if let Ok(_raw) = RawScreen::into_raw_mode() { + let mut context: Context = Context::blank(); + let input = crossterm::input(); + let _ = input.read_async(); + let cursor = cursor(); + + let buttons = vec![ + KeyCode::LShift, + KeyCode::LControl, + KeyCode::Tab, + KeyCode::Back, + KeyCode::UpArrow, + KeyCode::DownArrow, + KeyCode::LeftArrow, + KeyCode::RightArrow, + ]; + + cursor.hide()?; + + 'gameloop: loop { + let _ = context.update(); + nes.step_frame(); + + let image_buffer = nes.image_buffer(); + + let mut new_offscreen = vec![0; context.height * context.width * 4]; + let mut resizer = resize::new( + 256, + 240, + context.width, + context.height, + resize::Pixel::RGBA, + resize::Type::Triangle, + ); + let slice = unsafe { std::slice::from_raw_parts(image_buffer, 256 * 240 * 4) }; + resizer.resize(&slice, &mut new_offscreen); + + context.clear(); + + for row in 0..context.height { + for col in 0..(context.width) { + let red = new_offscreen[col * 4 + row * context.width * 4]; + let green = new_offscreen[col * 4 + 1 + row * context.width * 4]; + let blue = new_offscreen[col * 4 + 2 + row * context.width * 4]; + + context.frame_buffer[col + row * context.width] = ('@', (red, green, blue)); + } + } + context.flush()?; + + if rawkey.is_pressed(rawkey::KeyCode::Escape) { + break 'gameloop; + } else { + for i in 0..buttons.len() { + if rawkey.is_pressed(buttons[i]) { + nes.press_button(0, i as u8); + } else { + nes.release_button(0, i as u8); + } + } + } + } + } + + let cursor = cursor(); + let _ = cursor.show(); + + #[allow(unused)] + let screen = RawScreen::disable_raw_mode(); + + Ok(()) } fn main() {