Zsh completion, previews and startup diagnosis

10 min read
On this page

Tab completion has three stages: a completion function generates candidates, fzf-tab presents them, and a preview command explains the selection. Missing candidates, a broken menu and a failing preview require different checks.

Interactive configuration belongs in .zshrc. Login shells may also read .zprofile; .zshenv can affect noninteractive invocations, so avoid putting terminal-only output and interactive plugins there.

Establish native completion first

Add additional completion directories to fpath before initialising:

autoload -Uz compinit
compinit

In a new shell, test cd <Tab> and, inside a repository, git switch <Tab>. Expect directories and branches respectively. If compinit reports insecure directories, inspect them with compaudit and correct ownership or permissions rather than permanently bypassing the check.

To test without the usual user startup files:

zsh -f

Initialise completion manually in that shell. If it works, investigate the normal configuration and plugins. Exit to return to the original shell.

fzf-tab selects existing candidates

Install fzf and fzf-tab, then load the plugin after compinit. Replace this example path with the real installation path:

source ~/.local/share/zsh/plugins/fzf-tab/fzf-tab.plugin.zsh
zstyle ':completion:*' menu no

fzf-tab presents native completion results; changing its colours cannot fix an incorrect branch-completion source. fzf-tab documentation

OrderComponentReason
1fpath and completion definitionsMake functions discoverable
2compinitInitialise completion
3fzf-tabConnect candidates to selection
4Suggestions and editing pluginsPreserve widget integration
5Syntax highlightingFollow the installed version's ordering requirements

Start with one directory preview

zstyle ':fzf-tab:complete:cd:*' fzf-preview \
  'eza -1 --color=always -- "$realpath"'

realpath belongs to file/directory completion contexts. Quotes preserve spaces, and -- prevents a leading hyphen from becoming an option. Do not assume the variable is available for every command.

After that works, add a branch preview:

zstyle ':fzf-tab:complete:git-(checkout|switch):*' fzf-preview \
  'git log --oneline -n 5 "$word" --'

word is the selected candidate. The preview assists selection; pressing Enter still executes the eventual command. If candidates appear but the preview is empty, run the preview separately with a real path or branch.

Integrate carapace deliberately

carapace can register completion for many commands and may replace existing definitions. Decide which provider should own a command, then retest context-sensitive previews such as git switch.

The earlier setup filtered compdef lines from generated initialisation output. That depends on script format and also needs an adapter between _carapace and _carapace_completer; copying only the filter is incomplete. Prefer the official setup instructions for a new environment instead of treating output filtering as a stable API.

Suggestions, prompts and aliases

Autosuggestions use command history, highlighting examines the command line, and Starship displays project context. None replaces completion.

alias ll='eza -lh --git'
alias tree2='eza --tree --level=2 --git-ignore'

These are interactive conveniences. Scripts should use explicit program names and flags. Preview dependencies must actually be executable; see the CLI toolbox.

Diagnose startup and completion failures

zsh -n ~/.zshrc

This checks syntax without executing startup code, so it cannot prove plugin paths exist. In a fresh shell, add native completion, fzf-tab, one preview and other plugins in order. A suddenly empty menu can indicate an unsupported fzf option or a competing Tab binding.

For slow startup, temporarily place zmodload zsh/zprof near the beginning of .zshrc and zprof at the end. Inspect expensive functions, then remove the instrumentation. Network calls, duplicate initialisation and prompt computation are more useful targets than plugin count alone.

Verify paths containing spaces, branch selection, no-candidate cases and ordinary history suggestions before polishing menu appearance.