Sort inside complete_rec
This commit is contained in:
parent
a055e59309
commit
9744ffd375
|
@ -9,7 +9,7 @@ use nu_protocol::{
|
||||||
};
|
};
|
||||||
use reedline::Suggestion;
|
use reedline::Suggestion;
|
||||||
|
|
||||||
use super::{completion_common::sort_completions, SemanticSuggestion};
|
use super::{completion_common::sort_suggestions, SemanticSuggestion};
|
||||||
|
|
||||||
pub struct CommandCompletion {
|
pub struct CommandCompletion {
|
||||||
flattened: Vec<(Span, FlatShape)>,
|
flattened: Vec<(Span, FlatShape)>,
|
||||||
|
@ -224,7 +224,7 @@ impl Completer for CommandCompletion {
|
||||||
};
|
};
|
||||||
|
|
||||||
let all_suggestions = subcommands.into_iter().chain(commands).collect::<Vec<_>>();
|
let all_suggestions = subcommands.into_iter().chain(commands).collect::<Vec<_>>();
|
||||||
sort_completions(
|
sort_suggestions(
|
||||||
&String::from_utf8_lossy(&prefix),
|
&String::from_utf8_lossy(&prefix),
|
||||||
all_suggestions,
|
all_suggestions,
|
||||||
self.get_sort_by(),
|
self.get_sort_by(),
|
||||||
|
|
|
@ -50,6 +50,7 @@ fn complete_rec(
|
||||||
return completions;
|
return completions;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut entries = Vec::new();
|
||||||
for entry in result.filter_map(|e| e.ok()) {
|
for entry in result.filter_map(|e| e.ok()) {
|
||||||
let entry_name = entry.file_name().to_string_lossy().into_owned();
|
let entry_name = entry.file_name().to_string_lossy().into_owned();
|
||||||
let entry_isdir = entry.path().is_dir();
|
let entry_isdir = entry.path().is_dir();
|
||||||
|
@ -58,20 +59,26 @@ fn complete_rec(
|
||||||
built.isdir = entry_isdir;
|
built.isdir = entry_isdir;
|
||||||
|
|
||||||
if !dir || entry_isdir {
|
if !dir || entry_isdir {
|
||||||
match partial.split_first() {
|
entries.push((entry_name, built));
|
||||||
Some((base, rest)) => {
|
}
|
||||||
if matches(base, &entry_name, options) {
|
}
|
||||||
if !rest.is_empty() || isdir {
|
|
||||||
completions
|
let prefix = partial.first().unwrap_or(&"");
|
||||||
.extend(complete_rec(rest, &built, cwd, options, dir, isdir));
|
let sorted_entries = sort_completions(prefix, entries, SortBy::Ascending, |(entry, _)| entry);
|
||||||
} else {
|
|
||||||
completions.push(built);
|
for (entry_name, built) in sorted_entries {
|
||||||
}
|
match partial.split_first() {
|
||||||
|
Some((base, rest)) => {
|
||||||
|
if matches(base, &entry_name, options) {
|
||||||
|
if !rest.is_empty() || isdir {
|
||||||
|
completions.extend(complete_rec(rest, &built, cwd, options, dir, isdir));
|
||||||
|
} else {
|
||||||
|
completions.push(built);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
}
|
||||||
completions.push(built);
|
None => {
|
||||||
}
|
completions.push(built);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -262,24 +269,34 @@ pub fn adjust_if_intermediate(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Arguments
|
/// Convenience function to sort suggestions using [`sort_completions`]
|
||||||
/// * `prefix` - What the user's typed, for sorting by Levenshtein distance
|
pub fn sort_suggestions(
|
||||||
pub fn sort_completions(
|
|
||||||
prefix: &str,
|
prefix: &str,
|
||||||
mut items: Vec<SemanticSuggestion>,
|
items: Vec<SemanticSuggestion>,
|
||||||
sort_by: SortBy,
|
sort_by: SortBy,
|
||||||
) -> Vec<SemanticSuggestion> {
|
) -> Vec<SemanticSuggestion> {
|
||||||
|
sort_completions(prefix, items, sort_by, |it| &it.suggestion.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// # Arguments
|
||||||
|
/// * `prefix` - What the user's typed, for sorting by Levenshtein distance
|
||||||
|
pub fn sort_completions<T>(
|
||||||
|
prefix: &str,
|
||||||
|
mut items: Vec<T>,
|
||||||
|
sort_by: SortBy,
|
||||||
|
get_value: fn(&T) -> &str,
|
||||||
|
) -> Vec<T> {
|
||||||
// Sort items
|
// Sort items
|
||||||
match sort_by {
|
match sort_by {
|
||||||
SortBy::LevenshteinDistance => {
|
SortBy::LevenshteinDistance => {
|
||||||
items.sort_by(|a, b| {
|
items.sort_by(|a, b| {
|
||||||
let a_distance = levenshtein_distance(prefix, &a.suggestion.value);
|
let a_distance = levenshtein_distance(prefix, get_value(a));
|
||||||
let b_distance = levenshtein_distance(prefix, &b.suggestion.value);
|
let b_distance = levenshtein_distance(prefix, get_value(b));
|
||||||
a_distance.cmp(&b_distance)
|
a_distance.cmp(&b_distance)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
SortBy::Ascending => {
|
SortBy::Ascending => {
|
||||||
items.sort_by(|a, b| a.suggestion.value.cmp(&b.suggestion.value));
|
items.sort_by(|a, b| get_value(a).cmp(get_value(b)));
|
||||||
}
|
}
|
||||||
SortBy::None => {}
|
SortBy::None => {}
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,7 +12,7 @@ use nu_protocol::{
|
||||||
use nu_utils::IgnoreCaseExt;
|
use nu_utils::IgnoreCaseExt;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use super::completion_common::sort_completions;
|
use super::completion_common::sort_suggestions;
|
||||||
|
|
||||||
pub struct CustomCompletion {
|
pub struct CustomCompletion {
|
||||||
stack: Stack,
|
stack: Stack,
|
||||||
|
@ -129,7 +129,7 @@ impl Completer for CustomCompletion {
|
||||||
} else {
|
} else {
|
||||||
filter(&prefix, suggestions, completion_options)
|
filter(&prefix, suggestions, completion_options)
|
||||||
};
|
};
|
||||||
sort_completions(
|
sort_suggestions(
|
||||||
&String::from_utf8_lossy(&prefix),
|
&String::from_utf8_lossy(&prefix),
|
||||||
suggestions,
|
suggestions,
|
||||||
self.get_sort_by(),
|
self.get_sort_by(),
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
use crate::completions::{
|
use crate::completions::{
|
||||||
completion_common::{adjust_if_intermediate, complete_item, AdjustView},
|
completion_common::{adjust_if_intermediate, complete_item, AdjustView},
|
||||||
Completer, CompletionOptions, SortBy,
|
Completer, CompletionOptions,
|
||||||
};
|
};
|
||||||
use nu_ansi_term::Style;
|
use nu_ansi_term::Style;
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
engine::{EngineState, Stack, StateWorkingSet},
|
engine::{EngineState, Stack, StateWorkingSet},
|
||||||
levenshtein_distance, Span,
|
Span,
|
||||||
};
|
};
|
||||||
use reedline::Suggestion;
|
use reedline::Suggestion;
|
||||||
use std::path::{Path, MAIN_SEPARATOR as SEP};
|
use std::path::Path;
|
||||||
|
|
||||||
use super::SemanticSuggestion;
|
use super::SemanticSuggestion;
|
||||||
|
|
||||||
|
@ -62,34 +62,11 @@ impl Completer for DirectoryCompletion {
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// Sort items
|
|
||||||
let mut sorted_items = items;
|
|
||||||
|
|
||||||
match self.get_sort_by() {
|
|
||||||
SortBy::Ascending => {
|
|
||||||
sorted_items.sort_by(|a, b| {
|
|
||||||
// Ignore trailing slashes in folder names when sorting
|
|
||||||
a.suggestion
|
|
||||||
.value
|
|
||||||
.trim_end_matches(SEP)
|
|
||||||
.cmp(b.suggestion.value.trim_end_matches(SEP))
|
|
||||||
});
|
|
||||||
}
|
|
||||||
SortBy::LevenshteinDistance => {
|
|
||||||
sorted_items.sort_by(|a, b| {
|
|
||||||
let a_distance = levenshtein_distance(&prefix, &a.suggestion.value);
|
|
||||||
let b_distance = levenshtein_distance(&prefix, &b.suggestion.value);
|
|
||||||
a_distance.cmp(&b_distance)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
|
|
||||||
// Separate the results between hidden and non hidden
|
// Separate the results between hidden and non hidden
|
||||||
let mut hidden: Vec<SemanticSuggestion> = vec![];
|
let mut hidden: Vec<SemanticSuggestion> = vec![];
|
||||||
let mut non_hidden: Vec<SemanticSuggestion> = vec![];
|
let mut non_hidden: Vec<SemanticSuggestion> = vec![];
|
||||||
|
|
||||||
for item in sorted_items.into_iter() {
|
for item in items.into_iter() {
|
||||||
let item_path = Path::new(&item.suggestion.value);
|
let item_path = Path::new(&item.suggestion.value);
|
||||||
|
|
||||||
if let Some(value) = item_path.file_name() {
|
if let Some(value) = item_path.file_name() {
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
use crate::completions::{
|
use crate::completions::{
|
||||||
completion_common::{adjust_if_intermediate, complete_item, AdjustView},
|
completion_common::{adjust_if_intermediate, complete_item, AdjustView},
|
||||||
Completer, CompletionOptions, SortBy,
|
Completer, CompletionOptions,
|
||||||
};
|
};
|
||||||
use nu_ansi_term::Style;
|
use nu_ansi_term::Style;
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
engine::{EngineState, Stack, StateWorkingSet},
|
engine::{EngineState, Stack, StateWorkingSet},
|
||||||
levenshtein_distance, Span,
|
Span,
|
||||||
};
|
};
|
||||||
use nu_utils::IgnoreCaseExt;
|
use nu_utils::IgnoreCaseExt;
|
||||||
use reedline::Suggestion;
|
use reedline::Suggestion;
|
||||||
use std::path::{Path, MAIN_SEPARATOR as SEP};
|
use std::path::Path;
|
||||||
|
|
||||||
use super::SemanticSuggestion;
|
use super::SemanticSuggestion;
|
||||||
|
|
||||||
|
@ -69,34 +69,11 @@ impl Completer for FileCompletion {
|
||||||
|
|
||||||
// Sort results prioritizing the non hidden folders
|
// Sort results prioritizing the non hidden folders
|
||||||
|
|
||||||
// Sort items
|
|
||||||
let mut sorted_items = items;
|
|
||||||
|
|
||||||
match self.get_sort_by() {
|
|
||||||
SortBy::Ascending => {
|
|
||||||
sorted_items.sort_by(|a, b| {
|
|
||||||
// Ignore trailing slashes in folder names when sorting
|
|
||||||
a.suggestion
|
|
||||||
.value
|
|
||||||
.trim_end_matches(SEP)
|
|
||||||
.cmp(b.suggestion.value.trim_end_matches(SEP))
|
|
||||||
});
|
|
||||||
}
|
|
||||||
SortBy::LevenshteinDistance => {
|
|
||||||
sorted_items.sort_by(|a, b| {
|
|
||||||
let a_distance = levenshtein_distance(&prefix, &a.suggestion.value);
|
|
||||||
let b_distance = levenshtein_distance(&prefix, &b.suggestion.value);
|
|
||||||
a_distance.cmp(&b_distance)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
|
|
||||||
// Separate the results between hidden and non hidden
|
// Separate the results between hidden and non hidden
|
||||||
let mut hidden: Vec<SemanticSuggestion> = vec![];
|
let mut hidden: Vec<SemanticSuggestion> = vec![];
|
||||||
let mut non_hidden: Vec<SemanticSuggestion> = vec![];
|
let mut non_hidden: Vec<SemanticSuggestion> = vec![];
|
||||||
|
|
||||||
for item in sorted_items.into_iter() {
|
for item in items.into_iter() {
|
||||||
let item_path = Path::new(&item.suggestion.value);
|
let item_path = Path::new(&item.suggestion.value);
|
||||||
|
|
||||||
if let Some(value) = item_path.file_name() {
|
if let Some(value) = item_path.file_name() {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::completions::{completion_common::sort_completions, Completer, CompletionOptions};
|
use crate::completions::{completion_common::sort_suggestions, Completer, CompletionOptions};
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
ast::{Expr, Expression},
|
ast::{Expr, Expression},
|
||||||
engine::{Stack, StateWorkingSet},
|
engine::{Stack, StateWorkingSet},
|
||||||
|
@ -90,7 +90,7 @@ impl Completer for FlagCompletion {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return sort_completions(
|
return sort_suggestions(
|
||||||
&String::from_utf8_lossy(&prefix),
|
&String::from_utf8_lossy(&prefix),
|
||||||
output,
|
output,
|
||||||
self.get_sort_by(),
|
self.get_sort_by(),
|
||||||
|
|
|
@ -9,7 +9,7 @@ use nu_protocol::{
|
||||||
use reedline::Suggestion;
|
use reedline::Suggestion;
|
||||||
use std::str;
|
use std::str;
|
||||||
|
|
||||||
use super::completion_common::sort_completions;
|
use super::completion_common::sort_suggestions;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct VariableCompletion {
|
pub struct VariableCompletion {
|
||||||
|
@ -72,7 +72,7 @@ impl Completer for VariableCompletion {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return sort_completions(&prefix_str, output, self.get_sort_by());
|
return sort_suggestions(&prefix_str, output, self.get_sort_by());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// No nesting provided, return all env vars
|
// No nesting provided, return all env vars
|
||||||
|
@ -96,7 +96,7 @@ impl Completer for VariableCompletion {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return sort_completions(&prefix_str, output, self.get_sort_by());
|
return sort_suggestions(&prefix_str, output, self.get_sort_by());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ impl Completer for VariableCompletion {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return sort_completions(&prefix_str, output, self.get_sort_by());
|
return sort_suggestions(&prefix_str, output, self.get_sort_by());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ impl Completer for VariableCompletion {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return sort_completions(&prefix_str, output, self.get_sort_by());
|
return sort_suggestions(&prefix_str, output, self.get_sort_by());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user