Describe the bug
On NixOS with home-manager, fzf-tab's -ftb-generate-complist autoloaded function produces 0 entries in _ftb_complist despite _ftb_compcap being correctly populated. This causes fzf-tab to silently fall back to standard zsh completion — the fzf popup never appears.
Defining the exact same function inline (not autoloaded) fixes the issue.
I can make sure:
To Reproduce
- Install fzf-tab via NixOS home-manager
programs.zsh.plugins
- Type
ls / and press Tab
- Standard zsh completion runs instead of fzf popup
Debug findings
Extensive debugging revealed the following chain:
| Variable |
Value |
Expected |
bindkey ^I |
fzf-tab-complete |
✅ Correct |
IN_FZF_TAB |
1 during compadd |
✅ Correct |
_ftb_compcap count |
18 (for ls /) |
✅ Correct |
_ftb_complist count |
0 |
❌ Should be 18 |
_ftb_finish |
0 |
— |
The compiled module path (fzf-tab-candidates-generate builtin) also produces 0 candidates. Removing the module (modules/ directory) and falling back to the pure-zsh for loop in -ftb-generate-complist also produces 0 candidates.
However, defining -ftb-generate-complist as an inline function (identical logic, not autoloaded) produces the correct 18 candidates and the fzf popup works perfectly:
# This works — defined inline in .zshrc:
-ftb-generate-complist() {
local dsuf dpre k _v filepath first_word default_color prefix bs=$'\b'
local -a list_colors group_colors tcandidates
local -i same_word=1
local -A namecolors modecolors
(( $#_ftb_compcap == 0 )) && return
# ... same logic as the autoloaded file ...
typeset -gUa _ftb_complist=("${(@)tcandidates//[0-9]#$bs}")
}
Additionally, autoload +X -Uz -- -ftb-generate-complist (force-loading eagerly) works when sourced interactively but not in a fresh shell from .zshrc.
Environment
- OS: NixOS unstable (nixos-unstable, kernel 6.19.12-cachyos)
- zsh version: 5.9
- fzf version: 0.71.0
- fzf-tab version: 1.3.0 (also reproduced with 1.2.0)
- fzf-tab installed via: NixOS home-manager
programs.zsh.plugins with src = "${pkgs.zsh-fzf-tab}/share/fzf-tab"
- oh-my-zsh: enabled (plugins: git, vi-mode)
Generated .zshrc loading order
1. oh-my-zsh (compinit runs here)
2. zoxide
3. fzf-tab/fzf-tab.plugin.zsh ← plugin sourced
4. zsh-autosuggestions
5. fast-syntax-highlighting
6. zsh-syntax-highlighting
7. source <(fzf --zsh) ← from programs.fzf
8. initContent (zstyles, aliases, bindkeys)
Minimal zshrc
autoload -Uz compinit && compinit
source /path/to/fzf-tab/fzf-tab.plugin.zsh
zstyle ':completion:*' menu no
# Type "ls /" then press Tab — no fzf popup appears
Workaround
Override -ftb-generate-complist with an inline function definition in .zshrc (after fzf-tab loads). The function body is identical to the autoloaded file — only the loading mechanism differs.
Describe the bug
On NixOS with home-manager, fzf-tab's
-ftb-generate-complistautoloaded function produces 0 entries in_ftb_complistdespite_ftb_compcapbeing correctly populated. This causes fzf-tab to silently fall back to standard zsh completion — the fzf popup never appears.Defining the exact same function inline (not autoloaded) fixes the issue.
I can make sure:
compinitTo Reproduce
programs.zsh.pluginsls /and press TabDebug findings
Extensive debugging revealed the following chain:
bindkey ^Ifzf-tab-completeIN_FZF_TAB1during compadd_ftb_compcapcountls /)_ftb_complistcount_ftb_finishThe compiled module path (
fzf-tab-candidates-generatebuiltin) also produces 0 candidates. Removing the module (modules/directory) and falling back to the pure-zshforloop in-ftb-generate-complistalso produces 0 candidates.However, defining
-ftb-generate-complistas an inline function (identical logic, not autoloaded) produces the correct 18 candidates and the fzf popup works perfectly:Additionally,
autoload +X -Uz -- -ftb-generate-complist(force-loading eagerly) works when sourced interactively but not in a fresh shell from.zshrc.Environment
programs.zsh.pluginswithsrc = "${pkgs.zsh-fzf-tab}/share/fzf-tab"Generated .zshrc loading order
Minimal zshrc
Workaround
Override
-ftb-generate-complistwith an inline function definition in.zshrc(after fzf-tab loads). The function body is identical to the autoloaded file — only the loading mechanism differs.