diff --git a/bash_completion b/bash_completion index 38d14326615..06a3492fe23 100644 --- a/bash_completion +++ b/bash_completion @@ -895,7 +895,18 @@ _comp_delimited() _comp_compgen COMPREPLY "$@" -- "${cur##*"$delimiter"}" fi - ((${#COMPREPLY[@]} == 1)) && COMPREPLY=("$prefix$COMPREPLY") + # It would seem that in some specific cases we could avoid adding the + # prefix to all completions, thereby making the list of suggestions + # cleaner, and only adding it when there's exactly one completion. + # The cases where this opportunity has been observed involve having + # `show-all-if-ambiguous` on, but even that has cases where it fails + # and the last separator including everything before it is lost. + # https://github.com/scop/bash-completion/pull/913#issuecomment-1490140309 + local i + for i in "${!COMPREPLY[@]}"; do + COMPREPLY[i]="$prefix${COMPREPLY[i]}" + done + [[ $delimiter != : ]] || __ltrim_colon_completions "$cur" } diff --git a/test/t/test_pgrep.py b/test/t/test_pgrep.py index a319f60b55b..db3dfdd7b98 100644 --- a/test/t/test_pgrep.py +++ b/test/t/test_pgrep.py @@ -31,4 +31,3 @@ def test_nslist(self, completion): ) def test_nslist_after_comma(self, completion): assert completion - assert not any("," in x for x in completion) diff --git a/test/t/test_ssh_keygen.py b/test/t/test_ssh_keygen.py index 5c8adabba3a..cc6ff4ed028 100644 --- a/test/t/test_ssh_keygen.py +++ b/test/t/test_ssh_keygen.py @@ -27,13 +27,11 @@ def test_filedir_pub_at_end_of_s(self, completion): @pytest.mark.complete("ssh-keygen -s foo_key -n foo,") def test_usernames_for_n(self, completion): assert completion - assert not any("," in x for x in completion) # TODO check that these are usernames @pytest.mark.complete("ssh-keygen -s foo_key -h -n foo,") def test_host_for_h_n(self, completion): assert completion - assert not any("," in x for x in completion) # TODO check that these are hostnames @pytest.mark.complete("ssh-keygen -Y foo -n ") diff --git a/test/t/test_tox.py b/test/t/test_tox.py index 31ed4b04b23..b101b9be714 100644 --- a/test/t/test_tox.py +++ b/test/t/test_tox.py @@ -12,7 +12,7 @@ def test_2(self, completion): @pytest.mark.complete("tox -e foo,", cwd="tox") def test_3(self, completion): - assert all(x in completion for x in "py37 ALL".split()) + assert all("foo," + x in completion for x in "py37 ALL".split()) @pytest.mark.complete("tox -e foo -- ", cwd="tox") def test_default_after_dashdash(self, completion): diff --git a/test/t/test_tshark.py b/test/t/test_tshark.py index b28651f8a91..d44e62d48c7 100644 --- a/test/t/test_tshark.py +++ b/test/t/test_tshark.py @@ -14,7 +14,7 @@ def test_2(self, completion): @pytest.mark.complete("tshark -O foo,htt", require_cmd=True) def test_3(self, completion): # p: one completion only; http: e.g. http and http2 - assert completion == "p" or "http" in completion + assert completion == "p" or "foo,http" in completion @pytest.mark.complete("tshark -o tcp", require_cmd=True) def test_4(self, completion): diff --git a/test/t/unit/Makefile.am b/test/t/unit/Makefile.am index 1679cce5995..d23c14a8f7b 100644 --- a/test/t/unit/Makefile.am +++ b/test/t/unit/Makefile.am @@ -2,6 +2,7 @@ EXTRA_DIST = \ test_unit_command_offset.py \ test_unit_compgen.py \ test_unit_count_args.py \ + test_unit_delimited.py \ test_unit_deprecate_func.py \ test_unit_dequote.py \ test_unit_expand.py \ diff --git a/test/t/unit/test_unit_delimited.py b/test/t/unit/test_unit_delimited.py new file mode 100644 index 00000000000..e20dcd18967 --- /dev/null +++ b/test/t/unit/test_unit_delimited.py @@ -0,0 +1,42 @@ +import pytest + +from conftest import assert_bash_exec + + +@pytest.mark.bashcomp(cmd=None) +class TestUnitDelimited: + @pytest.fixture(scope="class") + def functions(self, request, bash): + assert_bash_exec( + bash, + "_comp_cmd_test_delim() {" + " local cur prev words cword comp_args;" + " _comp_get_words cur;" + " _comp_delimited , -W 'alpha beta bravo';" + "};" + "complete -F _comp_cmd_test_delim test_delim", + ) + + @pytest.mark.complete("test_delim --opt=a") + def test_1(self, functions, completion): + assert completion == ["lpha"] + + @pytest.mark.complete("test_delim --opt=b") + def test_2(self, functions, completion): + assert completion == ["beta", "bravo"] + + @pytest.mark.complete("test_delim --opt=alpha,b") + def test_3(self, functions, completion): + assert completion == ["alpha,beta", "alpha,bravo"] + + @pytest.mark.complete("test_delim --opt=alpha,be") + def test_4(self, functions, completion): + assert completion == ["ta"] + + @pytest.mark.complete("test_delim --opt=beta,a") + def test_5(self, functions, completion): + assert completion == ["lpha"] + + @pytest.mark.complete("test_delim --opt=c") + def test_6(self, functions, completion): + assert not completion