← Back to Blog

How to set up Deno task tab completion in zsh

To autocomplete task names from your deno.json, add this to ~/.zshrc after your existing compinit setup:

eval "$(deno completions zsh --dynamic)"

If you haven’t enabled zsh’s completion system yet, use:

autoload -Uz compinit
compinit
eval "$(deno completions zsh --dynamic)"

Open a new terminal, or run the eval line in your current shell if compinit is already loaded. Inside a project with tasks defined, type deno task and press Tab to see the available task names.

Deno marks dynamic completions as unstable. This setup was tested with Deno 2.9.6 and zsh 5.9 on macOS.

Why my copied setup didn’t work

I initially copied the output of deno completions zsh --dynamic into my .zshrc. Its last line appeared as:

compdef _clap_dynamic_completer_deno deno%

That trailing % was the problem. In the version I tested, Deno’s generated script ends without a newline. Zsh displays a highlighted % to mark an unfinished line—the symbol isn’t part of Deno’s output, but I copied it too.

You can see the same behavior by running:

printf 'hello'

With zsh’s default end-of-line marker, this displays hello% before the next prompt.

The copied line registered the completion function for deno%, leaving deno using its old static completion handler. Removing the % fixed the registration:

compdef _clap_dynamic_completer_deno deno

Using eval "$(deno completions zsh --dynamic)" avoids that copying mistake and loads the completion script from the installed Deno version each time the shell starts. It does run Deno at shell startup; generating and sourcing a completion file is another option if you prefer to refresh it manually.

References: Deno completions and zsh’s PROMPT_SP option.