mirror of
https://github.com/nushell/reedline.git
synced 2024-09-11 15:55:50 +03:00
Folderize prompt
- Fix docs for Prompt trait - Separate trait and default implementation - Hide constants that are of little use
This commit is contained in:
parent
ebafcdfe20
commit
804f31d181
@ -195,7 +195,7 @@ pub use history::{FileBackedHistory, History, HistoryNavigationQuery, HISTORY_SI
|
||||
mod prompt;
|
||||
pub use prompt::{
|
||||
DefaultPrompt, Prompt, PromptEditMode, PromptHistorySearch, PromptHistorySearchStatus,
|
||||
PromptViMode, DEFAULT_PROMPT_COLOR, DEFAULT_PROMPT_INDICATOR,
|
||||
PromptViMode,
|
||||
};
|
||||
|
||||
mod edit_mode;
|
||||
|
189
src/prompt.rs
189
src/prompt.rs
@ -1,189 +0,0 @@
|
||||
use {
|
||||
chrono::Local,
|
||||
crossterm::style::Color,
|
||||
serde::{Deserialize, Serialize},
|
||||
std::{
|
||||
borrow::Cow,
|
||||
env,
|
||||
fmt::{Display, Formatter},
|
||||
},
|
||||
strum_macros::EnumIter,
|
||||
};
|
||||
|
||||
/// The default color for the prompt
|
||||
pub static DEFAULT_PROMPT_COLOR: Color = Color::Blue;
|
||||
|
||||
/// The default prompt indicator
|
||||
pub static DEFAULT_PROMPT_INDICATOR: &str = "〉";
|
||||
pub static DEFAULT_VI_INSERT_PROMPT_INDICATOR: &str = ": ";
|
||||
pub static DEFAULT_VI_NORMAL_PROMPT_INDICATOR: &str = "〉";
|
||||
pub static DEFAULT_MULTILINE_INDICATOR: &str = "::: ";
|
||||
|
||||
/// The current success/failure of the history search
|
||||
pub enum PromptHistorySearchStatus {
|
||||
/// Success for the search
|
||||
Passing,
|
||||
|
||||
/// Failure to find the search
|
||||
Failing,
|
||||
}
|
||||
|
||||
/// A representation of the history search
|
||||
pub struct PromptHistorySearch {
|
||||
/// The status of the search
|
||||
pub status: PromptHistorySearchStatus,
|
||||
|
||||
/// The search term used during the search
|
||||
pub term: String,
|
||||
}
|
||||
|
||||
impl PromptHistorySearch {
|
||||
/// A constructor to create a history search
|
||||
pub fn new(status: PromptHistorySearchStatus, search_term: String) -> Self {
|
||||
PromptHistorySearch {
|
||||
status,
|
||||
term: search_term,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Modes that the prompt can be in
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, EnumIter)]
|
||||
pub enum PromptEditMode {
|
||||
/// The default mode
|
||||
Default,
|
||||
|
||||
/// Emacs normal mode
|
||||
Emacs,
|
||||
|
||||
/// A vi-specific mode
|
||||
Vi(PromptViMode),
|
||||
|
||||
/// A custom mode
|
||||
Custom(String),
|
||||
}
|
||||
|
||||
/// The vi-specific modes that the prompt can be in
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, EnumIter)]
|
||||
pub enum PromptViMode {
|
||||
/// The default mode
|
||||
Normal,
|
||||
|
||||
/// Insertion mode
|
||||
Insert,
|
||||
}
|
||||
|
||||
impl Default for PromptViMode {
|
||||
fn default() -> Self {
|
||||
PromptViMode::Normal
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for PromptEditMode {
|
||||
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
PromptEditMode::Default => write!(f, "Default"),
|
||||
PromptEditMode::Emacs => write!(f, "Emacs"),
|
||||
PromptEditMode::Vi(_) => write!(f, "Vi_Normal\nVi_Insert"),
|
||||
PromptEditMode::Custom(s) => write!(f, "Custom_{}", s),
|
||||
}
|
||||
}
|
||||
}
|
||||
/// API to provide a custom prompt.
|
||||
///
|
||||
/// Implementors have to provide [`str`]-based content which will be
|
||||
/// displayed before the `LineBuffer` is drawn.
|
||||
pub trait Prompt: Send {
|
||||
/// Provide content off the right full prompt
|
||||
fn render_prompt_left(&self) -> Cow<str>;
|
||||
/// Provide content off the left full prompt
|
||||
fn render_prompt_right(&self) -> Cow<str>;
|
||||
/// Render the default prompt indicator
|
||||
fn render_prompt_indicator(&self, prompt_mode: PromptEditMode) -> Cow<str>;
|
||||
/// Render the default prompt indicator
|
||||
fn render_prompt_multiline_indicator(&self) -> Cow<str>;
|
||||
/// Render the default prompt indicator
|
||||
fn render_prompt_history_search_indicator(
|
||||
&self,
|
||||
history_search: PromptHistorySearch,
|
||||
) -> Cow<str>;
|
||||
/// Render the vi insert mode prompt indicator
|
||||
/// Get back the prompt color
|
||||
fn get_prompt_color(&self) -> Color {
|
||||
DEFAULT_PROMPT_COLOR
|
||||
}
|
||||
}
|
||||
|
||||
impl Prompt for DefaultPrompt {
|
||||
fn render_prompt_left(&self) -> Cow<str> {
|
||||
{
|
||||
let left_prompt = get_working_dir().unwrap_or_else(|_| String::from("no path"));
|
||||
|
||||
Cow::Owned(left_prompt)
|
||||
}
|
||||
}
|
||||
|
||||
fn render_prompt_right(&self) -> Cow<str> {
|
||||
{
|
||||
Cow::Owned(get_now())
|
||||
}
|
||||
}
|
||||
|
||||
fn render_prompt_indicator(&self, edit_mode: PromptEditMode) -> Cow<str> {
|
||||
match edit_mode {
|
||||
PromptEditMode::Default | PromptEditMode::Emacs => DEFAULT_PROMPT_INDICATOR.into(),
|
||||
PromptEditMode::Vi(vi_mode) => match vi_mode {
|
||||
PromptViMode::Normal => DEFAULT_VI_NORMAL_PROMPT_INDICATOR.into(),
|
||||
PromptViMode::Insert => DEFAULT_VI_INSERT_PROMPT_INDICATOR.into(),
|
||||
},
|
||||
PromptEditMode::Custom(str) => format!("({})", str).into(),
|
||||
}
|
||||
}
|
||||
|
||||
fn render_prompt_multiline_indicator(&self) -> Cow<str> {
|
||||
Cow::Borrowed(DEFAULT_MULTILINE_INDICATOR)
|
||||
}
|
||||
|
||||
fn render_prompt_history_search_indicator(
|
||||
&self,
|
||||
history_search: PromptHistorySearch,
|
||||
) -> Cow<str> {
|
||||
let prefix = match history_search.status {
|
||||
PromptHistorySearchStatus::Passing => "",
|
||||
PromptHistorySearchStatus::Failing => "failing ",
|
||||
};
|
||||
// NOTE: magic strings, given there is logic on how these compose I am not sure if it
|
||||
// is worth extracting in to static constant
|
||||
Cow::Owned(format!(
|
||||
"({}reverse-search: {}) ",
|
||||
prefix, history_search.term
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for DefaultPrompt {
|
||||
fn default() -> Self {
|
||||
DefaultPrompt::new()
|
||||
}
|
||||
}
|
||||
|
||||
/// Simple two-line [`Prompt`] displaying the current working directory and the time above the entry line.
|
||||
#[derive(Clone)]
|
||||
pub struct DefaultPrompt;
|
||||
|
||||
impl DefaultPrompt {
|
||||
/// Constructor for the default prompt, which takes the amount of spaces required between the left and right-hand sides of the prompt
|
||||
pub fn new() -> DefaultPrompt {
|
||||
DefaultPrompt {}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_working_dir() -> Result<String, std::io::Error> {
|
||||
let path = env::current_dir()?;
|
||||
Ok(path.display().to_string())
|
||||
}
|
||||
|
||||
fn get_now() -> String {
|
||||
let now = Local::now();
|
||||
format!("{:>}", now.format("%m/%d/%Y %I:%M:%S %p"))
|
||||
}
|
106
src/prompt/base.rs
Normal file
106
src/prompt/base.rs
Normal file
@ -0,0 +1,106 @@
|
||||
use {
|
||||
crossterm::style::Color,
|
||||
serde::{Deserialize, Serialize},
|
||||
std::{
|
||||
borrow::Cow,
|
||||
fmt::{Display, Formatter},
|
||||
},
|
||||
strum_macros::EnumIter,
|
||||
};
|
||||
|
||||
/// The default color for the prompt
|
||||
pub static DEFAULT_PROMPT_COLOR: Color = Color::Blue;
|
||||
|
||||
/// The current success/failure of the history search
|
||||
pub enum PromptHistorySearchStatus {
|
||||
/// Success for the search
|
||||
Passing,
|
||||
|
||||
/// Failure to find the search
|
||||
Failing,
|
||||
}
|
||||
|
||||
/// A representation of the history search
|
||||
pub struct PromptHistorySearch {
|
||||
/// The status of the search
|
||||
pub status: PromptHistorySearchStatus,
|
||||
|
||||
/// The search term used during the search
|
||||
pub term: String,
|
||||
}
|
||||
|
||||
impl PromptHistorySearch {
|
||||
/// A constructor to create a history search
|
||||
pub fn new(status: PromptHistorySearchStatus, search_term: String) -> Self {
|
||||
PromptHistorySearch {
|
||||
status,
|
||||
term: search_term,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Modes that the prompt can be in
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, EnumIter)]
|
||||
pub enum PromptEditMode {
|
||||
/// The default mode
|
||||
Default,
|
||||
|
||||
/// Emacs normal mode
|
||||
Emacs,
|
||||
|
||||
/// A vi-specific mode
|
||||
Vi(PromptViMode),
|
||||
|
||||
/// A custom mode
|
||||
Custom(String),
|
||||
}
|
||||
|
||||
/// The vi-specific modes that the prompt can be in
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, EnumIter)]
|
||||
pub enum PromptViMode {
|
||||
/// The default mode
|
||||
Normal,
|
||||
|
||||
/// Insertion mode
|
||||
Insert,
|
||||
}
|
||||
|
||||
impl Default for PromptViMode {
|
||||
fn default() -> Self {
|
||||
PromptViMode::Normal
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for PromptEditMode {
|
||||
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
PromptEditMode::Default => write!(f, "Default"),
|
||||
PromptEditMode::Emacs => write!(f, "Emacs"),
|
||||
PromptEditMode::Vi(_) => write!(f, "Vi_Normal\nVi_Insert"),
|
||||
PromptEditMode::Custom(s) => write!(f, "Custom_{}", s),
|
||||
}
|
||||
}
|
||||
}
|
||||
/// API to provide a custom prompt.
|
||||
///
|
||||
/// Implementors have to provide [`str`]-based content which will be
|
||||
/// displayed before the `LineBuffer` is drawn.
|
||||
pub trait Prompt: Send {
|
||||
/// Provide content off the right full prompt
|
||||
fn render_prompt_left(&self) -> Cow<str>;
|
||||
/// Provide content off the left full prompt
|
||||
fn render_prompt_right(&self) -> Cow<str>;
|
||||
/// Render the prompt indicator (Last part of the prompt that changes based on the editor mode)
|
||||
fn render_prompt_indicator(&self, prompt_mode: PromptEditMode) -> Cow<str>;
|
||||
/// Indicator to show before explicit new lines
|
||||
fn render_prompt_multiline_indicator(&self) -> Cow<str>;
|
||||
/// Render the prompt indicator for `Ctrl-R` history search
|
||||
fn render_prompt_history_search_indicator(
|
||||
&self,
|
||||
history_search: PromptHistorySearch,
|
||||
) -> Cow<str>;
|
||||
/// Get back the prompt color
|
||||
fn get_prompt_color(&self) -> Color {
|
||||
DEFAULT_PROMPT_COLOR
|
||||
}
|
||||
}
|
86
src/prompt/default.rs
Normal file
86
src/prompt/default.rs
Normal file
@ -0,0 +1,86 @@
|
||||
use crate::{Prompt, PromptEditMode, PromptHistorySearch, PromptHistorySearchStatus, PromptViMode};
|
||||
|
||||
use {
|
||||
chrono::Local,
|
||||
std::{borrow::Cow, env},
|
||||
};
|
||||
|
||||
/// The default prompt indicator
|
||||
pub static DEFAULT_PROMPT_INDICATOR: &str = "〉";
|
||||
pub static DEFAULT_VI_INSERT_PROMPT_INDICATOR: &str = ": ";
|
||||
pub static DEFAULT_VI_NORMAL_PROMPT_INDICATOR: &str = "〉";
|
||||
pub static DEFAULT_MULTILINE_INDICATOR: &str = "::: ";
|
||||
|
||||
/// Simple two-line [`Prompt`] displaying the current working directory and the time above the entry line.
|
||||
#[derive(Clone)]
|
||||
pub struct DefaultPrompt;
|
||||
|
||||
impl Prompt for DefaultPrompt {
|
||||
fn render_prompt_left(&self) -> Cow<str> {
|
||||
{
|
||||
let left_prompt = get_working_dir().unwrap_or_else(|_| String::from("no path"));
|
||||
|
||||
Cow::Owned(left_prompt)
|
||||
}
|
||||
}
|
||||
|
||||
fn render_prompt_right(&self) -> Cow<str> {
|
||||
{
|
||||
Cow::Owned(get_now())
|
||||
}
|
||||
}
|
||||
|
||||
fn render_prompt_indicator(&self, edit_mode: PromptEditMode) -> Cow<str> {
|
||||
match edit_mode {
|
||||
PromptEditMode::Default | PromptEditMode::Emacs => DEFAULT_PROMPT_INDICATOR.into(),
|
||||
PromptEditMode::Vi(vi_mode) => match vi_mode {
|
||||
PromptViMode::Normal => DEFAULT_VI_NORMAL_PROMPT_INDICATOR.into(),
|
||||
PromptViMode::Insert => DEFAULT_VI_INSERT_PROMPT_INDICATOR.into(),
|
||||
},
|
||||
PromptEditMode::Custom(str) => format!("({})", str).into(),
|
||||
}
|
||||
}
|
||||
|
||||
fn render_prompt_multiline_indicator(&self) -> Cow<str> {
|
||||
Cow::Borrowed(DEFAULT_MULTILINE_INDICATOR)
|
||||
}
|
||||
|
||||
fn render_prompt_history_search_indicator(
|
||||
&self,
|
||||
history_search: PromptHistorySearch,
|
||||
) -> Cow<str> {
|
||||
let prefix = match history_search.status {
|
||||
PromptHistorySearchStatus::Passing => "",
|
||||
PromptHistorySearchStatus::Failing => "failing ",
|
||||
};
|
||||
// NOTE: magic strings, given there is logic on how these compose I am not sure if it
|
||||
// is worth extracting in to static constant
|
||||
Cow::Owned(format!(
|
||||
"({}reverse-search: {}) ",
|
||||
prefix, history_search.term
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for DefaultPrompt {
|
||||
fn default() -> Self {
|
||||
DefaultPrompt::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl DefaultPrompt {
|
||||
/// Constructor for the default prompt, which takes the amount of spaces required between the left and right-hand sides of the prompt
|
||||
pub fn new() -> DefaultPrompt {
|
||||
DefaultPrompt {}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_working_dir() -> Result<String, std::io::Error> {
|
||||
let path = env::current_dir()?;
|
||||
Ok(path.display().to_string())
|
||||
}
|
||||
|
||||
fn get_now() -> String {
|
||||
let now = Local::now();
|
||||
format!("{:>}", now.format("%m/%d/%Y %I:%M:%S %p"))
|
||||
}
|
8
src/prompt/mod.rs
Normal file
8
src/prompt/mod.rs
Normal file
@ -0,0 +1,8 @@
|
||||
mod base;
|
||||
mod default;
|
||||
|
||||
pub use base::{
|
||||
Prompt, PromptEditMode, PromptHistorySearch, PromptHistorySearchStatus, PromptViMode,
|
||||
};
|
||||
|
||||
pub use default::DefaultPrompt;
|
Loading…
Reference in New Issue
Block a user