shellenv: export FPATH so child zsh shells inherit fpath#21910
Conversation
zsh's fpath is not an exported environment variable, so child shells (tmux/Zellij panes, nested zsh) lose Homebrew's completions path. The shellenv idempotency check only inspects PATH, which IS inherited, so it early-returns and never emits the fpath line. Exporting FPATH after setting fpath ensures child zsh shells inherit it. Fixes Homebrew#21879 Supersedes Homebrew#21884
There was a problem hiding this comment.
Pull request overview
Updates brew shellenv output for zsh so that Homebrew’s completion search path is inherited by child zsh shells (e.g., tmux panes / nested shells) by exporting FPATH after updating fpath.
Changes:
- Emit
export FPATH;in thezshbranch ofbrew shellenvoutput. - Adjust the integration spec to assert that
FPATHis exported when runningbrew shellenv zsh.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| Library/Homebrew/cmd/shellenv.sh | Exports FPATH for zsh so child shells inherit Homebrew’s completion path. |
| Library/Homebrew/test/cmd/shellenv_spec.rb | Updates integration expectation to check for export FPATH in zsh output. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
The idempotency early return fires when PATH already contains Homebrew's bin/sbin, skipping all output. This is correct for exported env vars but breaks zsh's fpath which is not inherited. Move shell detection before the check so the early-return path can still emit fpath and export FPATH for zsh.
@sumanthratna you didn't use anything at all here? are you sure? |
sorry I forgot the checkbox; fixed. For this PR, I used Opus 4.6 with high reasoning, with context (a) from original issue, (b) output of below $ echo $FPATH
$ zsh
$ echo $FPATH
$ eval "$(./bin/brew shellenv zsh)"
$ echo $FPATH |
The parent shell's shellenv already exported FPATH with the Homebrew site-functions entry. Child shells inherit it, so re-prepending via fpath[1,0]= is unnecessary when the idempotency early return triggers.
|
Hi @MikeMcQuaid @carlocab gentle bump to see if you have any other feedback here? |
|
My comment from #21910 (comment) still applies. You made a change in 505e9dd, but that doesn't seem to address the comment fully. |
zsh preserves the export attribute of FPATH when inherited from the parent environment, so child shells already have FPATH exported without re-emitting it on the early-return path. Verified with `typeset -p FPATH` across parent, child, and grandchild zsh shells.
|
Thanks @carlocab I re-read your message and realized what you meant. I didn't know that zsh preserves the export attribute of Can you take another look whenever you get a chance? And thanks again for the help |
carlocab
left a comment
There was a problem hiding this comment.
One more suggestion, and I think this should be ready.
|
@sumanthratna Thanks a lot ❤️! This fixes autocompletions inside codex. I always thought the issue was in codex not using a login shell. |
|
I have no idea why, but the line added in this PR, when run inside tmux, never returns. i ran the commands all one by one and they all return immediately except for I can open a new issue i that is preferable. |
|
@mhanberg Given how many people use |
|
@MikeMcQuaid sorry for the noise. I went on a vision quest and determined that it was a confluence of zsh from nixpkgs + portable ruby + demons that was causing crowdstrike to give my shell startup the hug of death. I just reverted to using Apologies! |
zsh's fpath is not an exported environment variable, so child shells (tmux/Zellij panes, nested zsh) lose Homebrew's completions path. The shellenv idempotency check only inspects PATH, which IS inherited, so it early-returns and never emits the fpath line. Exporting FPATH after setting fpath ensures child zsh shells inherit it.
Fixes #21879
Supersedes #21884
brew lgtm(style, typechecking and tests) with your changes locally?