Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: why '_file -/' completes files if there is no directory?

This came in while I was on vacation, but I noticed it still has no

On Jul 25, 11:09pm, Jun T. wrote:
} Subject: why '_file -/' completes files if there is no directory?

The literal answer to this question is that _files always completes
anything in the filesystem.  The -g and -/ options don't mean that
matches will be restricted, just that they'll be grouped differently.

} With the following style:
} zstyle ':completion:*:warnings' format 'No match for: %d
} If there is no subdirectory in the current directory,
}     zsh$ cd <TAB>
} gives
}     No match for: `local directory'
} but
}     zsh$ rmdir <TAB>
} completes the normal files in the current directory.

I suspect it was left that way because people who were used to the
older, less context-aware completion preferred the visual feedback of
having *something* completed.

} Not a serious problem, but I prefer getting a warning than being
} offered a useless list of normal files.
} Are there any way to stop this behavior by using zstyle?

Yes, though it's not obvious.  More below.

} I tried
} zstyle ':completion:*:directories' file-patterns '*(-/)'
} but it didn't' work (it seems setting file-patterns for a specific
} tag has no meaning).

Right, the file-patterns style may be used to *define* the tags, so it
is evaluated before the tag part of the context is generated.

} Setting file-patterns (or tag-order?) to each
} context ':completion:*:gcc:option-I-1:*' etc. may work, but I don't
} want to do that even if it works.

Yes, tag-order is the "approved" mechanism.  However, zstyle provides
a convenient back-door for the cases where the approved method is not
general enough: the -e option calls "eval" on the style value at the
point where the style is looked up, which means you can examine the
current state of local variables, etc.  Here's your answer:

zstyle -e ':completion::*' file-patterns \
	'[[ $funcstack[1] = _files && $type = */* ]] && reply=("*(/)")'

This isn't ideal because it's fragile if _files is ever rewritten, but
those core completers are pretty stable at this point.

Messages sorted by: Reverse Date, Date, Thread, Author