FYI, here is the new autocompletion script I am now using on my machine. It shows in order 1) the commands 2) the options 3) the paths / files. Each of 1) 2) and 3) is internally sorted. Let me know if you want to merge into master / how I should perform a push request on your self-hosted repo :)
# completion file for bash # Copyright (C) 2012 - 2014 Jason A. Donenfeld <[email protected]> and # Brian Mattern <[email protected]>. All Rights Reserved. # This file is licensed under the GPLv2+. Please see COPYING for more information. # Edited by Jean Rabault 2020 _sort_entries_string () { # local sorted_list=$(echo $1 | xargs -n1 | sort | xargs) local sorted_list=$(echo $1 | tr ' ' '\n' | sort | tr '\n' ' ') echo $sorted_list } _setup_tmp_compreply () { TMP_COMPREPLY=() } _append_tmp_compreply () { # sort the TMP_COMPREPLY array IFS=$'\n' TMP_COMPREPLY=($(sort <<<"${TMP_COMPREPLY[*]}")); unset IFS # append the tmp array to the COMPREPLY COMPREPLY+=( "${TMP_COMPREPLY[@]}" ) } _pass_complete_entries () { _setup_tmp_compreply prefix="${PASSWORD_STORE_DIR:-$HOME/.password-store/}" prefix="${prefix%/}/" suffix=".gpg" autoexpand=${1:-0} local IFS=$'\n' local items=($(compgen -f $prefix$cur)) # Remember the value of the first item, to see if it is a directory. If # it is a directory, then don't add a space to the completion local firstitem="" # Use counter, can't use ${#items[@]} as we skip hidden directories local i=0 for item in ${items[@]}; do [[ $item =~ /\.[^/]*$ ]] && continue # if there is a unique match, and it is a directory with one entry # autocomplete the subentry as well (recursively) if [[ ${#items[@]} -eq 1 && $autoexpand -eq 1 ]]; then while [[ -d $item ]]; do local subitems=($(compgen -f "$item/")) local filtereditems=( ) for item2 in "${subitems[@]}"; do [[ $item2 =~ /\.[^/]*$ ]] && continue filtereditems+=( "$item2" ) done if [[ ${#filtereditems[@]} -eq 1 ]]; then item="${filtereditems[0]}" else break fi done fi # append / to directories [[ -d $item ]] && item="$item/" item="${item%$suffix}" TMP_COMPREPLY+=("${item#$prefix}") if [[ $i -eq 0 ]]; then firstitem=$item fi let i+=1 done # The only time we want to add a space to the end is if there is only # one match, and it is not a directory if [[ $i -gt 1 || ( $i -eq 1 && -d $firstitem ) ]]; then compopt -o nospace fi _append_tmp_compreply } _pass_complete_folders () { _setup_tmp_compreply prefix="${PASSWORD_STORE_DIR:-$HOME/.password-store/}" prefix="${prefix%/}/" local IFS=$'\n' local items=($(compgen -d $prefix$cur)) for item in ${items[@]}; do [[ $item == $prefix.* ]] && continue TMP_COMPREPLY+=("${item#$prefix}/") done _append_tmp_compreply } _pass_complete_keys () { _setup_tmp_compreply local IFS=$'\n' local GPG=gpg2 which $GPG >/dev/null || GPG=gpg # Extract names and email addresses from gpg --list-keys local keys="$($GPG --list-secret-keys --with-colons | cut -d : -f 10 | sort -u | sed '/^$/d')" TMP_COMPREPLY+=($(compgen -W "${keys}" -- ${cur})) _append_tmp_compreply } _pass() { COMPREPLY=() local cur="${COMP_WORDS[COMP_CWORD]}" local commands=$(_sort_entries_string "init ls find grep show insert generate edit rm mv cp git help version") if [[ $COMP_CWORD -gt 1 ]]; then local lastarg="${COMP_WORDS[$COMP_CWORD-1]}" case "${COMP_WORDS[1]}" in init) if [[ $lastarg == "-p" || $lastarg == "--path" ]]; then _pass_complete_folders compopt -o nospace else COMPREPLY+=($(compgen -W "-p --path" -- ${cur})) _pass_complete_keys fi ;; ls|list|edit) _pass_complete_entries ;; show|-*) COMPREPLY+=($(compgen -W "-c --clip" -- ${cur})) _pass_complete_entries 1 ;; insert) COMPREPLY+=($(compgen -W "-e --echo -m --multiline -f --force" -- ${cur})) _pass_complete_entries ;; generate) COMPREPLY+=($(compgen -W "-n --no-symbols -c --clip -f --force -i --in-place" -- ${cur})) _pass_complete_entries ;; cp|copy|mv|rename) COMPREPLY+=($(compgen -W "-f --force" -- ${cur})) _pass_complete_entries ;; rm|remove|delete) COMPREPLY+=($(compgen -W "-r --recursive -f --force" -- ${cur})) _pass_complete_entries ;; git) COMPREPLY+=($(compgen -W "init push pull config log reflog rebase" -- ${cur})) ;; esac else COMPREPLY+=($(compgen -W "${commands}" -- ${cur})) _pass_complete_entries 1 fi } complete -o nosort -o filenames -F _pass pass On Sat, Mar 28, 2020 at 2:45 PM J Rt <[email protected]> wrote: > > Thanks for your help, got it to work now. All was needed is change the > last line of the autocomplete script to: > > complete -o nosort -o filenames -F _pass pass > > the nosort option cancels the sorting done in the background by bash. > Found it there, should be ok with bash 4.4 and higher: > > https://unix.stackexchange.com/questions/215937/disable-sorting-of-compreply-in-bash-complete-function > > now when hitting tab tab I get first the (1){pass commands or > options}, then the (2){folders / files}. > > The sets (1) and (2) are not sorted though, but I think I will get it > done easily. > > On Sat, Mar 28, 2020 at 8:50 AM Reed Wade <[email protected]> wrote: > > > > > Ok, sounds good. Do you agree that this would be a bit nicer tab > > > autocompletion? Or do you mind a lot having to type 'show' to get the > > > second autocompletion? :) . > > > > I just always type 'show' so it only giving me the tree. > > > > > Do you think you would be able to implement the change you described > > > in your last message? > > > > I don't think anyone want to remove the command shortcut show sorry :D > > > > > If not I can give it a look / try, but I do not > > > have too much experience with this sort of scripting. > > > > I think the better thing to do in this case, is downloading the > > pass script and the autocompletion script, putting them in your ~/bin > > and .local/share/bash-completion/completions/ pathes and customize them. > > > > Removing the shortcut probably is easy, adapting the autocompletion > > script will need a little more understanding. > > > > A little tuto I use myself is : > > https://opensource.com/article/18/3/creating-bash-completion-script
