Skip to content

Commit

Permalink
Revert "Only run $env.PROMPT_COMMAND once per prompt" (nushell#11340)
Browse files Browse the repository at this point in the history
Reverts nushell#10986

@CAD97 This isn't working right. I have a 2 line prompt with a transient
prompt. on enter, you see the transient prompt drawn and then the normal
prompt overwrites it.
  • Loading branch information
fdncred authored Dec 15, 2023
1 parent 5b557a8 commit 9092fc1
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 96 deletions.
49 changes: 26 additions & 23 deletions crates/nu-cli/src/prompt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,29 +39,36 @@ impl NushellPrompt {
}
}

pub fn update_all_prompt_strings(
pub fn update_prompt_left(&mut self, prompt_string: Option<String>) {
self.left_prompt_string = prompt_string;
}

pub fn update_prompt_right(
&mut self,
left_prompt_string: Option<String>,
right_prompt_string: Option<String>,
prompt_indicator_string: Option<String>,
prompt_multiline_indicator_string: Option<String>,
prompt_vi: (Option<String>, Option<String>),
prompt_string: Option<String>,
render_right_prompt_on_last_line: bool,
) {
let (prompt_vi_insert_string, prompt_vi_normal_string) = prompt_vi;
self.right_prompt_string = prompt_string;
self.render_right_prompt_on_last_line = render_right_prompt_on_last_line;
}

self.left_prompt_string = left_prompt_string;
self.right_prompt_string = right_prompt_string;
pub fn update_prompt_indicator(&mut self, prompt_indicator_string: Option<String>) {
self.default_prompt_indicator = prompt_indicator_string;
self.default_multiline_indicator = prompt_multiline_indicator_string;
}

pub fn update_prompt_vi_insert(&mut self, prompt_vi_insert_string: Option<String>) {
self.default_vi_insert_prompt_indicator = prompt_vi_insert_string;
}

pub fn update_prompt_vi_normal(&mut self, prompt_vi_normal_string: Option<String>) {
self.default_vi_normal_prompt_indicator = prompt_vi_normal_string;
}

self.render_right_prompt_on_last_line = render_right_prompt_on_last_line;
pub fn update_prompt_multiline(&mut self, prompt_multiline_indicator_string: Option<String>) {
self.default_multiline_indicator = prompt_multiline_indicator_string;
}

pub fn overlay_all_prompt_strings(
pub fn update_all_prompt_strings(
&mut self,
left_prompt_string: Option<String>,
right_prompt_string: Option<String>,
Expand All @@ -72,17 +79,13 @@ impl NushellPrompt {
) {
let (prompt_vi_insert_string, prompt_vi_normal_string) = prompt_vi;

self.left_prompt_string = left_prompt_string.or(self.left_prompt_string.take());
self.right_prompt_string = right_prompt_string.or(self.right_prompt_string.take());
self.default_prompt_indicator =
prompt_indicator_string.or(self.default_prompt_indicator.take());
self.default_multiline_indicator =
prompt_multiline_indicator_string.or(self.default_multiline_indicator.take());

self.default_vi_insert_prompt_indicator =
prompt_vi_insert_string.or(self.default_vi_insert_prompt_indicator.take());
self.default_vi_normal_prompt_indicator =
prompt_vi_normal_string.or(self.default_vi_normal_prompt_indicator.take());
self.left_prompt_string = left_prompt_string;
self.right_prompt_string = right_prompt_string;
self.default_prompt_indicator = prompt_indicator_string;
self.default_multiline_indicator = prompt_multiline_indicator_string;

self.default_vi_insert_prompt_indicator = prompt_vi_insert_string;
self.default_vi_normal_prompt_indicator = prompt_vi_normal_string;

self.render_right_prompt_on_last_line = render_right_prompt_on_last_line;
}
Expand Down
173 changes: 107 additions & 66 deletions crates/nu-cli/src/prompt_update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ use nu_protocol::{
Config, PipelineData, Value,
};
use reedline::Prompt;
use std::borrow::Cow;
use std::sync::Arc;

// Name of environment variable where the prompt could be stored
pub(crate) const PROMPT_COMMAND: &str = "PROMPT_COMMAND";
Expand Down Expand Up @@ -151,79 +153,118 @@ pub(crate) fn update_prompt<'prompt>(
ret_val
}

pub(crate) fn make_transient_prompt(
struct TransientPrompt {
engine_state: Arc<EngineState>,
stack: Stack,
}

/// Try getting `$env.TRANSIENT_PROMPT_<X>`, and get `$env.PROMPT_<X>` if that fails
fn get_transient_prompt_string(
transient_prompt: &str,
prompt: &str,
config: &Config,
engine_state: &EngineState,
stack: &Stack,
nu_prompt: &NushellPrompt,
) -> Box<dyn Prompt> {
let mut stack = stack.clone();
let mut nu_prompt = nu_prompt.clone();
stack: &mut Stack,
) -> Option<String> {
get_prompt_string(transient_prompt, config, engine_state, stack)
.or_else(|| get_prompt_string(prompt, config, engine_state, stack))
}

let left_prompt_string =
get_prompt_string(TRANSIENT_PROMPT_COMMAND, config, engine_state, &mut stack);
impl Prompt for TransientPrompt {
fn render_prompt_left(&self) -> Cow<str> {
let mut nu_prompt = NushellPrompt::new();
let config = &self.engine_state.get_config().clone();
let mut stack = self.stack.clone();
nu_prompt.update_prompt_left(get_transient_prompt_string(
TRANSIENT_PROMPT_COMMAND,
PROMPT_COMMAND,
config,
&self.engine_state,
&mut stack,
));
nu_prompt.render_prompt_left().to_string().into()
}

// Now that we have the prompt string lets ansify it.
// <133 A><prompt><133 B><command><133 C><command output>
let left_prompt_string = if config.shell_integration {
if let Some(prompt_string) = left_prompt_string {
Some(format!(
"{PRE_PROMPT_MARKER}{prompt_string}{POST_PROMPT_MARKER}"
))
} else {
left_prompt_string
}
} else {
left_prompt_string
};
fn render_prompt_right(&self) -> Cow<str> {
let mut nu_prompt = NushellPrompt::new();
let config = &self.engine_state.get_config().clone();
let mut stack = self.stack.clone();
nu_prompt.update_prompt_right(
get_transient_prompt_string(
TRANSIENT_PROMPT_COMMAND_RIGHT,
PROMPT_COMMAND_RIGHT,
config,
&self.engine_state,
&mut stack,
),
config.render_right_prompt_on_last_line,
);
nu_prompt.render_prompt_right().to_string().into()
}

let right_prompt_string = get_prompt_string(
TRANSIENT_PROMPT_COMMAND_RIGHT,
config,
engine_state,
&mut stack,
);

let prompt_indicator_string =
get_prompt_string(TRANSIENT_PROMPT_INDICATOR, config, engine_state, &mut stack);
fn render_prompt_indicator(&self, prompt_mode: reedline::PromptEditMode) -> Cow<str> {
let mut nu_prompt = NushellPrompt::new();
let config = &self.engine_state.get_config().clone();
let mut stack = self.stack.clone();
nu_prompt.update_prompt_indicator(get_transient_prompt_string(
TRANSIENT_PROMPT_INDICATOR,
PROMPT_INDICATOR,
config,
&self.engine_state,
&mut stack,
));
nu_prompt.update_prompt_vi_insert(get_transient_prompt_string(
TRANSIENT_PROMPT_INDICATOR_VI_INSERT,
PROMPT_INDICATOR_VI_INSERT,
config,
&self.engine_state,
&mut stack,
));
nu_prompt.update_prompt_vi_normal(get_transient_prompt_string(
TRANSIENT_PROMPT_INDICATOR_VI_NORMAL,
PROMPT_INDICATOR_VI_NORMAL,
config,
&self.engine_state,
&mut stack,
));
nu_prompt
.render_prompt_indicator(prompt_mode)
.to_string()
.into()
}

let prompt_multiline_string = get_prompt_string(
TRANSIENT_PROMPT_MULTILINE_INDICATOR,
config,
engine_state,
&mut stack,
);
fn render_prompt_multiline_indicator(&self) -> Cow<str> {
let mut nu_prompt = NushellPrompt::new();
let config = &self.engine_state.get_config().clone();
let mut stack = self.stack.clone();
nu_prompt.update_prompt_multiline(get_transient_prompt_string(
TRANSIENT_PROMPT_MULTILINE_INDICATOR,
PROMPT_MULTILINE_INDICATOR,
config,
&self.engine_state,
&mut stack,
));
nu_prompt
.render_prompt_multiline_indicator()
.to_string()
.into()
}

let prompt_vi_insert_string = get_prompt_string(
TRANSIENT_PROMPT_INDICATOR_VI_INSERT,
config,
engine_state,
&mut stack,
);
fn render_prompt_history_search_indicator(
&self,
history_search: reedline::PromptHistorySearch,
) -> Cow<str> {
NushellPrompt::new()
.render_prompt_history_search_indicator(history_search)
.to_string()
.into()
}
}

let prompt_vi_normal_string = get_prompt_string(
TRANSIENT_PROMPT_INDICATOR_VI_NORMAL,
config,
/// Construct the transient prompt
pub(crate) fn transient_prompt(engine_state: Arc<EngineState>, stack: &Stack) -> Box<dyn Prompt> {
Box::new(TransientPrompt {
engine_state,
&mut stack,
);

// apply the other indicators
nu_prompt.overlay_all_prompt_strings(
left_prompt_string,
right_prompt_string,
prompt_indicator_string,
prompt_multiline_string,
(prompt_vi_insert_string, prompt_vi_normal_string),
config.render_right_prompt_on_last_line,
);

trace!(
"make_transient_prompt {}:{}:{}",
file!(),
line!(),
column!()
);

Box::new(nu_prompt)
stack: stack.clone(),
})
}
14 changes: 7 additions & 7 deletions crates/nu-cli/src/repl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,11 @@ pub fn evaluate_repl(
.with_quick_completions(config.quick_completions)
.with_partial_completions(config.partial_completions)
.with_ansi_colors(config.use_ansi_coloring)
.with_cursor_config(cursor_config);
.with_cursor_config(cursor_config)
.with_transient_prompt(prompt_update::transient_prompt(
engine_reference.clone(),
stack,
));
perf(
"reedline builder",
start_time,
Expand Down Expand Up @@ -419,11 +423,8 @@ pub fn evaluate_repl(
);

start_time = std::time::Instant::now();
// Now we compute the prompt after running the hooks
let config = &engine_state.get_config().clone();
prompt_update::update_prompt(config, engine_state, stack, &mut nu_prompt);
let transient_prompt =
prompt_update::make_transient_prompt(config, engine_state, stack, &nu_prompt);
let prompt = prompt_update::update_prompt(config, engine_state, stack, &mut nu_prompt);
perf(
"update_prompt",
start_time,
Expand All @@ -436,8 +437,7 @@ pub fn evaluate_repl(
entry_num += 1;

start_time = std::time::Instant::now();
line_editor = line_editor.with_transient_prompt(transient_prompt);
let input = line_editor.read_line(&nu_prompt);
let input = line_editor.read_line(prompt);
let shell_integration = config.shell_integration;

match input {
Expand Down

0 comments on commit 9092fc1

Please sign in to comment.