From 8a0d2b4e327b97e5f3d899340344f16cdb51f259 Mon Sep 17 00:00:00 2001 From: Fernando Herrera Date: Thu, 6 Jan 2022 12:57:55 +0000 Subject: [PATCH] double prompt (#686) * double prompt * prompt env var name --- Cargo.lock | 2 +- crates/nu-cli/src/prompt.rs | 37 +++++++++---- src/main.rs | 104 +++++++++++------------------------- 3 files changed, 60 insertions(+), 83 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a1a8194f1..5a45c1833 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2777,7 +2777,7 @@ dependencies = [ [[package]] name = "reedline" version = "0.2.0" -source = "git+https://github.com/nushell/reedline?branch=main#811dde6d03ff3059a6cdb9c0c05a2564258098da" +source = "git+https://github.com/nushell/reedline?branch=main#373c76a383b9cde471671047f739e65477b80481" dependencies = [ "chrono", "crossterm", diff --git a/crates/nu-cli/src/prompt.rs b/crates/nu-cli/src/prompt.rs index 0c7e3ada8..b5b320d69 100644 --- a/crates/nu-cli/src/prompt.rs +++ b/crates/nu-cli/src/prompt.rs @@ -10,7 +10,8 @@ use { /// Nushell prompt definition #[derive(Clone)] pub struct NushellPrompt { - prompt_string: Option, + left_prompt_string: Option, + right_prompt_string: Option, default_prompt_indicator: String, default_vi_insert_prompt_indicator: String, default_vi_visual_prompt_indicator: String, @@ -26,7 +27,8 @@ impl Default for NushellPrompt { impl NushellPrompt { pub fn new() -> NushellPrompt { NushellPrompt { - prompt_string: None, + left_prompt_string: None, + right_prompt_string: None, default_prompt_indicator: "〉".to_string(), default_vi_insert_prompt_indicator: ": ".to_string(), default_vi_visual_prompt_indicator: "v ".to_string(), @@ -34,8 +36,12 @@ impl NushellPrompt { } } - pub fn update_prompt(&mut self, prompt_string: Option) { - self.prompt_string = prompt_string; + pub fn update_prompt_left(&mut self, prompt_string: Option) { + self.left_prompt_string = prompt_string; + } + + pub fn update_prompt_right(&mut self, prompt_string: Option) { + self.right_prompt_string = prompt_string; } pub fn update_prompt_indicator(&mut self, prompt_indicator_string: String) { @@ -56,13 +62,15 @@ impl NushellPrompt { pub fn update_all_prompt_strings( &mut self, - prompt_string: Option, + left_prompt_string: Option, + right_prompt_string: Option, prompt_indicator_string: String, prompt_vi_insert_string: String, prompt_vi_visual_string: String, prompt_multiline_indicator_string: String, ) { - self.prompt_string = prompt_string; + 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; @@ -75,12 +83,21 @@ impl NushellPrompt { } impl Prompt for NushellPrompt { - fn render_prompt(&self, width: usize) -> Cow { - if let Some(prompt_string) = &self.prompt_string { + fn render_prompt_left(&self) -> Cow { + if let Some(prompt_string) = &self.left_prompt_string { prompt_string.into() } else { - let default = DefaultPrompt::new(1); - default.render_prompt(width).to_string().into() + let default = DefaultPrompt::new(); + default.render_prompt_left().to_string().into() + } + } + + fn render_prompt_right(&self) -> Cow { + if let Some(prompt_string) = &self.right_prompt_string { + prompt_string.into() + } else { + let default = DefaultPrompt::new(); + default.render_prompt_right().to_string().into() } } diff --git a/src/main.rs b/src/main.rs index 67f476d25..69acfdddb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -34,6 +34,7 @@ mod logger; // Name of environment variable where the prompt could be stored const PROMPT_COMMAND: &str = "PROMPT_COMMAND"; +const PROMPT_COMMAND_RIGHT: &str = "PROMPT_COMMAND_RIGHT"; const PROMPT_INDICATOR: &str = "PROMPT_INDICATOR"; const PROMPT_INDICATOR_VI_INSERT: &str = "PROMPT_INDICATOR_VI_INSERT"; const PROMPT_INDICATOR_VI_VISUAL: &str = "PROMPT_INDICATOR_VI_VISUAL"; @@ -851,84 +852,43 @@ fn update_prompt<'prompt>( prompt_multiline_string, ) = get_prompt_indicators(config, engine_state, stack); - let prompt_command_block_id = match stack.get_env_var(engine_state, PROMPT_COMMAND) { - Some(v) => match v.as_block() { - Ok(b) => b, - Err(_) => { - // apply the other indicators - nu_prompt.update_all_prompt_strings( - None, - prompt_indicator_string, - prompt_vi_insert_string, - prompt_vi_visual_string, - prompt_multiline_string, - ); - return nu_prompt as &dyn Prompt; - } - }, - None => { - // apply the other indicators - nu_prompt.update_all_prompt_strings( - None, - prompt_indicator_string, - prompt_vi_insert_string, - prompt_vi_visual_string, - prompt_multiline_string, - ); - return nu_prompt as &dyn Prompt; - } - }; - - let block = engine_state.get_block(prompt_command_block_id); - let mut stack = stack.clone(); - let evaluated_prompt = match eval_block( - engine_state, - &mut stack, - block, - PipelineData::new(Span::new(0, 0)), // Don't try this at home, 0 span is ignored - ) { - Ok(pipeline_data) => { - // let config = stack.get_config().unwrap_or_default(); - pipeline_data.collect_string("", config) - } - Err(..) => { - // If we can't run the custom prompt, give them the default - // apply the other indicators - nu_prompt.update_all_prompt_strings( - None, - prompt_indicator_string, - prompt_vi_insert_string, - prompt_vi_visual_string, - prompt_multiline_string, - ); - return nu_prompt as &dyn Prompt; - } - }; - - match evaluated_prompt { - Ok(evaluated_prompt) => { - nu_prompt.update_all_prompt_strings( - Some(evaluated_prompt), - prompt_indicator_string, - prompt_vi_insert_string, - prompt_vi_visual_string, - prompt_multiline_string, - ); - } - _ => nu_prompt.update_all_prompt_strings( - None, - prompt_indicator_string, - prompt_vi_insert_string, - prompt_vi_visual_string, - prompt_multiline_string, - ), - } + // apply the other indicators + nu_prompt.update_all_prompt_strings( + 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_multiline_string, + ); nu_prompt as &dyn Prompt } +fn get_prompt_string( + prompt: &str, + config: &Config, + engine_state: &EngineState, + stack: &mut Stack, +) -> Option { + stack + .get_env_var(engine_state, prompt) + .and_then(|v| v.as_block().ok()) + .and_then(|block_id| { + let block = engine_state.get_block(block_id); + eval_block( + engine_state, + stack, + block, + PipelineData::new(Span::new(0, 0)), // Don't try this at home, 0 span is ignored + ) + .ok() + }) + .and_then(|pipeline_data| pipeline_data.collect_string("", config).ok()) +} + fn eval_source( engine_state: &mut EngineState, stack: &mut Stack,