@@ -439,6 +439,7 @@ _comp_split()
439
439
# @var[in] $?
440
440
# @var[in] _var
441
441
# @var[in] _append
442
+ # @var[in] _upvars
442
443
# @return original $?
443
444
_comp_compgen__error_fallback ()
444
445
{
@@ -449,6 +450,10 @@ _comp_compgen__error_fallback()
449
450
else
450
451
eval -- " $_var =()"
451
452
fi
453
+ if (( ${# _upvars[@]} )) ; then
454
+ _comp_unlocal " ${_upvars[@]} "
455
+ _upvars=()
456
+ fi
452
457
return " $_status "
453
458
}
454
459
@@ -478,6 +483,13 @@ _comp_compgen__error_fallback()
478
483
# is ${cur-}.
479
484
# -R The same as -c ''. Use raw outputs without filtering.
480
485
# -C dir Evaluate compgen/generator in the specified directory.
486
+ # -P pref Prepend the prefix to the generated completions. Unlike `compgen
487
+ # -P prefix`, this prefix is subject to filtering by `cur`. When a
488
+ # non-empty prefix is specified, first `cur` is tested whether it is
489
+ # consistent with the prefix. Then, `cur` is reduced for the part
490
+ # excluding the prefix, and the normal completion generation is
491
+ # performed. Finally, the prefix is prepended to generated
492
+ # completions.
481
493
# @var[in,opt] cur Used as the default value of a prefix to filter the
482
494
# completions.
483
495
#
@@ -562,6 +574,7 @@ _comp_compgen()
562
574
local _var=
563
575
local _cur=${_comp_compgen__cur-${cur-} }
564
576
local _dir=" "
577
+ local _prefix=" "
565
578
local _ifs=$' \t\n ' _has_ifs=" "
566
579
local _icmd=" " _xcmd=" "
567
580
local -a _upvars=()
@@ -572,7 +585,7 @@ _comp_compgen()
572
585
shopt -u nocasematch
573
586
fi
574
587
local OPTIND=1 OPTARG=" " OPTERR=0 _opt
575
- while getopts ' :av:U:Rc:C:lF:i:x:' _opt " $@ " ; do
588
+ while getopts ' :av:U:Rc:C:P: lF:i:x:' _opt " $@ " ; do
576
589
case $_opt in
577
590
a) _append=set ;;
578
591
v)
@@ -601,6 +614,7 @@ _comp_compgen()
601
614
fi
602
615
_dir=$OPTARG
603
616
;;
617
+ P) _prefix=$OPTARG ;;
604
618
l) _has_ifs=set _ifs=$' \n ' ;;
605
619
F) _has_ifs=set _ifs=$OPTARG ;;
606
620
[ix])
@@ -636,6 +650,19 @@ _comp_compgen()
636
650
[[ $_append ]] || _append=${_comp_compgen__append-}
637
651
fi
638
652
653
+ local _prefix_fail=" "
654
+ if [[ $_prefix ]]; then
655
+ if [[ $_cur == " $_prefix " * ]]; then
656
+ _cur=${_cur# " $_prefix " }
657
+ elif [[ $_prefix == " $_cur " * ]]; then
658
+ _cur=" "
659
+ else
660
+ # No completions are generated because the current word does not match
661
+ # the prefix.
662
+ _prefix_fail=set
663
+ fi
664
+ fi
665
+
639
666
if [[ $1 != -* ]]; then
640
667
# usage: _comp_compgen [options] NAME args
641
668
if [[ $_has_ifs ]]; then
@@ -657,6 +684,11 @@ _comp_compgen()
657
684
fi
658
685
shift
659
686
687
+ if [[ $_prefix_fail ]]; then
688
+ _comp_compgen__error_fallback
689
+ return 1
690
+ fi
691
+
660
692
_comp_compgen__call_generator " $@ "
661
693
else
662
694
# usage: _comp_compgen [options] -- [compgen_options]
@@ -680,6 +712,11 @@ _comp_compgen()
680
712
return 2
681
713
fi
682
714
715
+ if [[ $_prefix_fail ]]; then
716
+ _comp_compgen__error_fallback
717
+ return 1
718
+ fi
719
+
683
720
_comp_compgen__call_builtin " $@ "
684
721
fi
685
722
}
@@ -694,8 +731,6 @@ _comp_compgen()
694
731
# @var[in] _var
695
732
_comp_compgen__call_generator ()
696
733
{
697
- (( ${# _upvars[@]} )) && _comp_unlocal " ${_upvars[@]} "
698
-
699
734
if [[ $_dir ]]; then
700
735
local _original_pwd=$PWD
701
736
local PWD=${PWD-} OLDPWD=${OLDPWD-}
@@ -708,14 +743,28 @@ _comp_compgen__call_generator()
708
743
}
709
744
fi
710
745
746
+ (( ${# _upvars[@]} )) && _comp_unlocal " ${_upvars[@]} "
747
+
711
748
local _comp_compgen__append=$_append
712
749
local _comp_compgen__var=$_var
713
750
local _comp_compgen__cur=$_cur cur=$_cur
751
+ if [[ $_prefix ]]; then
752
+ local -a tmp=()
753
+ local _comp_compgen__var=tmp
754
+ local _comp_compgen__append=" "
755
+ fi
714
756
# Note: we use $1 as a part of a function name, and we use $2... as
715
757
# arguments to the function if any.
716
758
# shellcheck disable=SC2145
717
759
" ${_generator[@]} " " $@ "
718
760
local _status=$?
761
+ if [[ $_prefix ]]; then
762
+ local _i
763
+ for _i in " ${! tmp[@]} " ; do
764
+ tmp[_i]=$_prefix ${tmp[_i]}
765
+ done
766
+ _comp_compgen -RU tmp ${_append: +-a} -v " $_var " -- -W ' "${tmp[@]}"'
767
+ fi
719
768
720
769
# Go back to the original directory.
721
770
# Note: Failure of this line results in the change of the current
@@ -770,6 +819,13 @@ if ((BASH_VERSINFO[0] > 5 || BASH_VERSINFO[0] == 5 && BASH_VERSINFO[1] >= 3)); t
770
819
771
820
(( ${# _upvars[@]} )) && _comp_unlocal " ${_upvars[@]} "
772
821
(( ${# _result[@]} )) || return
822
+
823
+ if [[ $_prefix ]]; then
824
+ local _i
825
+ for _i in " ${! _result[@]} " ; do
826
+ _result[_i]=$_prefix ${_result[_i]}
827
+ done
828
+ fi
773
829
if [[ $_append ]]; then
774
830
eval -- " $_var +=(\"\$ {_result[@]}\" )"
775
831
else
@@ -794,7 +850,13 @@ else
794
850
}
795
851
796
852
(( ${# _upvars[@]} )) && _comp_unlocal " ${_upvars[@]} "
797
- _comp_split -l ${_append: +-a} " $_var " " $_result "
853
+
854
+ if [[ $_prefix ]]; then
855
+ _comp_split -l ${_append: +-a} " $_var " \
856
+ " $( IFS=$' \n ' compgen -W ' $_result' -P " $_prefix " ) "
857
+ else
858
+ _comp_split -l ${_append: +-a} " $_var " " $_result "
859
+ fi
798
860
}
799
861
fi
800
862
0 commit comments