This actually seems to do what I want: _expand() { local -a expl local expansion expansion="${(b)$( eval print -r -- $words[CURRENT] )}" 2> /dev/null || return 1 _description expansions expl expansion compadd -QU "$expl[@]" -- $expansion } This code can of course cause undesirable side effects when expanding certain special parameters and command substitutions, but _expand suffers from this, too. Is there a way to locally disable special parameters and command substitutions? Are there any other drawbacks to this approach? Why isn't _expand doing something like this? On Tue, Apr 2, 2024 at 10:12 AM Marlon Richert wrote: > I would expect _expand to behave by default like expand-word or > list-expand, but it doesn't. > > For example, given default shell options, if `foo=*`, then expand-word > and list-expand will complete `$foo` to `*` and `$~foo` to the files > matched by `*` as a glob expression. > > However, no matter what zstyle options I set, _expand will either > complete both of these to `\*` or both of these to the files globbed by > `*`. > > By default, I would expect _expand to complete expressions in the same > way as the shell substitutes them when evaluating the command line. > > Is there a combination of zstyles that makes _expand complete `$foo` to > its literal value and `$~foo` to the files globbed by its value? > > If not, then I would like to see this being added somehow and preferably > be made the default behavior. > >