1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
use chrono::Local;
use crossterm::terminal;
use std::env;
pub struct Prompt {
prompt_indicator: String,
min_center_spacing: u16,
}
impl Prompt {
pub fn new<P: AsRef<str>>(prompt_indicator: P, min_center_spacing: u16) -> Prompt {
Prompt {
prompt_indicator: prompt_indicator.as_ref().into(),
min_center_spacing,
}
}
pub fn print_prompt(&mut self) -> String {
let mut prompt_str = String::new();
let cols = usize::from(get_terminal_size().0);
let mut left_prompt = get_working_dir().unwrap_or_else(|_| String::from("no path"));
left_prompt.truncate(cols);
let left_prompt_width = left_prompt.chars().count();
prompt_str.push_str(&left_prompt);
let right_prompt = get_now();
let right_prompt_width = right_prompt.chars().count();
if left_prompt_width + usize::from(self.min_center_spacing) + right_prompt_width <= cols {
let right_prompt = format!("{:>width$}", get_now(), width = cols - left_prompt_width);
prompt_str.push_str(&right_prompt);
} else if left_prompt_width < cols {
let right_padding = format!("{:>width$}", "", width = cols - left_prompt_width);
prompt_str.push_str(&right_padding);
}
prompt_str.push_str(&self.prompt_indicator);
prompt_str
}
}
fn get_terminal_size() -> (u16, u16) {
let ts = terminal::size();
match ts {
Ok((columns, rows)) => (columns, rows),
Err(_) => (0, 0),
}
}
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"))
}