From a3f628427f1b0646b87567d769b425582198104a Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Sun, 14 Jul 2019 19:28:56 +1200 Subject: [PATCH 1/6] Fix binary view for better approx --- src/plugins/binaryview.rs | 83 ++++++++++++++++++++++++++++++--------- 1 file changed, 65 insertions(+), 18 deletions(-) diff --git a/src/plugins/binaryview.rs b/src/plugins/binaryview.rs index d56037a02..1d6b21e70 100644 --- a/src/plugins/binaryview.rs +++ b/src/plugins/binaryview.rs @@ -75,40 +75,87 @@ impl Context { let cursor = cursor(); cursor.goto(0, 0)?; - let mut prev_color: Option<(u8, u8, u8)> = None; + let mut prev_fg: Option<(u8, u8, u8)> = None; + let mut prev_bg: Option<(u8, u8, u8)> = None; let mut prev_count = 1; - for pixel in &self.frame_buffer { - match prev_color { - Some(c) if c == pixel.1 => { + let mut pos = 0; + let fb_len = self.frame_buffer.len(); + while pos < (fb_len - self.width) { + let top_pixel = self.frame_buffer[pos].1; + let bottom_pixel = self.frame_buffer[pos + self.width].1; + + match (prev_fg, prev_bg) { + (Some(c), Some(d)) if c == top_pixel && d == bottom_pixel => { prev_count += 1; } - Some(c) => { + (Some(c), Some(d)) => { print!( "{}", ansi_term::Colour::RGB(c.0, c.1, c.2) - .paint((0..prev_count).map(|_| pixel.0).collect::()) + .on(ansi_term::Colour::RGB(d.0, d.1, d.2,)) + .paint((0..prev_count).map(|_| "▀").collect::()) ); - prev_color = Some(pixel.1); + prev_fg = Some(top_pixel); + prev_bg = Some(bottom_pixel); prev_count = 1; } _ => { - prev_color = Some(pixel.1); + prev_fg = Some(top_pixel); + prev_bg = Some(bottom_pixel); prev_count = 1; } } - } - - if prev_count > 0 { - if let Some(color) = prev_color { - print!( - "{}", - ansi_term::Colour::RGB(color.0, color.1, color.2) - .paint((0..prev_count).map(|_| "@").collect::()) - ); + pos += 1; + if pos % self.width == 0 { + pos += self.width; } } + if prev_count > 0 { + match (prev_fg, prev_bg) { + (Some(c), Some(d)) => { + print!( + "{}", + ansi_term::Colour::RGB(c.0, c.1, c.2) + .on(ansi_term::Colour::RGB(d.0, d.1, d.2,)) + .paint((0..prev_count).map(|_| "▀").collect::()) + ); + } + _ => {} + } + } + /* + for pixel in &self.frame_buffer { + match prev_color { + Some(c) if c == pixel.1 => { + prev_count += 1; + } + Some(c) => { + print!( + "{}", + ansi_term::Colour::RGB(c.0, c.1, c.2) + .paint((0..prev_count).map(|_| pixel.0).collect::()) + ); + prev_color = Some(pixel.1); + prev_count = 1; + } + _ => { + prev_color = Some(pixel.1); + prev_count = 1; + } + } + } + if prev_count > 0 { + if let Some(color) = prev_color { + print!( + "{}", + ansi_term::Colour::RGB(color.0, color.1, color.2) + .paint((0..prev_count).map(|_| "▄").collect::()) + ); + } + } + */ println!("{}", Attribute::Reset); Ok(()) @@ -122,7 +169,7 @@ impl Context { cursor.hide()?; self.width = terminal_size.0 as usize + 1; - self.height = terminal_size.1 as usize; + self.height = terminal_size.1 as usize * 2; } Ok(()) From 1a36f47bcb7daf97335528110455f4c84289c917 Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Sun, 14 Jul 2019 19:54:30 +1200 Subject: [PATCH 2/6] Don't redraw static frame --- src/plugins/binaryview.rs | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/plugins/binaryview.rs b/src/plugins/binaryview.rs index 1d6b21e70..ef39536ba 100644 --- a/src/plugins/binaryview.rs +++ b/src/plugins/binaryview.rs @@ -55,7 +55,8 @@ fn view_binary(b: &[u8]) -> Result<(), Box> { pub struct Context { pub width: usize, pub height: usize, - pub frame_buffer: Vec<(char, (u8, u8, u8))>, + pub frame_buffer: Vec<(u8, u8, u8)>, + pub prev_frame_buffer: Option>, pub since_last_button: Vec, } @@ -65,16 +66,24 @@ impl Context { width: 0, height: 0, frame_buffer: vec![], + prev_frame_buffer: None, since_last_button: vec![0; 8], } } pub fn clear(&mut self) { - self.frame_buffer = vec![(' ', (0, 0, 0)); self.width * self.height as usize]; + self.frame_buffer = vec![(0, 0, 0); self.width * self.height as usize]; } - pub fn flush(&self) -> Result<(), Box> { + pub fn flush(&mut self) -> Result<(), Box> { let cursor = cursor(); cursor.goto(0, 0)?; + // check if we should redraw + if let Some(ref prev) = self.prev_frame_buffer { + if self.frame_buffer == *prev { + return Ok(()); + } + } + let mut prev_fg: Option<(u8, u8, u8)> = None; let mut prev_bg: Option<(u8, u8, u8)> = None; let mut prev_count = 1; @@ -82,8 +91,8 @@ impl Context { let mut pos = 0; let fb_len = self.frame_buffer.len(); while pos < (fb_len - self.width) { - let top_pixel = self.frame_buffer[pos].1; - let bottom_pixel = self.frame_buffer[pos + self.width].1; + let top_pixel = self.frame_buffer[pos]; + let bottom_pixel = self.frame_buffer[pos + self.width]; match (prev_fg, prev_bg) { (Some(c), Some(d)) if c == top_pixel && d == bottom_pixel => { @@ -124,6 +133,8 @@ impl Context { _ => {} } } + + self.prev_frame_buffer = Some(self.frame_buffer.clone()); /* for pixel in &self.frame_buffer { match prev_color { @@ -262,7 +273,7 @@ pub fn view_contents(buffer: &[u8]) -> Result<(), Box> { use image::Pixel; let rgb = pixel.to_rgb(); //print!("{}", rgb[0]); - context.frame_buffer[count] = ('@', (rgb[0], rgb[1], rgb[2])); + context.frame_buffer[count] = (rgb[0], rgb[1], rgb[2]); count += 1; } } @@ -286,7 +297,7 @@ pub fn view_contents(buffer: &[u8]) -> Result<(), Box> { use image::Pixel; let rgb = pixel.to_rgb(); //print!("{}", rgb[0]); - context.frame_buffer[count] = ('@', (rgb[0], rgb[1], rgb[2])); + context.frame_buffer[count] = (rgb[0], rgb[1], rgb[2]); count += 1; } } @@ -359,7 +370,7 @@ pub fn view_contents_interactive(buffer: &[u8]) -> Result<(), Box Date: Mon, 15 Jul 2019 06:38:03 +1200 Subject: [PATCH 3/6] Try to add hires mode --- src/plugins/binaryview.rs | 163 +++++++++++++++++++++----------------- 1 file changed, 89 insertions(+), 74 deletions(-) diff --git a/src/plugins/binaryview.rs b/src/plugins/binaryview.rs index ef39536ba..4ed47d8bc 100644 --- a/src/plugins/binaryview.rs +++ b/src/plugins/binaryview.rs @@ -1,6 +1,6 @@ use crossterm::{cursor, terminal, Attribute, RawScreen}; use indexmap::IndexMap; -use nu::{serve_plugin, Args, CommandConfig, Plugin, ShellError, Spanned, Value}; +use nu::{serve_plugin, Args, CommandConfig, NamedType, Plugin, ShellError, Spanned, Value}; use pretty_hex::*; struct BinaryView; @@ -13,24 +13,26 @@ impl BinaryView { impl Plugin for BinaryView { fn config(&mut self) -> Result { + let mut named = IndexMap::new(); + named.insert("hires".to_string(), NamedType::Switch); Ok(CommandConfig { name: "binaryview".to_string(), positional: vec![], is_filter: false, is_sink: true, - named: IndexMap::new(), + named, rest_positional: true, }) } - fn sink(&mut self, _args: Args, input: Vec>) { + fn sink(&mut self, args: Args, input: Vec>) { for v in input { match v { Spanned { item: Value::Binary(b), .. } => { - let _ = view_binary(&b); + let _ = view_binary(&b, args.has("hires")); } _ => {} } @@ -38,58 +40,93 @@ impl Plugin for BinaryView { } } -fn view_binary(b: &[u8]) -> Result<(), Box> { +fn view_binary(b: &[u8], hires_mode: bool) -> Result<(), Box> { if b.len() > 3 { match (b[0], b[1], b[2]) { (0x4e, 0x45, 0x53) => { - view_contents_interactive(b)?; + view_contents_interactive(b, hires_mode)?; return Ok(()); } _ => {} } } - view_contents(b)?; + view_contents(b, hires_mode)?; Ok(()) } -pub struct Context { +pub struct RenderContext { pub width: usize, pub height: usize, pub frame_buffer: Vec<(u8, u8, u8)>, - pub prev_frame_buffer: Option>, pub since_last_button: Vec, + pub hires_mode: bool, } -impl Context { - pub fn blank() -> Context { - Context { +impl RenderContext { + pub fn blank(hires_mode: bool) -> RenderContext { + RenderContext { width: 0, height: 0, frame_buffer: vec![], - prev_frame_buffer: None, since_last_button: vec![0; 8], + hires_mode, } } pub fn clear(&mut self) { self.frame_buffer = vec![(0, 0, 0); self.width * self.height as usize]; } - pub fn flush(&mut self) -> Result<(), Box> { + + fn render_to_screen_lores(&mut self) -> Result<(), Box> { + let mut prev_color: Option<(u8, u8, u8)> = None; + let mut prev_count = 1; + let cursor = cursor(); cursor.goto(0, 0)?; - // check if we should redraw - if let Some(ref prev) = self.prev_frame_buffer { - if self.frame_buffer == *prev { - return Ok(()); + for pixel in &self.frame_buffer { + match prev_color { + Some(c) if c == *pixel => { + prev_count += 1; + } + Some(c) => { + print!( + "{}", + ansi_term::Colour::RGB(c.0, c.1, c.2) + .paint((0..prev_count).map(|_| "█").collect::()) + ); + prev_color = Some(*pixel); + prev_count = 1; + } + _ => { + prev_color = Some(*pixel); + prev_count = 1; + } } } + if prev_count > 0 { + if let Some(color) = prev_color { + print!( + "{}", + ansi_term::Colour::RGB(color.0, color.1, color.2) + .paint((0..prev_count).map(|_| "█").collect::()) + ); + } + } + println!("{}", Attribute::Reset); + Ok(()) + } + fn render_to_screen_hires(&mut self) -> Result<(), Box> { let mut prev_fg: Option<(u8, u8, u8)> = None; let mut prev_bg: Option<(u8, u8, u8)> = None; let mut prev_count = 1; let mut pos = 0; let fb_len = self.frame_buffer.len(); + + let cursor = cursor(); + cursor.goto(0, 0)?; + while pos < (fb_len - self.width) { let top_pixel = self.frame_buffer[pos]; let bottom_pixel = self.frame_buffer[pos + self.width]; @@ -133,44 +170,16 @@ impl Context { _ => {} } } - - self.prev_frame_buffer = Some(self.frame_buffer.clone()); - /* - for pixel in &self.frame_buffer { - match prev_color { - Some(c) if c == pixel.1 => { - prev_count += 1; - } - Some(c) => { - print!( - "{}", - ansi_term::Colour::RGB(c.0, c.1, c.2) - .paint((0..prev_count).map(|_| pixel.0).collect::()) - ); - prev_color = Some(pixel.1); - prev_count = 1; - } - _ => { - prev_color = Some(pixel.1); - prev_count = 1; - } - } - } - - if prev_count > 0 { - if let Some(color) = prev_color { - print!( - "{}", - ansi_term::Colour::RGB(color.0, color.1, color.2) - .paint((0..prev_count).map(|_| "▄").collect::()) - ); - } - } - */ println!("{}", Attribute::Reset); - Ok(()) } + pub fn flush(&mut self) -> Result<(), Box> { + if self.hires_mode { + self.render_to_screen_hires() + } else { + self.render_to_screen_lores() + } + } pub fn update(&mut self) -> Result<(), Box> { let terminal = terminal(); let terminal_size = terminal.terminal_size(); @@ -180,7 +189,11 @@ impl Context { cursor.hide()?; self.width = terminal_size.0 as usize + 1; - self.height = terminal_size.1 as usize * 2; + self.height = if self.hires_mode { + terminal_size.1 as usize * 2 + } else { + terminal_size.1 as usize + }; } Ok(()) @@ -234,7 +247,7 @@ fn load_from_jpg_buffer(buffer: &[u8]) -> Option<(RawImageBuffer)> { }) } -pub fn view_contents(buffer: &[u8]) -> Result<(), Box> { +pub fn view_contents(buffer: &[u8], hires_mode: bool) -> Result<(), Box> { let mut raw_image_buffer = load_from_png_buffer(buffer); if raw_image_buffer.is_none() { @@ -248,9 +261,9 @@ pub fn view_contents(buffer: &[u8]) -> Result<(), Box> { } let raw_image_buffer = raw_image_buffer.unwrap(); - let mut context: Context = Context::blank(); - let _ = context.update(); - context.clear(); + let mut render_context: RenderContext = RenderContext::blank(hires_mode); + let _ = render_context.update(); + render_context.clear(); match raw_image_buffer.colortype { image::ColorType::RGBA(8) => { @@ -263,8 +276,8 @@ pub fn view_contents(buffer: &[u8]) -> Result<(), Box> { let resized_img = image::imageops::resize( &img, - context.width as u32, - context.height as u32, + render_context.width as u32, + render_context.height as u32, image::FilterType::Lanczos3, ); @@ -272,8 +285,7 @@ pub fn view_contents(buffer: &[u8]) -> Result<(), Box> { for pixel in resized_img.pixels() { use image::Pixel; let rgb = pixel.to_rgb(); - //print!("{}", rgb[0]); - context.frame_buffer[count] = (rgb[0], rgb[1], rgb[2]); + render_context.frame_buffer[count] = (rgb[0], rgb[1], rgb[2]); count += 1; } } @@ -287,8 +299,8 @@ pub fn view_contents(buffer: &[u8]) -> Result<(), Box> { let resized_img = image::imageops::resize( &img, - context.width as u32, - context.height as u32, + render_context.width as u32, + render_context.height as u32, image::FilterType::Lanczos3, ); @@ -297,7 +309,7 @@ pub fn view_contents(buffer: &[u8]) -> Result<(), Box> { use image::Pixel; let rgb = pixel.to_rgb(); //print!("{}", rgb[0]); - context.frame_buffer[count] = (rgb[0], rgb[1], rgb[2]); + render_context.frame_buffer[count] = (rgb[0], rgb[1], rgb[2]); count += 1; } } @@ -308,7 +320,7 @@ pub fn view_contents(buffer: &[u8]) -> Result<(), Box> { } } - context.flush()?; + render_context.flush()?; let cursor = cursor(); let _ = cursor.show(); @@ -319,7 +331,10 @@ pub fn view_contents(buffer: &[u8]) -> Result<(), Box> { Ok(()) } -pub fn view_contents_interactive(buffer: &[u8]) -> Result<(), Box> { +pub fn view_contents_interactive( + buffer: &[u8], + hires_mode: bool, +) -> Result<(), Box> { use rawkey::{KeyCode, RawKey}; let mut nes = neso::Nes::new(48000.0); @@ -329,7 +344,7 @@ pub fn view_contents_interactive(buffer: &[u8]) -> Result<(), Box Result<(), Box Result<(), Box, &[u8]>::from_raw(256, 240, slice).unwrap(); let resized_img = image::imageops::resize( &img, - context.width as u32, - context.height as u32, + render_context.width as u32, + render_context.height as u32, image::FilterType::Lanczos3, ); - context.clear(); + render_context.clear(); let mut count = 0; for pixel in resized_img.pixels() { use image::Pixel; let rgb = pixel.to_rgb(); - context.frame_buffer[count] = (rgb[0], rgb[1], rgb[2]); + render_context.frame_buffer[count] = (rgb[0], rgb[1], rgb[2]); count += 1; } - context.flush()?; + render_context.flush()?; if rawkey.is_pressed(rawkey::KeyCode::Escape) { break 'gameloop; From 1ecb4401baa5fd30539a9768d04a45ad3b89fc70 Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Tue, 16 Jul 2019 15:25:36 +1200 Subject: [PATCH 4/6] WIP --- src/lib.rs | 2 +- src/plugins/binaryview.rs | 37 ++++++++++++++++++------------------- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 4528be06b..05b39f57a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -32,4 +32,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, NamedType, PositionalType}; +pub use parser::registry::{Args, CommandConfig, NamedType, NamedValue, PositionalType}; diff --git a/src/plugins/binaryview.rs b/src/plugins/binaryview.rs index 4ed47d8bc..ea600d62c 100644 --- a/src/plugins/binaryview.rs +++ b/src/plugins/binaryview.rs @@ -14,7 +14,7 @@ impl BinaryView { impl Plugin for BinaryView { fn config(&mut self) -> Result { let mut named = IndexMap::new(); - named.insert("hires".to_string(), NamedType::Switch); + named.insert("--lores".to_string(), NamedType::Switch); Ok(CommandConfig { name: "binaryview".to_string(), positional: vec![], @@ -32,7 +32,7 @@ impl Plugin for BinaryView { item: Value::Binary(b), .. } => { - let _ = view_binary(&b, args.has("hires")); + let _ = view_binary(&b, args.has("lores")); } _ => {} } @@ -40,17 +40,17 @@ impl Plugin for BinaryView { } } -fn view_binary(b: &[u8], hires_mode: bool) -> Result<(), Box> { +fn view_binary(b: &[u8], lores_mode: bool) -> Result<(), Box> { if b.len() > 3 { match (b[0], b[1], b[2]) { (0x4e, 0x45, 0x53) => { - view_contents_interactive(b, hires_mode)?; + view_contents_interactive(b, lores_mode)?; return Ok(()); } _ => {} } } - view_contents(b, hires_mode)?; + view_contents(b, lores_mode)?; Ok(()) } @@ -59,17 +59,17 @@ pub struct RenderContext { pub height: usize, pub frame_buffer: Vec<(u8, u8, u8)>, pub since_last_button: Vec, - pub hires_mode: bool, + pub lores_mode: bool, } impl RenderContext { - pub fn blank(hires_mode: bool) -> RenderContext { + pub fn blank(lores_mode: bool) -> RenderContext { RenderContext { width: 0, height: 0, frame_buffer: vec![], since_last_button: vec![0; 8], - hires_mode, + lores_mode, } } pub fn clear(&mut self) { @@ -174,10 +174,10 @@ impl RenderContext { Ok(()) } pub fn flush(&mut self) -> Result<(), Box> { - if self.hires_mode { - self.render_to_screen_hires() - } else { + if self.lores_mode { self.render_to_screen_lores() + } else { + self.render_to_screen_hires() } } pub fn update(&mut self) -> Result<(), Box> { @@ -189,10 +189,10 @@ impl RenderContext { cursor.hide()?; self.width = terminal_size.0 as usize + 1; - self.height = if self.hires_mode { - terminal_size.1 as usize * 2 - } else { + self.height = if self.lores_mode { terminal_size.1 as usize + } else { + terminal_size.1 as usize * 2 }; } @@ -247,7 +247,7 @@ fn load_from_jpg_buffer(buffer: &[u8]) -> Option<(RawImageBuffer)> { }) } -pub fn view_contents(buffer: &[u8], hires_mode: bool) -> Result<(), Box> { +pub fn view_contents(buffer: &[u8], lores_mode: bool) -> Result<(), Box> { let mut raw_image_buffer = load_from_png_buffer(buffer); if raw_image_buffer.is_none() { @@ -261,7 +261,7 @@ pub fn view_contents(buffer: &[u8], hires_mode: bool) -> Result<(), Box Result<(), Box Result<(), Box Result<(), Box> { use rawkey::{KeyCode, RawKey}; @@ -344,7 +343,7 @@ pub fn view_contents_interactive( nes.reset(); if let Ok(_raw) = RawScreen::into_raw_mode() { - let mut render_context: RenderContext = RenderContext::blank(hires_mode); + let mut render_context: RenderContext = RenderContext::blank(lores_mode); let input = crossterm::input(); let _ = input.read_async(); let cursor = cursor(); From 3ebb6ba99119e146281647dc5269b8e480778d72 Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Tue, 16 Jul 2019 19:08:35 +1200 Subject: [PATCH 5/6] Fix plugin's commandconfig --- src/cli.rs | 18 ++++++-------- src/commands/macros.rs | 1 + src/commands/plugin.rs | 41 +++++++++++++++++++++++++++++++- src/lib.rs | 2 +- src/object/types.rs | 5 +--- src/parser/hir/baseline_parse.rs | 2 +- src/parser/parse/token_tree.rs | 16 ++++++------- src/parser/registry.rs | 5 ++-- src/plugins/binaryview.rs | 4 ++-- src/prelude.rs | 2 +- 10 files changed, 65 insertions(+), 31 deletions(-) diff --git a/src/cli.rs b/src/cli.rs index 03025ebec..6dc62aa18 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -6,6 +6,7 @@ use crate::commands::classified::{ }; use crate::commands::command::sink; use crate::commands::plugin::JsonRpc; +use crate::commands::plugin::{PluginCommand, PluginSink}; use crate::context::Context; crate use crate::errors::ShellError; use crate::evaluate::Scope; @@ -43,8 +44,6 @@ impl MaybeOwned<'a, T> { } fn load_plugin(path: &std::path::Path, context: &mut Context) -> Result<(), ShellError> { - use crate::commands::{command, plugin}; - let mut child = std::process::Command::new(path) .stdin(std::process::Stdio::piped()) .stdout(std::process::Stdio::piped()) @@ -70,20 +69,17 @@ 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); 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)), - )]); + let name = params.name.clone(); + context.add_commands(vec![Arc::new(PluginCommand::new( + name, fname, params, + ))]); 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)), - )]); + let name = params.name.clone(); + context.add_sinks(vec![Arc::new(PluginSink::new(name, fname, params))]); Ok(()) } else { Ok(()) diff --git a/src/commands/macros.rs b/src/commands/macros.rs index 97818df54..44a88c189 100644 --- a/src/commands/macros.rs +++ b/src/commands/macros.rs @@ -1,4 +1,5 @@ #[doc(hidden)] +#[allow(unused)] macro_rules! named_type { ($name:ident) => { $crate::parser::registry::NamedType::$($name)* diff --git a/src/commands/plugin.rs b/src/commands/plugin.rs index 3d9ecb5c5..a27f1944a 100644 --- a/src/commands/plugin.rs +++ b/src/commands/plugin.rs @@ -1,6 +1,7 @@ -use crate::commands::command::SinkCommandArgs; use crate::errors::ShellError; +use crate::parser::registry; use crate::prelude::*; +use derive_new::new; use serde::{self, Deserialize, Serialize}; use std::io::prelude::*; use std::io::BufReader; @@ -32,6 +33,44 @@ pub enum NuResult { }, } +#[derive(new)] +pub struct PluginCommand { + name: String, + path: String, + config: registry::CommandConfig, +} + +impl Command for PluginCommand { + fn run(&self, args: CommandArgs) -> Result { + filter_plugin(self.path.clone(), args) + } + fn name(&self) -> &str { + &self.name + } + fn config(&self) -> registry::CommandConfig { + self.config.clone() + } +} + +#[derive(new)] +pub struct PluginSink { + name: String, + path: String, + config: registry::CommandConfig, +} + +impl Sink for PluginSink { + fn run(&self, args: SinkCommandArgs) -> Result<(), ShellError> { + sink_plugin(self.path.clone(), args) + } + fn name(&self) -> &str { + &self.name + } + fn config(&self) -> registry::CommandConfig { + self.config.clone() + } +} + pub fn filter_plugin(path: String, args: CommandArgs) -> Result { let mut child = std::process::Command::new(path) .stdin(std::process::Stdio::piped()) diff --git a/src/lib.rs b/src/lib.rs index 05b39f57a..4528be06b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -32,4 +32,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, NamedType, NamedValue, PositionalType}; +pub use parser::registry::{Args, CommandConfig, NamedType, PositionalType}; diff --git a/src/object/types.rs b/src/object/types.rs index abc4b7e8f..0264a3376 100644 --- a/src/object/types.rs +++ b/src/object/types.rs @@ -54,9 +54,6 @@ impl ExtractType for Spanned { } } -#[derive(Debug)] -pub struct FilePath; - impl ExtractType for std::path::PathBuf { fn syntax_type() -> hir::SyntaxType { hir::SyntaxType::Path @@ -66,7 +63,7 @@ impl ExtractType for std::path::PathBuf { match &value { Spanned { item: Value::Primitive(Primitive::String(p)), - span, + .. } => Ok(PathBuf::from(p)), other => Err(ShellError::type_error("Path", other.spanned_type_name())), } diff --git a/src/parser/hir/baseline_parse.rs b/src/parser/hir/baseline_parse.rs index b4dc38458..02fa63f54 100644 --- a/src/parser/hir/baseline_parse.rs +++ b/src/parser/hir/baseline_parse.rs @@ -21,7 +21,7 @@ pub fn baseline_parse_token_as_string(token: &Token, source: &Text) -> hir::Expr } RawToken::Variable(span) => hir::Expression::variable(span, token.span), RawToken::Integer(_) => hir::Expression::bare(token.span), - RawToken::Size(int, unit) => hir::Expression::bare(token.span), + RawToken::Size(_, _) => hir::Expression::bare(token.span), RawToken::Bare => hir::Expression::bare(token.span), RawToken::String(span) => hir::Expression::string(span, token.span), } diff --git a/src/parser/parse/token_tree.rs b/src/parser/parse/token_tree.rs index 573b04c5a..b12bc3e33 100644 --- a/src/parser/parse/token_tree.rs +++ b/src/parser/parse/token_tree.rs @@ -102,15 +102,15 @@ impl TokenNode { pub fn type_name(&self) -> String { match self { TokenNode::Token(t) => t.type_name(), - TokenNode::Call(s) => "command", + TokenNode::Call(_) => "command", TokenNode::Delimited(d) => d.type_name(), - TokenNode::Pipeline(s) => "pipeline", - TokenNode::Operator(s) => "operator", - TokenNode::Flag(s) => "flag", - TokenNode::Member(s) => "member", - TokenNode::Whitespace(s) => "whitespace", - TokenNode::Error(s) => "error", - TokenNode::Path(s) => "path", + TokenNode::Pipeline(_) => "pipeline", + TokenNode::Operator(_) => "operator", + TokenNode::Flag(_) => "flag", + TokenNode::Member(_) => "member", + TokenNode::Whitespace(_) => "whitespace", + TokenNode::Error(_) => "error", + TokenNode::Path(_) => "path", } .to_string() } diff --git a/src/parser/registry.rs b/src/parser/registry.rs index 0d54f0429..7a15071cb 100644 --- a/src/parser/registry.rs +++ b/src/parser/registry.rs @@ -9,7 +9,7 @@ use serde::{Deserialize, Serialize}; use std::fmt; #[allow(unused)] -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize, Clone)] pub enum NamedType { Switch, Mandatory(SyntaxType), @@ -36,6 +36,7 @@ impl PositionalType { PositionalType::Mandatory(name.to_string(), SyntaxType::Block) } + #[allow(unused)] crate fn to_coerce_hint(&self) -> Option { match self { PositionalType::Mandatory(_, SyntaxType::Block) @@ -59,7 +60,7 @@ impl PositionalType { } } -#[derive(Debug, Getters, Serialize, Deserialize)] +#[derive(Debug, Getters, Serialize, Deserialize, Clone)] #[get = "crate"] pub struct CommandConfig { pub name: String, diff --git a/src/plugins/binaryview.rs b/src/plugins/binaryview.rs index ea600d62c..8c525f388 100644 --- a/src/plugins/binaryview.rs +++ b/src/plugins/binaryview.rs @@ -14,14 +14,14 @@ impl BinaryView { impl Plugin for BinaryView { fn config(&mut self) -> Result { let mut named = IndexMap::new(); - named.insert("--lores".to_string(), NamedType::Switch); + named.insert("lores".to_string(), NamedType::Switch); Ok(CommandConfig { name: "binaryview".to_string(), positional: vec![], is_filter: false, is_sink: true, named, - rest_positional: true, + rest_positional: false, }) } diff --git a/src/prelude.rs b/src/prelude.rs index 7316efada..509a0866a 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -34,7 +34,7 @@ macro_rules! trace_stream { crate use crate::cli::MaybeOwned; crate use crate::commands::command::{ - Command, CommandAction, CommandArgs, ReturnSuccess, ReturnValue, + Command, CommandAction, CommandArgs, ReturnSuccess, ReturnValue, Sink, SinkCommandArgs, }; crate use crate::context::Context; crate use crate::env::host::handle_unexpected; From c7abb31b7cfaaff3f64b5147ff7a3f38bdfb53ed Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Tue, 16 Jul 2019 19:25:48 +1200 Subject: [PATCH 6/6] Fix inc plugin --- src/parser/registry.rs | 8 ++++++++ src/plugins/inc.rs | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/parser/registry.rs b/src/parser/registry.rs index 7a15071cb..2e910ae96 100644 --- a/src/parser/registry.rs +++ b/src/parser/registry.rs @@ -32,6 +32,14 @@ impl PositionalType { PositionalType::Mandatory(name.to_string(), SyntaxType::Any) } + pub fn optional(name: &str, ty: SyntaxType) -> PositionalType { + PositionalType::Optional(name.to_string(), ty) + } + + pub fn optional_any(name: &str) -> PositionalType { + PositionalType::Optional(name.to_string(), SyntaxType::Any) + } + pub fn mandatory_block(name: &str) -> PositionalType { PositionalType::Mandatory(name.to_string(), SyntaxType::Block) } diff --git a/src/plugins/inc.rs b/src/plugins/inc.rs index 0e41d585b..faf5ccc2b 100644 --- a/src/plugins/inc.rs +++ b/src/plugins/inc.rs @@ -17,7 +17,7 @@ impl Plugin for Inc { fn config(&mut self) -> Result { Ok(CommandConfig { name: "inc".to_string(), - positional: vec![PositionalType::mandatory_any("Increment")], + positional: vec![PositionalType::optional_any("Increment")], is_filter: true, is_sink: false, named: IndexMap::new(),