nu_cli/completions/
file_completions.rs

1use crate::completions::{
2    Completer, CompletionOptions,
3    completion_common::{AdjustView, adjust_if_intermediate, complete_item},
4};
5use nu_protocol::{
6    Span, SuggestionKind,
7    engine::{Stack, StateWorkingSet},
8};
9use reedline::Suggestion;
10use std::path::Path;
11
12use super::SemanticSuggestion;
13
14pub struct FileCompletion;
15
16impl Completer for FileCompletion {
17    fn fetch(
18        &mut self,
19        working_set: &StateWorkingSet,
20        stack: &Stack,
21        prefix: impl AsRef<str>,
22        span: Span,
23        offset: usize,
24        options: &CompletionOptions,
25    ) -> Vec<SemanticSuggestion> {
26        let AdjustView {
27            prefix,
28            span,
29            readjusted,
30        } = adjust_if_intermediate(prefix.as_ref(), working_set, span);
31
32        #[allow(deprecated)]
33        let items: Vec<_> = complete_item(
34            readjusted,
35            span,
36            &prefix,
37            &[&working_set.permanent_state.current_work_dir()],
38            options,
39            working_set.permanent_state,
40            stack,
41        )
42        .into_iter()
43        .map(move |x| SemanticSuggestion {
44            suggestion: Suggestion {
45                value: x.path,
46                style: x.style,
47                span: reedline::Span {
48                    start: x.span.start - offset,
49                    end: x.span.end - offset,
50                },
51                ..Suggestion::default()
52            },
53            kind: Some(if x.is_dir {
54                SuggestionKind::Directory
55            } else {
56                SuggestionKind::File
57            }),
58        })
59        .collect();
60
61        // Sort results prioritizing the non hidden folders
62
63        // Separate the results between hidden and non hidden
64        let mut hidden: Vec<SemanticSuggestion> = vec![];
65        let mut non_hidden: Vec<SemanticSuggestion> = vec![];
66
67        for item in items.into_iter() {
68            let item_path = Path::new(&item.suggestion.value);
69
70            if let Some(value) = item_path.file_name()
71                && let Some(value) = value.to_str()
72            {
73                if value.starts_with('.') {
74                    hidden.push(item);
75                } else {
76                    non_hidden.push(item);
77                }
78            }
79        }
80
81        // Append the hidden folders to the non hidden vec to avoid creating a new vec
82        non_hidden.append(&mut hidden);
83
84        non_hidden
85    }
86}