use crate::{
types::xvcroot::{find_root, XvcRootInner},
Result, XvcPath,
};
use std::{env, ffi::OsStr, path::Path};
use clap_complete::CompletionCandidate;
use xvc_ecs::{Storable, XvcStore};
pub fn git_reference_completer(current: &std::ffi::OsStr) -> Vec<CompletionCandidate> {
let current = current.to_string_lossy();
crate::git::gix_list_references(Path::new("."))
.map(|refs| {
refs.iter()
.filter_map(|r| {
if r.starts_with(current.as_ref()) {
Some(CompletionCandidate::new(r))
} else {
None
}
})
.collect()
})
.unwrap_or_default()
}
pub fn git_branch_completer(current: &std::ffi::OsStr) -> Vec<CompletionCandidate> {
let current = current.to_string_lossy();
crate::git::gix_list_branches(Path::new("."))
.map(|refs| {
refs.iter()
.filter_map(|r| {
if r.starts_with(current.as_ref()) {
Some(CompletionCandidate::new(r))
} else {
None
}
})
.collect()
})
.unwrap_or_default()
}
pub fn strum_variants_completer<T: strum::VariantNames>(
current: &std::ffi::OsStr,
) -> Vec<CompletionCandidate> {
let current = current.to_string_lossy();
let variants = T::VARIANTS;
variants
.iter()
.filter_map(|v| {
if (**v).starts_with(current.as_ref()) {
Some(CompletionCandidate::new(v))
} else {
None
}
})
.collect()
}
pub fn load_store_for_completion<T: Storable>(current_dir: &Path) -> Result<XvcStore<T>> {
let xvc_root_path = find_root(current_dir)?;
let xvc_dir = xvc_root_path.join(XvcRootInner::XVC_DIR);
let store_root = xvc_dir.join(XvcRootInner::STORE_DIR);
XvcStore::<T>::load_store(&store_root).map_err(|e| e.into())
}
pub fn xvc_path_completer(prefix: &OsStr) -> Vec<CompletionCandidate> {
let prefix = prefix.to_str().unwrap_or("");
if let Ok(current_dir) = env::current_dir() {
load_store_for_completion::<XvcPath>(¤t_dir)
.map(|xvc_path_store| {
let filtered = xvc_path_store.filter(|_, xp| xp.starts_with_str(prefix));
filtered
.iter()
.map(|(_, xp)| xp.to_string().into())
.collect()
})
.unwrap_or_default()
} else {
vec![]
}
}