Skip to main content

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                display_override: x.display_override,
52                match_indices: Some(x.match_indices),
53                ..Suggestion::default()
54            },
55            kind: Some(if x.is_dir {
56                SuggestionKind::Directory
57            } else {
58                SuggestionKind::File
59            }),
60        })
61        .collect();
62
63        // Sort results prioritizing the non hidden folders
64
65        // Separate the results between hidden and non hidden
66        let mut hidden: Vec<SemanticSuggestion> = vec![];
67        let mut non_hidden: Vec<SemanticSuggestion> = vec![];
68
69        for item in items.into_iter() {
70            let item_path = Path::new(&item.suggestion.value);
71
72            if let Some(value) = item_path.file_name()
73                && let Some(value) = value.to_str()
74            {
75                if value.starts_with('.') {
76                    hidden.push(item);
77                } else {
78                    non_hidden.push(item);
79                }
80            }
81        }
82
83        // Append the hidden folders to the non hidden vec to avoid creating a new vec
84        non_hidden.append(&mut hidden);
85
86        non_hidden
87    }
88}