mirror of
https://github.com/nushell/nushell
synced 2025-01-13 21:55:07 +00:00
Improve completer (#14004)
This pr does two optimization for the completer: - Switch `sort_by` to `sort_unstable_by` on `sort_completions` function since it reduces memory allocation and the orders of the identical completions are not matter. - Change `prefix` type from `Vec<u8>` to `&[u8]` to reduce cloning and memory.
This commit is contained in:
parent
33ae71f300
commit
d6f4e4c4fe
11 changed files with 36 additions and 36 deletions
|
@ -12,7 +12,7 @@ pub trait Completer {
|
||||||
&mut self,
|
&mut self,
|
||||||
working_set: &StateWorkingSet,
|
working_set: &StateWorkingSet,
|
||||||
stack: &Stack,
|
stack: &Stack,
|
||||||
prefix: Vec<u8>,
|
prefix: &[u8],
|
||||||
span: Span,
|
span: Span,
|
||||||
offset: usize,
|
offset: usize,
|
||||||
pos: usize,
|
pos: usize,
|
||||||
|
|
|
@ -158,7 +158,7 @@ impl Completer for CommandCompletion {
|
||||||
&mut self,
|
&mut self,
|
||||||
working_set: &StateWorkingSet,
|
working_set: &StateWorkingSet,
|
||||||
_stack: &Stack,
|
_stack: &Stack,
|
||||||
prefix: Vec<u8>,
|
prefix: &[u8],
|
||||||
span: Span,
|
span: Span,
|
||||||
offset: usize,
|
offset: usize,
|
||||||
pos: usize,
|
pos: usize,
|
||||||
|
@ -195,7 +195,7 @@ impl Completer for CommandCompletion {
|
||||||
};
|
};
|
||||||
|
|
||||||
if !subcommands.is_empty() {
|
if !subcommands.is_empty() {
|
||||||
return sort_suggestions(&String::from_utf8_lossy(&prefix), subcommands, options);
|
return sort_suggestions(&String::from_utf8_lossy(prefix), subcommands, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
let config = working_set.get_config();
|
let config = working_set.get_config();
|
||||||
|
@ -220,7 +220,7 @@ impl Completer for CommandCompletion {
|
||||||
vec![]
|
vec![]
|
||||||
};
|
};
|
||||||
|
|
||||||
sort_suggestions(&String::from_utf8_lossy(&prefix), commands, options)
|
sort_suggestions(&String::from_utf8_lossy(prefix), commands, options)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ impl NuCompleter {
|
||||||
&self,
|
&self,
|
||||||
completer: &mut T,
|
completer: &mut T,
|
||||||
working_set: &StateWorkingSet,
|
working_set: &StateWorkingSet,
|
||||||
prefix: Vec<u8>,
|
prefix: &[u8],
|
||||||
new_span: Span,
|
new_span: Span,
|
||||||
offset: usize,
|
offset: usize,
|
||||||
pos: usize,
|
pos: usize,
|
||||||
|
@ -55,7 +55,7 @@ impl NuCompleter {
|
||||||
completer.fetch(
|
completer.fetch(
|
||||||
working_set,
|
working_set,
|
||||||
&self.stack,
|
&self.stack,
|
||||||
prefix.clone(),
|
prefix,
|
||||||
new_span,
|
new_span,
|
||||||
offset,
|
offset,
|
||||||
pos,
|
pos,
|
||||||
|
@ -170,9 +170,9 @@ impl NuCompleter {
|
||||||
let new_span = Span::new(flat.0.start, flat.0.end - 1);
|
let new_span = Span::new(flat.0.start, flat.0.end - 1);
|
||||||
|
|
||||||
// Parses the prefix. Completion should look up to the cursor position, not after.
|
// Parses the prefix. Completion should look up to the cursor position, not after.
|
||||||
let mut prefix = working_set.get_span_contents(flat.0).to_vec();
|
let mut prefix = working_set.get_span_contents(flat.0);
|
||||||
let index = pos - flat.0.start;
|
let index = pos - flat.0.start;
|
||||||
prefix.drain(index..);
|
prefix = &prefix[..index];
|
||||||
|
|
||||||
// Variables completion
|
// Variables completion
|
||||||
if prefix.starts_with(b"$") || most_left_var.is_some() {
|
if prefix.starts_with(b"$") || most_left_var.is_some() {
|
||||||
|
@ -182,7 +182,7 @@ impl NuCompleter {
|
||||||
let mut variable_completions = self.process_completion(
|
let mut variable_completions = self.process_completion(
|
||||||
&mut variable_names_completer,
|
&mut variable_names_completer,
|
||||||
&working_set,
|
&working_set,
|
||||||
prefix.clone(),
|
prefix,
|
||||||
new_span,
|
new_span,
|
||||||
fake_offset,
|
fake_offset,
|
||||||
pos,
|
pos,
|
||||||
|
@ -211,7 +211,7 @@ impl NuCompleter {
|
||||||
let result = self.process_completion(
|
let result = self.process_completion(
|
||||||
&mut completer,
|
&mut completer,
|
||||||
&working_set,
|
&working_set,
|
||||||
prefix.clone(),
|
prefix,
|
||||||
new_span,
|
new_span,
|
||||||
fake_offset,
|
fake_offset,
|
||||||
pos,
|
pos,
|
||||||
|
@ -362,7 +362,7 @@ impl NuCompleter {
|
||||||
let mut out: Vec<_> = self.process_completion(
|
let mut out: Vec<_> = self.process_completion(
|
||||||
&mut completer,
|
&mut completer,
|
||||||
&working_set,
|
&working_set,
|
||||||
prefix.clone(),
|
prefix,
|
||||||
new_span,
|
new_span,
|
||||||
fake_offset,
|
fake_offset,
|
||||||
pos,
|
pos,
|
||||||
|
|
|
@ -335,7 +335,7 @@ pub fn sort_completions<T>(
|
||||||
} else {
|
} else {
|
||||||
matcher = matcher.ignore_case();
|
matcher = matcher.ignore_case();
|
||||||
};
|
};
|
||||||
items.sort_by(|a, b| {
|
items.sort_unstable_by(|a, b| {
|
||||||
let a_str = get_value(a);
|
let a_str = get_value(a);
|
||||||
let b_str = get_value(b);
|
let b_str = get_value(b);
|
||||||
let a_score = matcher.fuzzy_match(a_str, prefix).unwrap_or_default();
|
let a_score = matcher.fuzzy_match(a_str, prefix).unwrap_or_default();
|
||||||
|
@ -343,7 +343,7 @@ pub fn sort_completions<T>(
|
||||||
b_score.cmp(&a_score).then(a_str.cmp(b_str))
|
b_score.cmp(&a_score).then(a_str.cmp(b_str))
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
items.sort_by(|a, b| get_value(a).cmp(get_value(b)));
|
items.sort_unstable_by(|a, b| get_value(a).cmp(get_value(b)));
|
||||||
}
|
}
|
||||||
|
|
||||||
items
|
items
|
||||||
|
|
|
@ -35,7 +35,7 @@ impl Completer for CustomCompletion {
|
||||||
&mut self,
|
&mut self,
|
||||||
working_set: &StateWorkingSet,
|
working_set: &StateWorkingSet,
|
||||||
_stack: &Stack,
|
_stack: &Stack,
|
||||||
prefix: Vec<u8>,
|
prefix: &[u8],
|
||||||
span: Span,
|
span: Span,
|
||||||
offset: usize,
|
offset: usize,
|
||||||
pos: usize,
|
pos: usize,
|
||||||
|
@ -126,8 +126,8 @@ impl Completer for CustomCompletion {
|
||||||
let options = custom_completion_options
|
let options = custom_completion_options
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.unwrap_or(completion_options);
|
.unwrap_or(completion_options);
|
||||||
let suggestions = filter(&prefix, suggestions, options);
|
let suggestions = filter(prefix, suggestions, options);
|
||||||
sort_suggestions(&String::from_utf8_lossy(&prefix), suggestions, options)
|
sort_suggestions(&String::from_utf8_lossy(prefix), suggestions, options)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,13 +26,13 @@ impl Completer for DirectoryCompletion {
|
||||||
&mut self,
|
&mut self,
|
||||||
working_set: &StateWorkingSet,
|
working_set: &StateWorkingSet,
|
||||||
stack: &Stack,
|
stack: &Stack,
|
||||||
prefix: Vec<u8>,
|
prefix: &[u8],
|
||||||
span: Span,
|
span: Span,
|
||||||
offset: usize,
|
offset: usize,
|
||||||
_pos: usize,
|
_pos: usize,
|
||||||
options: &CompletionOptions,
|
options: &CompletionOptions,
|
||||||
) -> Vec<SemanticSuggestion> {
|
) -> Vec<SemanticSuggestion> {
|
||||||
let AdjustView { prefix, span, .. } = adjust_if_intermediate(&prefix, working_set, span);
|
let AdjustView { prefix, span, .. } = adjust_if_intermediate(prefix, working_set, span);
|
||||||
|
|
||||||
// Filter only the folders
|
// Filter only the folders
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
|
|
|
@ -22,13 +22,13 @@ impl Completer for DotNuCompletion {
|
||||||
&mut self,
|
&mut self,
|
||||||
working_set: &StateWorkingSet,
|
working_set: &StateWorkingSet,
|
||||||
stack: &Stack,
|
stack: &Stack,
|
||||||
prefix: Vec<u8>,
|
prefix: &[u8],
|
||||||
span: Span,
|
span: Span,
|
||||||
offset: usize,
|
offset: usize,
|
||||||
_pos: usize,
|
_pos: usize,
|
||||||
options: &CompletionOptions,
|
options: &CompletionOptions,
|
||||||
) -> Vec<SemanticSuggestion> {
|
) -> Vec<SemanticSuggestion> {
|
||||||
let prefix_str = String::from_utf8_lossy(&prefix).replace('`', "");
|
let prefix_str = String::from_utf8_lossy(prefix).replace('`', "");
|
||||||
let mut search_dirs: Vec<String> = vec![];
|
let mut search_dirs: Vec<String> = vec![];
|
||||||
|
|
||||||
// If prefix_str is only a word we want to search in the current dir
|
// If prefix_str is only a word we want to search in the current dir
|
||||||
|
|
|
@ -27,7 +27,7 @@ impl Completer for FileCompletion {
|
||||||
&mut self,
|
&mut self,
|
||||||
working_set: &StateWorkingSet,
|
working_set: &StateWorkingSet,
|
||||||
stack: &Stack,
|
stack: &Stack,
|
||||||
prefix: Vec<u8>,
|
prefix: &[u8],
|
||||||
span: Span,
|
span: Span,
|
||||||
offset: usize,
|
offset: usize,
|
||||||
_pos: usize,
|
_pos: usize,
|
||||||
|
@ -37,7 +37,7 @@ impl Completer for FileCompletion {
|
||||||
prefix,
|
prefix,
|
||||||
span,
|
span,
|
||||||
readjusted,
|
readjusted,
|
||||||
} = adjust_if_intermediate(&prefix, working_set, span);
|
} = adjust_if_intermediate(prefix, working_set, span);
|
||||||
|
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
let items: Vec<_> = complete_item(
|
let items: Vec<_> = complete_item(
|
||||||
|
|
|
@ -24,7 +24,7 @@ impl Completer for FlagCompletion {
|
||||||
&mut self,
|
&mut self,
|
||||||
working_set: &StateWorkingSet,
|
working_set: &StateWorkingSet,
|
||||||
_stack: &Stack,
|
_stack: &Stack,
|
||||||
prefix: Vec<u8>,
|
prefix: &[u8],
|
||||||
span: Span,
|
span: Span,
|
||||||
offset: usize,
|
offset: usize,
|
||||||
_pos: usize,
|
_pos: usize,
|
||||||
|
@ -44,7 +44,7 @@ impl Completer for FlagCompletion {
|
||||||
short.encode_utf8(&mut named);
|
short.encode_utf8(&mut named);
|
||||||
named.insert(0, b'-');
|
named.insert(0, b'-');
|
||||||
|
|
||||||
if options.match_algorithm.matches_u8(&named, &prefix) {
|
if options.match_algorithm.matches_u8(&named, prefix) {
|
||||||
output.push(SemanticSuggestion {
|
output.push(SemanticSuggestion {
|
||||||
suggestion: Suggestion {
|
suggestion: Suggestion {
|
||||||
value: String::from_utf8_lossy(&named).to_string(),
|
value: String::from_utf8_lossy(&named).to_string(),
|
||||||
|
@ -70,7 +70,7 @@ impl Completer for FlagCompletion {
|
||||||
named.insert(0, b'-');
|
named.insert(0, b'-');
|
||||||
named.insert(0, b'-');
|
named.insert(0, b'-');
|
||||||
|
|
||||||
if options.match_algorithm.matches_u8(&named, &prefix) {
|
if options.match_algorithm.matches_u8(&named, prefix) {
|
||||||
output.push(SemanticSuggestion {
|
output.push(SemanticSuggestion {
|
||||||
suggestion: Suggestion {
|
suggestion: Suggestion {
|
||||||
value: String::from_utf8_lossy(&named).to_string(),
|
value: String::from_utf8_lossy(&named).to_string(),
|
||||||
|
@ -88,7 +88,7 @@ impl Completer for FlagCompletion {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return sort_suggestions(&String::from_utf8_lossy(&prefix), output, options);
|
return sort_suggestions(&String::from_utf8_lossy(prefix), output, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec![]
|
vec![]
|
||||||
|
|
|
@ -24,7 +24,7 @@ impl Completer for OperatorCompletion {
|
||||||
&mut self,
|
&mut self,
|
||||||
working_set: &StateWorkingSet,
|
working_set: &StateWorkingSet,
|
||||||
_stack: &Stack,
|
_stack: &Stack,
|
||||||
_prefix: Vec<u8>,
|
_prefix: &[u8],
|
||||||
span: Span,
|
span: Span,
|
||||||
offset: usize,
|
offset: usize,
|
||||||
_pos: usize,
|
_pos: usize,
|
||||||
|
|
|
@ -27,7 +27,7 @@ impl Completer for VariableCompletion {
|
||||||
&mut self,
|
&mut self,
|
||||||
working_set: &StateWorkingSet,
|
working_set: &StateWorkingSet,
|
||||||
stack: &Stack,
|
stack: &Stack,
|
||||||
prefix: Vec<u8>,
|
prefix: &[u8],
|
||||||
span: Span,
|
span: Span,
|
||||||
offset: usize,
|
offset: usize,
|
||||||
_pos: usize,
|
_pos: usize,
|
||||||
|
@ -42,7 +42,7 @@ impl Completer for VariableCompletion {
|
||||||
end: span.end - offset,
|
end: span.end - offset,
|
||||||
};
|
};
|
||||||
let sublevels_count = self.var_context.1.len();
|
let sublevels_count = self.var_context.1.len();
|
||||||
let prefix_str = String::from_utf8_lossy(&prefix);
|
let prefix_str = String::from_utf8_lossy(prefix);
|
||||||
|
|
||||||
// Completions for the given variable
|
// Completions for the given variable
|
||||||
if !var_str.is_empty() {
|
if !var_str.is_empty() {
|
||||||
|
@ -66,7 +66,7 @@ impl Completer for VariableCompletion {
|
||||||
if options.match_algorithm.matches_u8_insensitive(
|
if options.match_algorithm.matches_u8_insensitive(
|
||||||
options.case_sensitive,
|
options.case_sensitive,
|
||||||
suggestion.suggestion.value.as_bytes(),
|
suggestion.suggestion.value.as_bytes(),
|
||||||
&prefix,
|
prefix,
|
||||||
) {
|
) {
|
||||||
output.push(suggestion);
|
output.push(suggestion);
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@ impl Completer for VariableCompletion {
|
||||||
if options.match_algorithm.matches_u8_insensitive(
|
if options.match_algorithm.matches_u8_insensitive(
|
||||||
options.case_sensitive,
|
options.case_sensitive,
|
||||||
env_var.0.as_bytes(),
|
env_var.0.as_bytes(),
|
||||||
&prefix,
|
prefix,
|
||||||
) {
|
) {
|
||||||
output.push(SemanticSuggestion {
|
output.push(SemanticSuggestion {
|
||||||
suggestion: Suggestion {
|
suggestion: Suggestion {
|
||||||
|
@ -111,7 +111,7 @@ impl Completer for VariableCompletion {
|
||||||
if options.match_algorithm.matches_u8_insensitive(
|
if options.match_algorithm.matches_u8_insensitive(
|
||||||
options.case_sensitive,
|
options.case_sensitive,
|
||||||
suggestion.suggestion.value.as_bytes(),
|
suggestion.suggestion.value.as_bytes(),
|
||||||
&prefix,
|
prefix,
|
||||||
) {
|
) {
|
||||||
output.push(suggestion);
|
output.push(suggestion);
|
||||||
}
|
}
|
||||||
|
@ -133,7 +133,7 @@ impl Completer for VariableCompletion {
|
||||||
if options.match_algorithm.matches_u8_insensitive(
|
if options.match_algorithm.matches_u8_insensitive(
|
||||||
options.case_sensitive,
|
options.case_sensitive,
|
||||||
suggestion.suggestion.value.as_bytes(),
|
suggestion.suggestion.value.as_bytes(),
|
||||||
&prefix,
|
prefix,
|
||||||
) {
|
) {
|
||||||
output.push(suggestion);
|
output.push(suggestion);
|
||||||
}
|
}
|
||||||
|
@ -149,7 +149,7 @@ impl Completer for VariableCompletion {
|
||||||
if options.match_algorithm.matches_u8_insensitive(
|
if options.match_algorithm.matches_u8_insensitive(
|
||||||
options.case_sensitive,
|
options.case_sensitive,
|
||||||
builtin.as_bytes(),
|
builtin.as_bytes(),
|
||||||
&prefix,
|
prefix,
|
||||||
) {
|
) {
|
||||||
output.push(SemanticSuggestion {
|
output.push(SemanticSuggestion {
|
||||||
suggestion: Suggestion {
|
suggestion: Suggestion {
|
||||||
|
@ -173,7 +173,7 @@ impl Completer for VariableCompletion {
|
||||||
if options.match_algorithm.matches_u8_insensitive(
|
if options.match_algorithm.matches_u8_insensitive(
|
||||||
options.case_sensitive,
|
options.case_sensitive,
|
||||||
v.0,
|
v.0,
|
||||||
&prefix,
|
prefix,
|
||||||
) {
|
) {
|
||||||
output.push(SemanticSuggestion {
|
output.push(SemanticSuggestion {
|
||||||
suggestion: Suggestion {
|
suggestion: Suggestion {
|
||||||
|
@ -201,7 +201,7 @@ impl Completer for VariableCompletion {
|
||||||
if options.match_algorithm.matches_u8_insensitive(
|
if options.match_algorithm.matches_u8_insensitive(
|
||||||
options.case_sensitive,
|
options.case_sensitive,
|
||||||
v.0,
|
v.0,
|
||||||
&prefix,
|
prefix,
|
||||||
) {
|
) {
|
||||||
output.push(SemanticSuggestion {
|
output.push(SemanticSuggestion {
|
||||||
suggestion: Suggestion {
|
suggestion: Suggestion {
|
||||||
|
|
Loading…
Reference in a new issue