double prompt (#686)

* double prompt

* prompt env var name
This commit is contained in:
Fernando Herrera 2022-01-06 12:57:55 +00:00 committed by GitHub
parent e44789556b
commit 8a0d2b4e32
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 60 additions and 83 deletions

2
Cargo.lock generated
View File

@ -2777,7 +2777,7 @@ dependencies = [
[[package]] [[package]]
name = "reedline" name = "reedline"
version = "0.2.0" 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 = [ dependencies = [
"chrono", "chrono",
"crossterm", "crossterm",

View File

@ -10,7 +10,8 @@ use {
/// Nushell prompt definition /// Nushell prompt definition
#[derive(Clone)] #[derive(Clone)]
pub struct NushellPrompt { pub struct NushellPrompt {
prompt_string: Option<String>, left_prompt_string: Option<String>,
right_prompt_string: Option<String>,
default_prompt_indicator: String, default_prompt_indicator: String,
default_vi_insert_prompt_indicator: String, default_vi_insert_prompt_indicator: String,
default_vi_visual_prompt_indicator: String, default_vi_visual_prompt_indicator: String,
@ -26,7 +27,8 @@ impl Default for NushellPrompt {
impl NushellPrompt { impl NushellPrompt {
pub fn new() -> NushellPrompt { pub fn new() -> NushellPrompt {
NushellPrompt { NushellPrompt {
prompt_string: None, left_prompt_string: None,
right_prompt_string: None,
default_prompt_indicator: "".to_string(), default_prompt_indicator: "".to_string(),
default_vi_insert_prompt_indicator: ": ".to_string(), default_vi_insert_prompt_indicator: ": ".to_string(),
default_vi_visual_prompt_indicator: "v ".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<String>) { pub fn update_prompt_left(&mut self, prompt_string: Option<String>) {
self.prompt_string = prompt_string; self.left_prompt_string = prompt_string;
}
pub fn update_prompt_right(&mut self, prompt_string: Option<String>) {
self.right_prompt_string = prompt_string;
} }
pub fn update_prompt_indicator(&mut self, prompt_indicator_string: String) { pub fn update_prompt_indicator(&mut self, prompt_indicator_string: String) {
@ -56,13 +62,15 @@ impl NushellPrompt {
pub fn update_all_prompt_strings( pub fn update_all_prompt_strings(
&mut self, &mut self,
prompt_string: Option<String>, left_prompt_string: Option<String>,
right_prompt_string: Option<String>,
prompt_indicator_string: String, prompt_indicator_string: String,
prompt_vi_insert_string: String, prompt_vi_insert_string: String,
prompt_vi_visual_string: String, prompt_vi_visual_string: String,
prompt_multiline_indicator_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_prompt_indicator = prompt_indicator_string;
self.default_vi_insert_prompt_indicator = prompt_vi_insert_string; self.default_vi_insert_prompt_indicator = prompt_vi_insert_string;
self.default_vi_visual_prompt_indicator = prompt_vi_visual_string; self.default_vi_visual_prompt_indicator = prompt_vi_visual_string;
@ -75,12 +83,21 @@ impl NushellPrompt {
} }
impl Prompt for NushellPrompt { impl Prompt for NushellPrompt {
fn render_prompt(&self, width: usize) -> Cow<str> { fn render_prompt_left(&self) -> Cow<str> {
if let Some(prompt_string) = &self.prompt_string { if let Some(prompt_string) = &self.left_prompt_string {
prompt_string.into() prompt_string.into()
} else { } else {
let default = DefaultPrompt::new(1); let default = DefaultPrompt::new();
default.render_prompt(width).to_string().into() default.render_prompt_left().to_string().into()
}
}
fn render_prompt_right(&self) -> Cow<str> {
if let Some(prompt_string) = &self.right_prompt_string {
prompt_string.into()
} else {
let default = DefaultPrompt::new();
default.render_prompt_right().to_string().into()
} }
} }

View File

@ -34,6 +34,7 @@ mod logger;
// Name of environment variable where the prompt could be stored // Name of environment variable where the prompt could be stored
const PROMPT_COMMAND: &str = "PROMPT_COMMAND"; const PROMPT_COMMAND: &str = "PROMPT_COMMAND";
const PROMPT_COMMAND_RIGHT: &str = "PROMPT_COMMAND_RIGHT";
const PROMPT_INDICATOR: &str = "PROMPT_INDICATOR"; const PROMPT_INDICATOR: &str = "PROMPT_INDICATOR";
const PROMPT_INDICATOR_VI_INSERT: &str = "PROMPT_INDICATOR_VI_INSERT"; const PROMPT_INDICATOR_VI_INSERT: &str = "PROMPT_INDICATOR_VI_INSERT";
const PROMPT_INDICATOR_VI_VISUAL: &str = "PROMPT_INDICATOR_VI_VISUAL"; const PROMPT_INDICATOR_VI_VISUAL: &str = "PROMPT_INDICATOR_VI_VISUAL";
@ -851,84 +852,43 @@ fn update_prompt<'prompt>(
prompt_multiline_string, prompt_multiline_string,
) = get_prompt_indicators(config, engine_state, stack); ) = 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 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 // apply the other indicators
nu_prompt.update_all_prompt_strings( nu_prompt.update_all_prompt_strings(
None, 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_indicator_string,
prompt_vi_insert_string, prompt_vi_insert_string,
prompt_vi_visual_string, prompt_vi_visual_string,
prompt_multiline_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,
),
}
nu_prompt as &dyn Prompt nu_prompt as &dyn Prompt
} }
fn get_prompt_string(
prompt: &str,
config: &Config,
engine_state: &EngineState,
stack: &mut Stack,
) -> Option<String> {
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( fn eval_source(
engine_state: &mut EngineState, engine_state: &mut EngineState,
stack: &mut Stack, stack: &mut Stack,