aboutsummaryrefslogtreecommitdiff
path: root/helix-term/src
diff options
context:
space:
mode:
authorMichael Davis2022-11-04 01:55:13 +0000
committerBlaž Hrastnik2022-11-07 04:38:16 +0000
commit1536a6528968f38adfac2e991b29006f5ded5968 (patch)
tree73b1b0ebe81b03e03af6e8098c7c92259b728d03 /helix-term/src
parent48a3965ab43718ce2a49724cbcc294b04c328b81 (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.rs18
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),