use std::io::Write;
use std::{string::String, vec::Vec};
pub struct CommandHistory {
history: Vec<String>,
current_index: usize,
max_size: usize,
}
impl CommandHistory {
pub fn new(max_size: usize) -> Self {
Self {
history: Vec::new(),
current_index: 0,
max_size,
}
}
pub fn add_command(&mut self, cmd: String) {
if !cmd.trim().is_empty() && self.history.last() != Some(&cmd) {
if self.history.len() >= self.max_size {
self.history.remove(0);
}
self.history.push(cmd);
}
self.current_index = self.history.len();
}
#[allow(dead_code)]
pub fn previous(&mut self) -> Option<&String> {
if self.current_index > 0 {
self.current_index -= 1;
self.history.get(self.current_index)
} else {
None
}
}
#[allow(dead_code)]
pub fn next(&mut self) -> Option<&String> {
if self.current_index < self.history.len() {
self.current_index += 1;
if self.current_index < self.history.len() {
self.history.get(self.current_index)
} else {
None
}
} else {
None
}
}
}
pub fn redraw_line(prompt: &str, content: &str, cursor_pos: usize) -> Vec<u8> {
let mut output = Vec::with_capacity(
prompt
.len()
.saturating_add(content.len())
.saturating_add(16),
);
output.extend_from_slice(b"\r\x1b[2K");
output.extend_from_slice(prompt.as_bytes());
output.extend_from_slice(content.as_bytes());
if cursor_pos < content.len() {
write!(output, "\x1b[{}D", content.len() - cursor_pos)
.expect("writing into Vec cannot fail");
}
output
}