On Sun, Jun 14, 2020 at 5:37 PM Bart Schaefer wrote: > > Incidentally the _prefix behavior with the unambiguous prefix is > itself a compromise; before workers/18841 (2003-07-09) it would > alarmingly delete the entire word from the line. That's this bit of code (line numbers because gmail will probably line wrap this): 51 if [[ "$tmp" != _prefix ]] && "$tmp"; then 52 [[ compstate[nmatches] -gt 1 ]] && return 0 53 compadd -U -i "$IPREFIX" -I "$ISUFFIX" - "${compstate[unambiguous]%$suf}x" 54 compstate[list]= 55 if [[ -n $compstate[unambiguous] ]]; then 56 compstate[insert]=unambiguous 57 else 58 compstate[insert]=0 59 fi 60 return 0 61 fi The doc says: The completion code breaks the string to complete into seven fields in the order: The first field is an ignored prefix taken from the command line, the contents of the IPREFIX parameter plus the string given with the -i option. With the -U option, only the string from the -i option is used. Unless this doc is inaccurate, it's useless to even pass the -I option on line 53. Diagnosing this a bit further, I find that the reason parts of the word vanish from the command line is because _path_files has already added a completion for the directory prefix. Consequently the compadd performed by _prefix is a second one, which adds an ambiguity that was not previously present, and compadd -U apparently selects the wrong match to insert. The below patch ALMOST fixes this. The remaining problem is that in the example % ls dir1/di_r2/dir3 The result is % ls dir1/dir2_/r2/dir3 where the "2" immediately left of the cursor is highlighted. The slash isn't wanted, and any insertion at this point (including another slash) appears after the 2; any cursor motion removes the 2. This is all side-effects of the way that _path_files has done its compadd, and I haven't found a way to retroactively disable it. [I'm sure gmail is going to line-wrap this.] diff --git a/Completion/Base/Completer/_prefix b/Completion/Base/Completer/_prefix index 74be5f4..e256079 100644 --- a/Completion/Base/Completer/_prefix +++ b/Completion/Base/Completer/_prefix @@ -50,13 +50,19 @@ for tmp in "$comp[@]"; do if [[ "$tmp" != _prefix ]] && "$tmp"; then [[ compstate[nmatches] -gt 1 ]] && return 0 - compadd -U -i "$IPREFIX" -I "$ISUFFIX" - "${compstate[unambiguous]%$suf}x" - compstate[list]= - if [[ -n $compstate[unambiguous] ]]; then - compstate[insert]=unambiguous - else + # Does the following need pattern quoting on $PREFIX? + if [[ ${compstate[unambiguous]} = "$PREFIX"* ]]; then + # We completed something following the original prefix compstate[insert]=0 + compstate[to_end]= + else + # We completed something inside the original prefix + compstate[insert]=unambiguous + fi + if [[ $compstate[nmatches] -eq 0 ]]; then + compadd -U -i "$IPREFIX" -S "$ISUFFIX" - "${compstate[unambiguous]%$suf}" fi + compstate[list]= return 0 fi (( _matcher_num++ ))