From b6189879e31e17b8c41b21a46af1f5c337a1a117 Mon Sep 17 00:00:00 2001 From: Reilly Wood <26268125+rgwood@users.noreply.github.com> Date: Thu, 7 Sep 2023 08:34:08 -0700 Subject: [PATCH] explore: remove `:config`, `:show-config`, `:tweak` commands (#10259) More trimming of underused `explore` functionality. The `explore` command has subcommands that can be run like `:config` or `:try` or whatnot. This PR removes the `:config`, `:show-config`, and `:tweak` commands which are all for viewing+modifying config. These are interesting commands and they were cool experiments, but ultimately I don't think they fit with our plans for a simplified `explore`. They'd need a lot more polish if we want to keep them and I don't think we do. Happy to discuss if I've missed a good reason to keep these. cc @fdncred --- crates/nu-explore/src/commands/config.rs | 172 ------- crates/nu-explore/src/commands/config_show.rs | 180 -------- crates/nu-explore/src/commands/expand.rs | 4 - crates/nu-explore/src/commands/help.rs | 4 - crates/nu-explore/src/commands/mod.rs | 8 - crates/nu-explore/src/commands/nu.rs | 4 - crates/nu-explore/src/commands/table.rs | 68 --- crates/nu-explore/src/commands/try.rs | 4 - crates/nu-explore/src/commands/tweak.rs | 92 ---- crates/nu-explore/src/lib.rs | 32 +- crates/nu-explore/src/nu_common/mod.rs | 2 +- crates/nu-explore/src/nu_common/value.rs | 4 - crates/nu-explore/src/registry/command.rs | 4 - crates/nu-explore/src/views/configuration.rs | 427 ------------------ crates/nu-explore/src/views/mod.rs | 3 - crates/nu-explore/src/views/preview.rs | 4 - 16 files changed, 2 insertions(+), 1010 deletions(-) delete mode 100644 crates/nu-explore/src/commands/config.rs delete mode 100644 crates/nu-explore/src/commands/config_show.rs delete mode 100644 crates/nu-explore/src/commands/tweak.rs delete mode 100644 crates/nu-explore/src/views/configuration.rs diff --git a/crates/nu-explore/src/commands/config.rs b/crates/nu-explore/src/commands/config.rs deleted file mode 100644 index 1dde0f4493..0000000000 --- a/crates/nu-explore/src/commands/config.rs +++ /dev/null @@ -1,172 +0,0 @@ -use std::io::Result; - -use nu_protocol::{ - engine::{EngineState, Stack}, - record, Value, -}; - -use crate::{ - nu_common::{nu_str, NuSpan}, - registry::Command, - views::{configuration, ConfigurationView, Preview}, -}; - -use super::{default_color_list, ConfigOption, HelpManual, ViewCommand}; - -#[derive(Default, Clone)] -pub struct ConfigCmd { - commands: Vec, - groups: Vec, -} - -impl ConfigCmd { - pub const NAME: &'static str = "config"; - - pub fn from_commands(commands: Vec) -> Self { - Self { - commands, - groups: Vec::new(), - } - } - - pub fn register_group(&mut self, group: ConfigOption) { - self.groups.push(group); - } -} - -impl ViewCommand for ConfigCmd { - type View = ConfigurationView; - - fn name(&self) -> &'static str { - Self::NAME - } - - fn usage(&self) -> &'static str { - "" - } - - fn help(&self) -> Option { - let config_options = vec![ - ConfigOption::new( - ":config options", - "A border color of menus", - "config.border_color", - default_color_list(), - ), - ConfigOption::new( - ":config options", - "Set a color of entries in a list", - "config.list_color", - default_color_list(), - ), - ConfigOption::new( - ":config options", - "Set a color of a chosen entry in a list", - "config.cursor_color", - default_color_list(), - ), - ]; - - Some(HelpManual { - name: Self::NAME, - description: - "Interactive configuration manager.\nCan be used to set various explore settings.\n\nLike an interactive version of :tweak", - config_options, - arguments: vec![], - examples: vec![], - input: vec![], - }) - } - - fn parse(&mut self, _: &str) -> Result<()> { - Ok(()) - } - - fn display_config_option(&mut self, _: String, _: String, _: String) -> bool { - false - } - - fn spawn( - &mut self, - engine_state: &EngineState, - stack: &mut Stack, - _: Option, - ) -> Result { - let mut options = vec![]; - - let default_table = create_default_value(); - for cmd in &self.commands { - let cmd = match cmd { - Command::Reactive(_) => continue, - Command::View { cmd, .. } => cmd, - }; - - let help = match cmd.help() { - Some(help) => help, - None => continue, - }; - - for opt in help.config_options { - let mut values = vec![]; - for value in opt.values { - let mut cmd = cmd.clone(); - - let can_be_displayed = cmd.display_config_option( - opt.group.clone(), - opt.key.clone(), - value.example.to_string(), - ); - let view = if can_be_displayed { - cmd.spawn(engine_state, stack, Some(default_table.clone()))? - } else { - Box::new(Preview::new(&opt.description)) - }; - - let option = configuration::ConfigOption::new(value.example.to_string(), view); - values.push(option); - } - - let group = configuration::ConfigGroup::new(opt.key, values, opt.description); - options.push((opt.group, group)); - } - } - - for opt in &self.groups { - let mut values = vec![]; - for value in &opt.values { - let view = Box::new(Preview::new(&opt.description)); - - let option = configuration::ConfigOption::new(value.example.to_string(), view); - values.push(option); - } - - let group = - configuration::ConfigGroup::new(opt.key.clone(), values, opt.description.clone()); - options.push((opt.group.clone(), group)); - } - - options.sort_by(|(group1, opt1), (group2, opt2)| { - group1.cmp(group2).then(opt1.group().cmp(opt2.group())) - }); - - let options = options.into_iter().map(|(_, opt)| opt).collect(); - - Ok(ConfigurationView::new(options)) - } -} - -fn create_default_value() -> Value { - let span = NuSpan::unknown(); - - let record = |i: usize| { - Value::record( - record! { - "key" => nu_str(format!("key-{i}")), - "value" => nu_str(format!("{i}")), - }, - span, - ) - }; - - Value::list(vec![record(0), record(1), record(2)], span) -} diff --git a/crates/nu-explore/src/commands/config_show.rs b/crates/nu-explore/src/commands/config_show.rs deleted file mode 100644 index 4abc819cd3..0000000000 --- a/crates/nu-explore/src/commands/config_show.rs +++ /dev/null @@ -1,180 +0,0 @@ -use nu_protocol::{ - engine::{EngineState, Stack}, - record, Value, -}; -use ratatui::layout::Rect; -use std::collections::HashMap; -use std::io::Result; - -use crate::{ - nu_common::{try_build_table, NuSpan}, - pager::Frame, - util::map_into_value, - views::{Layout, Preview, View, ViewConfig}, -}; - -use super::{HelpExample, HelpManual, ViewCommand}; - -#[derive(Clone)] -pub struct ConfigShowCmd { - format: ConfigFormat, -} - -#[derive(Clone)] -enum ConfigFormat { - Table, - Nu, -} - -impl ConfigShowCmd { - pub fn new() -> Self { - ConfigShowCmd { - format: ConfigFormat::Table, - } - } -} - -impl ConfigShowCmd { - pub const NAME: &'static str = "config-show"; -} - -impl ViewCommand for ConfigShowCmd { - type View = ConfigView; - - fn name(&self) -> &'static str { - Self::NAME - } - - fn usage(&self) -> &'static str { - "" - } - - fn help(&self) -> Option { - Some(HelpManual { - name: Self::NAME, - description: - "Show the current `explore` configuration.\nSome default fields might be missing.", - arguments: vec![HelpExample::new("nu", "Use a nuon format instead")], - config_options: vec![], - input: vec![], - examples: vec![], - }) - } - - fn display_config_option(&mut self, _: String, _: String, _: String) -> bool { - false - } - - fn parse(&mut self, args: &str) -> Result<()> { - if args.trim() == "nu" { - self.format = ConfigFormat::Nu; - } - - Ok(()) - } - - fn spawn(&mut self, _: &EngineState, _: &mut Stack, _: Option) -> Result { - Ok(ConfigView { - preview: Preview::new(""), - format: self.format.clone(), - }) - } -} - -pub struct ConfigView { - preview: Preview, - format: ConfigFormat, -} - -impl View for ConfigView { - fn draw(&mut self, f: &mut Frame, area: Rect, cfg: ViewConfig<'_>, layout: &mut Layout) { - self.preview.draw(f, area, cfg, layout) - } - - fn handle_input( - &mut self, - engine_state: &EngineState, - stack: &mut Stack, - layout: &Layout, - info: &mut crate::pager::ViewInfo, - key: crossterm::event::KeyEvent, - ) -> Option { - self.preview - .handle_input(engine_state, stack, layout, info, key) - } - - fn setup(&mut self, config: ViewConfig<'_>) { - let text = self.create_output_string(config); - - self.preview = Preview::new(&text); - self.preview - .set_value(map_into_value(config.config.clone())); - } - - fn exit(&mut self) -> Option { - self.preview.exit() - } - - fn collect_data(&self) -> Vec { - self.preview.collect_data() - } - - fn show_data(&mut self, i: usize) -> bool { - self.preview.show_data(i) - } -} - -impl ConfigView { - fn create_output_string(&mut self, config: ViewConfig) -> String { - match self.format { - ConfigFormat::Table => { - let mut m = config.config.clone(); - convert_styles(&mut m); - - let value = map_into_value(m); - try_build_table(None, config.nu_config, config.style_computer, value) - } - ConfigFormat::Nu => nu_json::to_string(&config.config).unwrap_or_default(), - } - } -} - -fn convert_styles(m: &mut HashMap) { - for value in m.values_mut() { - convert_styles_value(value); - } -} - -fn convert_styles_value(value: &mut Value) { - match value { - Value::String { val, .. } => { - if let Some(v) = convert_style_from_string(val) { - *value = v; - } - } - Value::List { vals, .. } => { - for value in vals { - convert_styles_value(value); - } - } - Value::Record { val, .. } => { - for value in &mut val.vals { - convert_styles_value(value); - } - } - _ => (), - } -} - -fn convert_style_from_string(s: &str) -> Option { - let style = nu_json::from_str::(s).ok()?; - - Some(Value::record( - record! { - "bg" => Value::string(style.bg.unwrap_or_default(), NuSpan::unknown()), - "fg" => Value::string(style.fg.unwrap_or_default(), NuSpan::unknown()), - "attr" => Value::string(style.attr.unwrap_or_default(), NuSpan::unknown()), - }, - NuSpan::unknown(), - )) -} diff --git a/crates/nu-explore/src/commands/expand.rs b/crates/nu-explore/src/commands/expand.rs index 6a50fdc567..faab60e41c 100644 --- a/crates/nu-explore/src/commands/expand.rs +++ b/crates/nu-explore/src/commands/expand.rs @@ -60,10 +60,6 @@ impl ViewCommand for ExpandCmd { }) } - fn display_config_option(&mut self, _: String, _: String, _: String) -> bool { - false - } - fn parse(&mut self, _: &str) -> Result<()> { Ok(()) } diff --git a/crates/nu-explore/src/commands/help.rs b/crates/nu-explore/src/commands/help.rs index 46ae961301..55e15ddb36 100644 --- a/crates/nu-explore/src/commands/help.rs +++ b/crates/nu-explore/src/commands/help.rs @@ -104,10 +104,6 @@ impl ViewCommand for HelpCmd { }) } - fn display_config_option(&mut self, _: String, _: String, _: String) -> bool { - false - } - fn parse(&mut self, args: &str) -> Result<()> { self.input_command = args.trim().to_owned(); diff --git a/crates/nu-explore/src/commands/mod.rs b/crates/nu-explore/src/commands/mod.rs index 19ac9a13e9..3f58e70a0f 100644 --- a/crates/nu-explore/src/commands/mod.rs +++ b/crates/nu-explore/src/commands/mod.rs @@ -13,19 +13,13 @@ mod nu; mod quit; mod table; mod r#try; -mod tweak; -pub mod config; -mod config_show; - -pub use config_show::ConfigShowCmd; pub use expand::ExpandCmd; pub use help::HelpCmd; pub use nu::NuCmd; pub use quit::QuitCmd; pub use r#try::TryCmd; pub use table::TableCmd; -pub use tweak::TweakCmd; pub trait SimpleCommand { fn name(&self) -> &'static str; @@ -56,8 +50,6 @@ pub trait ViewCommand { fn parse(&mut self, args: &str) -> Result<()>; - fn display_config_option(&mut self, group: String, key: String, value: String) -> bool; - fn spawn( &mut self, engine_state: &EngineState, diff --git a/crates/nu-explore/src/commands/nu.rs b/crates/nu-explore/src/commands/nu.rs index ad8a655ab2..b36c009d25 100644 --- a/crates/nu-explore/src/commands/nu.rs +++ b/crates/nu-explore/src/commands/nu.rs @@ -64,10 +64,6 @@ impl ViewCommand for NuCmd { }) } - fn display_config_option(&mut self, _: String, _: String, _: String) -> bool { - false - } - fn parse(&mut self, args: &str) -> Result<()> { self.command = args.trim().to_owned(); diff --git a/crates/nu-explore/src/commands/table.rs b/crates/nu-explore/src/commands/table.rs index 3eeff9ee90..7ebcde3eb5 100644 --- a/crates/nu-explore/src/commands/table.rs +++ b/crates/nu-explore/src/commands/table.rs @@ -1,7 +1,6 @@ use std::io::Result; use nu_ansi_term::Style; -use nu_color_config::lookup_ansi_color_style; use nu_protocol::{ engine::{EngineState, Stack}, Value, @@ -122,51 +121,6 @@ impl ViewCommand for TableCmd { }) } - fn display_config_option(&mut self, _group: String, key: String, value: String) -> bool { - match key.as_str() { - "table.orientation" => self.settings.orientation = orientation_from_str(&value), - "table.line_head_top" => self.settings.line_head_top = bool_from_str(&value), - "table.line_head_bottom" => self.settings.line_head_bottom = bool_from_str(&value), - "table.line_shift" => self.settings.line_shift = bool_from_str(&value), - "table.line_index" => self.settings.line_index = bool_from_str(&value), - "table.show_cursor" => { - self.settings.show_cursor = bool_from_str(&value); - self.settings.turn_on_cursor_mode = true; - } - "table.split_line" => { - self.settings.split_line_s = Some(lookup_ansi_color_style(&value)); - self.settings.turn_on_cursor_mode = true; - } - "table.selected_cell" => { - self.settings.selected_cell_s = Some(lookup_ansi_color_style(&value)); - self.settings.turn_on_cursor_mode = true; - } - "table.selected_row" => { - self.settings.selected_row_s = Some(lookup_ansi_color_style(&value)); - self.settings.turn_on_cursor_mode = true; - } - "table.selected_column" => { - self.settings.selected_column_s = Some(lookup_ansi_color_style(&value)); - self.settings.turn_on_cursor_mode = true; - } - "table.padding_column_left" => { - self.settings.padding_column_left = usize_from_str(&value); - } - "table.padding_column_right" => { - self.settings.padding_column_right = usize_from_str(&value); - } - "table.padding_index_left" => { - self.settings.padding_index_left = usize_from_str(&value); - } - "table.padding_index_right" => { - self.settings.padding_index_right = usize_from_str(&value); - } - _ => return false, - } - - true - } - fn parse(&mut self, _: &str) -> Result<()> { Ok(()) } @@ -257,25 +211,3 @@ impl ViewCommand for TableCmd { Ok(view) } } - -fn bool_from_str(s: &str) -> Option { - match s { - "true" => Some(true), - "false" => Some(false), - _ => None, - } -} - -fn usize_from_str(s: &str) -> Option { - s.parse::().ok() -} - -fn orientation_from_str(s: &str) -> Option { - match s { - "left" => Some(Orientation::Left), - "right" => Some(Orientation::Right), - "top" => Some(Orientation::Top), - "bottom" => Some(Orientation::Bottom), - _ => None, - } -} diff --git a/crates/nu-explore/src/commands/try.rs b/crates/nu-explore/src/commands/try.rs index 48661201b2..5d8016831a 100644 --- a/crates/nu-explore/src/commands/try.rs +++ b/crates/nu-explore/src/commands/try.rs @@ -67,10 +67,6 @@ impl ViewCommand for TryCmd { }) } - fn display_config_option(&mut self, _: String, _: String, _: String) -> bool { - false - } - fn parse(&mut self, args: &str) -> Result<()> { self.command = args.trim().to_owned(); diff --git a/crates/nu-explore/src/commands/tweak.rs b/crates/nu-explore/src/commands/tweak.rs deleted file mode 100644 index c0e392cecd..0000000000 --- a/crates/nu-explore/src/commands/tweak.rs +++ /dev/null @@ -1,92 +0,0 @@ -use std::io::{self, Result}; - -use nu_protocol::{ - engine::{EngineState, Stack}, - Value, -}; - -use crate::{ - nu_common::NuSpan, - pager::{Pager, Transition}, -}; - -use super::{HelpExample, HelpManual, SimpleCommand}; - -#[derive(Default, Clone)] -pub struct TweakCmd { - path: Vec, - value: Value, -} - -impl TweakCmd { - pub const NAME: &'static str = "tweak"; -} - -impl SimpleCommand for TweakCmd { - fn name(&self) -> &'static str { - Self::NAME - } - - fn usage(&self) -> &'static str { - "" - } - - fn help(&self) -> Option { - Some(HelpManual { - name: "tweak", - description: "Set `explore` settings.\nLike a non-interactive version of :config", - arguments: vec![], - examples: vec![ - HelpExample::new(":tweak table.show_index false", "Don't show index anymore"), - HelpExample::new(":tweak table.show_head false", "Don't show header anymore"), - HelpExample::new( - ":tweak try.border_color {bg: '#FFFFFF', fg: '#F213F1'}", - "Make a different color for borders in :try", - ), - ], - config_options: vec![], - input: vec![], - }) - } - - fn parse(&mut self, input: &str) -> Result<()> { - let input = input.trim(); - - let args = input.split_once(' '); - let (key, value) = args.ok_or_else(|| { - io::Error::new( - io::ErrorKind::Other, - "expected to get 2 arguments 'key value'", - ) - })?; - - self.value = parse_value(value); - - self.path = key - .split_terminator('.') - .map(|s| s.to_string()) - .collect::>(); - - Ok(()) - } - - fn react( - &mut self, - _: &EngineState, - _: &mut Stack, - p: &mut Pager<'_>, - _: Option, - ) -> Result { - p.set_config(&self.path, self.value.clone()); - - Ok(Transition::Ok) - } -} - -fn parse_value(value: &str) -> Value { - match value { - "true" => Value::bool(true, NuSpan::unknown()), - "false" => Value::bool(false, NuSpan::unknown()), - s => Value::string(s.to_owned(), NuSpan::unknown()), - } -} diff --git a/crates/nu-explore/src/lib.rs b/crates/nu-explore/src/lib.rs index f929d340ac..79c715278b 100644 --- a/crates/nu-explore/src/lib.rs +++ b/crates/nu-explore/src/lib.rs @@ -11,10 +11,7 @@ pub use explore::Explore; use std::io; -use commands::{ - config::ConfigCmd, default_color_list, ConfigOption, ConfigShowCmd, ExpandCmd, HelpCmd, - HelpManual, NuCmd, QuitCmd, TableCmd, TryCmd, TweakCmd, -}; +use commands::{ExpandCmd, HelpCmd, HelpManual, NuCmd, QuitCmd, TableCmd, TryCmd}; use nu_common::{collect_pipeline, has_simple_value, CtrlC}; use nu_protocol::{ engine::{EngineState, Stack}, @@ -96,10 +93,8 @@ fn create_command_registry() -> CommandRegistry { let aliases = registry.get_aliases().collect::>(); let help_cmd = create_help_command(&commands, &aliases); - let config_cmd = create_config_command(&commands); registry.register_command_view(help_cmd, true); - registry.register_command_view(config_cmd, true); registry } @@ -110,12 +105,9 @@ fn create_commands(registry: &mut CommandRegistry) { registry.register_command_view(ExpandCmd::new(), true); registry.register_command_view(TryCmd::new(), true); - registry.register_command_view(ConfigShowCmd::new(), true); - registry.register_command_view(ConfigCmd::default(), true); registry.register_command_view(HelpCmd::default(), true); registry.register_command_reactive(QuitCmd); - registry.register_command_reactive(TweakCmd::default()); } fn create_aliases(registry: &mut CommandRegistry) { @@ -125,28 +117,6 @@ fn create_aliases(registry: &mut CommandRegistry) { registry.create_aliases("q!", QuitCmd::NAME); } -#[rustfmt::skip] -fn create_config_command(commands: &[Command]) -> ConfigCmd { - const GROUP: &str = "Explore configuration"; - - let mut config = ConfigCmd::from_commands(commands.to_vec()); - - config.register_group(ConfigOption::new(GROUP, "Status bar information color", "status.info", default_color_list())); - config.register_group(ConfigOption::new(GROUP, "Status bar success color", "status.success", default_color_list())); - config.register_group(ConfigOption::new(GROUP, "Status bar warning color", "status.warn", default_color_list())); - config.register_group(ConfigOption::new(GROUP, "Status bar error color", "status.error", default_color_list())); - - config.register_group(ConfigOption::new(GROUP, "Status bar default text color", "status_bar_text", default_color_list())); - config.register_group(ConfigOption::new(GROUP, "Status bar background", "status_bar_background", default_color_list())); - - config.register_group(ConfigOption::new(GROUP, "Command bar text color", "command_bar_text", default_color_list())); - config.register_group(ConfigOption::new(GROUP, "Command bar background", "command_bar_background", default_color_list())); - - config.register_group(ConfigOption::new(GROUP, "Highlight color in search", "highlight", default_color_list())); - - config -} - fn create_help_command(commands: &[Command], aliases: &[(&str, &str)]) -> HelpCmd { let help_manuals = create_help_manuals(commands); diff --git a/crates/nu-explore/src/nu_common/mod.rs b/crates/nu-explore/src/nu_common/mod.rs index fbf47c2fc6..1808512985 100644 --- a/crates/nu-explore/src/nu_common/mod.rs +++ b/crates/nu-explore/src/nu_common/mod.rs @@ -19,7 +19,7 @@ pub use command::{is_ignored_command, run_command_with_value, run_nu_command}; pub use lscolor::{create_lscolors, lscolorize}; pub use string::{string_width, truncate_str}; pub use table::try_build_table; -pub use value::{collect_input, collect_pipeline, create_map, map_into_value, nu_str}; +pub use value::{collect_input, collect_pipeline, create_map, map_into_value}; pub fn has_simple_value(data: &[Vec]) -> Option<&Value> { if data.len() == 1 diff --git a/crates/nu-explore/src/nu_common/value.rs b/crates/nu-explore/src/nu_common/value.rs index 167cb44cdf..86f8896e64 100644 --- a/crates/nu-explore/src/nu_common/value.rs +++ b/crates/nu-explore/src/nu_common/value.rs @@ -194,10 +194,6 @@ pub fn map_into_value(hm: HashMap) -> Value { Value::record(hm.into_iter().collect(), NuSpan::unknown()) } -pub fn nu_str>(s: S) -> Value { - Value::string(s.as_ref().to_owned(), NuSpan::unknown()) -} - fn unknown_error_value() -> Value { Value::string(String::from("❎"), NuSpan::unknown()) } diff --git a/crates/nu-explore/src/registry/command.rs b/crates/nu-explore/src/registry/command.rs index 644a74fc03..ce06fb17d1 100644 --- a/crates/nu-explore/src/registry/command.rs +++ b/crates/nu-explore/src/registry/command.rs @@ -72,10 +72,6 @@ where self.0.help() } - fn display_config_option(&mut self, group: String, key: String, value: String) -> bool { - self.0.display_config_option(group, key, value) - } - fn parse(&mut self, args: &str) -> std::io::Result<()> { self.0.parse(args) } diff --git a/crates/nu-explore/src/views/configuration.rs b/crates/nu-explore/src/views/configuration.rs deleted file mode 100644 index b1c8212d4e..0000000000 --- a/crates/nu-explore/src/views/configuration.rs +++ /dev/null @@ -1,427 +0,0 @@ -use std::{cmp::Ordering, fmt::Debug, ptr::addr_of}; - -use crossterm::event::{KeyCode, KeyEvent}; -use nu_color_config::get_color_map; -use nu_protocol::{ - engine::{EngineState, Stack}, - Value, -}; -use nu_table::TextStyle; -use ratatui::{ - layout::Rect, - style::Style, - widgets::{BorderType, Borders, Paragraph}, -}; - -use crate::{ - nu_common::{truncate_str, NuText}, - pager::{Frame, Transition, ViewInfo}, - util::create_map, - views::util::nu_style_to_tui, -}; - -use super::{cursor::WindowCursor, Layout, View, ViewConfig}; - -#[derive(Debug, Default)] -pub struct ConfigurationView { - options: Vec, - peeked_cursor: Option, - cursor: WindowCursor, - border_color: Style, - cursor_color: Style, - list_color: Style, -} - -impl ConfigurationView { - pub fn new(options: Vec) -> Self { - let cursor = WindowCursor::new(options.len(), options.len()).expect("..."); - - Self { - options, - cursor, - peeked_cursor: None, - border_color: Style::default(), - cursor_color: Style::default(), - list_color: Style::default(), - } - } - - fn update_cursors(&mut self, height: usize) { - self.cursor.set_window(height); - - if let Some(cursor) = &mut self.peeked_cursor { - cursor.set_window(height); - } - } - - fn render_option_list( - &mut self, - f: &mut Frame, - area: Rect, - list_color: Style, - cursor_color: Style, - layout: &mut Layout, - ) { - let (data, data_c) = match self.peeked_cursor { - Some(cursor) => { - let i = self.cursor.index(); - let opt = &self.options[i]; - let data = opt - .options - .iter() - .map(|e| e.name.clone()) - .collect::>(); - - (data, cursor) - } - None => { - let data = self - .options - .iter() - .map(|o| o.group.clone()) - .collect::>(); - - (data, self.cursor) - } - }; - - render_list(f, area, &data, data_c, list_color, cursor_color, layout); - } - - fn peek_current(&self) -> Option<(&ConfigGroup, &ConfigOption)> { - let cursor = match self.peeked_cursor { - Some(cursor) => cursor, - None => return None, - }; - - let i = self.cursor.index(); - let j = cursor.index(); - let group = &self.options[i]; - let opt = &group.options[j]; - - Some((group, opt)) - } - - fn peek_current_group(&self) -> &ConfigGroup { - let i = self.cursor.index(); - &self.options[i] - } - - fn peek_current_opt(&mut self) -> Option<&mut ConfigOption> { - let cursor = match self.peeked_cursor { - Some(cursor) => cursor, - None => return None, - }; - - let i = self.cursor.index(); - let j = cursor.index(); - - Some(&mut self.options[i].options[j]) - } - - fn get_cursor_mut(&mut self) -> &mut WindowCursor { - self.peeked_cursor.as_mut().unwrap_or(&mut self.cursor) - } -} - -#[derive(Debug, Default)] -pub struct ConfigGroup { - group: String, - description: String, - options: Vec, -} - -impl ConfigGroup { - pub fn new(group: String, options: Vec, description: String) -> Self { - Self { - group, - options, - description, - } - } - - pub fn group(&self) -> &str { - self.group.as_ref() - } -} - -pub struct ConfigOption { - name: String, - view: Box, -} - -impl ConfigOption { - pub fn new(name: String, view: Box) -> Self { - Self { name, view } - } -} - -impl Debug for ConfigOption { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("ConfigOption") - .field("name", &self.name) - .field("view", &addr_of!(self.view)) - .finish() - } -} - -impl View for ConfigurationView { - fn draw(&mut self, f: &mut Frame, area: Rect, cfg: ViewConfig<'_>, layout: &mut Layout) { - const LEFT_PADDING: u16 = 1; - const BLOCK_PADDING: u16 = 1; - const OPTION_BLOCK_WIDTH: u16 = 30; - const USED_HEIGHT_BY_BORDERS: u16 = 2; - - if area.width < 40 { - return; - } - - let list_color = self.list_color; - let border_color = self.border_color; - let cursor_color = self.cursor_color; - - let height = area.height - USED_HEIGHT_BY_BORDERS; - - let option_b_x1 = area.x + LEFT_PADDING; - let option_b_x2 = area.x + LEFT_PADDING + OPTION_BLOCK_WIDTH; - - let view_b_x1 = option_b_x2 + BLOCK_PADDING; - let view_b_w = area.width - (LEFT_PADDING + BLOCK_PADDING + OPTION_BLOCK_WIDTH); - - let option_content_x1 = option_b_x1 + 1; - let option_content_w = OPTION_BLOCK_WIDTH - 2; - let option_content_h = height; - - let option_content_area = - Rect::new(option_content_x1, 1, option_content_w, option_content_h); - - let view_content_x1 = view_b_x1 + 1; - let view_content_w = view_b_w - 2; - let view_content_h = height; - - let view_content_area = Rect::new(view_content_x1, 1, view_content_w, view_content_h); - - let option_block = ratatui::widgets::Block::default() - .borders(Borders::ALL) - .border_type(BorderType::Plain) - .border_style(border_color); - let option_area = Rect::new(option_b_x1, area.y, OPTION_BLOCK_WIDTH, area.height); - - let view_block = ratatui::widgets::Block::default() - .borders(Borders::ALL) - .border_type(BorderType::Plain) - .border_style(border_color); - let view_area = Rect::new(view_b_x1, area.y, view_b_w, area.height); - - f.render_widget(option_block, option_area); - f.render_widget(view_block, view_area); - - self.render_option_list(f, option_content_area, list_color, cursor_color, layout); - - if let Some(opt) = self.peek_current_opt() { - let mut layout = Layout::default(); - opt.view.draw(f, view_content_area, cfg, &mut layout); - } else { - let group = self.peek_current_group(); - let description = &group.description; - - f.render_widget(Paragraph::new(description.as_str()), view_content_area); - } - - self.update_cursors(height as usize); - } - - fn handle_input( - &mut self, - _: &EngineState, - _: &mut Stack, - _: &Layout, - _: &mut ViewInfo, - key: KeyEvent, - ) -> Option { - match key.code { - KeyCode::Esc => { - if self.peeked_cursor.is_some() { - self.peeked_cursor = None; - Some(Transition::Ok) - } else { - Some(Transition::Exit) - } - } - KeyCode::Up => { - let cursor = self.get_cursor_mut(); - cursor.prev(1); - - Some(transition_tweak_if(self)) - } - KeyCode::Down => { - let cursor = self.get_cursor_mut(); - cursor.next(1); - - Some(transition_tweak_if(self)) - } - KeyCode::PageUp => { - let cursor = self.get_cursor_mut(); - cursor.prev_window(); - - Some(transition_tweak_if(self)) - } - KeyCode::PageDown => { - let cursor = self.get_cursor_mut(); - cursor.next_window(); - - Some(transition_tweak_if(self)) - } - KeyCode::Home => { - let cursor = self.get_cursor_mut(); - cursor.prev(cursor.index()); - - Some(transition_tweak_if(self)) - } - KeyCode::End => { - let cursor = self.get_cursor_mut(); - cursor.next(cursor.cap()); - - Some(transition_tweak_if(self)) - } - KeyCode::Enter => { - if self.peeked_cursor.is_some() { - return Some(Transition::Ok); - } - - self.peeked_cursor = Some(WindowCursor::default()); - let length = self.peek_current().expect("...").0.options.len(); - self.peeked_cursor = WindowCursor::new(length, length); - - let (group, opt) = self.peek_current().expect("..."); - - Some(Transition::Cmd(build_tweak_cmd(group, opt))) - } - _ => None, - } - } - - fn exit(&mut self) -> Option { - None - } - - fn collect_data(&self) -> Vec { - if self.peeked_cursor.is_some() { - let i = self.cursor.index(); - let opt = &self.options[i]; - opt.options - .iter() - .map(|e| (e.name.clone(), TextStyle::default())) - .collect::>() - } else { - self.options - .iter() - .map(|s| (s.group.to_string(), TextStyle::default())) - .collect() - } - } - - fn show_data(&mut self, i: usize) -> bool { - if let Some(c) = &mut self.peeked_cursor { - let i = self.cursor.index(); - if i > self.options[i].options.len() { - return false; - } - - loop { - let p = c.index(); - match i.cmp(&p) { - Ordering::Equal => return true, - Ordering::Less => c.prev(1), - Ordering::Greater => c.next(1), - }; - } - } else { - if i > self.options.len() { - return false; - } - - loop { - let p = self.cursor.index(); - match i.cmp(&p) { - Ordering::Equal => return true, - Ordering::Less => self.cursor.prev(1), - Ordering::Greater => self.cursor.next(1), - }; - } - } - } - - fn setup(&mut self, config: ViewConfig<'_>) { - if let Some(hm) = config.config.get("config").and_then(create_map) { - let colors = get_color_map(&hm); - - if let Some(style) = colors.get("border_color").copied() { - self.border_color = nu_style_to_tui(style); - } - - if let Some(style) = colors.get("cursor_color").copied() { - self.cursor_color = nu_style_to_tui(style); - } - - if let Some(style) = colors.get("list_color").copied() { - self.list_color = nu_style_to_tui(style); - } - } - - for group in &mut self.options { - for opt in &mut group.options { - opt.view.setup(config); - } - } - } -} - -fn build_tweak_cmd(group: &ConfigGroup, opt: &ConfigOption) -> String { - format!("tweak {} {}", group.group(), opt.name) -} - -fn render_list( - f: &mut Frame, - area: Rect, - data: &[String], - cursor: WindowCursor, - not_picked_s: Style, - picked_s: Style, - layout: &mut Layout, -) { - let height = area.height as usize; - let width = area.width as usize; - - let mut data = &data[cursor.starts_at()..]; - if data.len() > height { - data = &data[..height]; - } - - let selected_row = cursor.offset(); - - for (i, name) in data.iter().enumerate() { - let mut name = name.to_owned(); - truncate_str(&mut name, width); - - let area = Rect::new(area.x, area.y + i as u16, area.width, 1); - - let mut text = Paragraph::new(name.clone()); - - if i == selected_row { - text = text.style(picked_s); - } else { - text = text.style(not_picked_s); - } - - f.render_widget(text, area); - - layout.push(&name, area.x, area.y, area.width, 1); - } -} - -fn transition_tweak_if(view: &ConfigurationView) -> Transition { - view.peek_current().map_or(Transition::Ok, |(group, opt)| { - Transition::Cmd(build_tweak_cmd(group, opt)) - }) -} diff --git a/crates/nu-explore/src/views/mod.rs b/crates/nu-explore/src/views/mod.rs index 411ae4b966..a94d6cde1b 100644 --- a/crates/nu-explore/src/views/mod.rs +++ b/crates/nu-explore/src/views/mod.rs @@ -22,9 +22,6 @@ use super::{ pager::{Frame, Transition, ViewInfo}, }; -pub mod configuration; - -pub use configuration::ConfigurationView; pub use information::InformationView; pub use interactive::InteractiveView; pub use preview::Preview; diff --git a/crates/nu-explore/src/views/preview.rs b/crates/nu-explore/src/views/preview.rs index cfff9ee5f7..5fdf6159fc 100644 --- a/crates/nu-explore/src/views/preview.rs +++ b/crates/nu-explore/src/views/preview.rs @@ -37,10 +37,6 @@ impl Preview { underlying_value: None, } } - - pub fn set_value(&mut self, value: Value) { - self.underlying_value = Some(value); - } } impl View for Preview {