Skip to content

feat(completion): unify shell completions behind task __complete - #2897

Open
vmaerten wants to merge 3 commits into
mainfrom
feat/completion-engine
Open

feat(completion): unify shell completions behind task __complete#2897
vmaerten wants to merge 3 commits into
mainfrom
feat/completion-engine

Conversation

@vmaerten

@vmaerten vmaerten commented Jun 29, 2026

Copy link
Copy Markdown
Member

Summary

Adds a shell completion engine: a single task __complete command written in Go, that drives Bash, Fish, Zsh and PowerShell.
The shell scripts become thin wrappers that forward the current words to task __complete and render the suggestions, so every shell gets the same, richer behaviour and there is no more per-shell drift.

The wire protocol mirrors cobra v2 (value\tdescription lines followed by a :<directive> bitfield) behavior.

Why

It's painful to maintain 4 (or more) different completion scripts, and it's also difficult to test them. With this approach, all new flags will be included in every shell by default.

What it bring more than old completion

It's not only a drop in replacement of the old completions.
Now we can have requires vars being autocompleted, and even with enum 🚀

Testing

Following the cobra approach, the protocol is tested in Go and the generated scripts are only smoke-tested for how they route each directive:

  • internal/complete/complete_test.go: white-box tests of the engine.
  • completion/protocol_test.go: black-box test of the real binary's __complete output (candidates + directive).
  • completion/tests/: thin per-shell smokes (bash/zsh/fish/powershell) that assert directive routing (no-files, dir-only, extension filter, inline --flag=, …), runnable via task test:completion.
  • A completion CI job runs the smokes on Ubuntu and macOS (with fish and PowerShell installed, strict mode).

Disclaimer: I used AI to write the completion scripts & the testing protocol (in bash).

@vmaerten
vmaerten force-pushed the feat/completion-engine branch 3 times, most recently from b13cc89 to f9f2ecb Compare June 29, 2026 15:42
@vmaerten

Copy link
Copy Markdown
Member Author

@arturict, please don't comment on draft PRs. Also, your comments appear to be AI-generated. We're still open to meaningful, human-written comments. Finally, please avoid giving instructions to maintainers as if you were one of them.

@arturict

Copy link
Copy Markdown

Understood, and sorry about that. I should not have commented on a draft or phrased the comment as an instruction. I'll step back.

@vmaerten
vmaerten force-pushed the feat/completion-engine branch from 1521c9e to 32cfaec Compare July 19, 2026 15:47
@vmaerten
vmaerten marked this pull request as ready for review July 19, 2026 18:20
@vmaerten
vmaerten force-pushed the feat/completion-engine branch from 0b986fe to 3a37bf5 Compare August 3, 2026 20:39
@vmaerten
vmaerten force-pushed the feat/completion-engine branch 4 times, most recently from 9e8b673 to d0a53f4 Compare August 13, 2026 14:05
…mplete` engine

Bash, Fish, Zsh, Nushell and PowerShell now share a single backend: `task __complete` returns the suggestions plus a directive, and every wrapper is a thin shim around it. All five shells offer the same suggestions — task names, aliases, flags, flag values and per-task CLI variables. The Zsh `show-aliases` and `verbose` zstyles keep working, now backed by the `--no-aliases` and `--no-descriptions` completion flags.

The engine is opt-in via `task --new-completion <shell>`, leaving `--completion` and the legacy scripts untouched; it will become the default in a future release. The new wrappers live under `completion/next/`.

Completing a keystroke never reaches the network, never blocks on a stdin entrypoint, and honors every flag that decides how the Taskfile is loaded. Ref resolution shared by `requires` and enum completion moved to `internal/refs`.

A cross-shell test suite exercises the protocol in Go with thin shell smoke tests, and runs in CI.
@vmaerten
vmaerten force-pushed the feat/completion-engine branch from d0a53f4 to ed7a206 Compare August 20, 2026 12:22
The `--new-completion` section landed in website/src/latest/, which only release commits write to. Moved verbatim to website/src/next/, where the two files were byte-identical up to that point.
completion/protocol_test.go built a `task` binary in TestMain and drove it through 21 subprocess spawns. Every one of its table cases already had a one-for-one in-process equivalent in internal/complete, and the wire format is asserted by TestWrite_Format.

The one guarantee worth keeping was the `-t -` guard, which stops a keystroke from blocking on a Taskfile read from the terminal. It moves from cmd/task into complete.NeedsTaskfile, where it reads the flagset instead of the flags package global — testable in-process, and one less global read in cmd/task.

TestCompletionShells moves to internal/complete unchanged, and the in-process wildcard fixture gains `matches-exactly-*`, the only pattern of testdata/wildcards it was missing.

The binary path stays covered end to end by completion/tests/run.sh, which the CI completion job runs against five real shells on Linux and macOS.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants