Skip to main content

reedline/prompt/
base.rs

1use {
2    crossterm::style::Color,
3    serde::{Deserialize, Serialize},
4    std::{
5        borrow::Cow,
6        fmt::{Display, Formatter},
7    },
8    strum::{EnumIter, EnumString, IntoDiscriminant},
9};
10
11/// The default color for the prompt, indicator, and right prompt
12pub static DEFAULT_PROMPT_COLOR: Color = Color::Green;
13pub static DEFAULT_PROMPT_MULTILINE_COLOR: nu_ansi_term::Color = nu_ansi_term::Color::LightBlue;
14pub static DEFAULT_INDICATOR_COLOR: Color = Color::Cyan;
15pub static DEFAULT_PROMPT_RIGHT_COLOR: Color = Color::AnsiValue(5);
16
17/// The current success/failure of the history search
18pub enum PromptHistorySearchStatus {
19    /// Success for the search
20    Passing,
21
22    /// Failure to find the search
23    Failing,
24}
25
26/// A representation of the history search
27pub struct PromptHistorySearch {
28    /// The status of the search
29    pub status: PromptHistorySearchStatus,
30
31    /// The search term used during the search
32    pub term: String,
33}
34
35impl PromptHistorySearch {
36    /// A constructor to create a history search
37    pub const fn new(status: PromptHistorySearchStatus, search_term: String) -> Self {
38        PromptHistorySearch {
39            status,
40            term: search_term,
41        }
42    }
43}
44
45/// Modes that the prompt can be in
46#[derive(Serialize, Deserialize, Clone, Debug, EnumIter, Default)]
47pub enum PromptEditMode {
48    /// The default mode
49    #[default]
50    Default,
51
52    /// Emacs normal mode
53    Emacs,
54
55    /// A vi-specific mode
56    Vi(PromptViMode),
57
58    /// A custom mode
59    Custom(String),
60}
61
62/// The vi-specific modes that the prompt can be in
63#[derive(Serialize, Deserialize, Clone, Debug, EnumIter, Default)]
64pub enum PromptViMode {
65    /// The default mode
66    #[default]
67    Normal,
68
69    /// Insertion mode
70    Insert,
71}
72
73/// This is the discriminant type for [`PromptEditMode`]
74#[derive(Clone, Copy, Debug, PartialEq, Eq, Default, EnumIter, EnumString)]
75#[strum(ascii_case_insensitive)]
76pub enum PromptEditModeDiscriminants {
77    /// The default mode
78    #[default]
79    Default,
80
81    /// Emacs normal mode
82    Emacs,
83
84    /// Vi normal mode
85    #[strum(serialize = "ViNormal", serialize = "vi_normal")]
86    ViNormal,
87
88    /// Vi insert mode
89    #[strum(serialize = "ViInsert", serialize = "vi_insert")]
90    ViInsert,
91
92    /// A custom mode
93    Custom,
94}
95
96impl From<PromptViMode> for PromptEditMode {
97    fn from(value: PromptViMode) -> Self {
98        Self::Vi(value)
99    }
100}
101
102impl Display for PromptEditMode {
103    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
104        use PromptViMode as Vi;
105        match self {
106            Self::Default => write!(f, "Default"),
107            Self::Emacs => write!(f, "Emacs"),
108            Self::Vi(Vi::Normal) => write!(f, "Vi_Normal"),
109            Self::Vi(Vi::Insert) => write!(f, "Vi_Insert"),
110            Self::Custom(s) => write!(f, "Custom_{s}"),
111        }
112    }
113}
114
115impl IntoDiscriminant for PromptEditMode {
116    type Discriminant = PromptEditModeDiscriminants;
117
118    fn discriminant(&self) -> Self::Discriminant {
119        use PromptViMode as Vi;
120        match self {
121            Self::Default => Self::Discriminant::Default,
122            Self::Emacs => Self::Discriminant::Emacs,
123            Self::Vi(Vi::Normal) => Self::Discriminant::ViNormal,
124            Self::Vi(Vi::Insert) => Self::Discriminant::ViInsert,
125            Self::Custom(_) => Self::Discriminant::Custom,
126        }
127    }
128}
129
130/// API to provide a custom prompt.
131///
132/// Implementors have to provide [`str`]-based content which will be
133/// displayed before the `LineBuffer` is drawn.
134pub trait Prompt: Send {
135    /// Provide content of the left full prompt
136    fn render_prompt_left(&self) -> Cow<'_, str>;
137    /// Provide content of the right full prompt
138    fn render_prompt_right(&self) -> Cow<'_, str>;
139    /// Render the prompt indicator (Last part of the prompt that changes based on the editor mode)
140    fn render_prompt_indicator(&self, prompt_mode: PromptEditMode) -> Cow<'_, str>;
141    /// Indicator to show before explicit new lines
142    fn render_prompt_multiline_indicator(&self) -> Cow<'_, str>;
143    /// Render the prompt indicator for `Ctrl-R` history search
144    fn render_prompt_history_search_indicator(
145        &self,
146        history_search: PromptHistorySearch,
147    ) -> Cow<'_, str>;
148    /// Get the default prompt color
149    fn get_prompt_color(&self) -> Color {
150        DEFAULT_PROMPT_COLOR
151    }
152    /// Get the default multiline prompt color
153    fn get_prompt_multiline_color(&self) -> nu_ansi_term::Color {
154        DEFAULT_PROMPT_MULTILINE_COLOR
155    }
156    /// Get the default indicator color
157    fn get_indicator_color(&self) -> Color {
158        DEFAULT_INDICATOR_COLOR
159    }
160    /// Get the default right prompt color
161    fn get_prompt_right_color(&self) -> Color {
162        DEFAULT_PROMPT_RIGHT_COLOR
163    }
164
165    /// Whether to render right prompt on the last line
166    fn right_prompt_on_last_line(&self) -> bool {
167        false
168    }
169}