diff options
author | Michael Davis | 2022-11-04 01:55:13 +0000 |
---|---|---|
committer | Blaž Hrastnik | 2022-11-07 04:38:16 +0000 |
commit | 1536a6528968f38adfac2e991b29006f5ded5968 (patch) | |
tree | 73b1b0ebe81b03e03af6e8098c7c92259b728d03 /helix-term/src | |
parent | 48a3965ab43718ce2a49724cbcc294b04c328b81 (diff) |
Fix whitespace handling in command-mode completion
8584b38cfbe6ffe3e5d539ad953c413e44e90bfa switched to shellwords for
completion in command-mode. This changes the conditions for choosing
whether to complete the command or use the command's completer.
This change processes the input as shellwords up-front and uses
shellword logic about whitespace to determine whether the command
or argument should be completed.
Diffstat (limited to 'helix-term/src')
-rw-r--r-- | helix-term/src/commands/typed.rs | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index f4dfce7a..304b30f9 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -2183,10 +2183,11 @@ pub(super) fn command_mode(cx: &mut Context) { static FUZZY_MATCHER: Lazy<fuzzy_matcher::skim::SkimMatcherV2> = Lazy::new(fuzzy_matcher::skim::SkimMatcherV2::default); - // simple heuristic: if there's no just one part, complete command name. - // if there's a space, per command completion kicks in. - // we use .this over split_whitespace() because we care about empty segments - if input.split(' ').count() <= 1 { + let parts = shellwords::shellwords(input); + let ends_with_whitespace = shellwords::ends_with_whitespace(input); + + if parts.is_empty() || (parts.len() == 1 && !ends_with_whitespace) { + // If the command has not been finished yet, complete commands. let mut matches: Vec<_> = typed::TYPABLE_COMMAND_LIST .iter() .filter_map(|command| { @@ -2202,8 +2203,13 @@ pub(super) fn command_mode(cx: &mut Context) { .map(|(name, _)| (0.., name.into())) .collect() } else { - let parts = shellwords::shellwords(input); - let part = parts.last().unwrap(); + // Otherwise, use the command's completer and the last shellword + // as completion input. + let part = if parts.len() == 1 { + &Cow::Borrowed("") + } else { + parts.last().unwrap() + }; if let Some(typed::TypableCommand { completer: Some(completer), |