Add Hugo Shell Completion Without Touching Your Site

Typing hugo server or hugo --buildDrafts from memory gets old fast, and Hugo's own completion command fixes that in one line. You will finish with tab completion for the Hugo command in the shell you actually use, plus a generated file you can inspect and remove if needed. The examples match Hugo 0.123.7, installed here as package hugo 0.123.7-1ubuntu0.3+esm2.

Completion is a shell integration, not a Hugo site setting. The command prints a script for Bash, Zsh, Fish or PowerShell. It does not edit your project, its configuration, or your shell startup files by itself.

1. Confirm the installed command

Check the binary and package before copying a generated script. This is read-only and does not need elevated privileges:

$ command -v hugo
/usr/bin/hugo
$ hugo version
hugo v0.123.7-1ubuntu0.3+esm2 linux/amd64 BuildDate=unknown

Checkpoint: the build metadata can differ on another machine. The useful result is that hugo version runs and reports the version you intend to support.

2. Choose the shell script you need

Ask Hugo for the available completion commands:

$ hugo completion --help
Available Commands:
  bash        Generate the autocompletion script for bash
  fish        Generate the autocompletion script for fish
  powershell  Generate the autocompletion script for powershell
  zsh         Generate the autocompletion script for zsh

3. Test Bash completion in the current session

For Bash, the installed help says the generated script depends on the bash-completion package. Install that package through your normal distribution process only if Bash reports its completion support is absent. The Hugo command itself remains unprivileged.

$ source <(hugo completion bash)
$ type _hugo
_hugo is a function

The source command changes only the current Bash process; open a new terminal and the change is gone. Test it before making anything persistent: type hugo followed by Tab. Hugo subcommands such as build, completion and server should appear, depending on the generated script and the command position.

Checkpoint: if type _hugo says the function is not found, confirm you are in Bash, that hugo completion bash produced output, and that the bash-completion package is available. A silent source is normal; the function check is the useful result.

4. Install Bash completion for future terminals

To make Bash completion available to every user, write the generated file into /etc/bash_completion.d. Use a temporary file first, then make only the final installation step elevated:

$ hugo completion bash > /tmp/hugo-completion.bash
$ sudo install -m 0644 /tmp/hugo-completion.bash /etc/bash_completion.d/hugo

Check the result without executing it as a command:

$ bash -n /etc/bash_completion.d/hugo
$ test -s /etc/bash_completion.d/hugo && echo 'completion file is non-empty'
completion file is non-empty

Start a new Bash session, then test Tab completion again.

Recovery: to undo this system-wide change, remove exactly that file with elevated privileges, then start a new shell:

$ sudo rm /etc/bash_completion.d/hugo

That removal is destructive to the generated file, though it does not alter Hugo or your site. Keep the temporary copy if you want to reinstall the same script later.

5. Load Zsh completion

Zsh must have completion initialised before its generated Hugo function can be used. For a current session, run:

% autoload -U compinit
% compinit
% source <(hugo completion zsh)

Check the function and try hugo followed by Tab:

% whence -f _hugo
_hugo () {
  ...
}

The function body is generated code, so its exact formatting can change; the important result is that Zsh resolves _hugo. For a persistent setup, Hugo's installed help uses the first directory in fpath:

% hugo completion zsh > "${fpath[1]}/_hugo"

You may need to create or choose a writable site-functions directory already present in your Zsh configuration. Do not guess a path, and do not use sudo to put user completion into an unrelated directory. After writing the file, run compinit in a new session. Remove the generated _hugo file to undo this persistent change.

6. Load Fish or PowerShell completion

Fish reads completion files from its per-user directory. The command below creates or replaces only Hugo's generated file, so check the destination before running it:

$ mkdir -p "$HOME/.config/fish/completions"
$ hugo completion fish > "$HOME/.config/fish/completions/hugo.fish"
$ test -s "$HOME/.config/fish/completions/hugo.fish" && echo 'Fish completion file is non-empty'
Fish completion file is non-empty

Start Fish or reload the file with source "$HOME/.config/fish/completions/hugo.fish".

Warning: if the destination already contains a hand-written Hugo completion, do not overwrite it blindly. Save a copy first or keep the generated script in a separate file and decide which definition should win.

In PowerShell, load the generated function into the current session:

PS> hugo completion powershell | Out-String | Invoke-Expression

For future PowerShell sessions, add that command to your PowerShell profile after reviewing the generated text. The exact profile path is shell-specific, so use $PROFILE in PowerShell rather than copying a Unix path.

Warning: this changes your profile, which is executable shell configuration. Keep a backup and remove the Hugo line to undo it if completion causes startup errors.

7. Diagnose a completion failure safely

First separate generation from shell loading. Save the output to a temporary file and inspect its size:

$ hugo completion bash > /tmp/hugo-completion.bash
$ wc -c /tmp/hugo-completion.bash
11657 /tmp/hugo-completion.bash
$ head -n 1 /tmp/hugo-completion.bash
# bash completion V2 for hugo

Your byte count can differ between Hugo versions, and a generated script can contain more than the displayed first line. A zero-byte file means Hugo failed or output was redirected incorrectly. Run hugo completion bash --help and read the error before changing shell startup files.

Warning: do not run a generated script with sudo just to make completion work. Completion scripts are shell code: review any file before sourcing it, especially when it came from another machine or an untrusted repository. Generate it locally from the installed Hugo binary, then use bash -n for a Bash syntax check before installation.

Done means