fix(completion): harden the __complete engine and shell wrappers

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.
This commit is contained in:
Valentin Maerten
2026-07-03 16:03:33 +02:00
parent f9f2ecb8be
commit 57bc6dd8cb
11 changed files with 413 additions and 158 deletions

View File

@@ -7,7 +7,9 @@ TASK_CMD="${TASK_EXE:-task}"
_task() {
local cur prev words cword
_init_completion -n : || return
# Exclude both `=` and `:` from the word breaks so `--output=` and
# `docs:serve` reach the engine as single tokens.
_init_completion -n =: || return
local -a args=()
if (( cword > 0 )); then
@@ -48,13 +50,17 @@ _task() {
return
fi
local -a values=()
# Prefix-filter by hand instead of `compgen -W`: the latter joins/splits the
# word list on IFS, which mangles any suggestion value containing a space.
local value
COMPREPLY=()
for line in "${lines[@]}"; do
values+=( "${line%%$'\t'*}" )
value="${line%%$'\t'*}"
if [[ -z "$cur" || "$value" == "$cur"* ]]; then
COMPREPLY+=( "$value" )
fi
done
COMPREPLY=( $( compgen -W "${values[*]}" -- "$cur" ) )
if (( directive & 2 )); then
compopt -o nospace 2>/dev/null
fi