Follow cobra's testing philosophy: the completion protocol (candidates +
directive) is business logic and belongs in Go, while the shell wrappers only
need to be checked for how they interpret each directive.
- Add completion/protocol_test.go: a table-driven black-box test that runs the
real `task __complete` binary and asserts the offered values and the emitted
directive. Unlike the in-process engine tests, it exercises the actual
entrypoint dispatch, runComplete wiring and — crucially — the real flag set,
so it catches drift between the completion enum/directive maps and the flag
definitions. Runs on every OS, including Windows where the shell smokes don't.
- Delete completion/tests/engine.sh (the protocol is now covered in Go) and drop
it from run.sh.
- Reduce the bash/zsh/fish/powershell smokes to directive routing only (files vs
dirs vs no-files vs no-space), removing the task/alias/var assertions that the
Go tests already own.
Add completion/tests/ harnesses that exercise the engine protocol and every
shell wrapper without a TTY: the engine via `task __complete`, bash/zsh by
stubbing the completion-system helpers, fish via `complete -C`, and PowerShell
via the completion API. A `test:completion` task and a matching CI job (with a
strict mode that fails when an expected shell is missing) run them all.
Writing the suite surfaced and fixed real wrapper bugs:
- fish: `math` has no bitwise `&`, so every directive check errored; test bits
with integer division + modulo instead. Also filter FilterFileExt results
ourselves, as __fish_complete_suffix only prioritizes the extension.
- powershell: `Get-ChildItem -Include` is ignored without -Recurse, so file
extension filtering returned nothing; filter with Where-Object instead.
- bash: guard empty-array expansion so completion with zero candidates does not
trip `set -u` on bash 3.2.
Also name the completion directive bits (NO_SPACE, FILTER_FILE_EXT, …) in every
wrapper instead of using raw numbers.
Engine:
- Emit DirectiveKeepOrder for task variables so the `requires` declaration
order is preserved instead of being sorted by the shell.
- Return full `--flag=value` candidates for the inline `--output=` form so all
shells match against the whole current token.
- Add `--no-aliases` / `--no-descriptions` completion flags (via complete.Options)
parsed from the __complete invocation; the zsh wrapper maps its show-aliases
and verbose zstyles onto them.
- Skip Taskfile setup when completing flags (NeedsTaskfile) and load the task
list lazily; drop unused parameters; document exported identifiers.
Shell wrappers:
- zsh: reindent to tabs (.editorconfig), bridge zstyles to engine flags.
- fish: reindent to 2 spaces, handle every file-completion directive in the
wrapper (--no-files disables the native fallback), drop the duplicated
yml/yaml extension list now that it lives only in the engine.
- bash: prefix-filter by hand to preserve values containing spaces, exclude `=`
from word breaks so `--output=` reaches the engine as one token.
- powershell: filter candidates by the current word, fall back to file
completion for DirectiveDefault.
NoSpace is not representable in fish/PowerShell completion APIs; documented in
the wrappers.
As task is a very generic name that conflicts with for example
taskwarrior, some packagers might choose to change it. See my package in
the AUR: https://aur.archlinux.org/packages/go-task.
This change makes it easier to configure the name for downstream
packagers.
* List all current option flags
* Provide descriptions for every flag
* Pass the `task -l` descriptions as descriptions for the task completions
+ The prior logic had 4 invocations of sed and 1 of awk, and only kept the
task name
+ Do all filtering in zsh without forking (except for `task` itself)
* When `--taskfile` is used, complete tasks from _that_ file
+ And otherwise, enable completions if only the `.dist` variant files are
present
* Ensure mutually exclusive options preclude each other
+ the `+ '(groupname)'` clause defines this
* Fix `--dir` to take directories, not files
1. 'compgen -c' lists _all_ command names on the system, which is not
appropriate for this script, furthermore echo does not read from stdin
so the output is lost.
2. use _get_comp_words_by_ref and __ltrim_colon_completions to handle task
names with colons.
"...modifying COMP_WORDBREAKS in your completion script is not safe
(as it is a global variable and it has the side effect of affecting
the behavior of other completion scripts"
Ref.: https://stackoverflow.com/a/12495727/7044304
3. Add options completion
4. Use task --list-all