I am trying to create simple zsh completion rules for a password manager script pass.

pass stores its passwords in directory structure, the files itself are .gpg files.

I want to complete directories and files in given path $HOME/passwords, so that directories names are simply completed, and file names are completed without .gpg extension

The following rules complete directory names correctly,

#compdef pass

_pass() {
    _arguments '1: :->directory'
    case $state in

        _directories -W $HOME/passwords


but it completes filenames by their full name, ie foo.gpg.

How can I complete files without the .gpg extension ?

1 Answer 1


The basic idea is _files -g '*.gpg(:r)': complete *.gpg files, but strip their extension while doing so, using the r history modifier passed as a glob qualifier. However this doesn't automatically insert a space after successful completions.

So call _path_files separately for directories and files to add the appropriate suffix (/ or a space) explicitly with -S (which _path_files passes through to compadd.

_path_files -W $HOME/passwords -g '*(/)' -S /
_path_files -W $HOME/passwords -g '*.gpg(:r)' -S ' '
  • so where exactly should I add these two lines ? Inside directory) or should I add file) section ? Commented Apr 12, 2020 at 20:07
  • @400theCat Replace the call to _directories by this. Commented Apr 12, 2020 at 21:28

You must log in to answer this question.

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