Skip to content

Commit 895386d

Browse files
authored
Merge pull request #801 from akinomyoga/_command_offset-bash52
fix(_command_offset): support quoting of the command name in `complete -p` (bash 5.2)
2 parents 7b5d158 + 33dc624 commit 895386d

File tree

2 files changed

+26
-5
lines changed

2 files changed

+26
-5
lines changed

bash_completion

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2302,7 +2302,9 @@ _comp_command_offset()
23022302
compopt -o filenames
23032303
COMPREPLY=($(compgen -d -c -- "$cur"))
23042304
else
2305-
local cmd=${COMP_WORDS[0]} compcmd=${COMP_WORDS[0]}
2305+
local ret
2306+
_comp_dequote "${COMP_WORDS[0]}" || ret=${COMP_WORDS[0]}
2307+
local cmd=$ret compcmd=$ret
23062308
local cspec=$(complete -p "$cmd" 2>/dev/null)
23072309

23082310
# If we have no completion for $cmd yet, see if we have for basename
@@ -2367,8 +2369,10 @@ _comp_command_offset()
23672369
done
23682370
else
23692371
cspec=${cspec#complete}
2370-
cspec=${cspec%%"$compcmd"}
2371-
COMPREPLY=($(eval compgen "$cspec" -- '$cur'))
2372+
cspec=${cspec%%@("$compcmd"|"'${compcmd//\'/\'\\\'\'}'")}
2373+
local result=$(eval compgen "$cspec" -- '$cur')
2374+
local IFS=$'\n'
2375+
COMPREPLY=($result)
23722376
fi
23732377
break
23742378
done

test/t/unit/test_unit_command_offset.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import pytest
44

5-
from conftest import assert_bash_exec, assert_complete
5+
from conftest import assert_bash_exec, assert_complete, bash_env_saved
66

77

88
def join(words):
@@ -25,13 +25,13 @@ def functions(self, bash):
2525
"complete -F _comp_command meta; "
2626
"_compfunc() { COMPREPLY=(%s); }" % join(self.wordlist),
2727
)
28+
2829
completions = [
2930
'complete -F _compfunc "${COMP_WORDS[0]}"',
3031
'complete -W %s "${COMP_WORDS[0]}"' % quote(join(self.wordlist)),
3132
'COMPREPLY=(dummy); complete -r "${COMP_WORDS[0]}"',
3233
"COMPREPLY+=(${#COMPREPLY[@]})",
3334
]
34-
3535
for idx, comp in enumerate(completions, 2):
3636
assert_bash_exec(
3737
bash,
@@ -40,6 +40,11 @@ def functions(self, bash):
4040
% {"idx": idx, "comp": comp},
4141
)
4242

43+
assert_bash_exec(
44+
bash, "complete -W %s 'cmd!'" % quote(join(self.wordlist))
45+
)
46+
assert_bash_exec(bash, 'complete -W \'"$word1" "$word2"\' cmd6')
47+
4348
def test_1(self, bash, functions):
4449
assert_complete(bash, 'cmd1 "/tmp/aaa bbb" ')
4550
assert_bash_exec(bash, "! complete -p aaa", want_output=None)
@@ -72,3 +77,15 @@ def test_2(self, bash, functions, cmd, expected_completion):
7277
cleared before the retry.
7378
"""
7479
assert assert_complete(bash, "meta %s " % cmd) == expected_completion
80+
81+
def test_cmd_quoted(self, bash, functions):
82+
assert assert_complete(bash, "meta 'cmd2' ") == self.wordlist
83+
84+
def test_cmd_specialchar(self, bash, functions):
85+
assert assert_complete(bash, "meta 'cmd!' ") == self.wordlist
86+
87+
def test_space(self, bash, functions):
88+
with bash_env_saved(bash) as bash_env:
89+
bash_env.write_variable("word1", "a b c")
90+
bash_env.write_variable("word2", "d e f")
91+
assert assert_complete(bash, "meta cmd6 ") == ["a b c", "d e f"]

0 commit comments

Comments
 (0)