use super::*;
use cmdtree::completion::CompletionInfo;
use cmdtree::Commander;
use std::borrow::Cow;
pub struct TreeCompleter {
items: Vec<CompletionInfo>,
}
impl TreeCompleter {
pub fn build<T>(cmdr: &Commander<T>) -> Self {
let mut items = cmdtree::completion::create_tree_completion_items(&cmdr);
items.iter_mut().for_each(|x| {
if cmdr.at_root() {
x.completestr.insert_str(0, crate::CMD_PREFIX);
}
});
Self { items }
}
pub fn word_break(line: &str) -> usize {
word_break_start(line, &[' '])
}
pub fn complete<'b>(
&'b self,
line: &'b str,
) -> impl Iterator<Item = (&'b str, &'b CompletionInfo)> {
cmdtree::completion::tree_completions(line, self.items.iter())
}
}
pub struct ActionArgComplete {
pub items: Vec<cmdtree::completion::ActionMatch>,
}
impl ActionArgComplete {
pub fn build<T>(cmdr: &Commander<T>) -> Self {
let mut items = cmdtree::completion::create_action_completion_items(&cmdr);
items.iter_mut().for_each(|x| {
if cmdr.at_root() {
x.info.completestr.insert_str(0, crate::CMD_PREFIX);
}
});
Self { items }
}
pub fn find<'a>(&self, line: &'a str, valid: &[&str]) -> Option<ArgComplete<'a>> {
self.items
.iter()
.find(|x| line.starts_with(x.info.completestr.as_str()))
.and_then(|x| {
if valid.contains(&x.qualified_path.as_str()) {
let line = &line[x.info.completestr.len()..];
let word_start = word_break_start(line, &[' ']);
Some(ArgComplete {
line,
word: &line[word_start..],
word_start,
help_msg: x.info.help_msg.inner_cow.clone(),
})
} else {
None
}
})
}
}
#[derive(Debug, PartialEq)]
pub struct ArgComplete<'a> {
pub line: &'a str,
pub word: &'a str,
pub word_start: usize,
pub help_msg: Cow<'static, str>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn arg_complete_test() {
let items = vec![cmdtree::completion::ActionMatch {
info: CompletionInfo {
completestr: "some action ".to_string(),
itemtype: cmdtree::ItemType::Action,
help_msg: "".into(),
},
qualified_path: "some..action".to_string(),
}];
let valid = ["some..action"];
let a = ActionArgComplete { items };
let f = a.find("some action arg1", &valid).unwrap();
assert_eq!(
f,
ArgComplete {
line: "arg1",
word: "arg1",
word_start: 0,
help_msg: Cow::Borrowed("")
}
);
let f = a.find("some action arg1 argu", &valid).unwrap();
assert_eq!(
f,
ArgComplete {
line: "arg1 argu",
word: "argu",
word_start: 5,
help_msg: Cow::Borrowed("")
}
);
}
}