use crate::completer::ShellCompleter;
use core::time::Duration;
use linefeed::{terminal::DefaultTerminal, Interface, ReadResult};
use std::sync::{Arc, Mutex};
use std::thread::sleep;
pub struct AutoCompleteReader {
interface: Interface<DefaultTerminal>,
completer: Arc<ShellCompleter>,
}
impl AutoCompleteReader {
pub fn read(&self) -> Result<String, String> {
sleep(Duration::from_millis(10));
match self
.interface
.read_line()
.map_err(|err| format!("read error : {}", err))?
{
ReadResult::Input(line) => {
if !line.trim().is_empty() {
self.interface.add_history(line.clone());
}
Ok(line)
}
ReadResult::Eof => {
Ok("".to_owned())
}
ReadResult::Signal(s) => {
Err(format!("recv signal {:?}", s))
}
}
}
pub fn set_debug_command_complete_data(&mut self, data: Vec<(String, String)>) {
self.completer.set_autocomplete_data(data);
}
pub fn append_debug_command_complete_data(&mut self, data: Vec<(String, String)>) {
self.completer.append_complete_data(data);
}
pub fn set_prompt(&mut self, p: &str) {
self.interface.set_prompt(p).expect("set prompt failed");
}
}
#[macro_export]
macro_rules! reg_completer {
($($t:ty),*) => {
vec![
$(
(
<$t>::filter as fn(&str, &str) -> bool,
<$t>::new(),
),
)*
]
};
}
impl AutoCompleteReader {
pub fn new() -> Result<Arc<Mutex<Box<AutoCompleteReader>>>, String> {
let mut ret = Box::<AutoCompleteReader>::new(AutoCompleteReader {
interface: Interface::new("ushell-rust").expect("create interface failed"),
completer: ShellCompleter::new(),
});
ret.set_prompt(">> ");
ret.interface.set_completer(ret.completer.clone());
Ok(Arc::new(Mutex::new(ret)))
}
}