mod git;
mod jarvis;
pub mod starship;
use std::borrow::Cow;
use std::path::PathBuf;
use std::sync::atomic::{AtomicI32, AtomicU64};
use std::sync::Arc;
use reedline::{Color, Prompt, PromptEditMode, PromptHistorySearch};
use crate::config::PromptConfig;
use jarvis::JarvisPrompt;
use starship::StarshipPrompt;
pub use jarvis::EXIT_CODE_NONE;
pub enum ShellPrompt {
Builtin(JarvisPrompt),
Starship(StarshipPrompt),
}
impl ShellPrompt {
pub fn builtin(last_exit_code: Arc<AtomicI32>, config: PromptConfig) -> Self {
Self::Builtin(JarvisPrompt::new(last_exit_code, config))
}
pub fn starship(
last_exit_code: Arc<AtomicI32>,
cmd_duration_ms: Arc<AtomicU64>,
starship_path: PathBuf,
) -> Self {
Self::Starship(StarshipPrompt::new(
last_exit_code,
cmd_duration_ms,
starship_path,
))
}
pub fn refresh_git_status(&self) {
match self {
Self::Builtin(ref p) => p.refresh_git_status(),
Self::Starship(ref p) => p.mark_dirty(),
}
}
}
impl Prompt for ShellPrompt {
fn render_prompt_left(&self) -> Cow<'_, str> {
match self {
Self::Builtin(p) => p.render_prompt_left(),
Self::Starship(p) => p.render_prompt_left(),
}
}
fn get_prompt_color(&self) -> Color {
match self {
Self::Builtin(p) => p.get_prompt_color(),
Self::Starship(p) => p.get_prompt_color(),
}
}
fn render_prompt_right(&self) -> Cow<'_, str> {
match self {
Self::Builtin(p) => p.render_prompt_right(),
Self::Starship(p) => p.render_prompt_right(),
}
}
fn render_prompt_indicator(&self, edit_mode: PromptEditMode) -> Cow<'_, str> {
match self {
Self::Builtin(p) => p.render_prompt_indicator(edit_mode),
Self::Starship(p) => p.render_prompt_indicator(edit_mode),
}
}
fn render_prompt_multiline_indicator(&self) -> Cow<'_, str> {
match self {
Self::Builtin(p) => p.render_prompt_multiline_indicator(),
Self::Starship(p) => p.render_prompt_multiline_indicator(),
}
}
fn render_prompt_history_search_indicator(
&self,
history_search: PromptHistorySearch,
) -> Cow<'_, str> {
match self {
Self::Builtin(p) => p.render_prompt_history_search_indicator(history_search),
Self::Starship(p) => p.render_prompt_history_search_indicator(history_search),
}
}
}
#[cfg(test)]
mod tests {
use super::jarvis::{dirs_home, shorten_path};
use std::path::PathBuf;
#[test]
fn shorten_home_dir_itself() {
if let Some(home) = dirs_home() {
assert_eq!(shorten_path(&home), "~");
}
}
#[test]
fn shorten_home_subdir() {
if let Some(home) = dirs_home() {
let sub = home.join("dev").join("project");
assert_eq!(shorten_path(&sub), "~/dev/project");
}
}
#[test]
fn shorten_outside_home() {
let path = PathBuf::from("/tmp");
assert_eq!(shorten_path(&path), "/tmp");
}
}