use crate::completions::{
Completer, CompletionOptions,
completion_common::{AdjustView, adjust_if_intermediate, complete_item},
};
use nu_protocol::{
Span, SuggestionKind,
engine::{EngineState, Stack, StateWorkingSet},
};
use reedline::Suggestion;
use std::path::Path;
use super::{SemanticSuggestion, completion_common::FileSuggestion};
pub struct DirectoryCompletion;
impl Completer for DirectoryCompletion {
fn fetch(
&mut self,
working_set: &StateWorkingSet,
stack: &Stack,
prefix: impl AsRef<str>,
span: Span,
offset: usize,
options: &CompletionOptions,
) -> Vec<SemanticSuggestion> {
let AdjustView { prefix, span, .. } =
adjust_if_intermediate(prefix.as_ref(), working_set, span);
#[allow(deprecated)]
let items: Vec<_> = directory_completion(
span,
&prefix,
&working_set.permanent_state.current_work_dir(),
options,
working_set.permanent_state,
stack,
)
.into_iter()
.map(move |x| SemanticSuggestion {
suggestion: Suggestion {
value: x.path,
style: x.style,
span: reedline::Span {
start: x.span.start - offset,
end: x.span.end - offset,
},
display_override: x.display_override,
match_indices: Some(x.match_indices),
..Suggestion::default()
},
kind: Some(SuggestionKind::Directory),
})
.collect();
let mut hidden: Vec<SemanticSuggestion> = vec![];
let mut non_hidden: Vec<SemanticSuggestion> = vec![];
for item in items.into_iter() {
let item_path = Path::new(&item.suggestion.value);
if let Some(value) = item_path.file_name()
&& let Some(value) = value.to_str()
{
if value.starts_with('.') {
hidden.push(item);
} else {
non_hidden.push(item);
}
}
}
non_hidden.append(&mut hidden);
non_hidden
}
}
pub fn directory_completion(
span: nu_protocol::Span,
partial: &str,
cwd: &str,
options: &CompletionOptions,
engine_state: &EngineState,
stack: &Stack,
) -> Vec<FileSuggestion> {
complete_item(true, span, partial, &[cwd], options, engine_state, stack)
}