@@ -119,8 +119,7 @@ __get_machines() {
119119
120120_systemctl () {
121121 local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
122- local cur_orig=$cur
123- local i verb comps mode
122+ local i verb comps mode cur_orig
124123
125124 local -A OPTS=(
126125 [STANDALONE]=' --all -a --reverse --after --before --defaults --force -f --full -l --global
@@ -223,11 +222,26 @@ _systemctl () {
223222 done
224223
225224 # When trying to match a unit name with certain special characters in its name (i.e
226- # foo\x2dbar:01) they get escaped by bash along the way, thus causing any possible
227- # match to fail. Let's unescape such characters in the verb we're trying to
228- # autocomplete to avoid this, however, use the original verb (cur_orig)
229- # during the final match (COMPREPLY)
230- cur=" $( echo $cur | xargs echo) "
225+ # foo\x2dbar:01) they get (un)escaped by bash along the way, thus causing any possible
226+ # match to fail.
227+ # The following condition solves two cases:
228+ # 1) We're trying to complete an already escaped unit name part,
229+ # i.e foo\\x2dba. In this case we need to unescape the name, so it
230+ # gets properly matched with the systemctl output (i.e. foo\x2dba).
231+ # However, we need to keep the original escaped name as well for the
232+ # final match, as the completion machinery does the unescaping
233+ # automagically.
234+ # 2) We're trying to complete an unescaped (literal) unit name part,
235+ # i.e. foo\x2dba. That means we don't have to do the unescaping
236+ # required for correct matching with systemctl's output, however,
237+ # we need to escape the name for the final match, where the completion
238+ # expects the string to be escaped.
239+ cur_orig=$cur
240+ if [[ $cur =~ ' \\' ]]; then
241+ cur=" $( echo $cur | xargs echo) "
242+ else
243+ cur_orig=" $( printf ' %q' $cur ) "
244+ fi
231245
232246 if [[ -z $verb ]]; then
233247 comps=" ${VERBS[*]} "
0 commit comments