4

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

4
+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. 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. 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. 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? 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? Oct 26, 2021 at 11:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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