use super::config_gen::{BG_COLOR, PREFIX_COLOR, SEP_COLOR};
use super::settings::{PromptStyle, WizardSettings};
pub fn sample(s: &WizardSettings) -> (Vec<String>, Vec<String>) {
let v = |a: &[&str]| a.iter().map(|x| x.to_string()).collect::<Vec<_>>();
match s.style {
PromptStyle::Lean => (
v(&[
"%$FF╭─ ",
"%31F%B%39F~%b%31F/%B%39Fsrc%b%f $PFX1%76F$EI3master%f ",
"%$FF╰─",
"%76F$PC%f $CUR",
]),
v(&[
" $PFX2%101F$EI45s%f$TIMEBLK",
" %$FF─╮%f",
"",
" %$FF─╯%f",
]),
),
PromptStyle::Lean8 => (
v(&[
"%$FF╭─ ",
"%4F~/src%f $PFX1%2F$EI3master%f ",
"%$FF╰─",
"%2F$PC%f $CUR",
]),
v(&[
" $PFX2%3F$EI45s%f$TIMEBLK8",
" %$FF─╮%f",
"",
" %$FF─╯%f",
]),
),
PromptStyle::Classic => (
v(&[
"%$FF╭─",
"%F{$BG}$LTAIL%K{$BG} %31F%B%39F~%b%K{$BG}%31F/%B%39Fsrc%b%K{$BG} %$SEPF$LSUB%f %$PFXF$PFX1%76F$EI3master %k%$BGF$LHEAD%f",
"%$FF╰─",
"%f $CUR",
]),
v(&[
"%$BGF$RHEAD%K{$BG}%f %$PFXF$PFX2%101F5s $EI4$TIMEBLKC%k%F{$BG}$RTAIL%f",
"%$FF─╮%f",
"",
"%$FF─╯%f",
]),
),
PromptStyle::Rainbow => (
v(&[
"%$FF╭─",
"%F{4}$LTAIL%K{4}%254F $EI2%B%255F~%b%K{4}%254F/%B%255Fsrc%b%K{4} %K{2}%4F$LSEP %0F$PFX1$EI3master %k%2F$LHEAD%f",
"%$FF╰─",
"%f $CUR",
]),
v(&[
"%3F$RHEAD%K{3} %0F$PFX25s $EI4%3F$TIMEBLKR%k$RTAIL%f",
"%$FF─╮%f",
"",
"%$FF─╯%f",
]),
),
PromptStyle::Pure => (
v(&[
"",
"%F{$PBLUE}~/src%f %F{$PGREY}master%f $PURERP_L",
"",
"%F{$PMAG}$PC%f $CUR",
]),
v(&["$PURERP_R", "", "", ""]),
),
}
}
pub fn substitute(t: &str, s: &WizardSettings) -> String {
let ci = s.color as usize;
let fc = s.frame_color[ci.min(3)];
let cursor = "%S %s"; let ei = |n: usize| -> String {
let g = s.extra_icons.get(n).cloned().unwrap_or_default();
if g.is_empty() { String::new() } else { format!("{g} ") }
};
let pfx = |n: usize| -> String {
let p = s.prefixes.get(n).cloned().unwrap_or_default();
if p.is_empty() { String::new() } else { p }
};
let time_blk = |fg: &str| -> String {
match &s.time {
Some(t) => format!(" %{fg}F{t}%f"),
None => String::new(),
}
};
let pure_rp_l = if s.pure_use_rprompt { String::new() } else { format!("%F{{{}}}5s%f ", s.pure_color("yellow")) };
let pure_rp_r = if s.pure_use_rprompt {
let mut r = format!("%F{{{}}}5s%f", s.pure_color("yellow"));
if let Some(t) = &s.time {
r.push_str(&format!(" %F{{{}}}{t}%f", s.pure_color("grey")));
}
r
} else {
match &s.time {
Some(t) => format!("%F{{{}}}{t}%f", s.pure_color("grey")),
None => String::new(),
}
};
let mut out = t.to_string();
let reps: &[(&str, String)] = &[
("$FF", format!("{}F", fc)),
("$BGF", format!("{}F", BG_COLOR[ci])),
("$BG", BG_COLOR[ci].to_string()),
("$SEPF", format!("{}F", SEP_COLOR[ci])),
("$PFXF", format!("{}F", PREFIX_COLOR[ci])),
("$LSEP", s.left_sep.clone()),
("$RSEP", s.right_sep.clone()),
("$LSUB", s.left_subsep.clone()),
("$RSUB", s.right_subsep.clone()),
("$LHEAD", s.left_head.clone()),
("$RHEAD", s.right_head.clone()),
("$LTAIL", s.left_tail.clone()),
("$RTAIL", s.right_tail.clone()),
("$PC", s.prompt_char.clone()),
("$CUR", cursor.to_string()),
("$PFX1", pfx(0)),
("$PFX2", pfx(1)),
("$EI2", ei(1)),
("$EI3", ei(2)),
("$EI45", ei(3)),
("$TIMEBLK8", time_blk("6")),
("$TIMEBLKC", time_blk(&SEP_COLOR[ci].to_string())),
("$TIMEBLKR", time_blk("7")),
("$TIMEBLK", time_blk("66")),
("$PBLUE", s.pure_color("blue").to_string()),
("$PGREY", s.pure_color("grey").to_string()),
("$PMAG", s.pure_color("magenta").to_string()),
("$PURERP_L", pure_rp_l),
("$PURERP_R", pure_rp_r),
];
let mut ordered: Vec<&(&str, String)> = reps.iter().collect();
ordered.sort_by_key(|(k, _)| std::cmp::Reverse(k.len()));
for (k, val) in ordered {
if out.contains(k) {
out = out.replace(k, val);
}
}
out
}
pub fn visible_width(expanded: &str) -> usize {
let mut out = String::with_capacity(expanded.len());
let mut it = expanded.chars().peekable();
while let Some(c) = it.next() {
if c == '\u{1b}' {
if it.peek() == Some(&'[') {
it.next();
for c in it.by_ref() {
if ('\u{40}'..='\u{7e}').contains(&c) {
break;
}
}
} else {
it.next();
}
continue;
}
out.push(c);
}
out.chars()
.map(|c| crate::ported::zsh_h::WCWIDTH(c).max(0) as usize)
.sum()
}