From 846a048bba86c01e3c8746de594c1bff26ce829b Mon Sep 17 00:00:00 2001 From: Fernando Herrera Date: Fri, 21 Jan 2022 08:59:29 +0000 Subject: [PATCH] menu-performance (#793) --- Cargo.lock | 2 +- crates/nu-cli/Cargo.toml | 2 +- crates/nu-cli/src/prompt.rs | 10 ++++++++-- src/prompt_update.rs | 14 +++++++++++--- src/reedline_config.rs | 21 ++++++++++++++++----- 5 files changed, 37 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 87f0156db2..01a7c43d08 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2863,7 +2863,7 @@ dependencies = [ [[package]] name = "reedline" version = "0.2.0" -source = "git+https://github.com/nushell/reedline?branch=main#cd3516c0d5d0825d6942eff926652003f9c8138d" +source = "git+https://github.com/nushell/reedline?branch=main#180d3dd6c4c1982169f84083a29a1a2606b30d60" dependencies = [ "chrono", "crossterm", diff --git a/crates/nu-cli/Cargo.toml b/crates/nu-cli/Cargo.toml index 44496983e1..99e55ee6ee 100644 --- a/crates/nu-cli/Cargo.toml +++ b/crates/nu-cli/Cargo.toml @@ -16,4 +16,4 @@ miette = { version = "3.0.0", features = ["fancy"] } thiserror = "1.0.29" reedline = { git = "https://github.com/nushell/reedline", branch = "main" } log = "0.4" -is_executable = "1.0.1" \ No newline at end of file +is_executable = "1.0.1" diff --git a/crates/nu-cli/src/prompt.rs b/crates/nu-cli/src/prompt.rs index b5b320d692..fcc181bc12 100644 --- a/crates/nu-cli/src/prompt.rs +++ b/crates/nu-cli/src/prompt.rs @@ -15,6 +15,7 @@ pub struct NushellPrompt { default_prompt_indicator: String, default_vi_insert_prompt_indicator: String, default_vi_visual_prompt_indicator: String, + default_menu_prompt_indicator: String, default_multiline_indicator: String, } @@ -32,6 +33,7 @@ impl NushellPrompt { default_prompt_indicator: "〉".to_string(), default_vi_insert_prompt_indicator: ": ".to_string(), default_vi_visual_prompt_indicator: "v ".to_string(), + default_menu_prompt_indicator: "| ".to_string(), default_multiline_indicator: "::: ".to_string(), } } @@ -65,16 +67,19 @@ impl NushellPrompt { left_prompt_string: Option, right_prompt_string: Option, prompt_indicator_string: String, - prompt_vi_insert_string: String, - prompt_vi_visual_string: String, + prompt_indicator_menu: String, prompt_multiline_indicator_string: String, + prompt_vi: (String, String), ) { + let (prompt_vi_insert_string, prompt_vi_visual_string) = prompt_vi; + self.left_prompt_string = left_prompt_string; self.right_prompt_string = right_prompt_string; self.default_prompt_indicator = prompt_indicator_string; self.default_vi_insert_prompt_indicator = prompt_vi_insert_string; self.default_vi_visual_prompt_indicator = prompt_vi_visual_string; self.default_multiline_indicator = prompt_multiline_indicator_string; + self.default_menu_prompt_indicator = prompt_indicator_menu; } fn default_wrapped_custom_string(&self, str: String) -> String { @@ -111,6 +116,7 @@ impl Prompt for NushellPrompt { PromptViMode::Visual => self.default_vi_visual_prompt_indicator.as_str().into(), }, PromptEditMode::Custom(str) => self.default_wrapped_custom_string(str).into(), + PromptEditMode::Menu => self.default_menu_prompt_indicator.as_str().into(), } } diff --git a/src/prompt_update.rs b/src/prompt_update.rs index d7e1be08d1..b781d22d34 100644 --- a/src/prompt_update.rs +++ b/src/prompt_update.rs @@ -13,13 +13,14 @@ pub(crate) const PROMPT_COMMAND_RIGHT: &str = "PROMPT_COMMAND_RIGHT"; pub(crate) const PROMPT_INDICATOR: &str = "PROMPT_INDICATOR"; pub(crate) const PROMPT_INDICATOR_VI_INSERT: &str = "PROMPT_INDICATOR_VI_INSERT"; pub(crate) const PROMPT_INDICATOR_VI_VISUAL: &str = "PROMPT_INDICATOR_VI_VISUAL"; +pub(crate) const PROMPT_INDICATOR_MENU: &str = "PROMPT_INDICATOR_MENU"; pub(crate) const PROMPT_MULTILINE_INDICATOR: &str = "PROMPT_MULTILINE_INDICATOR"; pub(crate) fn get_prompt_indicators( config: &Config, engine_state: &EngineState, stack: &Stack, -) -> (String, String, String, String) { +) -> (String, String, String, String, String) { let prompt_indicator = match stack.get_env_var(engine_state, PROMPT_INDICATOR) { Some(pi) => pi.into_string("", config), None => "〉".to_string(), @@ -35,6 +36,11 @@ pub(crate) fn get_prompt_indicators( None => "v ".to_string(), }; + let prompt_menu = match stack.get_env_var(engine_state, PROMPT_INDICATOR_MENU) { + Some(pm) => pm.into_string("", config), + None => "| ".to_string(), + }; + let prompt_multiline = match stack.get_env_var(engine_state, PROMPT_MULTILINE_INDICATOR) { Some(pm) => pm.into_string("", config), None => "::: ".to_string(), @@ -44,6 +50,7 @@ pub(crate) fn get_prompt_indicators( prompt_indicator, prompt_vi_insert, prompt_vi_visual, + prompt_menu, prompt_multiline, ) } @@ -94,6 +101,7 @@ pub(crate) fn update_prompt<'prompt>( prompt_indicator_string, prompt_vi_insert_string, prompt_vi_visual_string, + prompt_indicator_menu, prompt_multiline_string, ) = get_prompt_indicators(config, engine_state, stack); @@ -104,9 +112,9 @@ pub(crate) fn update_prompt<'prompt>( get_prompt_string(PROMPT_COMMAND, config, engine_state, &mut stack), get_prompt_string(PROMPT_COMMAND_RIGHT, config, engine_state, &mut stack), prompt_indicator_string, - prompt_vi_insert_string, - prompt_vi_visual_string, + prompt_indicator_menu, prompt_multiline_string, + (prompt_vi_insert_string, prompt_vi_visual_string), ); nu_prompt as &dyn Prompt diff --git a/src/reedline_config.rs b/src/reedline_config.rs index 1c655c075b..c24922c698 100644 --- a/src/reedline_config.rs +++ b/src/reedline_config.rs @@ -1,6 +1,6 @@ use crossterm::event::{KeyCode, KeyModifiers}; use nu_color_config::lookup_ansi_color_style; -use nu_protocol::{extract_value, Config, ParsedKeybinding, ShellError, Span, Value}; +use nu_protocol::{extract_value, Config, ParsedKeybinding, ShellError, Span, Type, Value}; use reedline::{ default_emacs_keybindings, default_vi_insert_keybindings, default_vi_normal_keybindings, ContextMenuInput, EditCommand, Keybindings, ReedlineEvent, @@ -194,7 +194,6 @@ fn parse_event(value: Value, config: &Config) -> Result ReedlineEvent::None, "actionhandler" => ReedlineEvent::ActionHandler, "clearscreen" => ReedlineEvent::ClearScreen, - "contextmenu" => ReedlineEvent::ContextMenu, "complete" => ReedlineEvent::Complete, "ctrld" => ReedlineEvent::CtrlD, "ctrlc" => ReedlineEvent::CtrlC, @@ -204,14 +203,17 @@ fn parse_event(value: Value, config: &Config) -> Result ReedlineEvent::Down, "right" => ReedlineEvent::Right, "left" => ReedlineEvent::Left, + "searchhistory" => ReedlineEvent::SearchHistory, "nexthistory" => ReedlineEvent::NextHistory, "previoushistory" => ReedlineEvent::PreviousHistory, - "searchhistory" => ReedlineEvent::SearchHistory, "repaint" => ReedlineEvent::Repaint, + "contextmenu" => ReedlineEvent::ContextMenu, "menudown" => ReedlineEvent::MenuDown, "menuup" => ReedlineEvent::MenuUp, "menuleft" => ReedlineEvent::MenuLeft, "menuright" => ReedlineEvent::MenuRight, + "menunext" => ReedlineEvent::MenuNext, + "menuprevious" => ReedlineEvent::MenuPrevious, // TODO: add ReedlineEvent::Mouse // TODO: add ReedlineEvent::Resize @@ -224,8 +226,8 @@ fn parse_event(value: Value, config: &Config) -> Result { return Err(ShellError::UnsupportedConfigValue( - v.to_string(), "Reedline event".to_string(), + v.to_string(), span, )) } @@ -249,12 +251,21 @@ fn parse_event(value: Value, config: &Config) -> Result { + // If all the elements in the list are lists, then they represent an UntilFound event. + // This means that only one of the parsed events from the list will be executed. + // Otherwise, the expect shape should be lists of records which indicates a sequence + // of events that will happen one after the other + let until_found = vals.iter().all(|v| matches!(v.get_type(), Type::List(..))); let events = vals .into_iter() .map(|value| parse_event(value, config)) .collect::, ShellError>>()?; - Ok(ReedlineEvent::Multiple(events)) + if until_found { + Ok(ReedlineEvent::UntilFound(events)) + } else { + Ok(ReedlineEvent::Multiple(events)) + } } v => Err(ShellError::UnsupportedConfigValue( v.into_abbreviated_string(config),