3

In zsh, how can I enable extended_glob inline in a filename generation glob?

Say I want to run ls on all paths not named a, which can be done via:

setopt -o extendedglob
ls ^a

But is there any way to enable extended_glob for the above filename generation glob without using setopt -o extendedglob?

I know that I can use the (*) parameter expansion flag to enable extended_glob inline (without using setopt -o extendedglob) for regex parameter expansions like:

printf $'%s\n' "${(*)x#^a}"

2 Answers 2

4

Just enable extended_glob. I can't think of a reason not to do it.

The only reason extended_glob is off by default is because the default configuration is backward-compatible, and this goes back to before extended_glob existed. It doesn't change the behavior of many things that you're likely to write. The only thing I encounter in practice is that occasionally I need to quote a ^ or # in a command argument, but that's less common than me wanting to use ^ or # as a wildcard.

If you want to avoid changing the options in code, make the options local. You need to do that anyway in functions that may run in an unspecified context. Call emulate -L to set scripting-related options to their default value during the execution of the function, and restore them when the function returns.

function my_function {
  emulate -L zsh
  setopt extended_glob
  …
}

If you want to change the setting just for one line of code, you can put it in an anonymous function.

() { setopt local_options extended_glob; ls ^a }

By the way, currently the * parameter expansion flag doesn't help because it only affects substitutions, not filename generation (but affecting filename generation would be a useful feature). You can expand a glob inside a parameter substitution with the ${name:-word} form, which allows name to be omitted, combined with the ${~spec} form, e.g. echo ${~:-[^a]*} to list files whose name doesn't start with a. But echo ${(*)~:-^a*} doesn't work unless extended_glob is already enabled, because * (currently) has no effect on the globbing induced by glob_subst.

2
  • Thanks for the info. I guess I'll just use setopt -o extendedglob since there's no built-in inline syntax for enabling extended_glob in a filename generation glob.
    – XDR
    Commented Aug 13 at 2:13
  • Note that one can also now use emulate -L zsh -o extendedglob Commented Aug 13 at 7:11
3

One (ugly) trick if you want to keep extendedglob disabled could be to do:

alias -g '#x=/(Ne[! set -o extendedglob])' '#X=/(Ne[! set +o extendedglob])'

Then use #x to enable extendedglob in the following arguments up to #X which disables it:

$ touch {a..f}
$ echo with extendedglob: #x ^a #X and without: ^a
with extendedglob: b c d e f and without: ^a
1
  • Thanks for the info. I guess I'll just use setopt -o extendedglob since there's no built-in inline syntax for enabling extended_glob in a filename generation glob.
    – XDR
    Commented Aug 13 at 2:13

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .