Files
task/completion/nu/task-completions.nu
2026-08-11 20:12:17 +02:00

181 lines
9.0 KiB
Nu

# Nushell completions for Task (https://taskfile.dev).
#
# Nushell cannot source a script from stdin, so save this file where Nushell
# picks it up automatically:
# mkdir ($nu.data-dir | path join "vendor/autoload")
# task --completion nu | save --force ($nu.data-dir | path join "vendor/autoload/task-completions.nu")
#
# The file must not be named task.nu: Nushell refuses to export a known external
# named like its module, which would break `use task-completions.nu *`.
# Name or path of the Task executable, like the other completion scripts.
# The *completed* command is always `task`: an `extern` declaration requires a
# literal name. For a renamed executable, alias it instead: `alias go-task = task`.
def "nu-complete task-exe" [] {
$env.TASK_EXE? | default "task"
}
def "nu-complete task-words" [context: string] {
$context | split row --regex '\s+' | where {|word| $word != "" }
}
# Strips the quotes the user may have typed around a value and expands `~`,
# which Nushell does not do for a value coming from a variable.
def "nu-complete task-value" [value: string] {
let unquoted = ($value | str trim --char '"' | str trim --char "'")
if ($unquoted | str starts-with "~") {
$unquoted | path expand --no-symlink
} else {
$unquoted
}
}
# Rebuilds the flags deciding *which* Taskfile is read, so the task list follows
# the `-t/--taskfile`, `-d/--dir` and `-g/--global` already on the command line.
def "nu-complete task-scope" [words: list<string>] {
mut scope: list<string> = []
mut pending = ""
for word in ($words | skip 1) {
if $pending != "" {
$scope = ($scope | append [$pending, (nu-complete task-value $word)])
$pending = ""
continue
}
let parts = ($word | split row "=")
let name = ($parts | first)
let inline = if ($parts | length) > 1 { $parts | skip 1 | str join "=" } else { null }
if $name in ["-g", "--global"] {
$scope = ($scope | append "--global")
} else if $name in ["-t", "--taskfile", "-d", "--dir"] {
let long = if $name in ["-t", "--taskfile"] { "--taskfile" } else { "--dir" }
if $inline != null {
$scope = ($scope | append [$long, (nu-complete task-value $inline)])
} else {
$pending = $long
}
}
}
$scope
}
# Lists the tasks of the targeted Taskfile. `--no-status` keeps completion fast:
# without it Task fingerprints every task's sources on each keystroke. Returns an
# empty list when Task exits non-zero (no Taskfile, invalid Taskfile).
def "nu-complete task-list" [words: list<string>] {
let exe = (nu-complete task-exe)
let args = [...(nu-complete task-scope $words) "--list-all" "--json" "--no-status"]
let result = (try { do { ^$exe ...$args } | complete } catch { null })
if ($result | is-empty) or $result.exit_code != 0 {
return []
}
try { $result.stdout | from json | get tasks } catch { [] }
}
def "nu-complete task" [context: string] {
let words = (nu-complete task-words $context)
# Words after `--` are forwarded to the task as CLI_ARGS: stop offering task
# names and let Nushell fall back to its own file completion.
if "--" in $words {
return null
}
let completions = (
nu-complete task-list $words
| each {|item|
# `task` is the invocable name; `name` may be a display-only label.
let name = ($item.task | str trim --right --char ':')
let desc = ($item.desc? | default "")
let aliases = (
$item.aliases?
| default []
| each {|alias| {
value: ($alias | str trim --right --char ':')
description: (if ($desc | is-empty) { $"alias of ($name)" } else { $"($desc) \(alias of ($name)\)" })
} }
)
[{ value: $name, description: $desc }] | append $aliases
}
| flatten
)
# `sort: false` keeps the order Task chose, which honours --sort and .taskrc.
{ options: { sort: false }, completions: $completions }
}
def "nu-complete task-shells" [] {
["bash", "zsh", "fish", "powershell", "nu"]
}
def "nu-complete task-output" [] {
["interleaved", "group", "prefixed"]
}
def "nu-complete task-sort" [] {
["default", "alphanumeric", "none"]
}
# Runs the specified task(s). Falls back to the "default" task if no task name
# was specified, or lists all tasks if an unknown task name was specified.
#
# An `extern` signature is static, so the experimental flags at the bottom are
# always offered; Task rejects them when the experiment is off. Run
# `task --experiments` to see which ones are enabled.
export extern "task" [
...tasks: string@"nu-complete task" # task(s) to run
--list(-l) # list tasks with a description
--list-all(-a) # list all tasks, with or without a description
--json(-j) # format the task list as JSON
--no-status # ignore status when listing tasks as JSON
--nested # nest namespaces when listing tasks as JSON
--sort: string@"nu-complete task-sort" # change the order of the tasks when listed
--init(-i) # create a new Taskfile.yml in the current folder
--completion: string@"nu-complete task-shells" # generate a shell completion script
--taskfile(-t): glob # choose which Taskfile to run
--dir(-d): directory # set the directory in which Task will execute
--global(-g) # run the global Taskfile from $HOME
--temp-dir: directory # directory used to store Task temporary files
--force(-f) # force execution even when the task is up-to-date
--status # exit with a non-zero code if tasks are not up-to-date
--dry(-n) # compile and print the tasks without executing them
--summary # show the summary of a task instead of running it
--watch(-w) # watch the given tasks and re-run them on changes
--interval(-I): string # interval to watch for changes, e.g. 500ms
--parallel(-p) # run the tasks given on the command line in parallel
--concurrency(-C): int # limit the number of tasks run concurrently
--failfast(-F) # when running in parallel, stop everything if one task fails
--exit-code(-x) # pass through the exit code of the task command
--interactive # prompt for missing required variables
--yes(-y) # assume "yes" as the answer to all prompts
--output(-o): string@"nu-complete task-output" # set the output style
--output-group-begin: string # message template printed before a task's grouped output
--output-group-end: string # message template printed after a task's grouped output
--output-group-error-only # swallow the output of successful tasks
--color(-c) # colored output, enabled by default
--silent(-s) # disable echoing
--verbose(-v) # enable verbose mode
--disable-fuzzy # disable fuzzy matching for task names
--insecure # allow Taskfiles to be downloaded over insecure connections
--experiments # list the available experiments and whether they are enabled
--version # show the Task version
--help(-h) # show Task usage
--force-all # [GENTLE_FORCE] force the called task and all its dependencies
--download # [REMOTE_TASKFILES] download a cached version of a remote Taskfile
--offline # [REMOTE_TASKFILES] only use local or cached Taskfiles
--clear-cache # [REMOTE_TASKFILES] clear the remote Taskfile cache
--trusted-hosts: string # [REMOTE_TASKFILES] trusted hosts for remote Taskfiles (comma-separated)
--timeout: string # [REMOTE_TASKFILES] timeout for downloading remote Taskfiles
--expiry: string # [REMOTE_TASKFILES] expiry duration for cached remote Taskfiles
--remote-cache-dir: directory # [REMOTE_TASKFILES] directory used to cache remote Taskfiles
--cacert: path # [REMOTE_TASKFILES] custom CA certificate for HTTPS connections
--cert: path # [REMOTE_TASKFILES] client certificate for HTTPS connections
--cert-key: path # [REMOTE_TASKFILES] client certificate key for HTTPS connections
]