diff --git a/crates/nu-cli/src/completions/file_completions.rs b/crates/nu-cli/src/completions/file_completions.rs index 255b6c4457..2c9ff2fbf4 100644 --- a/crates/nu-cli/src/completions/file_completions.rs +++ b/crates/nu-cli/src/completions/file_completions.rs @@ -1,7 +1,7 @@ -use crate::completions::{Completer, CompletionOptions, SortBy}; +use crate::completions::{Completer, CompletionOptions}; use nu_protocol::{ engine::{EngineState, StateWorkingSet}, - Span, + levenshtein_distance, Span, }; use reedline::Suggestion; use std::path::{is_separator, Path}; @@ -52,10 +52,51 @@ impl Completer for FileCompletion { .collect(); // Options - let options = CompletionOptions::new(true, true, SortBy::LevenshteinDistance); + let options = CompletionOptions::default(); (output, options) } + + // Sort results prioritizing the non hidden folders + fn sort( + &self, + items: Vec, + prefix: Vec, + _: CompletionOptions, // Ignore the given options, once it's a custom sorting + ) -> Vec { + let prefix_str = String::from_utf8_lossy(&prefix).to_string(); + + // Sort items + let mut sorted_items = items; + sorted_items.sort_by(|a, b| { + let a_distance = levenshtein_distance(&prefix_str, &a.value); + let b_distance = levenshtein_distance(&prefix_str, &b.value); + a_distance.cmp(&b_distance) + }); + + // Separate the results between hidden and non hidden + let mut hidden: Vec = vec![]; + let mut non_hidden: Vec = vec![]; + + for item in sorted_items.into_iter() { + let item_path = Path::new(&item.value); + + if let Some(value) = item_path.file_name() { + if let Some(value) = value.to_str() { + if value.starts_with('.') { + hidden.push(item); + } else { + non_hidden.push(item); + } + } + } + } + + // Append the hidden folders to the non hidden vec to avoid creating a new vec + non_hidden.append(&mut hidden); + + non_hidden + } } pub fn file_path_completion(