diff --git a/internal/complete/complete_test.go b/internal/complete/complete_test.go index d047c8f0..390978bc 100644 --- a/internal/complete/complete_test.go +++ b/internal/complete/complete_test.go @@ -166,7 +166,9 @@ func TestComplete_WildcardTaskNames(t *testing.T) { // Patterns are cut at their first `*`: `wildcard-*` and `wildcard-*-*` // collapse into one candidate, and `*-wildcard-*` leaves nothing to insert. require.Equal(t, []string{"build", "matches-exactly-", "release-", "start-", "s-", "wildcard-"}, values(suggs)) - require.Equal(t, complete.DirectiveNoSpace|complete.DirectiveNoFileComp, dir) + // A truncated prefix costs the whole response its trailing space, so task + // names keep theirs and the wildcard prefix gets one it does not want. + require.Equal(t, complete.DirectiveNoFileComp, dir) // Without a desc, the pattern says what the prefix stands for. require.Contains(t, descriptions(suggs), "wildcard-*") diff --git a/internal/complete/engine.go b/internal/complete/engine.go index 99afea88..eda451b5 100644 --- a/internal/complete/engine.go +++ b/internal/complete/engine.go @@ -67,7 +67,6 @@ func completeTaskNames(e *task.Executor, opts Options) ([]Suggestion, Directive) out := make([]Suggestion, 0, len(tasks)) seen := make(map[string]bool, len(tasks)) - anyPartial := false add := func(name, desc string) { value, partial := suggestedName(name) // `*-wildcard-*` has no prefix, and `wildcard-*` / `wildcard-*-*` share one. @@ -75,11 +74,9 @@ func completeTaskNames(e *task.Executor, opts Options) ([]Suggestion, Directive) return } seen[value] = true - if partial { - anyPartial = true - if desc == "" && !opts.NoDescriptions { - desc = name - } + // Without a desc, a truncated pattern says what its prefix stands for. + if partial && desc == "" && !opts.NoDescriptions { + desc = name } out = append(out, Suggestion{Value: value, Description: desc}) } @@ -94,10 +91,8 @@ func completeTaskNames(e *task.Executor, opts Options) ([]Suggestion, Directive) } } - // A truncated pattern is half a name: the cursor must stay against it. - if anyPartial { - return out, DirectiveNoSpace | DirectiveNoFileComp - } + // A single truncated wildcard prefix would otherwise cost every complete + // name its trailing space: the directive covers the whole response. return out, DirectiveNoFileComp }