make prompt indicators configurable (#639)

* make prompt indicators configurable

* seems to be working now
This commit is contained in:
Darren Schroeder 2022-01-01 16:53:16 -06:00 committed by GitHub
parent ac487dfcbc
commit a56994ccc5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 124 additions and 24 deletions

View File

@ -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)
}

View File

@ -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<dyn Completer>,
@ -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