diff --git a/crates/nu-cli/src/prompt.rs b/crates/nu-cli/src/prompt.rs index 488a922c34..2315c494f2 100644 --- a/crates/nu-cli/src/prompt.rs +++ b/crates/nu-cli/src/prompt.rs @@ -9,8 +9,6 @@ use { #[derive(Clone)] pub struct NushellPrompt { prompt_string: String, - // These are part of the struct definition in case we want to allow - // further customization to the shell status default_prompt_indicator: String, default_vi_insert_prompt_indicator: String, default_vi_visual_prompt_indicator: String, @@ -38,6 +36,37 @@ impl NushellPrompt { self.prompt_string = prompt_string; } + pub fn update_prompt_indicator(&mut self, prompt_indicator_string: String) { + self.default_prompt_indicator = prompt_indicator_string; + } + + pub fn update_prompt_vi_insert(&mut self, prompt_vi_insert_string: String) { + self.default_vi_insert_prompt_indicator = prompt_vi_insert_string; + } + + pub fn update_prompt_vi_visual(&mut self, prompt_vi_visual_string: String) { + self.default_vi_visual_prompt_indicator = prompt_vi_visual_string; + } + + pub fn update_prompt_multiline(&mut self, prompt_multiline_indicator_string: String) { + self.default_multiline_indicator = prompt_multiline_indicator_string; + } + + pub fn update_all_prompt_strings( + &mut self, + prompt_string: String, + 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.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; + } + fn default_wrapped_custom_string(&self, str: String) -> String { format!("({})", str) } diff --git a/src/main.rs b/src/main.rs index d00cbfd6cc..77cb651731 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,9 +17,7 @@ use nu_protocol::{ engine::{EngineState, Stack, StateWorkingSet}, Config, PipelineData, ShellError, Span, Value, CONFIG_VARIABLE_ID, }; -use reedline::{ - Completer, CompletionActionHandler, DefaultHinter, DefaultPrompt, LineBuffer, Prompt, Vi, -}; +use reedline::{Completer, CompletionActionHandler, DefaultHinter, LineBuffer, Prompt, Vi}; use std::{ io::Write, sync::{ @@ -35,6 +33,10 @@ mod logger; // Name of environment variable where the prompt could be stored const PROMPT_COMMAND: &str = "PROMPT_COMMAND"; +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"; +const PROMPT_MULTILINE_INDICATOR: &str = "PROMPT_MULTILINE_INDICATOR"; struct FuzzyCompletion { completer: Box, @@ -249,7 +251,6 @@ fn main() -> Result<()> { let mut entry_num = 0; - let default_prompt = DefaultPrompt::new(1); let mut nu_prompt = NushellPrompt::new(); let mut stack = nu_protocol::engine::Stack::new(); @@ -419,13 +420,7 @@ fn main() -> Result<()> { line_editor }; - let prompt = update_prompt( - PROMPT_COMMAND, - &engine_state, - &stack, - &mut nu_prompt, - &default_prompt, - ); + let prompt = update_prompt(&config, &engine_state, &stack, &mut nu_prompt); entry_num += 1; @@ -719,22 +714,78 @@ fn print_pipeline_data( Ok(()) } +fn get_prompt_indicators(config: &Config, stack: &Stack) -> (String, String, String, String) { + let prompt_indicator = match stack.get_env_var(PROMPT_INDICATOR) { + Some(pi) => pi.into_string("", config), + None => "〉".to_string(), + }; + + let prompt_vi_insert = match stack.get_env_var(PROMPT_INDICATOR_VI_INSERT) { + Some(pvii) => pvii.into_string("", config), + None => ": ".to_string(), + }; + + let prompt_vi_visual = match stack.get_env_var(PROMPT_INDICATOR_VI_VISUAL) { + Some(pviv) => pviv.into_string("", config), + None => "v ".to_string(), + }; + + let prompt_multiline = match stack.get_env_var(PROMPT_MULTILINE_INDICATOR) { + Some(pm) => pm.into_string("", config), + None => "::: ".to_string(), + }; + + ( + prompt_indicator, + prompt_vi_insert, + prompt_vi_visual, + prompt_multiline, + ) +} + fn update_prompt<'prompt>( - env_variable: &str, + config: &Config, engine_state: &EngineState, stack: &Stack, nu_prompt: &'prompt mut NushellPrompt, - default_prompt: &'prompt DefaultPrompt, ) -> &'prompt dyn Prompt { - let block_id = match stack.get_env_var(env_variable) { + // get the other indicators + let ( + prompt_indicator_string, + prompt_vi_insert_string, + prompt_vi_visual_string, + prompt_multiline_string, + ) = get_prompt_indicators(config, stack); + + let prompt_command_block_id = match stack.get_env_var(PROMPT_COMMAND) { Some(v) => match v.as_block() { Ok(b) => b, - Err(_) => return default_prompt as &dyn Prompt, + Err(_) => { + // apply the other indicators + nu_prompt.update_all_prompt_strings( + String::new(), + prompt_indicator_string, + prompt_vi_insert_string, + prompt_vi_visual_string, + prompt_multiline_string, + ); + return nu_prompt as &dyn Prompt; + } }, - None => return default_prompt as &dyn Prompt, + None => { + // apply the other indicators + nu_prompt.update_all_prompt_strings( + String::new(), + 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(block_id); + let block = engine_state.get_block(prompt_command_block_id); let mut stack = stack.clone(); @@ -745,20 +796,40 @@ fn update_prompt<'prompt>( 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) + // 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 - return default_prompt as &dyn Prompt; + // apply the other indicators + nu_prompt.update_all_prompt_strings( + String::new(), + 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_prompt(evaluated_prompt); + nu_prompt.update_all_prompt_strings( + evaluated_prompt, + prompt_indicator_string, + prompt_vi_insert_string, + prompt_vi_visual_string, + prompt_multiline_string, + ); } - _ => nu_prompt.update_prompt(String::new()), + _ => nu_prompt.update_all_prompt_strings( + String::new(), + prompt_indicator_string, + prompt_vi_insert_string, + prompt_vi_visual_string, + prompt_multiline_string, + ), } nu_prompt as &dyn Prompt