From 9bfd760c1192da7b3d0d8f0f9c8bea8ed16f4e47 Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Fri, 11 Aug 2023 19:47:40 +0900 Subject: [PATCH] fix(_comp_{first_arg,count_args}): count any arguments after -- --- bash_completion | 6 ++++++ bash_completion.d/000_bash_completion_compat.bash | 6 ++++-- test/t/unit/test_unit_count_args.py | 12 ++++++++++++ test/t/unit/test_unit_get_first_arg.py | 14 ++++++++++++++ 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/bash_completion b/bash_completion index a71dd69a0df..63b63a042df 100644 --- a/bash_completion +++ b/bash_completion @@ -2168,6 +2168,9 @@ _comp_get_first_arg() if [[ ${words[i]} != -?* ]]; then arg=${words[i]} break + elif [[ ${words[i]} == -- ]]; then + ((i + 1 < cword)) && arg=${words[i + 1]} + break fi done } @@ -2190,6 +2193,9 @@ _comp_count_args() if [[ ${words[i]} != -?* && ${words[i - 1]} != ${2-} || ${words[i]} == ${3-} ]]; then ((ret++)) + elif [[ ${words[i]} == -- ]]; then + ((ret += cword - i - 1)) + break fi done } diff --git a/bash_completion.d/000_bash_completion_compat.bash b/bash_completion.d/000_bash_completion_compat.bash index 04fb6e7a9b0..715f6e7f141 100644 --- a/bash_completion.d/000_bash_completion_compat.bash +++ b/bash_completion.d/000_bash_completion_compat.bash @@ -401,7 +401,8 @@ _fstypes() # This function returns the first argument, excluding options # @deprecated 2.12 Use `_comp_get_first_arg`. Note that the new function # `_comp_get_first_arg` operates on `words` and `cword` instead of `COMP_WORDS` -# and `COMP_CWORD`. +# and `COMP_CWORD`. The new function considers a command-line argument after +# `--` as an argument. _get_first_arg() { local i @@ -423,7 +424,8 @@ _get_first_arg() # @var[out] args Return the number of arguments # @deprecated 2.12 Use `_comp_count_args`. Note that the new function # `_comp_count_args` returns the result in variable `ret` instead of `args`. -# In the new function, `-` is also counted as an argument. +# In the new function, `-` is also counted as an argument. The new function +# counts all the arguments after `--`. # shellcheck disable=SC2178 # assignments are not intended for global "args" _count_args() { diff --git a/test/t/unit/test_unit_count_args.py b/test/t/unit/test_unit_count_args.py index e942a67c64f..317db8bd196 100644 --- a/test/t/unit/test_unit_count_args.py +++ b/test/t/unit/test_unit_count_args.py @@ -78,3 +78,15 @@ def test_10_single_hyphen_2(self, bash): bash, "(a -b - c - e)", 5, "a -b - c - e", 11, arg='"" "-b"' ) assert output == "3" + + def test_11_double_hyphen_1(self, bash): + """all the words after -- should be counted""" + output = self._test( + bash, "(a -b -- -c -d e)", 5, "a -b -- -c -d e", 14 + ) + assert output == "3" + + def test_11_double_hyphen_2(self, bash): + """all the words after -- should be counted""" + output = self._test(bash, "(a b -- -c -d e)", 5, "a b -- -c -d e", 13) + assert output == "4" diff --git a/test/t/unit/test_unit_get_first_arg.py b/test/t/unit/test_unit_get_first_arg.py index 9a4245d212e..f03c2bb3543 100644 --- a/test/t/unit/test_unit_get_first_arg.py +++ b/test/t/unit/test_unit_get_first_arg.py @@ -55,3 +55,17 @@ def test_7_single_hyphen(self, bash, functions): bash, '_comp__test_unit "(a -b - c -d e)" 5', want_output=None ).strip() assert output == "-" + + def test_8_double_hyphen_1(self, bash, functions): + """any word after -- should be picked""" + output = assert_bash_exec( + bash, '_comp__test_unit "(a -b -- -c -d e)" 5', want_output=None + ).strip() + assert output == "-c" + + def test_8_double_hyphen_2(self, bash, functions): + """any word after -- should be picked only without any preceding argument""" + output = assert_bash_exec( + bash, '_comp__test_unit "(a b -- -c -d e)" 5', want_output=None + ).strip() + assert output == "b"