Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I'm wondering how I can configure zsh to not expand the wildcard in a filename. For example I have a directory of a couple hundred files named as following:

a.foo-bar a.foo b.foo-bar b.foo c.foo-bar c.foo

I would like to be able to perform a tab completion matching after a wildcard, so

cat *.foo-< tab > => cat *.foo-bar

This is what I get instead:

$  cat *.foo-
=> cat a.foo-bar
   file
   a.foo-bar b.foo-bar c.foo-bar
share|improve this question

3 Answers 3

I don't think that's possible. You're asking the shell not only to figure out which files you do and don't want to end up as "valid according to your wildcard expansion", but you want the shell to figure out the "best" wildcard expression that will expand this way. I would expect that the second part is NP-complete.

share|improve this answer

I don't see a way as yet that you can get quite what you're after, but you can get a bit of a modification (which may or may not be helpful to you) via setopt GLOB_COMPLETE (this will give you only one expansion, and then you can tab through them... or edit just that one to be a * again, which may at least be a small improvement).

You might also dig around in man zshoptions, man zshcompctl, man zshcompwid and/or similar. The completion stuff for zsh is pretty complex, so I'm guessing there may well be a way to do this.

Also note, a somewhat related question:

How do I get zsh's autocomplete to complete wildcards like bash does?

share|improve this answer

One option is, that you replace the default key binding for the TAB key

bindkey "^I" expand-or-complete

with

bindkey "^I" complete-word

which won't expand a * to all matching files, but leaves the star untouched. This way you get rid of the endless list, but it still won't complete the globbing expression.

To solve this is much more tricky. You have to write your own completion widget (see man zshcompwid).

  1. Let's begin with the definition:

    zle -C complete-glob menu-complete compglob
    

    This introduces the new widget complete-glob, which behaves like menu-complete and uses the shell function compglob to generate the matches.

    [ Note: If you don't want the menu-completion, use the much more rudimentary options complete-word or list-choices ]

  2. Bind this new widget to a convenient shortcut, like CTRL+K:

    bindkey "^K" complete-glob
    

    Don't bind this to TAB, as the widget in its current form only completes files!

  3. Define the shell function compglob as follows, which does the actual work:

    compglob () {
        setopt localoptions globsubst
        compset -P '*'
        files=(${IPREFIX}*) 
        display=(${files/${IPREFIX}/${(q)IPREFIX}}) 
        glob=(${files/${IPREFIX}/}) 
        compadd -d display -- $glob
    }
    
  4. Demonstration:

    $ touch a.foo-bar a.foo b.foo-bar b.foo c.foo-bar c.foo
    $ cat *.f<CTRL+K>
    $ cat *.foo
    \*.foo      \*.foo-bar
    

    The only flaw I see is the \ in front of the star in the presented list. But this is only an optical flaw, as the completion is correct: *.foo or *.foo-bar.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.