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:
Kither 2024-10-07 01:31:37 +07:00 committed by GitHub
parent 33ae71f300
commit d6f4e4c4fe
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 36 additions and 36 deletions

View file

@ -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,

View file

@ -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)
} }
} }

View file

@ -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,

View file

@ -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

View file

@ -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)
} }
} }

View file

@ -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)]

View file

@ -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

View file

@ -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(

View file

@ -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![]

View file

@ -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,

View file

@ -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 {