I am writing a completion function where at some point I use _files -W $somevar -/ to complete sub directories of $somevar. For simplicity of the question let's say it's $HOME/.local/lib and I have subdirectories for different python versions in there and actually want to complete python versions for which I have a $HOME/.local/lib/ directory:

_files -W $HOME/.local/lib -/

and the directory tree looks something like

├── lib
│   ├── python3.5
│   │   └── site-packages
│   │       ├── somepackage
│   │       ├── somepackage-1.0.1-py2.7.egg-info
│   │       ├── someotherpackage
│   │       └── someotherpackage-1.0.11-py2.7.egg-info
│   ├── python3.6
│   │   └── site-packages
│   │       ├── somepackage
│   │       │   └── __pycache__
│   │       ├── somepackage-0.1-py3.6.egg-info
│   │       ├── someotherpackage
│   │       │   └── __pycache__
│   │       ├── someotherpackage-2018.4.16.dist-info

If I use the above completion for mycommand <TAB> the suggestions are now python3.5/ and python3.6/ with the trailing slash inserted by the tab completion and once I picked one version, the completion further suggest python3.5/site-package. This is insofar correct behaviour as these are actually existing directories. For my use case, I don't want to go down the directory three, but only complete directories directly in $HOME/.local/lib. Is there an easy way to complete directories without completing into them with builtin completion functions? Or should I use glob expressions $HOME/.local/lib/*(/) and strip off the parts that I don't want?

1 Answer 1


_files -W $HOME/.local/lib -/ -S "" -F "*/*" does the job: -S "" to suppress the addition of a suffix /, and _F "*/*" excludes subdirectories (via _path_files and compadd)).

-F causes the ignored-patterns style to be ignored, which is a minor downside of this approach. There may be a better way.

You must log in to answer this question.

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