use reedline::{Prompt, PromptEditMode, PromptHistorySearch, PromptHistorySearchStatus};
use std::borrow::Cow;
pub struct SelfwarePrompt {
model: String,
step: usize,
context_pct: f64,
}
impl SelfwarePrompt {
pub fn new() -> Self {
Self {
model: String::new(),
step: 0,
context_pct: 0.0,
}
}
pub fn with_context(model: &str, step: usize) -> Self {
Self {
model: model.to_string(),
step,
context_pct: 0.0,
}
}
pub fn with_full_context(model: &str, step: usize, context_pct: f64) -> Self {
Self {
model: model.to_string(),
step,
context_pct,
}
}
fn fox(&self) -> &'static str {
"🦊"
}
fn garden_glyph(&self) -> &'static str {
match self.step % 4 {
0 => "🌱",
1 => "🌿",
2 => "🍃",
_ => "🌳",
}
}
}
impl Default for SelfwarePrompt {
fn default() -> Self {
Self::new()
}
}
#[allow(mismatched_lifetime_syntaxes)]
impl Prompt for SelfwarePrompt {
fn render_prompt_left(&self) -> Cow<str> {
if self.step > 0 {
Cow::Owned(format!("{} {} ", self.fox(), self.garden_glyph()))
} else {
Cow::Owned(format!("{} ", self.fox()))
}
}
fn render_prompt_right(&self) -> Cow<str> {
if !self.model.is_empty() {
let short_model = if self.model.len() > 20 {
let safe_truncate: String = self.model.chars().take(17).collect();
format!("{}...", safe_truncate)
} else {
self.model.clone()
};
if self.context_pct > 0.0 {
Cow::Owned(format!("[{}] {:.1}% used", short_model, self.context_pct))
} else {
Cow::Owned(format!("[{}]", short_model))
}
} else {
Cow::Borrowed("")
}
}
fn render_prompt_indicator(&self, edit_mode: PromptEditMode) -> Cow<str> {
match edit_mode {
PromptEditMode::Default | PromptEditMode::Emacs => Cow::Borrowed("❯ "),
PromptEditMode::Vi(vi_mode) => match vi_mode {
reedline::PromptViMode::Normal => Cow::Borrowed("❮ "),
reedline::PromptViMode::Insert => Cow::Borrowed("❯ "),
},
PromptEditMode::Custom(s) => Cow::Owned(format!("{} ", s)),
}
}
fn render_prompt_multiline_indicator(&self) -> Cow<str> {
Cow::Borrowed(" ⋮ ")
}
fn render_prompt_history_search_indicator(
&self,
history_search: PromptHistorySearch,
) -> Cow<str> {
let prefix = match history_search.status {
PromptHistorySearchStatus::Passing => "🔍",
PromptHistorySearchStatus::Failing => "❌",
};
Cow::Owned(format!("{} [{}]: ", prefix, history_search.term))
}
}
#[cfg(test)]
#[path = "../../tests/unit/input/prompt/prompt_test.rs"]
mod tests;