diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index b9b634580..bad55b3e2 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -62,7 +62,9 @@ use crate::{ filter_picker_entry, job::Callback, keymap::ReverseKeymap, - ui::{self, menu::Item, overlay::overlaid, Picker, Popup, Prompt, PromptEvent}, + ui::{ + self, menu::Item, overlay::overlaid, CompletionResult, Picker, Popup, Prompt, PromptEvent, + }, }; use crate::job::{self, Jobs}; @@ -2094,12 +2096,14 @@ fn searcher(cx: &mut Context, direction: Direction) { "search:".into(), Some(reg), move |_editor: &Editor, input: &str| { - completions - .iter() - .filter(|comp| comp.starts_with(input)) - .map(|comp| (0.., std::borrow::Cow::Owned(comp.clone()))) - .collect::>() - .into() + CompletionResult::new( + completions + .iter() + .filter(|comp| comp.starts_with(input)) + .map(|comp| (0.., std::borrow::Cow::Owned(comp.clone()))) + .collect::>(), + false, + ) }, move |cx, regex, event| { if event == PromptEvent::Validate { @@ -2287,12 +2291,14 @@ fn global_search(cx: &mut Context) { "global-search:".into(), Some(reg), move |_editor: &Editor, input: &str| { - completions - .iter() - .filter(|comp| comp.starts_with(input)) - .map(|comp| (0.., std::borrow::Cow::Owned(comp.clone()))) - .collect::>() - .into() + CompletionResult::new( + completions + .iter() + .filter(|comp| comp.starts_with(input)) + .map(|comp| (0.., std::borrow::Cow::Owned(comp.clone()))) + .collect::>(), + false, + ) }, move |cx, _, input, event| { if event != PromptEvent::Validate { diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index ac11f3679..75bd33a7d 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -3134,18 +3134,17 @@ pub(super) fn command_mode(cx: &mut Context) { let words = shellwords.words(); if words.is_empty() || (words.len() == 1 && !shellwords.ends_with_whitespace()) { - let mut result: CompletionResult = fuzzy_match( - input, - TYPABLE_COMMAND_LIST.iter().map(|command| command.name), - false, + CompletionResult::new( + fuzzy_match( + input, + TYPABLE_COMMAND_LIST.iter().map(|command| command.name), + false, + ) + .into_iter() + .map(|(name, _)| (0.., name.into())) + .collect(), + matches!(editor.config().command_hints, CommandHints::Always), ) - .into_iter() - .map(|(name, _)| (0.., name.into())) - .collect::>() - .into(); - result.show_popup = matches!(editor.config().command_hints, CommandHints::Always); - - result } else { // Otherwise, use the command's completer and the last shellword // as completion input. @@ -3161,19 +3160,21 @@ pub(super) fn command_mode(cx: &mut Context) { .get(&words[0] as &str) .map(|tc| tc.completer_for_argument_number(argument_number)) { - completer(editor, word) - .completions - .into_iter() - .map(|(range, file)| { - let file = shellwords::escape(file); - - // offset ranges to input - let offset = input.len() - word_len; - let range = (range.start + offset)..; - (range, file) - }) - .collect::>() - .into() + CompletionResult::new( + completer(editor, word) + .completions + .into_iter() + .map(|(range, file)| { + let file = shellwords::escape(file); + + // offset ranges to input + let offset = input.len() - word_len; + let range = (range.start + offset)..; + (range, file) + }) + .collect::>(), + false, + ) } else { CompletionResult::default() }; diff --git a/helix-term/src/ui/mod.rs b/helix-term/src/ui/mod.rs index 36d53eb23..d6c6f3360 100644 --- a/helix-term/src/ui/mod.rs +++ b/helix-term/src/ui/mod.rs @@ -278,11 +278,13 @@ pub mod completers { .unwrap_or_else(|| Cow::from(SCRATCH_BUFFER_NAME)) }); - fuzzy_match(input, names, true) - .into_iter() - .map(|(name, _)| ((0..), name)) - .collect::>() - .into() + CompletionResult::new( + fuzzy_match(input, names, true) + .into_iter() + .map(|(name, _)| ((0..), name)) + .collect::>(), + false, + ) } pub fn theme(_editor: &Editor, input: &str) -> CompletionResult { @@ -295,11 +297,13 @@ pub mod completers { names.sort(); names.dedup(); - fuzzy_match(input, names, false) - .into_iter() - .map(|(name, _)| ((0..), name.into())) - .collect::>() - .into() + CompletionResult::new( + fuzzy_match(input, names, false) + .into_iter() + .map(|(name, _)| ((0..), name.into())) + .collect::>(), + false, + ) } /// Recursive function to get all keys from this value and add them to vec @@ -326,11 +330,13 @@ pub mod completers { keys }); - fuzzy_match(input, &*KEYS, false) - .into_iter() - .map(|(name, _)| ((0..), name.into())) - .collect::>() - .into() + CompletionResult::new( + fuzzy_match(input, &*KEYS, false) + .into_iter() + .map(|(name, _)| ((0..), name.into())) + .collect::>(), + false, + ) } pub fn filename(editor: &Editor, input: &str) -> CompletionResult { @@ -363,11 +369,13 @@ pub mod completers { .map(|config| &config.language_id) .chain(std::iter::once(&text)); - fuzzy_match(input, language_ids, false) - .into_iter() - .map(|(name, _)| ((0..), name.to_owned().into())) - .collect::>() - .into() + CompletionResult::new( + fuzzy_match(input, language_ids, false) + .into_iter() + .map(|(name, _)| ((0..), name.to_owned().into())) + .collect::>(), + false, + ) } pub fn lsp_workspace_command(editor: &Editor, input: &str) -> CompletionResult { @@ -378,11 +386,13 @@ pub mod completers { return CompletionResult::default(); }; - fuzzy_match(input, &options.commands, false) - .into_iter() - .map(|(name, _)| ((0..), name.to_owned().into())) - .collect::>() - .into() + CompletionResult::new( + fuzzy_match(input, &options.commands, false) + .into_iter() + .map(|(name, _)| ((0..), name.to_owned().into())) + .collect::>(), + false, + ) } pub fn directory(editor: &Editor, input: &str) -> CompletionResult { @@ -504,17 +514,19 @@ pub mod completers { // if empty, return a list of dirs and files in current dir if let Some(file_name) = file_name { let range = (input.len().saturating_sub(file_name.len()))..; - fuzzy_match(&file_name, files, true) - .into_iter() - .map(|(name, _)| (range.clone(), name)) - .collect::>() - .into() + CompletionResult::new( + fuzzy_match(&file_name, files, true) + .into_iter() + .map(|(name, _)| (range.clone(), name)) + .collect::>(), + false, + ) // TODO: complete to longest common match } else { let mut files: Vec<_> = files.map(|file| (end.clone(), file)).collect(); files.sort_unstable_by(|(_, path1), (_, path2)| path1.cmp(path2)); - files.into() + CompletionResult::new(files, false) } } @@ -526,10 +538,10 @@ pub mod completers { .filter(|(ch, _)| !matches!(ch, '%' | '#' | '.')) .map(|(ch, _)| ch.to_string()); - fuzzy_match(input, iter, false) + let results = fuzzy_match(input, iter, false) .into_iter() .map(|(name, _)| ((0..), name.into())) - .collect::>() - .into() + .collect::>(); + CompletionResult::new(results, false) } } diff --git a/helix-term/src/ui/prompt.rs b/helix-term/src/ui/prompt.rs index 778441b6d..8a0d20b53 100644 --- a/helix-term/src/ui/prompt.rs +++ b/helix-term/src/ui/prompt.rs @@ -29,11 +29,11 @@ pub struct CompletionResult { pub show_popup: bool, } -impl From> for CompletionResult { - fn from(completions: Vec) -> Self { +impl CompletionResult { + pub fn new(completions: Vec, show_popup: bool) -> Self { Self { - show_popup: true, completions, + show_popup, } } }