3

I have zsh completion for my custom script. It takes 3 optional arguments --insert, --edit, --rm and it completes files from given path:

#compdef pass

_pass() {

  local -a args

  args+=(
    '--insert[Create a new password entry]'
    '--edit[Edit a password entry]'
    '--rm[Delete a password entry]'
  )

  _arguments $args '1: :->directory'

  case $state in
  directory)
    _path_files -W $HOME/passwords -g '*(/)' -S /
    _path_files -W $HOME/passwords -g '*.gpg(:r)' -S ' '
    ;;
  esac
}

I need to add another option -P, that will also be offered for completion (when I type - and TAB), but does not offer path completion. This option should only take a string. So it should not match a path, and also it should not offer the other options if -P has been specified.

How can I add this new option to my completion script?

UPDATE:

The completion does not work for option -P, ie when i do:

pass -P <TAB>

it completes nothing because option -P needs a string. This is good. But, when I do

pass -P foo <TAB> 

it also does not complete nothing. But it should complete directories in current path. How can do that?

1 Answer 1

3
+100

Presuming all of the options you mentioned are mutually exclusive with each other, then the solution is as follows:

#compdef pass

_pass() {
  local -a args=(
      # (-) makes an option mutually exclusive with all other options. 
      '(-)--insert[Create a new password entry]'
      '(-)--edit[Edit a password entry]'
      '(-)--rm[Delete a password entry]'
      '(-)-P:string:'
      '1:password entry:->directory'
  )

  _arguments $args

  case $state in
    directory)
      _path_files -W $HOME/passwords -g '*(/)' -S /
      _path_files -W $HOME/passwords -g '*.gpg(:r)' -S ' '
      ;;
  esac
}

Documentation here: http://zsh.sourceforge.net/Doc/Release/Completion-System.html#index-_005farguments

5
  • works great. Thank you. Commented Dec 27, 2020 at 5:01
  • sorry, I have discovered small problem: Now it seems the completion requires an argument, before it completes from the path $HOME/passwords. Before your change, I could also use my script without any argument, ie pass TAB would complete from the path. Now it only works when i provide an argument. Commented Dec 29, 2020 at 4:51
  • 1
    That's easily fixed: Just add ':password entry:->directory' to the (options) group. I've updated my answer with it. Commented Dec 29, 2020 at 14:02
  • when I do pass -P foo <TAB>, it does not complete anything. It should complete directories in current path. See my update for more details. Would you know how to fix that? Commented Oct 20, 2021 at 5:57
  • @400theCat I updated my answer to add the behavior you want for -P. Will you award me the bounty before it expires? Commented Oct 26, 2021 at 11:07

You must log in to answer this question.

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