bash-completion
bash-completion copied to clipboard
[RFC] Reset state of hostcomplete shopt after local unset
The patch message describes the problem that I want to fix... However, the fix, as I implemented it, causes a regression in the unit test for the _variables
function.
Before this patch, completing an array reference when the array index contained the @
character worked properly:
$ declare -A assoc1=([idx]=1)
$ : ${assoc1[@<TAB>
$ : ${assoc1[@] <CURSOR>
After this patch, completion is broken:
$ declare -A assoc1=([idx]=1)
$ : ${assoc1[@<TAB>
$ : ${assoc1[${assoc1[@]} <CURSOR>
Initially, I though that the _variables
function only worked if the hostcomplete
shopt was unset, so I tried to unset it inside the function (see diff below), however, that didn't help, at all.
Then, I learned about the __ltrim_colon_completions
function, which sounded like it would remove the duplication... However, running the completion with set -x
produces exactly the same output before and after these patches.
Does anybody know how to fix this?
--- a/bash_completion
+++ b/bash_completion
@@ -610,6 +610,8 @@ _split_longopt()
# False (> 0) if not.
_variables()
{
+ local shopt_reset=$( shopt -p hostcomplete )
+ $( shopt -u hostcomplete )
if [[ $cur =~ ^(\$(\{[!#]?)?)([A-Za-z0-9_]*)$ ]]; then
# Completing $var / ${var / ${!var / ${#var
if [[ $cur == \${* ]]; then
@@ -628,6 +630,7 @@ _variables()
# Complete $var with $variable
COMPREPLY+=( $( compgen -A variable -P '$' -- "${BASH_REMATCH[3]}" ) )
fi
+ $( eval ${shopt_reset} )
return 0
elif [[ $cur =~ ^(\$\{[#!]?)([A-Za-z0-9_]*)\[([^]]*)$ ]]; then
# Complete ${array[i with ${array[idx]}
@@ -639,11 +642,13 @@ _variables()
COMPREPLY+=( "${BASH_REMATCH[1]}${BASH_REMATCH[2]}[${BASH_REMATCH[3]}]}" )
fi
__ltrim_colon_completions "$cur" # array indexes may have colons
+ $( eval ${shopt_reset} )
return 0
elif [[ $cur =~ ^\$\{[#!]?[A-Za-z0-9_]*\[.*\]$ ]]; then
# Complete ${array[idx] with ${array[idx]}
COMPREPLY+=( "$cur}" )
__ltrim_colon_completions "$cur"
+ $( eval ${shopt_reset} )
return 0
else
case $prev in
@@ -660,10 +665,12 @@ _variables()
fi
COMPREPLY[i]=${COMPREPLY[i]#/usr/share/zoneinfo/}
done
+ $( eval ${shopt_reset} )
return 0
;;
esac
fi
+ $( eval ${shopt_reset} )
return 1
}
There's also a nice deduplicated trap
recipe in https://github.com/scop/bash-completion/issues/44#issuecomment-291136367 that could be adapted to automatically reset shopt as well at return.