Skip to content

fix(ftb-tmux-popup): strip --tmux/--popup from FZF_DEFAULT_OPTS - #588

Open
HaleTom wants to merge 6 commits into
Aloxaf:masterfrom
HaleTom:fix/ftb-tmux-popup-fdo-strip
Open

fix(ftb-tmux-popup): strip --tmux/--popup from FZF_DEFAULT_OPTS#588
HaleTom wants to merge 6 commits into
Aloxaf:masterfrom
HaleTom:fix/ftb-tmux-popup-fdo-strip

Conversation

@HaleTom

@HaleTom HaleTom commented Aug 18, 2026

Copy link
Copy Markdown

Fixes #587

Problem

ftb-tmux-popup (lib/ftb-tmux-popup:27) only strips --height*/--layout* from fzf_opts. With zstyle ':fzf-tab:*' use-fzf-default-opts yes and export FZF_DEFAULT_OPTS='--tmux' (or --popup), the popup does a nested popup: outer tmux popup -E (from ftb-tmux-popup) + inner fzf --tmux popup. Result: popup flashes and disappears, inserting the query text instead of showing matches.

History: #455 reported --tmux in FZF_DEFAULT_OPTS breaks ftb-tmux-popup. #509 fixed it by propagating FZF_DEFAULT_OPTS into the popup (01dad759 changed FZF_DEFAULT_OPTS=''FZF_DEFAULT_OPTS=${(qq)FZF_DEFAULT_OPTS}), which re-exposes the nested-popup case.

Fix

Strip --tmux/--popup (bare and =value forms) from the FZF_DEFAULT_OPTS env value passed to fzf inside the popup. Keep --height/--layout and all other opts.

# ${array:#pattern} filters the array as a whole and drops matching elements.
local -a _ftb_fdo_opts=(${(z)FZF_DEFAULT_OPTS})
local _ftb_fdo=${(j: :)_ftb_fdo_opts:#--(tmux|popup)*}

Note: filtering fzf_opts is NOT sufficient — fzf-tab's own fzf_opts never contains --tmux/--popup; the nesting comes from the FZF_DEFAULT_OPTS env propagated into the popup script (upstream #509). The env must be filtered.

Tests

21 new ztst cases in test/ftb-tmux-popup.ztst covering:

  • bare --tmux, --popup
  • --tmux=center,50%, --popup=bottom,30%
  • mixed with --height=40% --color=fg:1 (others kept)
  • bare --tmux does not eat the next arg
  • empty input
  • no tmux/popup untouched
  • --popup= stripped among others
  • --height 40% separate-arg kept, --tmux stripped
  • both --tmux and --popup stripped
  • both =value forms stripped
  • tmux/popup at ends, middle kept
  • height/layout kept, tmux= stripped
  • all four forms stripped
  • stripped result has zero elements (no '' placeholder) — via $#_r on (z)-split result
  • kept args round-trip through %q unchanged
  • quoted arg with space (--'has space') stays one element after (z) split; %q round-trips as --\'has space\' proving no '' placeholder is introduced

Verified: zsh +Z -f ./test/ztst.zsh test/ftb-tmux-popup.ztst → all tests successful. Existing test/fzftab.ztst still passes.

Verification

Minimal zshrc + tmux 3.7b with attached client:

  • Before: ls <TAB> → popup flashes and disappears; buffer becomes ls ls (query text inserted, no match list).
  • After: popup stays open, env FZF_DEFAULT_OPTS='' in generated script.

With use-fzf-default-opts yes, FZF_DEFAULT_OPTS is propagated into the
popup env (upstream Aloxaf#509). If it contains --tmux or --popup, fzf opens a
second (nested) popup inside the outer tmux popup -E, which flashes and
closes, inserting the query text instead of showing matches.

Strip --tmux/--popup (bare and =value forms) from the env value passed to
fzf inside the popup. Keep --height/--layout and all other opts.

Add 15 ztst cases covering bare/=value/mixed/separate-arg/empty inputs.
@HaleTom
HaleTom marked this pull request as draft August 18, 2026 10:43
Verify stripped results contain zero elements (no '' placeholder) and
kept args round-trip through %q unchanged.
--'has space' stays one element after (z) split; %q round-trips as
--\'has space\' proving no '' placeholder is introduced.
${array:#pattern} filters the array as a whole and drops matching
elements — no loop, no function, no '' placeholder.
@HaleTom
HaleTom force-pushed the fix/ftb-tmux-popup-fdo-strip branch from 43ae2b0 to 462e6c3 Compare August 18, 2026 11:01
egrep is obsolescent; use grep -E. The ztst run generates .zcompdump
in the repo root; ignore it so it never gets committed.
Capture strip output to a var before (z)-split. (z)$(cmd) re-splits the
command-substitution output and loses the quoting context, so
--'has  space' became 3 tokens. Capture-then-split preserves it as one
token with the double space intact.
@HaleTom

HaleTom commented Aug 18, 2026

Copy link
Copy Markdown
Author

Two incidental test-hygiene changes in commit dfb27f6 — explaining why they're in this PR:

1. test/fzftab.ztst: egrepgrep -E

-         $(locale -a 2>/dev/null | egrep 'utf8|UTF-8'))
+         $(locale -a 2>/dev/null | grep -E 'utf8|UTF-8'))

egrep is obsolescent — GNU grep 3.8+ emits egrep: warning: egrep is obsolescent; using grep -E on every invocation. The %prep block runs locale -a | egrep to build the $langs array for the é = ? locale probe, so every ztst run printed the warning to stderr. grep -E is the drop-in equivalent (same POSIX ERE semantics), so the locale-detection behaviour is unchanged — it just silences the deprecation noise. This is a test-only change; no runtime code touched.

2. .gitignore: add .zcompdump

 *.zwc
+.zcompdump

The ztst harness (test/ztst.zshtest/comptest, which sets export ZDOTDIR=$ZTST_testdir) generates a .zcompdump in the repo root on every test run. It's a generated cache file (60KB, machine-specific), not source. It got accidentally committed twice while iterating on this PR (I had to git rm --cached it both times). Adding it to .gitignore prevents it from ever being staged again. The existing *.zwc entry already ignores the compiled zsh bytecode; .zcompdump is the same class of generated artefact.

Both are unrelated to the --tmux/--popup fix itself but were necessary to keep the test suite clean and warning-free while running the new test/ftb-tmux-popup.ztst cases. Happy to split them into a separate commit if preferred.

@HaleTom
HaleTom marked this pull request as ready for review August 18, 2026 11:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] ftb-tmux-popup nests when FZF_DEFAULT_OPTS contains --tmux/--popup → DA ?1;2;4c leak

1 participant