<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body text="#FFFFFF" bgcolor="#333333">
    Thanks Benjamin.<br>
    <br>
    The autocompletion for the password names wasn't working for me in
    your revision. Not sure why. However, some of the bugs I reported
    where still in there.<br>
    <br>
    I did take a look at some of the improvements you made, specifically
    enhancing autocompletion of commands, and also fixed the bugs I
    reported, with the exception of not having any passwords in the
    store. That one still throws an error, and is kinda redundant
    anyways.<br>
    <br>
    I also put in some addition hints for some commands such as `show`.
    Very user friendly and quick now. <br>
    <br>
    Code below if it helps you out:<br>
    <br>
    #!/usr/bin/env fish<br>
    <br>
    # Copyright (C) 2012-2014 Dmitry Medvinsky
    <a class="moz-txt-link-rfc2396E" href="mailto:me@dmedvinsky.name"><me@dmedvinsky.name></a>. All Rights Reserved.<br>
    # This file is licensed under the GPLv2+. Please see COPYING for
    more information.<br>
    <br>
    # Updated 2019.<br>
    <br>
    set PROG 'pass'<br>
    <br>
    function __fish_pass_get_prefix<br>
        set -l prefix "$PASSWORD_STORE_DIR"<br>
        if [ -z "$prefix" ]<br>
            set prefix "$HOME/.password-store"<br>
        end<br>
        echo "$prefix"<br>
    end<br>
    <br>
    function __fish_pass_needs_command<br>
        set -l cmd (commandline -opc)<br>
        if [ (count $cmd) -eq 1 -a $cmd[1] = $PROG ]<br>
            return 0<br>
        end<br>
        return 1<br>
    end<br>
    <br>
    function __fish_pass_uses_command<br>
        set cmd (commandline -opc)<br>
        if [ (count $cmd) -gt 1 ]<br>
            if [ $argv[1] = $cmd[2] ]<br>
                return 0<br>
            end<br>
        end<br>
        return 1<br>
    end<br>
    <br>
    function __fish_pass_print_gpg_keys<br>
        gpg2 --list-keys | grep uid | sed 's/.*<\(.*\)>/\1/'<br>
    end<br>
    <br>
    function __fish_pass_print<br>
        set -l ext $argv[1]<br>
        set -l strip $argv[2]<br>
        set -l prefix (__fish_pass_get_prefix)<br>
        printf '%s\n' "$prefix"/**"$ext" | sed
    "s#$prefix/\(.*\)$strip#\1#"<br>
    end<br>
    <br>
    function __fish_pass_print_entry_dirs<br>
        # print directories if they exist<br>
        set -l prefix (__fish_pass_get_prefix)<br>
        set -l subdircount (find "$prefix" -maxdepth 1 -type d | wc -l)<br>
        if [ $subdircount -gt 2 ]<br>
            __fish_pass_print "/"<br>
        end<br>
    end<br>
    <br>
    function __fish_pass_print_entries<br>
        __fish_pass_print ".gpg" ".gpg"<br>
    end<br>
    <br>
    <br>
    function __fish_pass_print_entries_and_dirs<br>
        __fish_pass_print_entry_dirs<br>
        __fish_pass_print_entries<br>
    end<br>
    <br>
    <br>
    complete -c $PROG -e<br>
    <br>
    # help<br>
    complete -c $PROG -f -A -n '__fish_pass_needs_command' -a
    0__autocomplete_tip__0 -d 'TIP: type `-` then tab to get list of
    options on each command'<br>
    <br>
    # help<br>
    complete -c $PROG -f -A -n '__fish_pass_needs_command' -a help -d
    'Command: show usage help'<br>
    <br>
    # version<br>
    complete -c $PROG -f -A -n '__fish_pass_needs_command' -a version -d
    'Command: show program version'<br>
    <br>
    # init<br>
    complete -c $PROG -f -A -n '__fish_pass_needs_command' -a init -d
    'Command: initialize new password storage'<br>
    complete -c $PROG -f -A -n '__fish_pass_uses_command init' -s p -l
    path -d 'Assign gpg-id for specified sub folder of password store'<br>
    <br>
    # ls or list <br>
    complete -c $PROG -f -A -n '__fish_pass_needs_command' -a "ls list"
    -d 'Command: list passwords'<br>
    complete -c $PROG -f -A -n '__fish_pass_uses_command ls' -a
    "(__fish_pass_print_entry_dirs)"<br>
    complete -c $PROG -f -A -n '__fish_pass_uses_command list' -a
    "(__fish_pass_print_entry_dirs)"<br>
    <br>
    # insert or add<br>
    complete -c $PROG -f -A -n '__fish_pass_needs_command' -a "insert
    add" -d 'Command: insert new password'<br>
    complete -c $PROG -f -A -n '__fish_pass_uses_command insert' -s e -l
    echo -d 'Echo the password on console'<br>
    complete -c $PROG -f -A -n '__fish_pass_uses_command insert' -s m -l
    multiline -d 'Provide multiline password entry'<br>
    complete -c $PROG -f -A -n '__fish_pass_uses_command insert' -s f -l
    force -d 'Do not prompt before overwritting'<br>
    complete -c $PROG -f -A -n '__fish_pass_uses_command insert' -a
    "(__fish_pass_print_entry_dirs)"<br>
    complete -c $PROG -f -A -n '__fish_pass_uses_command add' -s e -l
    echo -d 'Echo the password on console'<br>
    complete -c $PROG -f -A -n '__fish_pass_uses_command add' -s m -l
    multiline -d 'Provide multiline password entry'<br>
    complete -c $PROG -f -A -n '__fish_pass_uses_command add' -s f -l
    force -d 'Do not prompt before overwritting'<br>
    complete -c $PROG -f -A -n '__fish_pass_uses_command add' -a
    "(__fish_pass_print_entry_dirs)"<br>
    <br>
    # generate<br>
    complete -c $PROG -f -A -n '__fish_pass_needs_command' -a generate
    -d 'Command: generate new password'<br>
    complete -c $PROG -f -A -n '__fish_pass_uses_command generate' -s n
    -l no-symbols -d 'Do not use special symbols'<br>
    complete -c $PROG -f -A -n '__fish_pass_uses_command generate' -s c
    -l clip -d 'Put the password in clipboard'<br>
    complete -c $PROG -f -A -n '__fish_pass_uses_command generate' -s f
    -l force -d 'Do not prompt before overwritting'<br>
    complete -c $PROG -f -A -n '__fish_pass_uses_command generate' -s i
    -l in-place -d 'Replace only the first line with the generated
    password'<br>
    complete -c $PROG -f -A -n '__fish_pass_uses_command generate' -a
    "(__fish_pass_print_entry_dirs)"<br>
    <br>
    # mv<br>
    complete -c $PROG -f -A -n '__fish_pass_needs_command' -a mv -d
    'Command: rename existing password'<br>
    complete -c $PROG -f -A -n '__fish_pass_uses_command mv' -s f -l
    force -d 'Force rename'<br>
    complete -c $PROG -f -A -n '__fish_pass_uses_command mv' -a
    "(__fish_pass_print_entries_and_dirs)"<br>
    <br>
    # cp<br>
    complete -c $PROG -f -A -n '__fish_pass_needs_command' -a cp -d
    'Command: copy existing password'<br>
    complete -c $PROG -f -A -n '__fish_pass_uses_command cp' -s f -l
    force -d 'Force copy'<br>
    complete -c $PROG -f -A -n '__fish_pass_uses_command cp' -a
    "(__fish_pass_print_entries_and_dirs)"<br>
    <br>
    # rm<br>
    complete -c $PROG -f -A -n '__fish_pass_needs_command' -a rm -d
    'Command: remove existing password'<br>
    complete -c $PROG -f -A -n '__fish_pass_uses_command rm' -s r -l
    recursive -d 'Remove password groups recursively'<br>
    complete -c $PROG -f -A -n '__fish_pass_uses_command rm' -s f -l
    force -d 'Force removal'<br>
    complete -c $PROG -f -A -n '__fish_pass_uses_command rm' -a
    "(__fish_pass_print_entries_and_dirs)"<br>
    <br>
    # edit<br>
    complete -c $PROG -f -A -n '__fish_pass_needs_command' -a edit -d
    'Command: edit password using text editor'<br>
    complete -c $PROG -f -A -n '__fish_pass_uses_command edit' -a
    "(__fish_pass_print_entries)"<br>
    <br>
    # show<br>
    complete -c $PROG -f -A -n '__fish_pass_needs_command' -a show -d
    'Command: show existing password. Options: --clip -c'<br>
    complete -c $PROG -f -A -n '__fish_pass_uses_command show' -s c -l
    clip -d 'Put password in clipboard. Use -c1 to clip first line of a
    multiline. Usage: -c[line-number]'<br>
    complete -c $PROG -f -A -n '__fish_pass_uses_command show' -a
    "(__fish_pass_print_entries)"<br>
    <br>
    # When no command is given, `show` is defaulted.<br>
    # DISABLED for better usability. Auto complete on pass command
    itself should only show the available commands, and not all the keys
    in the folder!<br>
    # complete -c $PROG -f -A -n '__fish_pass_needs_command' -s c -l
    clip -d 'Put password in clipboard'<br>
    # complete -c $PROG -f -A -n '__fish_pass_needs_command' -a
    "(__fish_pass_print_entries)"<br>
    # complete -c $PROG -f -A -n '__fish_pass_uses_command -c' -a
    "(__fish_pass_print_entries)"<br>
    # complete -c $PROG -f -A -n '__fish_pass_uses_command --clip' -a
    "(__fish_pass_print_entries)"<br>
    <br>
    # git<br>
    complete -c $PROG -f -A -n '__fish_pass_needs_command' -a git -d
    'Command: execute a git command'<br>
    complete -c $PROG -f -A -n '__fish_pass_uses_command git' -a 'init'
    -d 'Initialize git repository'<br>
    complete -c $PROG -f -A -n '__fish_pass_uses_command git' -a
    'status' -d 'Show status of the repo'<br>
    complete -c $PROG -f -A -n '__fish_pass_uses_command git' -a 'add'
    -d 'Add changes to the index'<br>
    complete -c $PROG -f -A -n '__fish_pass_uses_command git' -a
    'commit' -d 'Commit changes to the repo'<br>
    complete -c $PROG -f -A -n '__fish_pass_uses_command git' -a 'push'
    -d 'Push changes to remote repo'<br>
    complete -c $PROG -f -A -n '__fish_pass_uses_command git' -a 'pull'
    -d 'Pull changes from remote repo'<br>
    complete -c $PROG -f -A -n '__fish_pass_uses_command git' -a 'log'
    -d 'View changelog'<br>
    <br>
    # find or search<br>
    complete -f -c pass -n '__fish_pass_needs_command' -a "find search"
    -d 'find a password file or directory matching pattern'<br>
    complete -x -c pass -n '__fish_pass_uses_command search' <br>
    complete -x -c pass -n '__fish_pass_uses_command find'<br>
    <br>
    # grep<br>
    complete -c $PROG -f -A -n '__fish_pass_needs_command' -a grep -d
    'Command: search inside of decrypted password files for matching
    pattern'<br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <div class="moz-cite-prefix">On 2019-07-12 01:17, Benjamin Martin
      wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:9F778B26-6503-4980-9C60-04A6513DB7DD@gmail.com">
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      Hey Eric,
      <div class=""><br class="">
      </div>
      <div class="">The fish completions available from <a
href="https://git.zx2c4.com/password-store/tree/src/completion/pass.fish-completion"
          class="" moz-do-not-send="true">https://git.zx2c4.com/password-store/tree/src/completion/pass.fish-completion</a> are
        quite broken. I sent an email a long time ago on this mailing
        list with a fixed version of the fish completions, but nobody
        seemed to care nor were the broken completions ever fixed. If
        you want working fish completions save the below text in
        ~/.config/fish/completions/pass.fish (it does require you have
        both awk and find in your path, let me know if you run into any
        bugs):</div>
      <div class=""><br class="">
      </div>
      <div class="">
        <div class="">function __fish_pass_get_prefix</div>
        <div class="">    set -l prefix "$PASSWORD_STORE_DIR"</div>
        <div class="">    if [ -z "$prefix" ]</div>
        <div class="">        set prefix "$HOME/.password-store"</div>
        <div class="">    end</div>
        <div class="">    echo "$prefix"</div>
        <div class="">end</div>
        <div class=""><br class="">
        </div>
        <div class="">function __fish_pass_needs_command</div>
        <div class="">    set -l cmd (commandline -opc)</div>
        <div class="">    if [ (count $cmd) -eq 1 -a $cmd[1] = pass ]</div>
        <div class="">        return 0</div>
        <div class="">    end</div>
        <div class="">    return 1</div>
        <div class="">end</div>
        <div class=""><br class="">
        </div>
        <div class="">function __fish_pass_uses_command</div>
        <div class="">    set cmd (commandline -opc)</div>
        <div class="">    if [ (count $cmd) -gt 1 ]</div>
        <div class="">        if [ $argv[1] = $cmd[2] ]</div>
        <div class="">            return 0</div>
        <div class="">        end</div>
        <div class="">    end</div>
        <div class="">    return 1</div>
        <div class="">end</div>
        <div class=""><br class="">
        </div>
        <div class="">function __fish_pass_print_gpg_keys</div>
        <div class="">    gpg2 --list-secret-keys | awk '/sec/{getline
          l1; getline l2; gsub(/ /, "",l1); print l1 "\011" l2}'</div>
        <div class="">end</div>
        <div class=""><br class="">
        </div>
        <div class="">function __fish_pass_print_entry_dirs</div>
        <div class="">    cd (__fish_pass_get_prefix); ls -d **/</div>
        <div class="">end</div>
        <div class=""><br class="">
        </div>
        <div class="">function __fish_pass_print_entries</div>
        <div class="">    cd (__fish_pass_get_prefix); find . -type f
          -name "*.gpg" | sed "s/\.\/\|.gpg//g"</div>
        <div class="">end</div>
        <div class=""><br class="">
        </div>
        <div class="">function __fish_pass_print_entries_and_dirs</div>
        <div class="">    __fish_pass_print_entry_dirs</div>
        <div class="">    __fish_pass_print_entries</div>
        <div class="">end</div>
        <div class=""><br class="">
        </div>
        <div class=""># init</div>
        <div class="">complete -f -c pass -n '__fish_pass_needs_command'
          -a init -d 'initialize new password storage'</div>
        <div class="">complete -x -c pass -n '__fish_pass_uses_command
          init' -s p -l path -a '(__fish_pass_print_entry_dirs)' -d
          'Assign gpg-id for specified sub folder of password store'</div>
        <div class="">complete -f -k -c pass -n
          '__fish_pass_uses_command init' -a
          '(__fish_pass_print_gpg_keys)'</div>
        <div class=""><br class="">
        </div>
        <div class=""># ls</div>
        <div class="">complete -f -c pass -n '__fish_pass_needs_command'
          -a ls -d 'list passwords'</div>
        <div class="">complete -x -c pass -n '__fish_pass_uses_command
          ls' -a '(__fish_pass_print_entry_dirs)'</div>
        <div class=""><br class="">
        </div>
        <div class=""># grep</div>
        <div class="">complete -f -c pass -n '__fish_pass_needs_command'
          -a grep -d 'search inside of decrypted password files for
          matching pattern'</div>
        <div class="">complete -x -c pass -n '__fish_pass_uses_command
          grep' </div>
        <div class=""><br class="">
        </div>
        <div class=""># find or search</div>
        <div class="">complete -f -c pass -n '__fish_pass_needs_command'
          -a "find search" -d 'find a password file or directory
          matching pattern'</div>
        <div class="">complete -x -c pass -n '__fish_pass_uses_command
          search' </div>
        <div class="">complete -x -c pass -n '__fish_pass_uses_command
          find'</div>
        <div class=""><br class="">
        </div>
        <div class=""># show</div>
        <div class="">complete -f -c pass -n '__fish_pass_needs_command'
          -a show -d 'show existing password'</div>
        <div class="">complete -f -c pass -n '__fish_pass_uses_command
          show' -s c -l clip -d 'copy first (or otherwise specified)
          line to the clipboard'</div>
        <div class="">complete -f -c pass -n '__fish_pass_uses_command
          show' -s q -l qrcode -d 'display a QR code of the (or
          otherwise specified) first line'</div>
        <div class="">complete -f -c pass -n '__fish_pass_uses_command
          show' -a '(__fish_pass_print_entries)' </div>
        <div class=""><br class="">
        </div>
        <div class=""># insert</div>
        <div class="">complete -f -c pass -n '__fish_pass_needs_command'
          -a insert -d 'insert new password'</div>
        <div class="">complete -f -c pass -n '__fish_pass_uses_command
          insert' -s e -l echo -d 'Echo the password on console'</div>
        <div class="">complete -f -c pass -n '__fish_pass_uses_command
          insert' -s m -l multiline -d 'Provide multiline password
          entry'</div>
        <div class="">complete -f -c pass -n '__fish_pass_uses_command
          insert' -s f -l force -d 'Do not prompt before overwritting'</div>
        <div class="">complete -f -c pass -n '__fish_pass_uses_command
          insert' -a "(__fish_pass_print_entry_dirs)"</div>
        <div class=""><br class="">
        </div>
        <div class=""># edit</div>
        <div class="">complete -f -c pass -n '__fish_pass_needs_command'
          -a edit -d 'edit password using text editor'</div>
        <div class="">complete -f -c pass -n '__fish_pass_uses_command
          edit' -a "(__fish_pass_print_entries)"</div>
        <div class=""><br class="">
        </div>
        <div class=""># generate</div>
        <div class="">complete -f -c pass -n '__fish_pass_needs_command'
          -a generate -d 'generate new password'</div>
        <div class="">complete -f -c pass -n '__fish_pass_uses_command
          generate' -s n -l no-symbols -d 'Do not use special symbols'</div>
        <div class="">complete -f -c pass -n '__fish_pass_uses_command
          generate' -s c -l clip -d 'Put the password in clipboard'</div>
        <div class="">complete -f -c pass -n '__fish_pass_uses_command
          generate' -s f -l force -d 'Do not prompt before overwritting'</div>
        <div class="">complete -f -c pass -n '__fish_pass_uses_command
          generate' -s i -l in-place -d 'Replace only the first line
          with the generated password'</div>
        <div class="">complete -f -c pass -n '__fish_pass_uses_command
          generate' -a "(__fish_pass_print_entries_and_dirs)"</div>
        <div class=""><br class="">
        </div>
        <div class=""># rm</div>
        <div class="">complete -f -c pass -n '__fish_pass_needs_command'
          -a rm -d 'remove existing password'</div>
        <div class="">complete -f -c pass -n '__fish_pass_uses_command
          rm' -s r -l recursive -d 'Remove password groups recursively'</div>
        <div class="">complete -f -c pass -n '__fish_pass_uses_command
          rm' -s f -l force -d 'Force removal'</div>
        <div class="">complete -f -c pass -n '__fish_pass_uses_command
          rm' -a "(__fish_pass_print_entries_and_dirs)"</div>
        <div class=""><br class="">
        </div>
        <div class=""># mv</div>
        <div class="">complete -f -c pass -n '__fish_pass_needs_command'
          -a mv -d 'rename existing password'</div>
        <div class="">complete -f -c pass -n '__fish_pass_uses_command
          mv' -s f -l force -d 'Force rename'</div>
        <div class="">complete -f -c pass -n '__fish_pass_uses_command
          mv' -a "(__fish_pass_print_entries_and_dirs)"</div>
        <div class=""><br class="">
        </div>
        <div class=""># cp</div>
        <div class="">complete -f -c pass -n '__fish_pass_needs_command'
          -a cp -d 'copy existing password'</div>
        <div class="">complete -f -c pass -n '__fish_pass_uses_command
          cp' -s f -l force -d 'Force copy'</div>
        <div class="">complete -f -c pass -n '__fish_pass_uses_command
          cp' -a "(__fish_pass_print_entries_and_dirs)"</div>
        <div class=""><br class="">
        </div>
        <div class=""># git</div>
        <div class="">complete -f -c pass -n '__fish_pass_needs_command'
          -a git -d 'execute a git command'</div>
        <div class="">complete -f -c pass -f -n
          '__fish_pass_uses_command git' -a 'init' -d 'Initialize git
          repository'</div>
        <div class="">complete -f -c pass -f -n
          '__fish_pass_uses_command git' -a 'status' -d 'Show status of
          the repo'</div>
        <div class="">complete -f -c pass -f -n
          '__fish_pass_uses_command git' -a 'add' -d 'Add changes to the
          index'</div>
        <div class="">complete -f -c pass -f -n
          '__fish_pass_uses_command git' -a 'commit' -d 'Commit changes
          to the repo'</div>
        <div class="">complete -f -c pass -f -n
          '__fish_pass_uses_command git' -a 'push' -d 'Push changes to
          remote repo'</div>
        <div class="">complete -f -c pass -f -n
          '__fish_pass_uses_command git' -a 'pull' -d 'Pull changes from
          remote repo'</div>
        <div class="">complete -f -c pass -f -n
          '__fish_pass_uses_command git' -a 'log' -d 'View changelog'</div>
        <div class=""><br class="">
        </div>
        <div class=""># help</div>
        <div class="">complete -f -c pass -n '__fish_pass_needs_command'
          -a help -d 'show usage help'</div>
        <div class=""><br class="">
        </div>
        <div class=""># version</div>
        <div class="">complete -f -c pass -n '__fish_pass_needs_command'
          -a version -d 'show program version'</div>
        <div class=""><br class="">
        </div>
        <div><br class="">
          <blockquote type="cite" class="">
            <div class="">On 12 Jul 2019, at 4:52 pm, Eric D. <<a
                href="mailto:nospamthankyou@ericdeis.com" class=""
                moz-do-not-send="true">nospamthankyou@ericdeis.com</a>>
              wrote:</div>
            <br class="Apple-interchange-newline">
            <div class="">
              <meta http-equiv="content-type" content="text/html;
                charset=UTF-8" class="">
              <div text="#FFFFFF" bgcolor="#333333" class=""> Given the
                following passwords, without any folders:<br class="">
                Password Store<br class="">
                ├── app1<br class="">
                ├── app2<br class="">
                ├── test<br class="">
                ├── test2<br class="">
                └── test3<br class="">
                <br class="">
                Autocompletion fails via rm command.<br class="">
                $ pass rm t[tab]<br class="">
                ~/.config/fish/completions/pass.fish (line 4): No
                matches for wildcard '"$prefix"/**"$ext"'. See `help
                expand`.        23:37:31<br class="">
                    printf '%s\n' "$prefix"/**"$ext" | sed
                "s#$prefix/\(.*\)$strip#\1#"<br class="">
                                  ^<br class="">
                in function '__fish_pass_print'<br class="">
                    called on line 50 of file
                ~/.config/fish/completions/pass.fish<br class="">
                    with parameter list '.gpg .gpg'<br class="">
                <br class="">
                in function '__fish_pass_print_entries'<br class="">
                    called on standard input<br class="">
                <br class="">
                Given the following passwords, with one folder:<br
                  class="">
                Password Store<br class="">
                ├── app1<br class="">
                ├── app2<br class="">
                ├── foo<br class="">
                │   └── bar<br class="">
                ├── test<br class="">
                ├── test2<br class="">
                └── test3<br class="">
                <br class="">
                $ pass rm t[tab]<br class="">
                Autocompletion now works!<br class="">
                <br class="">
                Also if there are zero passwords in the store,
                Autocompletion throws the same error below. <br
                  class="">
                $ pass fo[tab]<br class="">
                ~/.config/fish/completions/pass.fish (line 4): No
                matches for wildcard '"$prefix"/**"$ext"'. See `help
                expand`.           23:47:40<br class="">
                    printf '%s\n' "$prefix"/**"$ext" | sed
                "s#$prefix/\(.*\)$strip#\1#"<br class="">
                <br class="">
              </div>
              _______________________________________________<br
                class="">
              Password-Store mailing list<br class="">
              <a href="mailto:Password-Store@lists.zx2c4.com" class=""
                moz-do-not-send="true">Password-Store@lists.zx2c4.com</a><br
                class="">
              <a class="moz-txt-link-freetext" href="https://lists.zx2c4.com/mailman/listinfo/password-store">https://lists.zx2c4.com/mailman/listinfo/password-store</a><br
                class="">
            </div>
          </blockquote>
        </div>
        <br class="">
      </div>
    </blockquote>
    <br>
  </body>
</html>