diff --git a/crates/nu-cli/src/prompt.rs b/crates/nu-cli/src/prompt.rs index 9264c1b646..4ec0e677f9 100644 --- a/crates/nu-cli/src/prompt.rs +++ b/crates/nu-cli/src/prompt.rs @@ -1,3 +1,4 @@ +use crate::prompt_update::{POST_PROMPT_MARKER, PRE_PROMPT_MARKER}; #[cfg(windows)] use nu_utils::enable_vt_processing; use reedline::DefaultPrompt; @@ -11,6 +12,7 @@ use { /// Nushell prompt definition #[derive(Clone)] pub struct NushellPrompt { + shell_integration: bool, left_prompt_string: Option, right_prompt_string: Option, default_prompt_indicator: Option, @@ -20,15 +22,10 @@ pub struct NushellPrompt { render_right_prompt_on_last_line: bool, } -impl Default for NushellPrompt { - fn default() -> Self { - NushellPrompt::new() - } -} - impl NushellPrompt { - pub fn new() -> NushellPrompt { + pub fn new(shell_integration: bool) -> NushellPrompt { NushellPrompt { + shell_integration, left_prompt_string: None, right_prompt_string: None, default_prompt_indicator: None, @@ -111,7 +108,11 @@ impl Prompt for NushellPrompt { .to_string() .replace('\n', "\r\n"); - prompt.into() + if self.shell_integration { + format!("{PRE_PROMPT_MARKER}{prompt}{POST_PROMPT_MARKER}").into() + } else { + prompt.into() + } } } diff --git a/crates/nu-cli/src/prompt_update.rs b/crates/nu-cli/src/prompt_update.rs index e691a3e32c..bacb1167a2 100644 --- a/crates/nu-cli/src/prompt_update.rs +++ b/crates/nu-cli/src/prompt_update.rs @@ -28,8 +28,8 @@ pub(crate) const TRANSIENT_PROMPT_MULTILINE_INDICATOR: &str = "TRANSIENT_PROMPT_MULTILINE_INDICATOR"; // According to Daniel Imms @Tyriar, we need to do these this way: // <133 A><133 B><133 C> -const PRE_PROMPT_MARKER: &str = "\x1b]133;A\x1b\\"; -const POST_PROMPT_MARKER: &str = "\x1b]133;B\x1b\\"; +pub(crate) const PRE_PROMPT_MARKER: &str = "\x1b]133;A\x1b\\"; +pub(crate) const POST_PROMPT_MARKER: &str = "\x1b]133;B\x1b\\"; fn get_prompt_string( prompt: &str, @@ -160,19 +160,19 @@ struct TransientPrompt { } impl TransientPrompt { - fn new_prompt(&self) -> NushellPrompt { + fn new_prompt(&self, shell_integration: bool) -> NushellPrompt { if let Ok(prompt) = self.prompt_lock.read() { prompt.clone() } else { - NushellPrompt::new() + NushellPrompt::new(shell_integration) } } } impl Prompt for TransientPrompt { fn render_prompt_left(&self) -> Cow { - let mut nu_prompt = self.new_prompt(); - let config = &self.engine_state.get_config().clone(); + let config = self.engine_state.get_config(); + let mut nu_prompt = self.new_prompt(config.shell_integration); let mut stack = self.stack.clone(); if let Some(s) = get_prompt_string( TRANSIENT_PROMPT_COMMAND, @@ -182,12 +182,17 @@ impl Prompt for TransientPrompt { ) { nu_prompt.update_prompt_left(Some(s)) } - nu_prompt.render_prompt_left().to_string().into() + let left_prompt = nu_prompt.render_prompt_left(); + if config.shell_integration { + format!("{PRE_PROMPT_MARKER}{left_prompt}{POST_PROMPT_MARKER}").into() + } else { + left_prompt.to_string().into() + } } fn render_prompt_right(&self) -> Cow { - let mut nu_prompt = self.new_prompt(); - let config = &self.engine_state.get_config().clone(); + let config = self.engine_state.get_config(); + let mut nu_prompt = self.new_prompt(config.shell_integration); let mut stack = self.stack.clone(); if let Some(s) = get_prompt_string( TRANSIENT_PROMPT_COMMAND_RIGHT, @@ -201,8 +206,8 @@ impl Prompt for TransientPrompt { } fn render_prompt_indicator(&self, prompt_mode: reedline::PromptEditMode) -> Cow { - let mut nu_prompt = self.new_prompt(); - let config = &self.engine_state.get_config().clone(); + let config = self.engine_state.get_config(); + let mut nu_prompt = self.new_prompt(config.shell_integration); let mut stack = self.stack.clone(); if let Some(s) = get_prompt_string( TRANSIENT_PROMPT_INDICATOR, @@ -235,8 +240,8 @@ impl Prompt for TransientPrompt { } fn render_prompt_multiline_indicator(&self) -> Cow { - let mut nu_prompt = self.new_prompt(); - let config = &self.engine_state.get_config().clone(); + let config = self.engine_state.get_config(); + let mut nu_prompt = self.new_prompt(config.shell_integration); let mut stack = self.stack.clone(); if let Some(s) = get_prompt_string( TRANSIENT_PROMPT_MULTILINE_INDICATOR, @@ -256,7 +261,7 @@ impl Prompt for TransientPrompt { &self, history_search: reedline::PromptHistorySearch, ) -> Cow { - NushellPrompt::new() + NushellPrompt::new(self.engine_state.get_config().shell_integration) .render_prompt_history_search_indicator(history_search) .to_string() .into() diff --git a/crates/nu-cli/src/repl.rs b/crates/nu-cli/src/repl.rs index 25f1e60926..48014e68e8 100644 --- a/crates/nu-cli/src/repl.rs +++ b/crates/nu-cli/src/repl.rs @@ -54,7 +54,8 @@ pub fn evaluate_repl( ) -> Result<()> { use nu_cmd_base::hook; use reedline::Signal; - let use_color = engine_state.get_config().use_ansi_coloring; + let config = engine_state.get_config(); + let use_color = config.use_ansi_coloring; // Guard against invocation without a connected terminal. // reedline / crossterm event polling will fail without a connected tty @@ -68,7 +69,7 @@ pub fn evaluate_repl( let mut entry_num = 0; - let nu_prompt = Arc::new(RwLock::new(NushellPrompt::new())); + let nu_prompt = Arc::new(RwLock::new(NushellPrompt::new(config.shell_integration))); let start_time = std::time::Instant::now(); // Translate environment variables from Strings to Values