mirror of
https://github.com/nushell/reedline.git
synced 2024-11-09 13:09:10 +03:00
Extending PromptMode (#74)
* Revamp Prompt states The idea here is that what we want to display on the screen which can impact the prompt should be available as part of the prompt's interface. So here are the things that can impact what we show with our prompt - The line-editor can either be in Emacs mode or VI mode (for now) [These are exclusive to one another] - The line-editor can be either in editing a command or searching history mode [These two states are also exclusive] - Lastly the command can be either single-line or multi-line. Now all these variables can happen togeter (i.e. they for a cross prodcut) - example 1: You can be in vi-normal mode and be editing history search term and that particular term earlier resulted in a multi-line command. (So, we need to showcase all these three variations together) one way to do this is using a struct. I found that it was making the more frequent case (of being in edit mode) overly complex so I chose to expose the functionality as separate methonds. * Cleanup custom strings from engine
This commit is contained in:
parent
1ad2fcc46a
commit
ca445820ae
@ -2,7 +2,7 @@ use crate::{
|
|||||||
clip_buffer::{get_default_clipboard, Clipboard},
|
clip_buffer::{get_default_clipboard, Clipboard},
|
||||||
default_emacs_keybindings,
|
default_emacs_keybindings,
|
||||||
keybindings::{default_vi_insert_keybindings, default_vi_normal_keybindings, Keybindings},
|
keybindings::{default_vi_insert_keybindings, default_vi_normal_keybindings, Keybindings},
|
||||||
prompt::PromptMode,
|
prompt::{PromptEditMode, PromptHistorySearch, PromptHistorySearchStatus, PromptViMode},
|
||||||
DefaultPrompt, Prompt,
|
DefaultPrompt, Prompt,
|
||||||
};
|
};
|
||||||
use crate::{history::History, line_buffer::LineBuffer};
|
use crate::{history::History, line_buffer::LineBuffer};
|
||||||
@ -147,10 +147,11 @@ impl Reedline {
|
|||||||
self.edit_mode
|
self.edit_mode
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prompt_mode(&self) -> PromptMode {
|
pub fn prompt_edit_mode(&self) -> PromptEditMode {
|
||||||
match self.edit_mode {
|
match self.edit_mode {
|
||||||
EditMode::ViInsert => PromptMode::ViInsert,
|
EditMode::ViInsert => PromptEditMode::Vi(PromptViMode::Insert),
|
||||||
_ => PromptMode::Normal,
|
EditMode::ViNormal => PromptEditMode::Vi(PromptViMode::Normal),
|
||||||
|
EditMode::Emacs => PromptEditMode::Emacs,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -636,7 +637,7 @@ impl Reedline {
|
|||||||
/// Used at the beginning of each [`Reedline::read_line()`] call.
|
/// Used at the beginning of each [`Reedline::read_line()`] call.
|
||||||
fn queue_prompt(&mut self, screen_width: usize) -> Result<()> {
|
fn queue_prompt(&mut self, screen_width: usize) -> Result<()> {
|
||||||
// print our prompt
|
// print our prompt
|
||||||
let prompt_mode = self.prompt_mode();
|
let prompt_mode = self.prompt_edit_mode();
|
||||||
|
|
||||||
self.stdout
|
self.stdout
|
||||||
.queue(MoveToColumn(0))?
|
.queue(MoveToColumn(0))?
|
||||||
@ -654,7 +655,7 @@ impl Reedline {
|
|||||||
/// the prompt
|
/// the prompt
|
||||||
fn queue_prompt_indicator(&mut self) -> Result<()> {
|
fn queue_prompt_indicator(&mut self) -> Result<()> {
|
||||||
// print our prompt
|
// print our prompt
|
||||||
let prompt_mode = self.prompt_mode();
|
let prompt_mode = self.prompt_edit_mode();
|
||||||
self.stdout
|
self.stdout
|
||||||
.queue(MoveToColumn(0))?
|
.queue(MoveToColumn(0))?
|
||||||
.queue(SetForegroundColor(self.prompt.get_prompt_color()))?
|
.queue(SetForegroundColor(self.prompt.get_prompt_color()))?
|
||||||
@ -724,19 +725,21 @@ impl Reedline {
|
|||||||
.expect("couldn't get history_search reference");
|
.expect("couldn't get history_search reference");
|
||||||
|
|
||||||
let status = if search.result.is_none() && !search.search_string.is_empty() {
|
let status = if search.result.is_none() && !search.search_string.is_empty() {
|
||||||
"failed "
|
PromptHistorySearchStatus::Failing
|
||||||
} else {
|
} else {
|
||||||
""
|
PromptHistorySearchStatus::Passing
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let prompt_history_search = PromptHistorySearch::new(status, search.search_string.clone());
|
||||||
|
let history_indicator = self
|
||||||
|
.prompt
|
||||||
|
.render_prompt_history_search_indicator(prompt_history_search);
|
||||||
|
|
||||||
// print search prompt
|
// print search prompt
|
||||||
self.stdout
|
self.stdout
|
||||||
.queue(MoveToColumn(0))?
|
.queue(MoveToColumn(0))?
|
||||||
.queue(SetForegroundColor(Color::Blue))?
|
.queue(SetForegroundColor(Color::Blue))?
|
||||||
.queue(Print(format!(
|
.queue(Print(history_indicator))?
|
||||||
"({}reverse-search)`{}':",
|
|
||||||
status, search.search_string
|
|
||||||
)))?
|
|
||||||
.queue(ResetColor)?;
|
.queue(ResetColor)?;
|
||||||
|
|
||||||
match search.result {
|
match search.result {
|
||||||
|
@ -5,13 +5,39 @@ use std::env;
|
|||||||
pub static DEFAULT_PROMPT_COLOR: Color = Color::Blue;
|
pub static DEFAULT_PROMPT_COLOR: Color = Color::Blue;
|
||||||
pub static DEFAULT_PROMPT_INDICATOR: &str = "〉";
|
pub static DEFAULT_PROMPT_INDICATOR: &str = "〉";
|
||||||
pub static DEFAULT_VI_INSERT_PROMPT_INDICATOR: &str = ": ";
|
pub static DEFAULT_VI_INSERT_PROMPT_INDICATOR: &str = ": ";
|
||||||
|
pub static DEFAULT_VI_VISUAL_PROMPT_INDICATOR: &str = "v ";
|
||||||
pub static DEFAULT_MULTILINE_INDICATOR: &str = "::: ";
|
pub static DEFAULT_MULTILINE_INDICATOR: &str = "::: ";
|
||||||
|
|
||||||
/// The type of prompt indicator to display
|
pub enum PromptHistorySearchStatus {
|
||||||
pub enum PromptMode {
|
Passing,
|
||||||
|
Failing,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct PromptHistorySearch {
|
||||||
|
status: PromptHistorySearchStatus,
|
||||||
|
term: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PromptHistorySearch {
|
||||||
|
pub fn new(status: PromptHistorySearchStatus, search_term: String) -> Self {
|
||||||
|
PromptHistorySearch {
|
||||||
|
status,
|
||||||
|
term: search_term,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum PromptEditMode {
|
||||||
|
Default,
|
||||||
|
Emacs,
|
||||||
|
Vi(PromptViMode),
|
||||||
|
Custom(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum PromptViMode {
|
||||||
Normal,
|
Normal,
|
||||||
ViInsert,
|
Insert,
|
||||||
Multiline,
|
Visual,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// API to provide a custom prompt.
|
/// API to provide a custom prompt.
|
||||||
@ -22,7 +48,12 @@ pub trait Prompt {
|
|||||||
/// Provide content off the full prompt. May use a line above the entry buffer that fits into `screen_width`.
|
/// Provide content off the full prompt. May use a line above the entry buffer that fits into `screen_width`.
|
||||||
fn render_prompt(&self, screen_width: usize) -> String;
|
fn render_prompt(&self, screen_width: usize) -> String;
|
||||||
/// Render the default prompt indicator
|
/// Render the default prompt indicator
|
||||||
fn render_prompt_indicator(&self, prompt_mode: PromptMode) -> String;
|
fn render_prompt_indicator(&self, prompt_mode: PromptEditMode) -> String;
|
||||||
|
/// Render the default prompt indicator
|
||||||
|
fn render_prompt_multiline_indicator(&self) -> String;
|
||||||
|
/// Render the default prompt indicator
|
||||||
|
fn render_prompt_history_search_indicator(&self, history_search: PromptHistorySearch)
|
||||||
|
-> String;
|
||||||
/// Render the vi insert mode prompt indicator
|
/// Render the vi insert mode prompt indicator
|
||||||
/// Get back the prompt color
|
/// Get back the prompt color
|
||||||
fn get_prompt_color(&self) -> Color {
|
fn get_prompt_color(&self) -> Color {
|
||||||
@ -35,13 +66,35 @@ impl Prompt for DefaultPrompt {
|
|||||||
DefaultPrompt::render_prompt(self, screen_width)
|
DefaultPrompt::render_prompt(self, screen_width)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_prompt_indicator(&self, prompt_mode: PromptMode) -> String {
|
fn render_prompt_indicator(&self, edit_mode: PromptEditMode) -> String {
|
||||||
match prompt_mode {
|
match edit_mode {
|
||||||
PromptMode::Normal => DEFAULT_PROMPT_INDICATOR.into(),
|
PromptEditMode::Default => DEFAULT_PROMPT_INDICATOR.into(),
|
||||||
PromptMode::ViInsert => DEFAULT_VI_INSERT_PROMPT_INDICATOR.into(),
|
PromptEditMode::Emacs => DEFAULT_PROMPT_INDICATOR.into(),
|
||||||
PromptMode::Multiline => DEFAULT_MULTILINE_INDICATOR.into(),
|
PromptEditMode::Vi(vi_mode) => match vi_mode {
|
||||||
|
PromptViMode::Normal => DEFAULT_PROMPT_INDICATOR.into(),
|
||||||
|
PromptViMode::Insert => DEFAULT_VI_INSERT_PROMPT_INDICATOR.into(),
|
||||||
|
PromptViMode::Visual => DEFAULT_VI_VISUAL_PROMPT_INDICATOR.into(),
|
||||||
|
},
|
||||||
|
PromptEditMode::Custom(str) => self.default_wrapped_custom_string(str),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn render_prompt_multiline_indicator(&self) -> String {
|
||||||
|
DEFAULT_MULTILINE_INDICATOR.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_prompt_history_search_indicator(
|
||||||
|
&self,
|
||||||
|
history_search: PromptHistorySearch,
|
||||||
|
) -> String {
|
||||||
|
let prefix = match history_search.status {
|
||||||
|
PromptHistorySearchStatus::Passing => "",
|
||||||
|
PromptHistorySearchStatus::Failing => "failing ",
|
||||||
|
};
|
||||||
|
// NOTE: magic strings, givent there is logic on how these compose I am not sure if it
|
||||||
|
// is worth extracting in to static constant
|
||||||
|
format!("({}reverse-search: {})", prefix, history_search.term)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for DefaultPrompt {
|
impl Default for DefaultPrompt {
|
||||||
@ -90,6 +143,10 @@ impl DefaultPrompt {
|
|||||||
|
|
||||||
prompt_str
|
prompt_str
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn default_wrapped_custom_string(&self, str: String) -> String {
|
||||||
|
format!("({})", str)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_working_dir() -> Result<String, std::io::Error> {
|
fn get_working_dir() -> Result<String, std::io::Error> {
|
||||||
|
Loading…
Reference in New Issue
Block a user