{"thread":{"id":"54615","subject":"[PATCH v2 00/26] completion: bash: a bunch of fixes, cleanups, and reorganization","startedAt":"2020-11-10T21:21:41Z","lastAt":"2020-11-25T21:47:07Z","messageCount":36,"participants":["Felipe Contreras","Junio C Hamano","SZEDER Gábor"],"isPatch":true,"patchVersion":2,"patchTotal":26},"messages":[{"id":"409522","messageId":"20201110212136.870769-1-felipe.contreras@gmail.com","threadId":"54615","inReplyTo":null,"subject":"[PATCH v2 00/26] completion: bash: a bunch of fixes, cleanups, and reorganization","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-11-10T21:21:10Z","receivedAt":"2020-11-10T21:21:41Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"I found a couple of bugs and inconsistencies.\n\nAlso low-hanging fruit in terms of redundant code that can be merged and removed.\n\nTons of cleanups.\n\nAnd refactoring the ancient _get_comp_words_by_ref.\n\nSince v1:\n\n * Added bug fixes\n * A lot more reorganization\n\n\nFelipe Contreras (26):\n  completion: bash: fix prefix detection in branch.*\n  completion: bash: add correct suffix in variables\n  completion: bash: fix for suboptions with value\n  completion: bash: do not modify COMP_WORDBREAKS\n  test: completion: fix currently typed words\n  test: completion: add run_func() helper\n  completion: bash: remove non-append functionality\n  completion: bash: get rid of _append() functions\n  completion: bash: get rid of any non-append code\n  completion: bash: factor out check in __gitcomp\n  completion: bash: simplify equal suffix check\n  completion: bash: refactor __gitcomp\n  completion: bash: simplify __gitcomp\n  completion: bash: change suffix check in __gitcomp\n  completion: bash: improve __gitcomp suffix code\n  completion: bash: simplify config_variable_name\n  test: completion: switch __gitcomp_nl prefix test\n  completion: bash: simplify _get_comp_words_by_ref()\n  completion: bash: refactor _get_comp_words_by_ref()\n  completion: bash: cleanup _get_comp_words_by_ref()\n  completion: bash: trivial cleanup\n  completion: bash: rename _get_comp_words_by_ref()\n  completion: bash: improve __gitcomp description\n  completion: bash: add __gitcomp_opts\n  completion: bash: cleanup __gitcomp* invocations\n  completion: bash: shuffle __gitcomp functions\n\n contrib/completion/git-completion.bash | 648 +++++++++++--------------\n contrib/completion/git-completion.zsh  |  20 +-\n t/t9902-completion.sh                  | 159 +++---\n 3 files changed, 377 insertions(+), 450 deletions(-)\n\n-- \n2.29.2\n\n"},{"id":"409523","messageId":"20201110212136.870769-2-felipe.contreras@gmail.com","threadId":"54615","inReplyTo":"20201110212136.870769-1-felipe.contreras@gmail.com","subject":"[PATCH v2 01/26] completion: bash: fix prefix detection in branch.*","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-11-10T21:21:11Z","receivedAt":"2020-11-10T21:21:45Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Otherwise we are completely ignoring the --cur argument.\n\nThe issue can be tested with:\n\n  git clone --config=branch.<tab>\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n contrib/completion/git-completion.bash | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 7c81e4ba49..b866b68b3c 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2615,8 +2615,8 @@ __git_complete_config_variable_name ()\n \t\treturn\n \t\t;;\n \tbranch.*)\n-\t\tlocal pfx=\"${cur%.*}.\"\n-\t\tcur_=\"${cur#*.}\"\n+\t\tlocal pfx=\"${cur_%.*}.\"\n+\t\tcur_=\"${cur_#*.}\"\n \t\t__gitcomp_direct \"$(__git_heads \"$pfx\" \"$cur_\" \".\")\"\n \t\t__gitcomp_nl_append $'autoSetupMerge\\nautoSetupRebase\\n' \"$pfx\" \"$cur_\" \"$sfx\"\n \t\treturn\n-- \n2.29.2\n\n"},{"id":"409524","messageId":"20201110212136.870769-3-felipe.contreras@gmail.com","threadId":"54615","inReplyTo":"20201110212136.870769-1-felipe.contreras@gmail.com","subject":"[PATCH v2 02/26] completion: bash: add correct suffix in variables","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-11-10T21:21:12Z","receivedAt":"2020-11-10T21:21:47Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"__gitcomp automatically adds a suffix, but __gitcomp_nl and others\ndon't, we need to specify a space by default.\n\nCan be tested with:\n\n  git config branch.autoSetupMe<tab>\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n contrib/completion/git-completion.bash | 6 +++---\n t/t9902-completion.sh                  | 7 +++++++\n 2 files changed, 10 insertions(+), 3 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex b866b68b3c..bbdb46d87e 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2618,7 +2618,7 @@ __git_complete_config_variable_name ()\n \t\tlocal pfx=\"${cur_%.*}.\"\n \t\tcur_=\"${cur_#*.}\"\n \t\t__gitcomp_direct \"$(__git_heads \"$pfx\" \"$cur_\" \".\")\"\n-\t\t__gitcomp_nl_append $'autoSetupMerge\\nautoSetupRebase\\n' \"$pfx\" \"$cur_\" \"$sfx\"\n+\t\t__gitcomp_nl_append $'autoSetupMerge\\nautoSetupRebase\\n' \"$pfx\" \"$cur_\" \"${sfx- }\"\n \t\treturn\n \t\t;;\n \tguitool.*.*)\n@@ -2652,7 +2652,7 @@ __git_complete_config_variable_name ()\n \t\tlocal pfx=\"${cur_%.*}.\"\n \t\tcur_=\"${cur_#*.}\"\n \t\t__git_compute_all_commands\n-\t\t__gitcomp_nl \"$__git_all_commands\" \"$pfx\" \"$cur_\" \"$sfx\"\n+\t\t__gitcomp_nl \"$__git_all_commands\" \"$pfx\" \"$cur_\" \"${sfx- }\"\n \t\treturn\n \t\t;;\n \tremote.*.*)\n@@ -2668,7 +2668,7 @@ __git_complete_config_variable_name ()\n \t\tlocal pfx=\"${cur_%.*}.\"\n \t\tcur_=\"${cur_#*.}\"\n \t\t__gitcomp_nl \"$(__git_remotes)\" \"$pfx\" \"$cur_\" \".\"\n-\t\t__gitcomp_nl_append \"pushDefault\" \"$pfx\" \"$cur_\" \"$sfx\"\n+\t\t__gitcomp_nl_append \"pushDefault\" \"$pfx\" \"$cur_\" \"${sfx- }\"\n \t\treturn\n \t\t;;\n \turl.*.*)\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex 2be9190425..4a3d3d1597 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -2293,6 +2293,13 @@ test_expect_success 'git config - value' '\n \tEOF\n '\n \n+test_expect_success 'git config - direct completions' '\n+\ttest_completion \"git config branch.autoSetup\" <<-\\EOF\n+\tbranch.autoSetupMerge Z\n+\tbranch.autoSetupRebase Z\n+\tEOF\n+'\n+\n test_expect_success 'git -c - section' '\n \ttest_completion \"git -c br\" <<-\\EOF\n \tbranch.Z\n-- \n2.29.2\n\n"},{"id":"409525","messageId":"20201110212136.870769-4-felipe.contreras@gmail.com","threadId":"54615","inReplyTo":"20201110212136.870769-1-felipe.contreras@gmail.com","subject":"[PATCH v2 03/26] completion: bash: fix for suboptions with value","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-11-10T21:21:13Z","receivedAt":"2020-11-10T21:21:49Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"We need to ignore options that don't start with -- as well.\n\nDepending on the value of COMP_WORDBREAKS the last word could be\nduplicated otherwise.\n\nCan be tested with:\n\n  git merge -X diff-algorithm=<tab>\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n contrib/completion/git-completion.bash |  2 +-\n t/t9902-completion.sh                  | 15 +++++++++++++++\n 2 files changed, 16 insertions(+), 1 deletion(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex bbdb46d87e..5b2dff150d 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -347,7 +347,7 @@ __gitcomp ()\n \tlocal cur_=\"${3-$cur}\"\n \n \tcase \"$cur_\" in\n-\t--*=)\n+\t*=)\n \t\t;;\n \t--no-*)\n \t\tlocal c i=0 IFS=$' \\t\\n'\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex 4a3d3d1597..4deda01153 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -537,6 +537,15 @@ test_expect_success '__gitcomp - expand/narrow all negative options' '\n \tEOF\n '\n \n+test_expect_success '__gitcomp - equal skip' '\n+\ttest_gitcomp \"--option=\" \"--option=\" <<-\\EOF &&\n+\n+\tEOF\n+\ttest_gitcomp \"option=\" \"option=\" <<-\\EOF\n+\n+\tEOF\n+'\n+\n test_expect_success '__gitcomp - doesnt fail because of invalid variable name' '\n \t__gitcomp \"$invalid_variable_name\"\n '\n@@ -2342,6 +2351,12 @@ test_expect_success 'git clone --config= - value' '\n \tEOF\n '\n \n+test_expect_success 'options with value' '\n+\ttest_completion \"git merge -X diff-algorithm=\" <<-\\EOF\n+\n+\tEOF\n+'\n+\n test_expect_success 'sourcing the completion script clears cached commands' '\n \t__git_compute_all_commands &&\n \tverbose test -n \"$__git_all_commands\" &&\n-- \n2.29.2\n\n"},{"id":"409526","messageId":"20201110212136.870769-5-felipe.contreras@gmail.com","threadId":"54615","inReplyTo":"20201110212136.870769-1-felipe.contreras@gmail.com","subject":"[PATCH v2 04/26] completion: bash: do not modify COMP_WORDBREAKS","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-11-10T21:21:14Z","receivedAt":"2020-11-10T21:21:53Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"There was no need for this once __git_reassemble_comp_words_by_ref() was\nintroduced. Now irrespective of the value of COMP_WORDBREAKS, words are\nalways joined together.\n\nBy default COMP_WORDBREAKS does contain a colon, and if it doesn't\nsomebody probably has a reason for it.\n\nCompletions are not supposed to modify COMP_WORDBREAKS and none of the\ncompletions in the bash-completion project do.\n\nWe manually set it in Zsh so the Bash script is not confused.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n contrib/completion/git-completion.bash | 5 -----\n contrib/completion/git-completion.zsh  | 1 +\n 2 files changed, 1 insertion(+), 5 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 5b2dff150d..12275a3558 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -45,11 +45,6 @@\n #     When set to \"1\" suggest all options, including options which are\n #     typically hidden (e.g. '--allow-empty' for 'git commit').\n \n-case \"$COMP_WORDBREAKS\" in\n-*:*) : great ;;\n-*)   COMP_WORDBREAKS=\"$COMP_WORDBREAKS:\"\n-esac\n-\n # Discovers the path to the git repository taking any '--git-dir=<path>' and\n # '-C <path>' options into account and stores it in the $__git_repo_path\n # variable.\ndiff --git a/contrib/completion/git-completion.zsh b/contrib/completion/git-completion.zsh\nindex e0fda27f4c..fa7f88bbb3 100644\n--- a/contrib/completion/git-completion.zsh\n+++ b/contrib/completion/git-completion.zsh\n@@ -45,6 +45,7 @@ fi\n \n local old_complete=\"$functions[complete]\"\n functions[complete]=:\n+COMP_WORDBREAKS=':'\n GIT_SOURCING_ZSH_COMPLETION=y . \"$script\"\n functions[complete]=\"$old_complete\"\n \n-- \n2.29.2\n\n"},{"id":"409527","messageId":"20201110212136.870769-6-felipe.contreras@gmail.com","threadId":"54615","inReplyTo":"20201110212136.870769-1-felipe.contreras@gmail.com","subject":"[PATCH v2 05/26] test: completion: fix currently typed words","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-11-10T21:21:15Z","receivedAt":"2020-11-10T21:21:54Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"They don't match what we are supposed to be completing.\n\nNo functional change.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n t/t9902-completion.sh | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex 4deda01153..2e04462bb0 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -486,7 +486,7 @@ test_expect_success '__gitcomp - option parameter' '\n '\n \n test_expect_success '__gitcomp - prefix' '\n-\ttest_gitcomp \"branch.me\" \"remote merge mergeoptions rebase\" \\\n+\ttest_gitcomp \"branch.maint.me\" \"remote merge mergeoptions rebase\" \\\n \t\t\"branch.maint.\" \"me\" <<-\\EOF\n \tbranch.maint.merge Z\n \tbranch.maint.mergeoptions Z\n@@ -494,7 +494,7 @@ test_expect_success '__gitcomp - prefix' '\n '\n \n test_expect_success '__gitcomp - suffix' '\n-\ttest_gitcomp \"branch.me\" \"master maint next seen\" \"branch.\" \\\n+\ttest_gitcomp \"branch.ma\" \"master maint next seen\" \"branch.\" \\\n \t\t\"ma\" \".\" <<-\\EOF\n \tbranch.master.Z\n \tbranch.maint.Z\n-- \n2.29.2\n\n"},{"id":"409528","messageId":"20201110212136.870769-7-felipe.contreras@gmail.com","threadId":"54615","inReplyTo":"20201110212136.870769-1-felipe.contreras@gmail.com","subject":"[PATCH v2 06/26] test: completion: add run_func() helper","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-11-10T21:21:16Z","receivedAt":"2020-11-10T21:21:55Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Pretty straightforward: runs functions.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n t/t9902-completion.sh | 58 ++++++++++++++++++-------------------------\n 1 file changed, 24 insertions(+), 34 deletions(-)\n\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex 2e04462bb0..3ec9ff9308 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -75,6 +75,12 @@ run_completion ()\n \t__git_wrap__git_main && print_comp\n }\n \n+run_func ()\n+{\n+\tlocal -a COMPREPLY &&\n+\t\"$@\" && print_comp\n+}\n+\n # Test high-level completion\n # Arguments are:\n # 1: typed text so far (cur)\n@@ -452,8 +458,7 @@ test_expect_success '__gitcomp_direct - puts everything into COMPREPLY as-is' '\n \tEOF\n \t(\n \t\tcur=should_be_ignored &&\n-\t\t__gitcomp_direct \"$(cat expected)\" &&\n-\t\tprint_comp\n+\t\trun_func __gitcomp_direct \"$(cat expected)\"\n \t) &&\n \ttest_cmp expected out\n '\n@@ -547,7 +552,7 @@ test_expect_success '__gitcomp - equal skip' '\n '\n \n test_expect_success '__gitcomp - doesnt fail because of invalid variable name' '\n-\t__gitcomp \"$invalid_variable_name\"\n+\trun_func __gitcomp \"$invalid_variable_name\"\n '\n \n read -r -d \"\" refs <<-\\EOF\n@@ -586,7 +591,7 @@ test_expect_success '__gitcomp_nl - no suffix' '\n '\n \n test_expect_success '__gitcomp_nl - doesnt fail because of invalid variable name' '\n-\t__gitcomp_nl \"$invalid_variable_name\"\n+\trun_func __gitcomp_nl \"$invalid_variable_name\"\n '\n \n test_expect_success '__git_remotes - list remotes from $GIT_DIR/remotes and from config file' '\n@@ -1086,8 +1091,7 @@ test_expect_success '__git_complete_refs - simple' '\n \tEOF\n \t(\n \t\tcur= &&\n-\t\t__git_complete_refs &&\n-\t\tprint_comp\n+\t\trun_func __git_complete_refs\n \t) &&\n \ttest_cmp expected out\n '\n@@ -1099,8 +1103,7 @@ test_expect_success '__git_complete_refs - matching' '\n \tEOF\n \t(\n \t\tcur=mat &&\n-\t\t__git_complete_refs &&\n-\t\tprint_comp\n+\t\trun_func __git_complete_refs\n \t) &&\n \ttest_cmp expected out\n '\n@@ -1113,8 +1116,7 @@ test_expect_success '__git_complete_refs - remote' '\n \tEOF\n \t(\n \t\tcur= &&\n-\t\t__git_complete_refs --remote=other &&\n-\t\tprint_comp\n+\t\trun_func __git_complete_refs --remote=other\n \t) &&\n \ttest_cmp expected out\n '\n@@ -1132,8 +1134,7 @@ test_expect_success '__git_complete_refs - track' '\n \tEOF\n \t(\n \t\tcur= &&\n-\t\t__git_complete_refs --track &&\n-\t\tprint_comp\n+\t\trun_func __git_complete_refs --track\n \t) &&\n \ttest_cmp expected out\n '\n@@ -1145,8 +1146,7 @@ test_expect_success '__git_complete_refs - current word' '\n \tEOF\n \t(\n \t\tcur=\"--option=mat\" &&\n-\t\t__git_complete_refs --cur=\"${cur#*=}\" &&\n-\t\tprint_comp\n+\t\trun_func __git_complete_refs --cur=\"${cur#*=}\"\n \t) &&\n \ttest_cmp expected out\n '\n@@ -1158,8 +1158,7 @@ test_expect_success '__git_complete_refs - prefix' '\n \tEOF\n \t(\n \t\tcur=v1.0..mat &&\n-\t\t__git_complete_refs --pfx=v1.0.. --cur=mat &&\n-\t\tprint_comp\n+\t\trun_func __git_complete_refs --pfx=v1.0.. --cur=mat\n \t) &&\n \ttest_cmp expected out\n '\n@@ -1175,8 +1174,7 @@ test_expect_success '__git_complete_refs - suffix' '\n \tEOF\n \t(\n \t\tcur= &&\n-\t\t__git_complete_refs --sfx=. &&\n-\t\tprint_comp\n+\t\trun_func __git_complete_refs --sfx=.\n \t) &&\n \ttest_cmp expected out\n '\n@@ -1189,8 +1187,7 @@ test_expect_success '__git_complete_fetch_refspecs - simple' '\n \tEOF\n \t(\n \t\tcur= &&\n-\t\t__git_complete_fetch_refspecs other &&\n-\t\tprint_comp\n+\t\trun_func __git_complete_fetch_refspecs other\n \t) &&\n \ttest_cmp expected out\n '\n@@ -1201,8 +1198,7 @@ test_expect_success '__git_complete_fetch_refspecs - matching' '\n \tEOF\n \t(\n \t\tcur=br &&\n-\t\t__git_complete_fetch_refspecs other \"\" br &&\n-\t\tprint_comp\n+\t\trun_func __git_complete_fetch_refspecs other \"\" br\n \t) &&\n \ttest_cmp expected out\n '\n@@ -1215,8 +1211,7 @@ test_expect_success '__git_complete_fetch_refspecs - prefix' '\n \tEOF\n \t(\n \t\tcur=\"+\" &&\n-\t\t__git_complete_fetch_refspecs other \"+\" \"\"  &&\n-\t\tprint_comp\n+\t\trun_func __git_complete_fetch_refspecs other \"+\" \"\"\n \t) &&\n \ttest_cmp expected out\n '\n@@ -1229,8 +1224,7 @@ test_expect_success '__git_complete_fetch_refspecs - fully qualified' '\n \tEOF\n \t(\n \t\tcur=refs/ &&\n-\t\t__git_complete_fetch_refspecs other \"\" refs/ &&\n-\t\tprint_comp\n+\t\trun_func __git_complete_fetch_refspecs other \"\" refs/\n \t) &&\n \ttest_cmp expected out\n '\n@@ -1243,8 +1237,7 @@ test_expect_success '__git_complete_fetch_refspecs - fully qualified & prefix' '\n \tEOF\n \t(\n \t\tcur=+refs/ &&\n-\t\t__git_complete_fetch_refspecs other + refs/ &&\n-\t\tprint_comp\n+\t\trun_func __git_complete_fetch_refspecs other + refs/\n \t) &&\n \ttest_cmp expected out\n '\n@@ -1775,8 +1768,7 @@ test_path_completion ()\n \t\t# unusual characters in path names.  By requesting only\n \t\t# untracked files we do not have to bother adding any\n \t\t# paths to the index in those tests.\n-\t\t__git_complete_index_file --others &&\n-\t\tprint_comp\n+\t\trun_func __git_complete_index_file --others\n \t) &&\n \ttest_cmp expected out\n }\n@@ -2261,8 +2253,7 @@ do\n \t\t(\n \t\t\twords=(git push '$flag' other ma) &&\n \t\t\tcword=${#words[@]} cur=${words[cword-1]} &&\n-\t\t\t__git_complete_remote_or_refspec &&\n-\t\t\tprint_comp\n+\t\t\trun_func __git_complete_remote_or_refspec\n \t\t) &&\n \t\ttest_cmp expected out\n \t'\n@@ -2274,8 +2265,7 @@ do\n \t\t(\n \t\t\twords=(git push other '$flag' ma) &&\n \t\t\tcword=${#words[@]} cur=${words[cword-1]} &&\n-\t\t\t__git_complete_remote_or_refspec &&\n-\t\t\tprint_comp\n+\t\t\trun_func __git_complete_remote_or_refspec\n \t\t) &&\n \t\ttest_cmp expected out\n \t'\n-- \n2.29.2\n\n"},{"id":"409529","messageId":"20201110212136.870769-8-felipe.contreras@gmail.com","threadId":"54615","inReplyTo":"20201110212136.870769-1-felipe.contreras@gmail.com","subject":"[PATCH v2 07/26] completion: bash: remove non-append functionality","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-11-10T21:21:17Z","receivedAt":"2020-11-10T21:21:59Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"There's no point in setting COMPREPLY only to override it later, and in\nfact; we don't do that.\n\nTherefore there's no functional difference between __gitcomp_direct()\nand __gitcomp_direct_append(), since __gitcomp_direct() *always*\noperates on empty COMPREPLY.\n\nThe same goes for __gitcomp_nl().\n\nThis patch makes the functionality of append and non-append functions\nthe same.\n\nThere should be no functional changes.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n contrib/completion/git-completion.bash | 3 +--\n 1 file changed, 1 insertion(+), 2 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 12275a3558..6a1106f17d 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -298,7 +298,7 @@ __gitcomp_direct ()\n {\n \tlocal IFS=$'\\n'\n \n-\tCOMPREPLY=($1)\n+\tCOMPREPLY+=($1)\n }\n \n # Similar to __gitcomp_direct, but appends to COMPREPLY instead.\n@@ -450,7 +450,6 @@ __gitcomp_nl_append ()\n #    appended.\n __gitcomp_nl ()\n {\n-\tCOMPREPLY=()\n \t__gitcomp_nl_append \"$@\"\n }\n \n-- \n2.29.2\n\n"},{"id":"409530","messageId":"20201110212136.870769-9-felipe.contreras@gmail.com","threadId":"54615","inReplyTo":"20201110212136.870769-1-felipe.contreras@gmail.com","subject":"[PATCH v2 08/26] completion: bash: get rid of _append() functions","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-11-10T21:21:18Z","receivedAt":"2020-11-10T21:22:01Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"There's no need to have duplicated functionality.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n contrib/completion/git-completion.bash | 35 ++++++--------------------\n contrib/completion/git-completion.zsh  | 10 --------\n 2 files changed, 7 insertions(+), 38 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 6a1106f17d..7ecec00624 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -287,8 +287,7 @@ _get_comp_words_by_ref ()\n }\n fi\n \n-# Fills the COMPREPLY array with prefiltered words without any additional\n-# processing.\n+# Appends prefiltered words to COMPREPLY without any additional processing.\n # Callers must take care of providing only words that match the current word\n # to be completed and adding any prefix and/or suffix (trailing space!), if\n # necessary.\n@@ -301,19 +300,6 @@ __gitcomp_direct ()\n \tCOMPREPLY+=($1)\n }\n \n-# Similar to __gitcomp_direct, but appends to COMPREPLY instead.\n-# Callers must take care of providing only words that match the current word\n-# to be completed and adding any prefix and/or suffix (trailing space!), if\n-# necessary.\n-# 1: List of newline-separated matching completion words, complete with\n-#    prefix and suffix.\n-__gitcomp_direct_append ()\n-{\n-\tlocal IFS=$'\\n'\n-\n-\tCOMPREPLY+=($1)\n-}\n-\n __gitcompappend ()\n {\n \tlocal x i=${#COMPREPLY[@]}\n@@ -431,16 +417,8 @@ __gitcomp_builtin ()\n \t__gitcomp \"$options\"\n }\n \n-# Variation of __gitcomp_nl () that appends to the existing list of\n-# completion candidates, COMPREPLY.\n-__gitcomp_nl_append ()\n-{\n-\tlocal IFS=$'\\n'\n-\t__gitcompappend \"$1\" \"${2-}\" \"${3-$cur}\" \"${4- }\"\n-}\n-\n # Generates completion reply from newline-separated possible completion words\n-# by appending a space to all of them.\n+# by appending a space to all of them. The result is appended to COMPREPLY.\n # It accepts 1 to 4 arguments:\n # 1: List of possible completion words, separated by a single newline.\n # 2: A prefix to be added to each possible completion word (optional).\n@@ -450,7 +428,8 @@ __gitcomp_nl_append ()\n #    appended.\n __gitcomp_nl ()\n {\n-\t__gitcomp_nl_append \"$@\"\n+\tlocal IFS=$'\\n'\n+\t__gitcompappend \"$1\" \"${2-}\" \"${3-$cur}\" \"${4- }\"\n }\n \n # Fills the COMPREPLY array with prefiltered paths without any additional\n@@ -837,7 +816,7 @@ __git_complete_refs ()\n \n \t# Append DWIM remote branch names if requested\n \tif [ \"$dwim\" = \"yes\" ]; then\n-\t\t__gitcomp_direct_append \"$(__git_dwim_remote_heads \"$pfx\" \"$cur_\" \"$sfx\")\"\n+\t\t__gitcomp_direct \"$(__git_dwim_remote_heads \"$pfx\" \"$cur_\" \"$sfx\")\"\n \tfi\n }\n \n@@ -2612,7 +2591,7 @@ __git_complete_config_variable_name ()\n \t\tlocal pfx=\"${cur_%.*}.\"\n \t\tcur_=\"${cur_#*.}\"\n \t\t__gitcomp_direct \"$(__git_heads \"$pfx\" \"$cur_\" \".\")\"\n-\t\t__gitcomp_nl_append $'autoSetupMerge\\nautoSetupRebase\\n' \"$pfx\" \"$cur_\" \"${sfx- }\"\n+\t\t__gitcomp_nl $'autoSetupMerge\\nautoSetupRebase\\n' \"$pfx\" \"$cur_\" \"${sfx- }\"\n \t\treturn\n \t\t;;\n \tguitool.*.*)\n@@ -2662,7 +2641,7 @@ __git_complete_config_variable_name ()\n \t\tlocal pfx=\"${cur_%.*}.\"\n \t\tcur_=\"${cur_#*.}\"\n \t\t__gitcomp_nl \"$(__git_remotes)\" \"$pfx\" \"$cur_\" \".\"\n-\t\t__gitcomp_nl_append \"pushDefault\" \"$pfx\" \"$cur_\" \"${sfx- }\"\n+\t\t__gitcomp_nl \"pushDefault\" \"$pfx\" \"$cur_\" \"${sfx- }\"\n \t\treturn\n \t\t;;\n \turl.*.*)\ndiff --git a/contrib/completion/git-completion.zsh b/contrib/completion/git-completion.zsh\nindex fa7f88bbb3..1781401f5d 100644\n--- a/contrib/completion/git-completion.zsh\n+++ b/contrib/completion/git-completion.zsh\n@@ -120,16 +120,6 @@ __gitcomp_file ()\n \tcompadd -f -p \"${2-}\" -- ${(f)1} && _ret=0\n }\n \n-__gitcomp_direct_append ()\n-{\n-\t__gitcomp_direct \"$@\"\n-}\n-\n-__gitcomp_nl_append ()\n-{\n-\t__gitcomp_nl \"$@\"\n-}\n-\n __gitcomp_file_direct ()\n {\n \t__gitcomp_file \"$1\" \"\"\n-- \n2.29.2\n\n"},{"id":"409531","messageId":"20201110212136.870769-11-felipe.contreras@gmail.com","threadId":"54615","inReplyTo":"20201110212136.870769-1-felipe.contreras@gmail.com","subject":"[PATCH v2 10/26] completion: bash: factor out check in __gitcomp","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-11-10T21:21:20Z","receivedAt":"2020-11-10T21:22:02Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"This way we can reorganize the rest of the function.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n contrib/completion/git-completion.bash | 6 ++++--\n 1 file changed, 4 insertions(+), 2 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 15d7490cfd..bb1250f10c 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -321,9 +321,11 @@ __gitcomp ()\n {\n \tlocal cur_=\"${3-$cur}\"\n \n+\tif [[ \"$cur_\" == *= ]]; then\n+\t\treturn\n+\tfi\n+\n \tcase \"$cur_\" in\n-\t*=)\n-\t\t;;\n \t--no-*)\n \t\tlocal c i=0 IFS=$' \\t\\n'\n \t\tfor c in $1; do\n-- \n2.29.2\n\n"},{"id":"409532","messageId":"20201110212136.870769-10-felipe.contreras@gmail.com","threadId":"54615","inReplyTo":"20201110212136.870769-1-felipe.contreras@gmail.com","subject":"[PATCH v2 09/26] completion: bash: get rid of any non-append code","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-11-10T21:21:19Z","receivedAt":"2020-11-10T21:22:03Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n contrib/completion/git-completion.bash | 12 +++---------\n 1 file changed, 3 insertions(+), 9 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 7ecec00624..15d7490cfd 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -300,7 +300,7 @@ __gitcomp_direct ()\n \tCOMPREPLY+=($1)\n }\n \n-__gitcompappend ()\n+__gitcompadd ()\n {\n \tlocal x i=${#COMPREPLY[@]}\n \tfor x in $1; do\n@@ -310,12 +310,6 @@ __gitcompappend ()\n \tdone\n }\n \n-__gitcompadd ()\n-{\n-\tCOMPREPLY=()\n-\t__gitcompappend \"$@\"\n-}\n-\n # Generates completion reply, appending a space to possible completion words,\n # if necessary.\n # It accepts 1 to 4 arguments:\n@@ -429,7 +423,7 @@ __gitcomp_builtin ()\n __gitcomp_nl ()\n {\n \tlocal IFS=$'\\n'\n-\t__gitcompappend \"$1\" \"${2-}\" \"${3-$cur}\" \"${4- }\"\n+\t__gitcompadd \"$1\" \"${2-}\" \"${3-$cur}\" \"${4- }\"\n }\n \n # Fills the COMPREPLY array with prefiltered paths without any additional\n@@ -442,7 +436,7 @@ __gitcomp_file_direct ()\n {\n \tlocal IFS=$'\\n'\n \n-\tCOMPREPLY=($1)\n+\tCOMPREPLY+=($1)\n \n \t# use a hack to enable file mode in bash < 4\n \tcompopt -o filenames +o nospace 2>/dev/null ||\n-- \n2.29.2\n\n"},{"id":"409533","messageId":"20201110212136.870769-12-felipe.contreras@gmail.com","threadId":"54615","inReplyTo":"20201110212136.870769-1-felipe.contreras@gmail.com","subject":"[PATCH v2 11/26] completion: bash: simplify equal suffix check","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-11-10T21:21:21Z","receivedAt":"2020-11-10T21:22:05Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"We know the prefix is already '--no-', there's no need to check for the\nfirst '--'.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n contrib/completion/git-completion.bash | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex bb1250f10c..3f684cfe59 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -335,7 +335,7 @@ __gitcomp ()\n \t\t\tc=\"$c${4-}\"\n \t\t\tif [[ $c == \"$cur_\"* ]]; then\n \t\t\t\tcase $c in\n-\t\t\t\t--*=|*.) ;;\n+\t\t\t\t*=|*.) ;;\n \t\t\t\t*) c=\"$c \" ;;\n \t\t\t\tesac\n \t\t\t\tCOMPREPLY[i++]=\"${2-}$c\"\n-- \n2.29.2\n\n"},{"id":"409534","messageId":"20201110212136.870769-13-felipe.contreras@gmail.com","threadId":"54615","inReplyTo":"20201110212136.870769-1-felipe.contreras@gmail.com","subject":"[PATCH v2 12/26] completion: bash: refactor __gitcomp","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-11-10T21:21:22Z","receivedAt":"2020-11-10T21:22:07Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"We have to chunks of code doing exactly the same. There's no need for\nthat.\n\nNo functional changes.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n contrib/completion/git-completion.bash | 52 +++++++++-----------------\n 1 file changed, 18 insertions(+), 34 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 3f684cfe59..8b4308fc99 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -325,44 +325,28 @@ __gitcomp ()\n \t\treturn\n \tfi\n \n-\tcase \"$cur_\" in\n-\t--no-*)\n-\t\tlocal c i=0 IFS=$' \\t\\n'\n-\t\tfor c in $1; do\n-\t\t\tif [[ $c == \"--\" ]]; then\n+\tlocal c i=0 IFS=$' \\t\\n'\n+\tfor c in $1; do\n+\t\tif [[ $c == \"--\" ]]; then\n+\t\t\tif [[ \"$cur_\" == --no-* ]]; then\n \t\t\t\tcontinue\n \t\t\tfi\n-\t\t\tc=\"$c${4-}\"\n+\n+\t\t\tc=\"--no-...${4-}\"\n \t\t\tif [[ $c == \"$cur_\"* ]]; then\n-\t\t\t\tcase $c in\n-\t\t\t\t*=|*.) ;;\n-\t\t\t\t*) c=\"$c \" ;;\n-\t\t\t\tesac\n-\t\t\t\tCOMPREPLY[i++]=\"${2-}$c\"\n-\t\t\tfi\n-\t\tdone\n-\t\t;;\n-\t*)\n-\t\tlocal c i=0 IFS=$' \\t\\n'\n-\t\tfor c in $1; do\n-\t\t\tif [[ $c == \"--\" ]]; then\n-\t\t\t\tc=\"--no-...${4-}\"\n-\t\t\t\tif [[ $c == \"$cur_\"* ]]; then\n-\t\t\t\t\tCOMPREPLY[i++]=\"${2-}$c \"\n-\t\t\t\tfi\n-\t\t\t\tbreak\n+\t\t\t\tCOMPREPLY[i++]=\"${2-}$c \"\n \t\t\tfi\n-\t\t\tc=\"$c${4-}\"\n-\t\t\tif [[ $c == \"$cur_\"* ]]; then\n-\t\t\t\tcase $c in\n-\t\t\t\t*=|*.) ;;\n-\t\t\t\t*) c=\"$c \" ;;\n-\t\t\t\tesac\n-\t\t\t\tCOMPREPLY[i++]=\"${2-}$c\"\n-\t\t\tfi\n-\t\tdone\n-\t\t;;\n-\tesac\n+\t\t\tbreak\n+\t\tfi\n+\t\tc=\"$c${4-}\"\n+\t\tif [[ $c == \"$cur_\"* ]]; then\n+\t\t\tcase $c in\n+\t\t\t*=|*.) ;;\n+\t\t\t*) c=\"$c \" ;;\n+\t\t\tesac\n+\t\t\tCOMPREPLY[i++]=\"${2-}$c\"\n+\t\tfi\n+\tdone\n }\n \n # Clear the variables caching builtins' options when (re-)sourcing\n-- \n2.29.2\n\n"},{"id":"409535","messageId":"20201110212136.870769-14-felipe.contreras@gmail.com","threadId":"54615","inReplyTo":"20201110212136.870769-1-felipe.contreras@gmail.com","subject":"[PATCH v2 13/26] completion: bash: simplify __gitcomp","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-11-10T21:21:23Z","receivedAt":"2020-11-10T21:22:08Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"It's not possible for $cur_ to have anything more than --no- at this\npoint, so there's no need to add a suffix, nor check anything else.\n\nAll we are doing is checking that $cur_ matches --no, and adding a\ncompletion if so.\n\nThis way the code reflects what we are doing.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n contrib/completion/git-completion.bash | 5 ++---\n 1 file changed, 2 insertions(+), 3 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 8b4308fc99..9f5dd4e3e7 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -332,9 +332,8 @@ __gitcomp ()\n \t\t\t\tcontinue\n \t\t\tfi\n \n-\t\t\tc=\"--no-...${4-}\"\n-\t\t\tif [[ $c == \"$cur_\"* ]]; then\n-\t\t\t\tCOMPREPLY[i++]=\"${2-}$c \"\n+\t\t\tif [[ --no == \"$cur_\"* ]]; then\n+\t\t\t\tCOMPREPLY[i++]=\"--no-... \"\n \t\t\tfi\n \t\t\tbreak\n \t\tfi\n-- \n2.29.2\n\n"},{"id":"409536","messageId":"20201110212136.870769-16-felipe.contreras@gmail.com","threadId":"54615","inReplyTo":"20201110212136.870769-1-felipe.contreras@gmail.com","subject":"[PATCH v2 15/26] completion: bash: improve __gitcomp suffix code","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-11-10T21:21:25Z","receivedAt":"2020-11-10T21:22:11Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"There's no point in adding a suffix after a suffix.\n\nIf a suffix is provided, we add it, if not, then the default heuristic\nis used.\n\nThere's no functional change since most callers don't specify a suffix,\nand the ones that do use an =, which by default doesn't add an\nadditional suffix.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n contrib/completion/git-completion.bash | 9 ++++-----\n 1 file changed, 4 insertions(+), 5 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 829985e4fb..594e41276e 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -325,7 +325,7 @@ __gitcomp ()\n \t\treturn\n \tfi\n \n-\tlocal c i=0 IFS=$' \\t\\n'\n+\tlocal c i=0 IFS=$' \\t\\n' sfx\n \tfor c in $1; do\n \t\tif [[ $c == \"--\" ]]; then\n \t\t\tif [[ \"$cur_\" == --no-* ]]; then\n@@ -338,12 +338,11 @@ __gitcomp ()\n \t\t\tbreak\n \t\tfi\n \t\tif [[ $c == \"$cur_\"* ]]; then\n-\t\t\tc=\"$c${4-}\"\n \t\t\tcase $c in\n-\t\t\t*=|*.) ;;\n-\t\t\t*) c=\"$c \" ;;\n+\t\t\t*=|*.) sfx=\"\" ;;\n+\t\t\t*) sfx=\" \" ;;\n \t\t\tesac\n-\t\t\tCOMPREPLY[i++]=\"${2-}$c\"\n+\t\t\tCOMPREPLY[i++]=\"${2-}$c${4:-$sfx}\"\n \t\tfi\n \tdone\n }\n-- \n2.29.2\n\n"},{"id":"409537","messageId":"20201110212136.870769-15-felipe.contreras@gmail.com","threadId":"54615","inReplyTo":"20201110212136.870769-1-felipe.contreras@gmail.com","subject":"[PATCH v2 14/26] completion: bash: change suffix check in __gitcomp","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-11-10T21:21:24Z","receivedAt":"2020-11-10T21:22:12Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"We don't match the prefix, we shouldn't match the suffix either.\n\nThere are no functional changes since all the callers that add a suffix\nadd an =, and if $cur_ ended with that suffix, we would return\nimmediately.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n contrib/completion/git-completion.bash | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 9f5dd4e3e7..829985e4fb 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -337,8 +337,8 @@ __gitcomp ()\n \t\t\tfi\n \t\t\tbreak\n \t\tfi\n-\t\tc=\"$c${4-}\"\n \t\tif [[ $c == \"$cur_\"* ]]; then\n+\t\t\tc=\"$c${4-}\"\n \t\t\tcase $c in\n \t\t\t*=|*.) ;;\n \t\t\t*) c=\"$c \" ;;\n-- \n2.29.2\n\n"},{"id":"409538","messageId":"20201110212136.870769-17-felipe.contreras@gmail.com","threadId":"54615","inReplyTo":"20201110212136.870769-1-felipe.contreras@gmail.com","subject":"[PATCH v2 16/26] completion: bash: simplify config_variable_name","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-11-10T21:21:26Z","receivedAt":"2020-11-10T21:22:13Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Now that we can actually pass a suffix to __gitcomp function, and it\ndoes the right thing, all the functions can receive the same suffix.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n contrib/completion/git-completion.bash | 8 ++++----\n 1 file changed, 4 insertions(+), 4 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 594e41276e..56a66a375a 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -2547,7 +2547,7 @@ __git_complete_config_variable_value ()\n #                 subsections) instead of the default space.\n __git_complete_config_variable_name ()\n {\n-\tlocal cur_=\"$cur\" sfx\n+\tlocal cur_=\"$cur\" sfx=\" \"\n \n \twhile test $# != 0; do\n \t\tcase \"$1\" in\n@@ -2569,7 +2569,7 @@ __git_complete_config_variable_name ()\n \t\tlocal pfx=\"${cur_%.*}.\"\n \t\tcur_=\"${cur_#*.}\"\n \t\t__gitcomp_direct \"$(__git_heads \"$pfx\" \"$cur_\" \".\")\"\n-\t\t__gitcomp_nl $'autoSetupMerge\\nautoSetupRebase\\n' \"$pfx\" \"$cur_\" \"${sfx- }\"\n+\t\t__gitcomp_nl $'autoSetupMerge\\nautoSetupRebase\\n' \"$pfx\" \"$cur_\" \"$sfx\"\n \t\treturn\n \t\t;;\n \tguitool.*.*)\n@@ -2603,7 +2603,7 @@ __git_complete_config_variable_name ()\n \t\tlocal pfx=\"${cur_%.*}.\"\n \t\tcur_=\"${cur_#*.}\"\n \t\t__git_compute_all_commands\n-\t\t__gitcomp_nl \"$__git_all_commands\" \"$pfx\" \"$cur_\" \"${sfx- }\"\n+\t\t__gitcomp_nl \"$__git_all_commands\" \"$pfx\" \"$cur_\" \"$sfx\"\n \t\treturn\n \t\t;;\n \tremote.*.*)\n@@ -2619,7 +2619,7 @@ __git_complete_config_variable_name ()\n \t\tlocal pfx=\"${cur_%.*}.\"\n \t\tcur_=\"${cur_#*.}\"\n \t\t__gitcomp_nl \"$(__git_remotes)\" \"$pfx\" \"$cur_\" \".\"\n-\t\t__gitcomp_nl \"pushDefault\" \"$pfx\" \"$cur_\" \"${sfx- }\"\n+\t\t__gitcomp_nl \"pushDefault\" \"$pfx\" \"$cur_\" \"$sfx\"\n \t\treturn\n \t\t;;\n \turl.*.*)\n-- \n2.29.2\n\n"},{"id":"409539","messageId":"20201110212136.870769-18-felipe.contreras@gmail.com","threadId":"54615","inReplyTo":"20201110212136.870769-1-felipe.contreras@gmail.com","subject":"[PATCH v2 17/26] test: completion: switch __gitcomp_nl prefix test","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-11-10T21:21:27Z","receivedAt":"2020-11-10T21:22:15Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"By default COMP_WORDBREAKS includes =, so it's not realistic to test for\na prefix that almost never will be there.\n\nNo functional changes.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n t/t9902-completion.sh | 6 +++---\n 1 file changed, 3 insertions(+), 3 deletions(-)\n\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex 3ec9ff9308..012dade4a5 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -570,9 +570,9 @@ test_expect_success '__gitcomp_nl - trailing space' '\n '\n \n test_expect_success '__gitcomp_nl - prefix' '\n-\ttest_gitcomp_nl \"--fixup=m\" \"$refs\" \"--fixup=\" \"m\" <<-EOF\n-\t--fixup=main Z\n-\t--fixup=maint Z\n+\ttest_gitcomp_nl \"branch.m\" \"$refs\" \"branch.\" \"m\" <<-EOF\n+\tbranch.main Z\n+\tbranch.maint Z\n \tEOF\n '\n \n-- \n2.29.2\n\n"},{"id":"409540","messageId":"20201110212136.870769-19-felipe.contreras@gmail.com","threadId":"54615","inReplyTo":"20201110212136.870769-1-felipe.contreras@gmail.com","subject":"[PATCH v2 18/26] completion: bash: simplify _get_comp_words_by_ref()","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-11-10T21:21:28Z","receivedAt":"2020-11-10T21:22:18Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"We don't need the whole functionality of _get_comp_words_by_ref(), we\nknow exactly what we need from that function, so only do that.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n contrib/completion/git-completion.bash | 30 ++++++--------------------\n t/t9902-completion.sh                  | 21 ++++--------------\n 2 files changed, 10 insertions(+), 41 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 56a66a375a..4548f0c5bf 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -260,30 +260,12 @@ __git_reassemble_comp_words_by_ref()\n if ! type _get_comp_words_by_ref >/dev/null 2>&1; then\n _get_comp_words_by_ref ()\n {\n-\tlocal exclude cur_ words_ cword_\n-\tif [ \"$1\" = \"-n\" ]; then\n-\t\texclude=$2\n-\t\tshift 2\n-\tfi\n-\t__git_reassemble_comp_words_by_ref \"$exclude\"\n-\tcur_=${words_[cword_]}\n-\twhile [ $# -gt 0 ]; do\n-\t\tcase \"$1\" in\n-\t\tcur)\n-\t\t\tcur=$cur_\n-\t\t\t;;\n-\t\tprev)\n-\t\t\tprev=${words_[$cword_-1]}\n-\t\t\t;;\n-\t\twords)\n-\t\t\twords=(\"${words_[@]}\")\n-\t\t\t;;\n-\t\tcword)\n-\t\t\tcword=$cword_\n-\t\t\t;;\n-\t\tesac\n-\t\tshift\n-\tdone\n+\tlocal words_ cword_\n+\t__git_reassemble_comp_words_by_ref \"=:\"\n+\tcword=$cword_\n+\tcur=${words_[cword]}\n+\tprev=${words_[cword-1]}\n+\twords=(\"${words_[@]}\")\n }\n fi\n \ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex 012dade4a5..e39febcc4a 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -40,23 +40,10 @@ GIT_TESTING_PORCELAIN_COMMAND_LIST='add checkout rebase'\n # So let's override it with a minimal version for testing purposes.\n _get_comp_words_by_ref ()\n {\n-\twhile [ $# -gt 0 ]; do\n-\t\tcase \"$1\" in\n-\t\tcur)\n-\t\t\tcur=${_words[_cword]}\n-\t\t\t;;\n-\t\tprev)\n-\t\t\tprev=${_words[_cword-1]}\n-\t\t\t;;\n-\t\twords)\n-\t\t\twords=(\"${_words[@]}\")\n-\t\t\t;;\n-\t\tcword)\n-\t\t\tcword=$_cword\n-\t\t\t;;\n-\t\tesac\n-\t\tshift\n-\tdone\n+\tcword=$_cword\n+\tcur=${_words[cword]}\n+\tprev=${_words[cword-1]}\n+\twords=(\"${_words[@]}\")\n }\n \n print_comp ()\n-- \n2.29.2\n\n"},{"id":"409541","messageId":"20201110212136.870769-20-felipe.contreras@gmail.com","threadId":"54615","inReplyTo":"20201110212136.870769-1-felipe.contreras@gmail.com","subject":"[PATCH v2 19/26] completion: bash: refactor _get_comp_words_by_ref()","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-11-10T21:21:29Z","receivedAt":"2020-11-10T21:22:20Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"We don't need a separate function to do what we already know we want to\ndo.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n contrib/completion/git-completion.bash | 93 +++++++++++---------------\n 1 file changed, 39 insertions(+), 54 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 4548f0c5bf..a7dd04bb31 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -186,21 +186,11 @@ __git_dequote ()\n #\n #   RELEASE: 2.x\n \n-# This function can be used to access a tokenized list of words\n-# on the command line:\n-#\n-#\t__git_reassemble_comp_words_by_ref '=:'\n-#\tif test \"${words_[cword_-1]}\" = -w\n-#\tthen\n-#\t\t...\n-#\tfi\n-#\n-# The argument should be a collection of characters from the list of\n-# word completion separators (COMP_WORDBREAKS) to treat as ordinary\n-# characters.\n+# This function reorganizes the words on the command line to be processed by\n+# the rest of the script.\n #\n # This is roughly equivalent to going back in time and setting\n-# COMP_WORDBREAKS to exclude those characters.  The intent is to\n+# COMP_WORDBREAKS to exclude '=' and ':'.  The intent is to\n # make option types like --date=<type> and <rev>:<path> easy to\n # recognize by treating each shell word as a single token.\n #\n@@ -208,60 +198,55 @@ __git_dequote ()\n # shared with other completion scripts.  By the time the completion\n # function gets called, COMP_WORDS has already been populated so local\n # changes to COMP_WORDBREAKS have no effect.\n-#\n-# Output: words_, cword_, cur_.\n \n-__git_reassemble_comp_words_by_ref()\n+if ! type _get_comp_words_by_ref >/dev/null 2>&1; then\n+_get_comp_words_by_ref ()\n {\n+\tlocal words_ cword_\n \tlocal exclude i j first\n+\n \t# Which word separators to exclude?\n-\texclude=\"${1//[^$COMP_WORDBREAKS]}\"\n+\texclude=\"${COMP_WORDBREAKS//[^=:]}\"\n \tcword_=$COMP_CWORD\n \tif [ -z \"$exclude\" ]; then\n \t\twords_=(\"${COMP_WORDS[@]}\")\n-\t\treturn\n-\tfi\n-\t# List of word completion separators has shrunk;\n-\t# re-assemble words to complete.\n-\tfor ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do\n-\t\t# Append each nonempty word consisting of just\n-\t\t# word separator characters to the current word.\n-\t\tfirst=t\n-\t\twhile\n-\t\t\t[ $i -gt 0 ] &&\n-\t\t\t[ -n \"${COMP_WORDS[$i]}\" ] &&\n-\t\t\t# word consists of excluded word separators\n-\t\t\t[ \"${COMP_WORDS[$i]//[^$exclude]}\" = \"${COMP_WORDS[$i]}\" ]\n-\t\tdo\n-\t\t\t# Attach to the previous token,\n-\t\t\t# unless the previous token is the command name.\n-\t\t\tif [ $j -ge 2 ] && [ -n \"$first\" ]; then\n-\t\t\t\t((j--))\n-\t\t\tfi\n-\t\t\tfirst=\n+\telse\n+\t\t# List of word completion separators has shrunk;\n+\t\t# re-assemble words to complete.\n+\t\tfor ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do\n+\t\t\t# Append each nonempty word consisting of just\n+\t\t\t# word separator characters to the current word.\n+\t\t\tfirst=t\n+\t\t\twhile\n+\t\t\t\t[ $i -gt 0 ] &&\n+\t\t\t\t[ -n \"${COMP_WORDS[$i]}\" ] &&\n+\t\t\t\t# word consists of excluded word separators\n+\t\t\t\t[ \"${COMP_WORDS[$i]//[^$exclude]}\" = \"${COMP_WORDS[$i]}\" ]\n+\t\t\tdo\n+\t\t\t\t# Attach to the previous token,\n+\t\t\t\t# unless the previous token is the command name.\n+\t\t\t\tif [ $j -ge 2 ] && [ -n \"$first\" ]; then\n+\t\t\t\t\t((j--))\n+\t\t\t\tfi\n+\t\t\t\tfirst=\n+\t\t\t\twords_[$j]=${words_[j]}${COMP_WORDS[i]}\n+\t\t\t\tif [ $i = $COMP_CWORD ]; then\n+\t\t\t\t\tcword_=$j\n+\t\t\t\tfi\n+\t\t\t\tif (($i < ${#COMP_WORDS[@]} - 1)); then\n+\t\t\t\t\t((i++))\n+\t\t\t\telse\n+\t\t\t\t\t# Done.\n+\t\t\t\t\tbreak 2\n+\t\t\t\tfi\n+\t\t\tdone\n \t\t\twords_[$j]=${words_[j]}${COMP_WORDS[i]}\n \t\t\tif [ $i = $COMP_CWORD ]; then\n \t\t\t\tcword_=$j\n \t\t\tfi\n-\t\t\tif (($i < ${#COMP_WORDS[@]} - 1)); then\n-\t\t\t\t((i++))\n-\t\t\telse\n-\t\t\t\t# Done.\n-\t\t\t\treturn\n-\t\t\tfi\n \t\tdone\n-\t\twords_[$j]=${words_[j]}${COMP_WORDS[i]}\n-\t\tif [ $i = $COMP_CWORD ]; then\n-\t\t\tcword_=$j\n-\t\tfi\n-\tdone\n-}\n+\tfi\n \n-if ! type _get_comp_words_by_ref >/dev/null 2>&1; then\n-_get_comp_words_by_ref ()\n-{\n-\tlocal words_ cword_\n-\t__git_reassemble_comp_words_by_ref \"=:\"\n \tcword=$cword_\n \tcur=${words_[cword]}\n \tprev=${words_[cword-1]}\n-- \n2.29.2\n\n"},{"id":"409542","messageId":"20201110212136.870769-21-felipe.contreras@gmail.com","threadId":"54615","inReplyTo":"20201110212136.870769-1-felipe.contreras@gmail.com","subject":"[PATCH v2 20/26] completion: bash: cleanup _get_comp_words_by_ref()","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-11-10T21:21:30Z","receivedAt":"2020-11-10T21:22:21Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Remove temporary variables.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n contrib/completion/git-completion.bash | 19 ++++++++-----------\n 1 file changed, 8 insertions(+), 11 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex a7dd04bb31..6da7aca481 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -202,14 +202,13 @@ __git_dequote ()\n if ! type _get_comp_words_by_ref >/dev/null 2>&1; then\n _get_comp_words_by_ref ()\n {\n-\tlocal words_ cword_\n \tlocal exclude i j first\n \n \t# Which word separators to exclude?\n \texclude=\"${COMP_WORDBREAKS//[^=:]}\"\n-\tcword_=$COMP_CWORD\n+\tcword=$COMP_CWORD\n \tif [ -z \"$exclude\" ]; then\n-\t\twords_=(\"${COMP_WORDS[@]}\")\n+\t\twords=(\"${COMP_WORDS[@]}\")\n \telse\n \t\t# List of word completion separators has shrunk;\n \t\t# re-assemble words to complete.\n@@ -229,9 +228,9 @@ _get_comp_words_by_ref ()\n \t\t\t\t\t((j--))\n \t\t\t\tfi\n \t\t\t\tfirst=\n-\t\t\t\twords_[$j]=${words_[j]}${COMP_WORDS[i]}\n+\t\t\t\twords[$j]=${words[j]}${COMP_WORDS[i]}\n \t\t\t\tif [ $i = $COMP_CWORD ]; then\n-\t\t\t\t\tcword_=$j\n+\t\t\t\t\tcword=$j\n \t\t\t\tfi\n \t\t\t\tif (($i < ${#COMP_WORDS[@]} - 1)); then\n \t\t\t\t\t((i++))\n@@ -240,17 +239,15 @@ _get_comp_words_by_ref ()\n \t\t\t\t\tbreak 2\n \t\t\t\tfi\n \t\t\tdone\n-\t\t\twords_[$j]=${words_[j]}${COMP_WORDS[i]}\n+\t\t\twords[$j]=${words[j]}${COMP_WORDS[i]}\n \t\t\tif [ $i = $COMP_CWORD ]; then\n-\t\t\t\tcword_=$j\n+\t\t\t\tcword=$j\n \t\t\tfi\n \t\tdone\n \tfi\n \n-\tcword=$cword_\n-\tcur=${words_[cword]}\n-\tprev=${words_[cword-1]}\n-\twords=(\"${words_[@]}\")\n+\tcur=${words[cword]}\n+\tprev=${words[cword-1]}\n }\n fi\n \n-- \n2.29.2\n\n"},{"id":"409543","messageId":"20201110212136.870769-22-felipe.contreras@gmail.com","threadId":"54615","inReplyTo":"20201110212136.870769-1-felipe.contreras@gmail.com","subject":"[PATCH v2 21/26] completion: bash: trivial cleanup","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-11-10T21:21:31Z","receivedAt":"2020-11-10T21:22:26Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"The most typical case first (COMP_WORDBREAKS contains our wanted words).\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n contrib/completion/git-completion.bash | 6 +++---\n 1 file changed, 3 insertions(+), 3 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 6da7aca481..26f9accc30 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -207,9 +207,7 @@ _get_comp_words_by_ref ()\n \t# Which word separators to exclude?\n \texclude=\"${COMP_WORDBREAKS//[^=:]}\"\n \tcword=$COMP_CWORD\n-\tif [ -z \"$exclude\" ]; then\n-\t\twords=(\"${COMP_WORDS[@]}\")\n-\telse\n+\tif [ -n \"$exclude\" ]; then\n \t\t# List of word completion separators has shrunk;\n \t\t# re-assemble words to complete.\n \t\tfor ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do\n@@ -244,6 +242,8 @@ _get_comp_words_by_ref ()\n \t\t\t\tcword=$j\n \t\t\tfi\n \t\tdone\n+\telse\n+\t\twords=(\"${COMP_WORDS[@]}\")\n \tfi\n \n \tcur=${words[cword]}\n-- \n2.29.2\n\n"},{"id":"409544","messageId":"20201110212136.870769-23-felipe.contreras@gmail.com","threadId":"54615","inReplyTo":"20201110212136.870769-1-felipe.contreras@gmail.com","subject":"[PATCH v2 22/26] completion: bash: rename _get_comp_words_by_ref()","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-11-10T21:21:32Z","receivedAt":"2020-11-10T21:22:27Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"It's only used in one place, rename it, and use it even if\nbash-completion's more inefficient version of _get_comp_words_by_ref()\nis available.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n contrib/completion/git-completion.bash | 184 ++++++++++++-------------\n t/t9902-completion.sh                  |   2 +-\n 2 files changed, 92 insertions(+), 94 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 26f9accc30..ffff7e2317 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -159,98 +159,6 @@ __git_dequote ()\n \tdone\n }\n \n-# The following function is based on code from:\n-#\n-#   bash_completion - programmable completion functions for bash 3.2+\n-#\n-#   Copyright © 2006-2008, Ian Macdonald <ian@caliban.org>\n-#             © 2009-2010, Bash Completion Maintainers\n-#                     <bash-completion-devel@lists.alioth.debian.org>\n-#\n-#   This program is free software; you can redistribute it and/or modify\n-#   it under the terms of the GNU General Public License as published by\n-#   the Free Software Foundation; either version 2, or (at your option)\n-#   any later version.\n-#\n-#   This program is distributed in the hope that it will be useful,\n-#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n-#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n-#   GNU General Public License for more details.\n-#\n-#   You should have received a copy of the GNU General Public License\n-#   along with this program; if not, see <http://www.gnu.org/licenses/>.\n-#\n-#   The latest version of this software can be obtained here:\n-#\n-#   http://bash-completion.alioth.debian.org/\n-#\n-#   RELEASE: 2.x\n-\n-# This function reorganizes the words on the command line to be processed by\n-# the rest of the script.\n-#\n-# This is roughly equivalent to going back in time and setting\n-# COMP_WORDBREAKS to exclude '=' and ':'.  The intent is to\n-# make option types like --date=<type> and <rev>:<path> easy to\n-# recognize by treating each shell word as a single token.\n-#\n-# It is best not to set COMP_WORDBREAKS directly because the value is\n-# shared with other completion scripts.  By the time the completion\n-# function gets called, COMP_WORDS has already been populated so local\n-# changes to COMP_WORDBREAKS have no effect.\n-\n-if ! type _get_comp_words_by_ref >/dev/null 2>&1; then\n-_get_comp_words_by_ref ()\n-{\n-\tlocal exclude i j first\n-\n-\t# Which word separators to exclude?\n-\texclude=\"${COMP_WORDBREAKS//[^=:]}\"\n-\tcword=$COMP_CWORD\n-\tif [ -n \"$exclude\" ]; then\n-\t\t# List of word completion separators has shrunk;\n-\t\t# re-assemble words to complete.\n-\t\tfor ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do\n-\t\t\t# Append each nonempty word consisting of just\n-\t\t\t# word separator characters to the current word.\n-\t\t\tfirst=t\n-\t\t\twhile\n-\t\t\t\t[ $i -gt 0 ] &&\n-\t\t\t\t[ -n \"${COMP_WORDS[$i]}\" ] &&\n-\t\t\t\t# word consists of excluded word separators\n-\t\t\t\t[ \"${COMP_WORDS[$i]//[^$exclude]}\" = \"${COMP_WORDS[$i]}\" ]\n-\t\t\tdo\n-\t\t\t\t# Attach to the previous token,\n-\t\t\t\t# unless the previous token is the command name.\n-\t\t\t\tif [ $j -ge 2 ] && [ -n \"$first\" ]; then\n-\t\t\t\t\t((j--))\n-\t\t\t\tfi\n-\t\t\t\tfirst=\n-\t\t\t\twords[$j]=${words[j]}${COMP_WORDS[i]}\n-\t\t\t\tif [ $i = $COMP_CWORD ]; then\n-\t\t\t\t\tcword=$j\n-\t\t\t\tfi\n-\t\t\t\tif (($i < ${#COMP_WORDS[@]} - 1)); then\n-\t\t\t\t\t((i++))\n-\t\t\t\telse\n-\t\t\t\t\t# Done.\n-\t\t\t\t\tbreak 2\n-\t\t\t\tfi\n-\t\t\tdone\n-\t\t\twords[$j]=${words[j]}${COMP_WORDS[i]}\n-\t\t\tif [ $i = $COMP_CWORD ]; then\n-\t\t\t\tcword=$j\n-\t\t\tfi\n-\t\tdone\n-\telse\n-\t\twords=(\"${COMP_WORDS[@]}\")\n-\tfi\n-\n-\tcur=${words[cword]}\n-\tprev=${words[cword-1]}\n-}\n-fi\n-\n # Appends prefiltered words to COMPREPLY without any additional processing.\n # Callers must take care of providing only words that match the current word\n # to be completed and adding any prefix and/or suffix (trailing space!), if\n@@ -3383,10 +3291,100 @@ if [[ -n ${ZSH_VERSION-} && -z ${GIT_SOURCING_ZSH_COMPLETION-} ]]; then\n \treturn\n fi\n \n+# The following function is based on code from:\n+#\n+#   bash_completion - programmable completion functions for bash 3.2+\n+#\n+#   Copyright © 2006-2008, Ian Macdonald <ian@caliban.org>\n+#             © 2009-2010, Bash Completion Maintainers\n+#                     <bash-completion-devel@lists.alioth.debian.org>\n+#\n+#   This program is free software; you can redistribute it and/or modify\n+#   it under the terms of the GNU General Public License as published by\n+#   the Free Software Foundation; either version 2, or (at your option)\n+#   any later version.\n+#\n+#   This program is distributed in the hope that it will be useful,\n+#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+#   GNU General Public License for more details.\n+#\n+#   You should have received a copy of the GNU General Public License\n+#   along with this program; if not, see <http://www.gnu.org/licenses/>.\n+#\n+#   The latest version of this software can be obtained here:\n+#\n+#   http://bash-completion.alioth.debian.org/\n+#\n+#   RELEASE: 2.x\n+\n+# This function reorganizes the words on the command line to be processed by\n+# the rest of the script.\n+#\n+# This is roughly equivalent to going back in time and setting\n+# COMP_WORDBREAKS to exclude '=' and ':'.  The intent is to\n+# make option types like --date=<type> and <rev>:<path> easy to\n+# recognize by treating each shell word as a single token.\n+#\n+# It is best not to set COMP_WORDBREAKS directly because the value is\n+# shared with other completion scripts.  By the time the completion\n+# function gets called, COMP_WORDS has already been populated so local\n+# changes to COMP_WORDBREAKS have no effect.\n+\n+__git_get_comp_words_by_ref ()\n+{\n+\tlocal exclude i j first\n+\n+\t# Which word separators to exclude?\n+\texclude=\"${COMP_WORDBREAKS//[^=:]}\"\n+\tcword=$COMP_CWORD\n+\tif [ -n \"$exclude\" ]; then\n+\t\t# List of word completion separators has shrunk;\n+\t\t# re-assemble words to complete.\n+\t\tfor ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do\n+\t\t\t# Append each nonempty word consisting of just\n+\t\t\t# word separator characters to the current word.\n+\t\t\tfirst=t\n+\t\t\twhile\n+\t\t\t\t[ $i -gt 0 ] &&\n+\t\t\t\t[ -n \"${COMP_WORDS[$i]}\" ] &&\n+\t\t\t\t# word consists of excluded word separators\n+\t\t\t\t[ \"${COMP_WORDS[$i]//[^$exclude]}\" = \"${COMP_WORDS[$i]}\" ]\n+\t\t\tdo\n+\t\t\t\t# Attach to the previous token,\n+\t\t\t\t# unless the previous token is the command name.\n+\t\t\t\tif [ $j -ge 2 ] && [ -n \"$first\" ]; then\n+\t\t\t\t\t((j--))\n+\t\t\t\tfi\n+\t\t\t\tfirst=\n+\t\t\t\twords[$j]=${words[j]}${COMP_WORDS[i]}\n+\t\t\t\tif [ $i = $COMP_CWORD ]; then\n+\t\t\t\t\tcword=$j\n+\t\t\t\tfi\n+\t\t\t\tif (($i < ${#COMP_WORDS[@]} - 1)); then\n+\t\t\t\t\t((i++))\n+\t\t\t\telse\n+\t\t\t\t\t# Done.\n+\t\t\t\t\tbreak 2\n+\t\t\t\tfi\n+\t\t\tdone\n+\t\t\twords[$j]=${words[j]}${COMP_WORDS[i]}\n+\t\t\tif [ $i = $COMP_CWORD ]; then\n+\t\t\t\tcword=$j\n+\t\t\tfi\n+\t\tdone\n+\telse\n+\t\twords=(\"${COMP_WORDS[@]}\")\n+\tfi\n+\n+\tcur=${words[cword]}\n+\tprev=${words[cword-1]}\n+}\n+\n __git_func_wrap ()\n {\n \tlocal cur words cword prev\n-\t_get_comp_words_by_ref -n =: cur words cword prev\n+\t__git_get_comp_words_by_ref\n \t$1\n }\n \ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex e39febcc4a..efb98cc96c 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -38,7 +38,7 @@ GIT_TESTING_PORCELAIN_COMMAND_LIST='add checkout rebase'\n # We don't need this function to actually join words or do anything special.\n # Also, it's cleaner to avoid touching bash's internal completion variables.\n # So let's override it with a minimal version for testing purposes.\n-_get_comp_words_by_ref ()\n+__git_get_comp_words_by_ref ()\n {\n \tcword=$_cword\n \tcur=${_words[cword]}\n-- \n2.29.2\n\n"},{"id":"409545","messageId":"20201110212136.870769-24-felipe.contreras@gmail.com","threadId":"54615","inReplyTo":"20201110212136.870769-1-felipe.contreras@gmail.com","subject":"[PATCH v2 23/26] completion: bash: improve __gitcomp description","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-11-10T21:21:33Z","receivedAt":"2020-11-10T21:22:30Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"It does a lot more than what is stated now.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n contrib/completion/git-completion.bash | 3 +--\n 1 file changed, 1 insertion(+), 2 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex ffff7e2317..8e6723874e 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -182,8 +182,7 @@ __gitcompadd ()\n \tdone\n }\n \n-# Generates completion reply, appending a space to possible completion words,\n-# if necessary.\n+# Creates completion replies, reorganizing options and adding suffixes as needed.\n # It accepts 1 to 4 arguments:\n # 1: List of possible completion words.\n # 2: A prefix to be added to each possible completion word (optional).\n-- \n2.29.2\n\n"},{"id":"409546","messageId":"20201110212136.870769-25-felipe.contreras@gmail.com","threadId":"54615","inReplyTo":"20201110212136.870769-1-felipe.contreras@gmail.com","subject":"[PATCH v2 24/26] completion: bash: add __gitcomp_opts","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-11-10T21:21:34Z","receivedAt":"2020-11-10T21:22:32Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Create a new simplified version of __gitcomp for most callers, and\n__gitcomp_opts for the ones that need reorganizing all the options.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n contrib/completion/git-completion.bash | 114 ++++++++++++++-----------\n contrib/completion/git-completion.zsh  |   9 ++\n t/t9902-completion.sh                  |  58 ++++++-------\n 3 files changed, 101 insertions(+), 80 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 8e6723874e..324793368d 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -182,13 +182,25 @@ __gitcompadd ()\n \tdone\n }\n \n-# Creates completion replies, reorganizing options and adding suffixes as needed.\n+# Creates completion replies.\n # It accepts 1 to 4 arguments:\n # 1: List of possible completion words.\n # 2: A prefix to be added to each possible completion word (optional).\n # 3: Generate possible completion matches for this word (optional).\n # 4: A suffix to be appended to each possible completion word (optional).\n __gitcomp ()\n+{\n+\tlocal IFS=$' \\t\\n'\n+\t__gitcompadd \"$1\" \"${2-}\" \"${3-$cur}\" \"${4- }\"\n+}\n+\n+# Creates completion replies, reorganizing options and adding suffixes as needed.\n+# It accepts 1 to 4 arguments:\n+# 1: List of possible completion words.\n+# 2: A prefix to be added to each possible completion word (optional).\n+# 3: Generate possible completion matches for this word (optional).\n+# 4: A suffix to be appended to each possible completion word (optional).\n+__gitcomp_opts ()\n {\n \tlocal cur_=\"${3-$cur}\"\n \n@@ -228,7 +240,7 @@ fi\n \n # This function is equivalent to\n #\n-#    __gitcomp \"$(git xxx --git-completion-helper) ...\"\n+#    __gitcomp_opts \"$(git xxx --git-completion-helper) ...\"\n #\n # except that the output is cached. Accept 1-3 arguments:\n # 1: the git command to execute, this is also the cache key\n@@ -263,7 +275,7 @@ __gitcomp_builtin ()\n \t\teval \"$var=\\\"$options\\\"\"\n \tfi\n \n-\t__gitcomp \"$options\"\n+\t__gitcomp_opts \"$options\"\n }\n \n # Generates completion reply from newline-separated possible completion words\n@@ -900,7 +912,7 @@ __git_complete_strategy ()\n \t\treturn 0\n \t\t;;\n \t-X)\n-\t\t__gitcomp \"$__git_merge_strategy_options\"\n+\t\t__gitcomp_opts \"$__git_merge_strategy_options\"\n \t\treturn 0\n \t\t;;\n \tesac\n@@ -910,7 +922,7 @@ __git_complete_strategy ()\n \t\treturn 0\n \t\t;;\n \t--strategy-option=*)\n-\t\t__gitcomp \"$__git_merge_strategy_options\" \"\" \"${cur##--strategy-option=}\"\n+\t\t__gitcomp_opts \"$__git_merge_strategy_options\" \"\" \"${cur##--strategy-option=}\"\n \t\treturn 0\n \t\t;;\n \tesac\n@@ -1133,7 +1145,7 @@ _git_am ()\n {\n \t__git_find_repo_path\n \tif [ -d \"$__git_repo_path\"/rebase-apply ]; then\n-\t\t__gitcomp \"$__git_am_inprogress_options\"\n+\t\t__gitcomp_opts \"$__git_am_inprogress_options\"\n \t\treturn\n \tfi\n \tcase \"$cur\" in\n@@ -1387,7 +1399,7 @@ _git_cherry_pick ()\n {\n \t__git_find_repo_path\n \tif [ -f \"$__git_repo_path\"/CHERRY_PICK_HEAD ]; then\n-\t\t__gitcomp \"$__git_cherry_pick_inprogress_options\"\n+\t\t__gitcomp_opts \"$__git_cherry_pick_inprogress_options\"\n \t\treturn\n \tfi\n \n@@ -1545,7 +1557,7 @@ _git_diff ()\n \t\treturn\n \t\t;;\n \t--*)\n-\t\t__gitcomp \"$__git_diff_difftool_options\"\n+\t\t__gitcomp_opts \"$__git_diff_difftool_options\"\n \t\treturn\n \t\t;;\n \tesac\n@@ -1839,7 +1851,7 @@ _git_log ()\n \t\treturn\n \t\t;;\n \t--*)\n-\t\t__gitcomp \"\n+\t\t__gitcomp_opts \"\n \t\t\t$__git_log_common_options\n \t\t\t$__git_log_shortlog_options\n \t\t\t$__git_log_gitk_options\n@@ -1902,7 +1914,7 @@ _git_mergetool ()\n \t\treturn\n \t\t;;\n \t--*)\n-\t\t__gitcomp \"--tool= --prompt --no-prompt --gui --no-gui\"\n+\t\t__gitcomp_opts \"--tool= --prompt --no-prompt --gui --no-gui\"\n \t\treturn\n \t\t;;\n \tesac\n@@ -2050,7 +2062,7 @@ _git_range_diff ()\n {\n \tcase \"$cur\" in\n \t--*)\n-\t\t__gitcomp \"\n+\t\t__gitcomp_opts \"\n \t\t\t--creation-factor= --no-dual-color\n \t\t\t$__git_diff_common_options\n \t\t\"\n@@ -2067,11 +2079,11 @@ _git_rebase ()\n {\n \t__git_find_repo_path\n \tif [ -f \"$__git_repo_path\"/rebase-merge/interactive ]; then\n-\t\t__gitcomp \"$__git_rebase_interactive_inprogress_options\"\n+\t\t__gitcomp_opts \"$__git_rebase_interactive_inprogress_options\"\n \t\treturn\n \telif [ -d \"$__git_repo_path\"/rebase-apply ] || \\\n \t     [ -d \"$__git_repo_path\"/rebase-merge ]; then\n-\t\t__gitcomp \"$__git_rebase_inprogress_options\"\n+\t\t__gitcomp_opts \"$__git_rebase_inprogress_options\"\n \t\treturn\n \tfi\n \t__git_complete_strategy && return\n@@ -2513,7 +2525,7 @@ __git_complete_config_variable_name ()\n \t\t\t\t\tfor (s in sections)\n \t\t\t\t\t\tprint s \".\"\n \t\t\t\t}\n-\t\t\t\t')\" \"\" \"$cur_\"\n+\t\t\t\t')\" \"\" \"$cur_\" \"\"\n \t\t;;\n \tesac\n }\n@@ -2691,7 +2703,7 @@ _git_revert ()\n {\n \t__git_find_repo_path\n \tif [ -f \"$__git_repo_path\"/REVERT_HEAD ]; then\n-\t\t__gitcomp \"$__git_revert_inprogress_options\"\n+\t\t__gitcomp_opts \"$__git_revert_inprogress_options\"\n \t\treturn\n \tfi\n \t__git_complete_strategy && return\n@@ -2723,7 +2735,7 @@ _git_shortlog ()\n \n \tcase \"$cur\" in\n \t--*)\n-\t\t__gitcomp \"\n+\t\t__gitcomp_opts \"\n \t\t\t$__git_log_common_options\n \t\t\t$__git_log_shortlog_options\n \t\t\t--numbered --summary --email\n@@ -2761,7 +2773,7 @@ _git_show ()\n \t\treturn\n \t\t;;\n \t--*)\n-\t\t__gitcomp \"--pretty= --format= --abbrev-commit --no-abbrev-commit\n+\t\t__gitcomp_opts \"--pretty= --format= --abbrev-commit --no-abbrev-commit\n \t\t\t--oneline --show-signature\n \t\t\t--expand-tabs --expand-tabs= --no-expand-tabs\n \t\t\t$__git_diff_common_options\n@@ -2794,10 +2806,10 @@ _git_sparse_checkout ()\n \n \tcase \"$subcommand,$cur\" in\n \tinit,--*)\n-\t\t__gitcomp \"--cone\"\n+\t\t__gitcomp_opts \"--cone\"\n \t\t;;\n \tset,--*)\n-\t\t__gitcomp \"--stdin\"\n+\t\t__gitcomp_opts \"--stdin\"\n \t\t;;\n \t*)\n \t\t;;\n@@ -2815,7 +2827,7 @@ _git_stash ()\n \tif [ -z \"$subcommand\" ]; then\n \t\tcase \"$cur\" in\n \t\t--*)\n-\t\t\t__gitcomp \"$save_opts\"\n+\t\t\t__gitcomp_opts \"$save_opts\"\n \t\t\t;;\n \t\tsa*)\n \t\t\tif [ -z \"$(__git_find_on_cmdline \"$save_opts\")\" ]; then\n@@ -2831,22 +2843,22 @@ _git_stash ()\n \telse\n \t\tcase \"$subcommand,$cur\" in\n \t\tpush,--*)\n-\t\t\t__gitcomp \"$save_opts --message\"\n+\t\t\t__gitcomp_opts \"$save_opts --message\"\n \t\t\t;;\n \t\tsave,--*)\n-\t\t\t__gitcomp \"$save_opts\"\n+\t\t\t__gitcomp_opts \"$save_opts\"\n \t\t\t;;\n \t\tapply,--*|pop,--*)\n-\t\t\t__gitcomp \"--index --quiet\"\n+\t\t\t__gitcomp_opts \"--index --quiet\"\n \t\t\t;;\n \t\tdrop,--*)\n-\t\t\t__gitcomp \"--quiet\"\n+\t\t\t__gitcomp_opts \"--quiet\"\n \t\t\t;;\n \t\tlist,--*)\n-\t\t\t__gitcomp \"--name-status --oneline --patch-with-stat\"\n+\t\t\t__gitcomp_opts \"--name-status --oneline --patch-with-stat\"\n \t\t\t;;\n \t\tshow,--*)\n-\t\t\t__gitcomp \"$__git_diff_common_options\"\n+\t\t\t__gitcomp_opts \"$__git_diff_common_options\"\n \t\t\t;;\n \t\tbranch,--*)\n \t\t\t;;\n@@ -2877,7 +2889,7 @@ _git_submodule ()\n \tif [ -z \"$subcommand\" ]; then\n \t\tcase \"$cur\" in\n \t\t--*)\n-\t\t\t__gitcomp \"--quiet\"\n+\t\t\t__gitcomp_opts \"--quiet\"\n \t\t\t;;\n \t\t*)\n \t\t\t__gitcomp \"$subcommands\"\n@@ -2888,29 +2900,29 @@ _git_submodule ()\n \n \tcase \"$subcommand,$cur\" in\n \tadd,--*)\n-\t\t__gitcomp \"--branch --force --name --reference --depth\"\n+\t\t__gitcomp_opts \"--branch --force --name --reference --depth\"\n \t\t;;\n \tstatus,--*)\n-\t\t__gitcomp \"--cached --recursive\"\n+\t\t__gitcomp_opts \"--cached --recursive\"\n \t\t;;\n \tdeinit,--*)\n-\t\t__gitcomp \"--force --all\"\n+\t\t__gitcomp_opts \"--force --all\"\n \t\t;;\n \tupdate,--*)\n-\t\t__gitcomp \"\n+\t\t__gitcomp_opts \"\n \t\t\t--init --remote --no-fetch\n \t\t\t--recommend-shallow --no-recommend-shallow\n \t\t\t--force --rebase --merge --reference --depth --recursive --jobs\n \t\t\"\n \t\t;;\n \tset-branch,--*)\n-\t\t__gitcomp \"--default --branch\"\n+\t\t__gitcomp_opts \"--default --branch\"\n \t\t;;\n \tsummary,--*)\n-\t\t__gitcomp \"--cached --files --summary-limit\"\n+\t\t__gitcomp_opts \"--cached --files --summary-limit\"\n \t\t;;\n \tforeach,--*|sync,--*)\n-\t\t__gitcomp \"--recursive\"\n+\t\t__gitcomp_opts \"--recursive\"\n \t\t;;\n \t*)\n \t\t;;\n@@ -2951,64 +2963,64 @@ _git_svn ()\n \n \t\tcase \"$subcommand,$cur\" in\n \t\tfetch,--*)\n-\t\t\t__gitcomp \"--revision= --fetch-all $fc_opts\"\n+\t\t\t__gitcomp_opts \"--revision= --fetch-all $fc_opts\"\n \t\t\t;;\n \t\tclone,--*)\n-\t\t\t__gitcomp \"--revision= $fc_opts $init_opts\"\n+\t\t\t__gitcomp_opts \"--revision= $fc_opts $init_opts\"\n \t\t\t;;\n \t\tinit,--*)\n-\t\t\t__gitcomp \"$init_opts\"\n+\t\t\t__gitcomp_opts \"$init_opts\"\n \t\t\t;;\n \t\tdcommit,--*)\n-\t\t\t__gitcomp \"\n+\t\t\t__gitcomp_opts \"\n \t\t\t\t--merge --strategy= --verbose --dry-run\n \t\t\t\t--fetch-all --no-rebase --commit-url\n \t\t\t\t--revision --interactive $cmt_opts $fc_opts\n \t\t\t\t\"\n \t\t\t;;\n \t\tset-tree,--*)\n-\t\t\t__gitcomp \"--stdin $cmt_opts $fc_opts\"\n+\t\t\t__gitcomp_opts \"--stdin $cmt_opts $fc_opts\"\n \t\t\t;;\n \t\tcreate-ignore,--*|propget,--*|proplist,--*|show-ignore,--*|\\\n \t\tshow-externals,--*|mkdirs,--*)\n-\t\t\t__gitcomp \"--revision=\"\n+\t\t\t__gitcomp_opts \"--revision=\"\n \t\t\t;;\n \t\tlog,--*)\n-\t\t\t__gitcomp \"\n+\t\t\t__gitcomp_opts \"\n \t\t\t\t--limit= --revision= --verbose --incremental\n \t\t\t\t--oneline --show-commit --non-recursive\n \t\t\t\t--authors-file= --color\n \t\t\t\t\"\n \t\t\t;;\n \t\trebase,--*)\n-\t\t\t__gitcomp \"\n+\t\t\t__gitcomp_opts \"\n \t\t\t\t--merge --verbose --strategy= --local\n \t\t\t\t--fetch-all --dry-run $fc_opts\n \t\t\t\t\"\n \t\t\t;;\n \t\tcommit-diff,--*)\n-\t\t\t__gitcomp \"--message= --file= --revision= $cmt_opts\"\n+\t\t\t__gitcomp_opts \"--message= --file= --revision= $cmt_opts\"\n \t\t\t;;\n \t\tinfo,--*)\n-\t\t\t__gitcomp \"--url\"\n+\t\t\t__gitcomp_opts \"--url\"\n \t\t\t;;\n \t\tbranch,--*)\n-\t\t\t__gitcomp \"--dry-run --message --tag\"\n+\t\t\t__gitcomp_opts \"--dry-run --message --tag\"\n \t\t\t;;\n \t\ttag,--*)\n-\t\t\t__gitcomp \"--dry-run --message\"\n+\t\t\t__gitcomp_opts \"--dry-run --message\"\n \t\t\t;;\n \t\tblame,--*)\n-\t\t\t__gitcomp \"--git-format\"\n+\t\t\t__gitcomp_opts \"--git-format\"\n \t\t\t;;\n \t\tmigrate,--*)\n-\t\t\t__gitcomp \"\n+\t\t\t__gitcomp_opts \"\n \t\t\t\t--config-dir= --ignore-paths= --minimize\n \t\t\t\t--no-auth-cache --username=\n \t\t\t\t\"\n \t\t\t;;\n \t\treset,--*)\n-\t\t\t__gitcomp \"--revision= --parent\"\n+\t\t\t__gitcomp_opts \"--revision= --parent\"\n \t\t\t;;\n \t\t*)\n \t\t\t;;\n@@ -3223,7 +3235,7 @@ __git_main ()\n \t\t\t;;\n \t\tesac\n \t\tcase \"$cur\" in\n-\t\t--*)   __gitcomp \"\n+\t\t--*)   __gitcomp_opts \"\n \t\t\t--paginate\n \t\t\t--no-pager\n \t\t\t--git-dir=\n@@ -3274,7 +3286,7 @@ __gitk_main ()\n \tfi\n \tcase \"$cur\" in\n \t--*)\n-\t\t__gitcomp \"\n+\t\t__gitcomp_opts \"\n \t\t\t$__git_log_common_options\n \t\t\t$__git_log_gitk_options\n \t\t\t$merge\ndiff --git a/contrib/completion/git-completion.zsh b/contrib/completion/git-completion.zsh\nindex 1781401f5d..fc6d44bce0 100644\n--- a/contrib/completion/git-completion.zsh\n+++ b/contrib/completion/git-completion.zsh\n@@ -53,6 +53,15 @@ __gitcomp ()\n {\n \temulate -L zsh\n \n+\tlocal IFS=$' \\t\\n'\n+\tcompset -P '*[=:]'\n+\tcompadd -Q -S \"${4- }\" -p \"${2-}\" -- ${=1} && _ret=0\n+}\n+\n+__gitcomp_opts ()\n+{\n+\temulate -L zsh\n+\n \tlocal cur_=\"${3-$cur}\"\n \n \tcase \"$cur_\" in\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex efb98cc96c..ea572960de 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -85,17 +85,17 @@ test_completion ()\n \ttest_cmp expected out_sorted\n }\n \n-# Test __gitcomp.\n+# Test __gitcomp_opts.\n # The first argument is the typed text so far (cur); the rest are\n-# passed to __gitcomp.  Expected output comes is read from the\n+# passed to __gitcomp_opts.  Expected output comes is read from the\n # standard input, like test_completion().\n-test_gitcomp ()\n+test_gitcomp_opts ()\n {\n \tlocal -a COMPREPLY &&\n \tsed -e 's/Z$//' >expected &&\n \tlocal cur=\"$1\" &&\n \tshift &&\n-\t__gitcomp \"$@\" &&\n+\t__gitcomp_opts \"$@\" &&\n \tprint_comp &&\n \ttest_cmp expected out\n }\n@@ -450,8 +450,8 @@ test_expect_success '__gitcomp_direct - puts everything into COMPREPLY as-is' '\n \ttest_cmp expected out\n '\n \n-test_expect_success '__gitcomp - trailing space - options' '\n-\ttest_gitcomp \"--re\" \"--dry-run --reuse-message= --reedit-message=\n+test_expect_success '__gitcomp_opts - trailing space - options' '\n+\ttest_gitcomp_opts \"--re\" \"--dry-run --reuse-message= --reedit-message=\n \t\t--reset-author\" <<-EOF\n \t--reuse-message=Z\n \t--reedit-message=Z\n@@ -459,8 +459,8 @@ test_expect_success '__gitcomp - trailing space - options' '\n \tEOF\n '\n \n-test_expect_success '__gitcomp - trailing space - config keys' '\n-\ttest_gitcomp \"br\" \"branch. branch.autosetupmerge\n+test_expect_success '__gitcomp_opts - trailing space - config keys' '\n+\ttest_gitcomp_opts \"br\" \"branch. branch.autosetupmerge\n \t\tbranch.autosetuprebase browser.\" <<-\\EOF\n \tbranch.Z\n \tbranch.autosetupmerge Z\n@@ -469,32 +469,32 @@ test_expect_success '__gitcomp - trailing space - config keys' '\n \tEOF\n '\n \n-test_expect_success '__gitcomp - option parameter' '\n-\ttest_gitcomp \"--strategy=re\" \"octopus ours recursive resolve subtree\" \\\n+test_expect_success '__gitcomp_opts - option parameter' '\n+\ttest_gitcomp_opts \"--strategy=re\" \"octopus ours recursive resolve subtree\" \\\n \t\t\"\" \"re\" <<-\\EOF\n \trecursive Z\n \tresolve Z\n \tEOF\n '\n \n-test_expect_success '__gitcomp - prefix' '\n-\ttest_gitcomp \"branch.maint.me\" \"remote merge mergeoptions rebase\" \\\n+test_expect_success '__gitcomp_opts - prefix' '\n+\ttest_gitcomp_opts \"branch.maint.me\" \"remote merge mergeoptions rebase\" \\\n \t\t\"branch.maint.\" \"me\" <<-\\EOF\n \tbranch.maint.merge Z\n \tbranch.maint.mergeoptions Z\n \tEOF\n '\n \n-test_expect_success '__gitcomp - suffix' '\n-\ttest_gitcomp \"branch.ma\" \"master maint next seen\" \"branch.\" \\\n+test_expect_success '__gitcomp_opts - suffix' '\n+\ttest_gitcomp_opts \"branch.ma\" \"master maint next seen\" \"branch.\" \\\n \t\t\"ma\" \".\" <<-\\EOF\n \tbranch.master.Z\n \tbranch.maint.Z\n \tEOF\n '\n \n-test_expect_success '__gitcomp - ignore optional negative options' '\n-\ttest_gitcomp \"--\" \"--abc --def --no-one -- --no-two\" <<-\\EOF\n+test_expect_success '__gitcomp_opts - ignore optional negative options' '\n+\ttest_gitcomp_opts \"--\" \"--abc --def --no-one -- --no-two\" <<-\\EOF\n \t--abc Z\n \t--def Z\n \t--no-one Z\n@@ -502,44 +502,44 @@ test_expect_success '__gitcomp - ignore optional negative options' '\n \tEOF\n '\n \n-test_expect_success '__gitcomp - ignore/narrow optional negative options' '\n-\ttest_gitcomp \"--a\" \"--abc --abcdef --no-one -- --no-two\" <<-\\EOF\n+test_expect_success '__gitcomp_opts - ignore/narrow optional negative options' '\n+\ttest_gitcomp_opts \"--a\" \"--abc --abcdef --no-one -- --no-two\" <<-\\EOF\n \t--abc Z\n \t--abcdef Z\n \tEOF\n '\n \n-test_expect_success '__gitcomp - ignore/narrow optional negative options' '\n-\ttest_gitcomp \"--n\" \"--abc --def --no-one -- --no-two\" <<-\\EOF\n+test_expect_success '__gitcomp_opts - ignore/narrow optional negative options' '\n+\ttest_gitcomp_opts \"--n\" \"--abc --def --no-one -- --no-two\" <<-\\EOF\n \t--no-one Z\n \t--no-... Z\n \tEOF\n '\n \n-test_expect_success '__gitcomp - expand all negative options' '\n-\ttest_gitcomp \"--no-\" \"--abc --def --no-one -- --no-two\" <<-\\EOF\n+test_expect_success '__gitcomp_opts - expand all negative options' '\n+\ttest_gitcomp_opts \"--no-\" \"--abc --def --no-one -- --no-two\" <<-\\EOF\n \t--no-one Z\n \t--no-two Z\n \tEOF\n '\n \n-test_expect_success '__gitcomp - expand/narrow all negative options' '\n-\ttest_gitcomp \"--no-o\" \"--abc --def --no-one -- --no-two\" <<-\\EOF\n+test_expect_success '__gitcomp_opts - expand/narrow all negative options' '\n+\ttest_gitcomp_opts \"--no-o\" \"--abc --def --no-one -- --no-two\" <<-\\EOF\n \t--no-one Z\n \tEOF\n '\n \n-test_expect_success '__gitcomp - equal skip' '\n-\ttest_gitcomp \"--option=\" \"--option=\" <<-\\EOF &&\n+test_expect_success '__gitcomp_opts - equal skip' '\n+\ttest_gitcomp_opts \"--option=\" \"--option=\" <<-\\EOF &&\n \n \tEOF\n-\ttest_gitcomp \"option=\" \"option=\" <<-\\EOF\n+\ttest_gitcomp_opts \"option=\" \"option=\" <<-\\EOF\n \n \tEOF\n '\n \n-test_expect_success '__gitcomp - doesnt fail because of invalid variable name' '\n-\trun_func __gitcomp \"$invalid_variable_name\"\n+test_expect_success '__gitcomp_opts - doesnt fail because of invalid variable name' '\n+\trun_func __gitcomp_opts \"$invalid_variable_name\"\n '\n \n read -r -d \"\" refs <<-\\EOF\n-- \n2.29.2\n\n"},{"id":"409547","messageId":"20201110212136.870769-26-felipe.contreras@gmail.com","threadId":"54615","inReplyTo":"20201110212136.870769-1-felipe.contreras@gmail.com","subject":"[PATCH v2 25/26] completion: bash: cleanup __gitcomp* invocations","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-11-10T21:21:35Z","receivedAt":"2020-11-10T21:22:35Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Some __gitcomp calls should be __gitcomp_nl, and vice versa.\n\nNo functional changes.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n contrib/completion/git-completion.bash | 22 +++++++++-------------\n 1 file changed, 9 insertions(+), 13 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 324793368d..d73cdb7096 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -1205,7 +1205,7 @@ _git_archive ()\n {\n \tcase \"$cur\" in\n \t--format=*)\n-\t\t__gitcomp \"$(git archive --list)\" \"\" \"${cur##--format=}\"\n+\t\t__gitcomp_nl \"$(git archive --list)\" \"\" \"${cur##--format=}\"\n \t\treturn\n \t\t;;\n \t--remote=*)\n@@ -1616,9 +1616,7 @@ _git_format_patch ()\n {\n \tcase \"$cur\" in\n \t--thread=*)\n-\t\t__gitcomp \"\n-\t\t\tdeep shallow\n-\t\t\t\" \"\" \"${cur##--thread=}\"\n+\t\t__gitcomp \"deep shallow\" \"\" \"${cur##--thread=}\"\n \t\treturn\n \t\t;;\n \t--base=*|--interdiff=*|--range-diff=*)\n@@ -2124,7 +2122,7 @@ _git_send_email ()\n {\n \tcase \"$prev\" in\n \t--to|--cc|--bcc|--from)\n-\t\t__gitcomp \"$(__git send-email --dump-aliases)\"\n+\t\t__gitcomp_nl \"$(__git send-email --dump-aliases)\"\n \t\treturn\n \t\t;;\n \tesac\n@@ -2148,9 +2146,7 @@ _git_send_email ()\n \t\treturn\n \t\t;;\n \t--thread=*)\n-\t\t__gitcomp \"\n-\t\t\tdeep shallow\n-\t\t\t\" \"\" \"${cur##--thread=}\"\n+\t\t__gitcomp \"deep shallow\" \"\" \"${cur##--thread=}\"\n \t\treturn\n \t\t;;\n \t--to=*|--cc=*|--bcc=*|--from=*)\n@@ -2452,7 +2448,7 @@ __git_complete_config_variable_name ()\n \t\tlocal pfx=\"${cur_%.*}.\"\n \t\tcur_=\"${cur_#*.}\"\n \t\t__gitcomp_direct \"$(__git_heads \"$pfx\" \"$cur_\" \".\")\"\n-\t\t__gitcomp_nl $'autoSetupMerge\\nautoSetupRebase\\n' \"$pfx\" \"$cur_\" \"$sfx\"\n+\t\t__gitcomp \"autoSetupMerge autoSetupRebase\" \"$pfx\" \"$cur_\" \"$sfx\"\n \t\treturn\n \t\t;;\n \tguitool.*.*)\n@@ -2502,7 +2498,7 @@ __git_complete_config_variable_name ()\n \t\tlocal pfx=\"${cur_%.*}.\"\n \t\tcur_=\"${cur_#*.}\"\n \t\t__gitcomp_nl \"$(__git_remotes)\" \"$pfx\" \"$cur_\" \".\"\n-\t\t__gitcomp_nl \"pushDefault\" \"$pfx\" \"$cur_\" \"$sfx\"\n+\t\t__gitcomp \"pushDefault\" \"$pfx\" \"$cur_\" \"$sfx\"\n \t\treturn\n \t\t;;\n \turl.*.*)\n@@ -2517,7 +2513,7 @@ __git_complete_config_variable_name ()\n \t\t;;\n \t*)\n \t\t__git_compute_config_vars\n-\t\t__gitcomp \"$(echo \"$__git_config_vars\" |\n+\t\t__gitcomp_nl \"$(echo \"$__git_config_vars\" |\n \t\t\t\tawk -F . '{\n \t\t\t\t\tsections[$1] = 1\n \t\t\t\t}\n@@ -2619,7 +2615,7 @@ _git_remote ()\n \t\t__gitcomp_builtin remote_update\n \t\t;;\n \tupdate,*)\n-\t\t__gitcomp \"$(__git_remotes) $(__git_get_config_variables \"remotes\")\"\n+\t\t__gitcomp_nl \"$(__git_remotes) $(__git_get_config_variables \"remotes\")\"\n \t\t;;\n \tset-url,--*)\n \t\t__gitcomp_builtin remote_set-url\n@@ -3257,7 +3253,7 @@ __git_main ()\n \t\t\tthen\n \t\t\t\t__gitcomp \"$GIT_TESTING_PORCELAIN_COMMAND_LIST\"\n \t\t\telse\n-\t\t\t\t__gitcomp \"$(__git --list-cmds=list-mainporcelain,others,nohelpers,alias,list-complete,config)\"\n+\t\t\t\t__gitcomp_nl \"$(__git --list-cmds=list-mainporcelain,others,nohelpers,alias,list-complete,config)\"\n \t\t\tfi\n \t\t\t;;\n \t\tesac\n-- \n2.29.2\n\n"},{"id":"409548","messageId":"20201110212136.870769-27-felipe.contreras@gmail.com","threadId":"54615","inReplyTo":"20201110212136.870769-1-felipe.contreras@gmail.com","subject":"[PATCH v2 26/26] completion: bash: shuffle __gitcomp functions","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-11-10T21:21:36Z","receivedAt":"2020-11-10T21:22:36Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"They are the ones that actually do the completion, put them at the top.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n contrib/completion/git-completion.bash | 262 +++++++++++++------------\n 1 file changed, 135 insertions(+), 127 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex d73cdb7096..578b6b0d2f 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -45,6 +45,141 @@\n #     When set to \"1\" suggest all options, including options which are\n #     typically hidden (e.g. '--allow-empty' for 'git commit').\n \n+# The following functions are meant to modify COMPREPLY, which should not be\n+# modified directly.  The purpose is to localize the modifications so it's\n+# easier to emulate it in Zsh. Every time a new __gitcomp* function is added,\n+# the corresponding function should be added to Zsh.\n+\n+__gitcompadd ()\n+{\n+\tlocal x i=${#COMPREPLY[@]}\n+\tfor x in $1; do\n+\t\tif [[ \"$x\" == \"$3\"* ]]; then\n+\t\t\tCOMPREPLY[i++]=\"$2$x$4\"\n+\t\tfi\n+\tdone\n+}\n+\n+# Creates completion replies.\n+# It accepts 1 to 4 arguments:\n+# 1: List of possible completion words.\n+# 2: A prefix to be added to each possible completion word (optional).\n+# 3: Generate possible completion matches for this word (optional).\n+# 4: A suffix to be appended to each possible completion word (optional).\n+__gitcomp ()\n+{\n+\tlocal IFS=$' \\t\\n'\n+\t__gitcompadd \"$1\" \"${2-}\" \"${3-$cur}\" \"${4- }\"\n+}\n+\n+# Generates completion reply from newline-separated possible completion words\n+# by appending a space to all of them. The result is appended to COMPREPLY.\n+# It accepts 1 to 4 arguments:\n+# 1: List of possible completion words, separated by a single newline.\n+# 2: A prefix to be added to each possible completion word (optional).\n+# 3: Generate possible completion matches for this word (optional).\n+# 4: A suffix to be appended to each possible completion word instead of\n+#    the default space (optional).  If specified but empty, nothing is\n+#    appended.\n+__gitcomp_nl ()\n+{\n+\tlocal IFS=$'\\n'\n+\t__gitcompadd \"$1\" \"${2-}\" \"${3-$cur}\" \"${4- }\"\n+}\n+\n+# Appends prefiltered words to COMPREPLY without any additional processing.\n+# Callers must take care of providing only words that match the current word\n+# to be completed and adding any prefix and/or suffix (trailing space!), if\n+# necessary.\n+# 1: List of newline-separated matching completion words, complete with\n+#    prefix and suffix.\n+__gitcomp_direct ()\n+{\n+\tlocal IFS=$'\\n'\n+\n+\tCOMPREPLY+=($1)\n+}\n+\n+# Generates completion reply with compgen from newline-separated possible\n+# completion filenames.\n+# It accepts 1 to 3 arguments:\n+# 1: List of possible completion filenames, separated by a single newline.\n+# 2: A directory prefix to be added to each possible completion filename\n+#    (optional).\n+# 3: Generate possible completion matches for this word (optional).\n+__gitcomp_file ()\n+{\n+\tlocal IFS=$'\\n'\n+\n+\t# XXX does not work when the directory prefix contains a tilde,\n+\t# since tilde expansion is not applied.\n+\t# This means that COMPREPLY will be empty and Bash default\n+\t# completion will be used.\n+\t__gitcompadd \"$1\" \"${2-}\" \"${3-$cur}\" \"\"\n+\n+\t# use a hack to enable file mode in bash < 4\n+\tcompopt -o filenames +o nospace 2>/dev/null ||\n+\tcompgen -f /non-existing-dir/ >/dev/null ||\n+\ttrue\n+}\n+\n+# Fills the COMPREPLY array with prefiltered paths without any additional\n+# processing.\n+# Callers must take care of providing only paths that match the current path\n+# to be completed and adding any prefix path components, if necessary.\n+# 1: List of newline-separated matching paths, complete with all prefix\n+#    path components.\n+__gitcomp_file_direct ()\n+{\n+\tlocal IFS=$'\\n'\n+\n+\tCOMPREPLY+=($1)\n+\n+\t# use a hack to enable file mode in bash < 4\n+\tcompopt -o filenames +o nospace 2>/dev/null ||\n+\tcompgen -f /non-existing-dir/ >/dev/null ||\n+\ttrue\n+}\n+\n+# Creates completion replies, reorganizing options and adding suffixes as needed.\n+# It accepts 1 to 4 arguments:\n+# 1: List of possible completion words.\n+# 2: A prefix to be added to each possible completion word (optional).\n+# 3: Generate possible completion matches for this word (optional).\n+# 4: A suffix to be appended to each possible completion word (optional).\n+__gitcomp_opts ()\n+{\n+\tlocal cur_=\"${3-$cur}\"\n+\n+\tif [[ \"$cur_\" == *= ]]; then\n+\t\treturn\n+\tfi\n+\n+\tlocal c i=0 IFS=$' \\t\\n' sfx\n+\tfor c in $1; do\n+\t\tif [[ $c == \"--\" ]]; then\n+\t\t\tif [[ \"$cur_\" == --no-* ]]; then\n+\t\t\t\tcontinue\n+\t\t\tfi\n+\n+\t\t\tif [[ --no == \"$cur_\"* ]]; then\n+\t\t\t\tCOMPREPLY[i++]=\"--no-... \"\n+\t\t\tfi\n+\t\t\tbreak\n+\t\tfi\n+\t\tif [[ $c == \"$cur_\"* ]]; then\n+\t\t\tcase $c in\n+\t\t\t*=|*.) sfx=\"\" ;;\n+\t\t\t*) sfx=\" \" ;;\n+\t\t\tesac\n+\t\t\tCOMPREPLY[i++]=\"${2-}$c${4:-$sfx}\"\n+\t\tfi\n+\tdone\n+}\n+\n+# __gitcomp functions end here\n+# ==============================================================================\n+\n # Discovers the path to the git repository taking any '--git-dir=<path>' and\n # '-C <path>' options into account and stores it in the $__git_repo_path\n # variable.\n@@ -159,77 +294,6 @@ __git_dequote ()\n \tdone\n }\n \n-# Appends prefiltered words to COMPREPLY without any additional processing.\n-# Callers must take care of providing only words that match the current word\n-# to be completed and adding any prefix and/or suffix (trailing space!), if\n-# necessary.\n-# 1: List of newline-separated matching completion words, complete with\n-#    prefix and suffix.\n-__gitcomp_direct ()\n-{\n-\tlocal IFS=$'\\n'\n-\n-\tCOMPREPLY+=($1)\n-}\n-\n-__gitcompadd ()\n-{\n-\tlocal x i=${#COMPREPLY[@]}\n-\tfor x in $1; do\n-\t\tif [[ \"$x\" == \"$3\"* ]]; then\n-\t\t\tCOMPREPLY[i++]=\"$2$x$4\"\n-\t\tfi\n-\tdone\n-}\n-\n-# Creates completion replies.\n-# It accepts 1 to 4 arguments:\n-# 1: List of possible completion words.\n-# 2: A prefix to be added to each possible completion word (optional).\n-# 3: Generate possible completion matches for this word (optional).\n-# 4: A suffix to be appended to each possible completion word (optional).\n-__gitcomp ()\n-{\n-\tlocal IFS=$' \\t\\n'\n-\t__gitcompadd \"$1\" \"${2-}\" \"${3-$cur}\" \"${4- }\"\n-}\n-\n-# Creates completion replies, reorganizing options and adding suffixes as needed.\n-# It accepts 1 to 4 arguments:\n-# 1: List of possible completion words.\n-# 2: A prefix to be added to each possible completion word (optional).\n-# 3: Generate possible completion matches for this word (optional).\n-# 4: A suffix to be appended to each possible completion word (optional).\n-__gitcomp_opts ()\n-{\n-\tlocal cur_=\"${3-$cur}\"\n-\n-\tif [[ \"$cur_\" == *= ]]; then\n-\t\treturn\n-\tfi\n-\n-\tlocal c i=0 IFS=$' \\t\\n' sfx\n-\tfor c in $1; do\n-\t\tif [[ $c == \"--\" ]]; then\n-\t\t\tif [[ \"$cur_\" == --no-* ]]; then\n-\t\t\t\tcontinue\n-\t\t\tfi\n-\n-\t\t\tif [[ --no == \"$cur_\"* ]]; then\n-\t\t\t\tCOMPREPLY[i++]=\"--no-... \"\n-\t\t\tfi\n-\t\t\tbreak\n-\t\tfi\n-\t\tif [[ $c == \"$cur_\"* ]]; then\n-\t\t\tcase $c in\n-\t\t\t*=|*.) sfx=\"\" ;;\n-\t\t\t*) sfx=\" \" ;;\n-\t\t\tesac\n-\t\t\tCOMPREPLY[i++]=\"${2-}$c${4:-$sfx}\"\n-\t\tfi\n-\tdone\n-}\n-\n # Clear the variables caching builtins' options when (re-)sourcing\n # the completion script.\n if [[ -n ${ZSH_VERSION-} ]]; then\n@@ -278,62 +342,6 @@ __gitcomp_builtin ()\n \t__gitcomp_opts \"$options\"\n }\n \n-# Generates completion reply from newline-separated possible completion words\n-# by appending a space to all of them. The result is appended to COMPREPLY.\n-# It accepts 1 to 4 arguments:\n-# 1: List of possible completion words, separated by a single newline.\n-# 2: A prefix to be added to each possible completion word (optional).\n-# 3: Generate possible completion matches for this word (optional).\n-# 4: A suffix to be appended to each possible completion word instead of\n-#    the default space (optional).  If specified but empty, nothing is\n-#    appended.\n-__gitcomp_nl ()\n-{\n-\tlocal IFS=$'\\n'\n-\t__gitcompadd \"$1\" \"${2-}\" \"${3-$cur}\" \"${4- }\"\n-}\n-\n-# Fills the COMPREPLY array with prefiltered paths without any additional\n-# processing.\n-# Callers must take care of providing only paths that match the current path\n-# to be completed and adding any prefix path components, if necessary.\n-# 1: List of newline-separated matching paths, complete with all prefix\n-#    path components.\n-__gitcomp_file_direct ()\n-{\n-\tlocal IFS=$'\\n'\n-\n-\tCOMPREPLY+=($1)\n-\n-\t# use a hack to enable file mode in bash < 4\n-\tcompopt -o filenames +o nospace 2>/dev/null ||\n-\tcompgen -f /non-existing-dir/ >/dev/null ||\n-\ttrue\n-}\n-\n-# Generates completion reply with compgen from newline-separated possible\n-# completion filenames.\n-# It accepts 1 to 3 arguments:\n-# 1: List of possible completion filenames, separated by a single newline.\n-# 2: A directory prefix to be added to each possible completion filename\n-#    (optional).\n-# 3: Generate possible completion matches for this word (optional).\n-__gitcomp_file ()\n-{\n-\tlocal IFS=$'\\n'\n-\n-\t# XXX does not work when the directory prefix contains a tilde,\n-\t# since tilde expansion is not applied.\n-\t# This means that COMPREPLY will be empty and Bash default\n-\t# completion will be used.\n-\t__gitcompadd \"$1\" \"${2-}\" \"${3-$cur}\" \"\"\n-\n-\t# use a hack to enable file mode in bash < 4\n-\tcompopt -o filenames +o nospace 2>/dev/null ||\n-\tcompgen -f /non-existing-dir/ >/dev/null ||\n-\ttrue\n-}\n-\n # Execute 'git ls-files', unless the --committable option is specified, in\n # which case it runs 'git diff-index' to find out the files that can be\n # committed.  It return paths relative to the directory specified in the first\n-- \n2.29.2\n\n"},{"id":"409589","messageId":"xmqq1rh05p6f.fsf@gitster.c.googlers.com","threadId":"54615","inReplyTo":"20201110212136.870769-7-felipe.contreras@gmail.com","subject":"Re: [PATCH v2 06/26] test: completion: add run_func() helper","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-11-11T07:27:04Z","receivedAt":"2020-11-11T07:27:12Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Felipe Contreras <felipe.contreras@gmail.com> writes:\n\n> Pretty straightforward: runs functions.\n\nHmph, sorry but this is not straight-forward at least to me.  Yes,\nthe helper runs whatever is given on the command line, but then it\ndoes \"print_comp\", too.  And the proposed log message is not\nentirely clear on the most important thing: why?\n\nWhat is this \"helper\" meant to help?  Reduce repetition?\n\n> +run_func ()\n> +{\n> +\tlocal -a COMPREPLY &&\n> +\t\"$@\" && print_comp\n> +}\n> +\n>  # Test high-level completion\n>  # Arguments are:\n>  # 1: typed text so far (cur)\n> @@ -452,8 +458,7 @@ test_expect_success '__gitcomp_direct - puts everything into COMPREPLY as-is' '\n>  \tEOF\n>  \t(\n>  \t\tcur=should_be_ignored &&\n> -\t\t__gitcomp_direct \"$(cat expected)\" &&\n> -\t\tprint_comp\n> +\t\trun_func __gitcomp_direct \"$(cat expected)\"\n\nThis is an no-op rewrite, as we used to do the gitcomp-direct\nfollowed by print-comp, which is exactly what the helper does.  So\nthe helper does reduce repetition, which by itself would be a good\nthing but is there other benefit we are trying to seek (there does\nnot have to be any)?\n\n>  test_expect_success '__gitcomp - doesnt fail because of invalid variable name' '\n> -\t__gitcomp \"$invalid_variable_name\"\n> +\trun_func __gitcomp \"$invalid_variable_name\"\n\nThis one changes the behaviour in that it starts running print_comp\nwhich we didn't run.  It may be a good thing and improvement, but\nthen we'd better advertise it in the proposed log message.\n\n>  '\n>  \n>  read -r -d \"\" refs <<-\\EOF\n> @@ -586,7 +591,7 @@ test_expect_success '__gitcomp_nl - no suffix' '\n>  '\n>  \n>  test_expect_success '__gitcomp_nl - doesnt fail because of invalid variable name' '\n> -\t__gitcomp_nl \"$invalid_variable_name\"\n> +\trun_func __gitcomp_nl \"$invalid_variable_name\"\n\nLikewise.\n\n>  '\n\n\nThanks.\n"},{"id":"409605","messageId":"CAMP44s0XA6QjOZTJaC5CK9Rp9ySfoH9_rJu-AoEGgprstzprfw@mail.gmail.com","threadId":"54615","inReplyTo":"xmqq1rh05p6f.fsf@gitster.c.googlers.com","subject":"Re: [PATCH v2 06/26] test: completion: add run_func() helper","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-11-11T11:43:24Z","receivedAt":"2020-11-11T11:43:53Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Wed, Nov 11, 2020 at 1:27 AM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Felipe Contreras <felipe.contreras@gmail.com> writes:\n>\n> > Pretty straightforward: runs functions.\n>\n> Hmph, sorry but this is not straight-forward at least to me.  Yes,\n> the helper runs whatever is given on the command line, but then it\n> does \"print_comp\", too.  And the proposed log message is not\n> entirely clear on the most important thing: why?\n>\n> What is this \"helper\" meant to help?  Reduce repetition?\n\nWell, I thought the \"helper\" part of the title made it obvious: the\nhelper function does help in not having to type the same code over and\nover. But there's in fact multiple benefits.\n\n1. It makes the code more consistent. Everything in the test script\neither calls a test_ function, or a run_ function, except the code\nthat is testing the functions directly.\n\n2. It reduces code (obvious in a helper function), as the same\n__gitcomp* && print_comp is executed over and over, with zero\nvariation.\n\n3. It makes the code more maintainable (I also thought this was\nobvious); if we want to add something we don't have to do it dozens of\ntimes, we just do it on the helper function.\n\nIs this enough of a \"why\"?\n\nIt is in fact number 3 the one I'm after, and a line that shouldn't be\npart of this patch was smuggled in, so perhaps that's why future\npatches don't obviate the need for this one.\n\nBut even with no other reason for it, the patch stands on its own.\n\n> > +run_func ()\n> > +{\n> > +     local -a COMPREPLY &&\n\nThis is the line that was smuggled in. It should be part of a separate\npatch, since this is behavior change.\n\n> > +     \"$@\" && print_comp\n> > +}\n> > +\n> >  # Test high-level completion\n> >  # Arguments are:\n> >  # 1: typed text so far (cur)\n> > @@ -452,8 +458,7 @@ test_expect_success '__gitcomp_direct - puts everything into COMPREPLY as-is' '\n> >       EOF\n> >       (\n> >               cur=should_be_ignored &&\n> > -             __gitcomp_direct \"$(cat expected)\" &&\n> > -             print_comp\n> > +             run_func __gitcomp_direct \"$(cat expected)\"\n>\n> This is an no-op rewrite, as we used to do the gitcomp-direct\n> followed by print-comp, which is exactly what the helper does.  So\n> the helper does reduce repetition, which by itself would be a good\n> thing but is there other benefit we are trying to seek (there does\n> not have to be any)?\n\nIt's not exactly a no-op, since I cleared COMPREPLY. That should be\ndone in a separate patch so it's truly a no-op.\n\nIt is the clearing of COMPREPLY that I'm eventually interested in.\nFirst; that's how the testing framework is supposed to work: test #1\nshould not interfere with test #2, but second; once the gitcomp\nfunctions are changed to append code instead of clearing COMPREPLY by\nthemselves and then appending, this prevents the tests from failing.\n\n> >  test_expect_success '__gitcomp - doesnt fail because of invalid variable name' '\n> > -     __gitcomp \"$invalid_variable_name\"\n> > +     run_func __gitcomp \"$invalid_variable_name\"\n>\n> This one changes the behaviour in that it starts running print_comp\n> which we didn't run.  It may be a good thing and improvement, but\n> then we'd better advertise it in the proposed log message.\n\nBut nothing is done with the output; the behavior doesn't change. The\ntest still passes or fails irrespective of what print_comp does.\n\n  test_expect_success 'test 1' 'true'\n  test_expect_success 'test 2' ': echo foobar'\n  test_expect_success 'test 3' 'echo foobar > /dev/null'\n\nThese three tests may do different things, but their behavior is the\nsame, that is to say: with the same input they generate the same\noutput.\n\nDo you want me to add: \"In two places we generate an output that\ndidn't exist before, but nothing ever reads it.\" ?\n\nCheers.\n\n-- \nFelipe Contreras\n"},{"id":"409644","messageId":"xmqqsg9f4zme.fsf@gitster.c.googlers.com","threadId":"54615","inReplyTo":"CAMP44s0XA6QjOZTJaC5CK9Rp9ySfoH9_rJu-AoEGgprstzprfw@mail.gmail.com","subject":"Re: [PATCH v2 06/26] test: completion: add run_func() helper","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-11-11T16:39:05Z","receivedAt":"2020-11-11T16:39:13Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Felipe Contreras <felipe.contreras@gmail.com> writes:\n\n> But even with no other reason for it, the patch stands on its own.\n>\n>> > +run_func ()\n>> > +{\n>> > +     local -a COMPREPLY &&\n>\n> This is the line that was smuggled in. It should be part of a separate\n> patch, since this is behavior change.\n> ...\n> Do you want me to add: \"In two places we generate an output that\n> didn't exist before, but nothing ever reads it.\" ?\n\nThat would be very friendly to readers who may later wonder why the\nchange was made, yes.\n\nIn any case, I am not a shell-completion person, so even if I said\n\"yes that would make the patch perfect\", that would not count as\nmuch ;-)\n"},{"id":"409789","messageId":"xmqqo8k2cppj.fsf@gitster.c.googlers.com","threadId":"54615","inReplyTo":"20201110212136.870769-13-felipe.contreras@gmail.com","subject":"Re: [PATCH v2 12/26] completion: bash: refactor __gitcomp","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-11-12T19:58:16Z","receivedAt":"2020-11-12T19:58:25Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Felipe Contreras <felipe.contreras@gmail.com> writes:\n\n> We have to chunks of code doing exactly the same. There's no need for\n> that.\n\nYou mean \"2 chunks\"?\n\n>\n> No functional changes.\n>\n> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n> ---\n"},{"id":"409802","messageId":"CAMP44s2bVqMGGOcBBVUP01f49C5tTxVRZNacRzAqpO8JwE7DTA@mail.gmail.com","threadId":"54615","inReplyTo":"xmqqo8k2cppj.fsf@gitster.c.googlers.com","subject":"Re: [PATCH v2 12/26] completion: bash: refactor __gitcomp","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-11-12T22:00:04Z","receivedAt":"2020-11-12T22:00:23Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Thu, Nov 12, 2020 at 1:58 PM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Felipe Contreras <felipe.contreras@gmail.com> writes:\n>\n> > We have to chunks of code doing exactly the same. There's no need for\n> > that.\n>\n> You mean \"2 chunks\"?\n\nYes. I noticed the error right after I sent the patch.\n\n-- \nFelipe Contreras\n"},{"id":"409836","messageId":"CAMP44s02ytq9gpa1S-Kp7dhMknrZkGtwcqu7mssCCzJY2v=S6Q@mail.gmail.com","threadId":"54615","inReplyTo":"xmqqsg9f4zme.fsf@gitster.c.googlers.com","subject":"Re: [PATCH v2 06/26] test: completion: add run_func() helper","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-11-12T22:54:10Z","receivedAt":"2020-11-12T22:54:25Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Wed, Nov 11, 2020 at 10:39 AM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Felipe Contreras <felipe.contreras@gmail.com> writes:\n>\n> > But even with no other reason for it, the patch stands on its own.\n> >\n> >> > +run_func ()\n> >> > +{\n> >> > +     local -a COMPREPLY &&\n> >\n> > This is the line that was smuggled in. It should be part of a separate\n> > patch, since this is behavior change.\n> > ...\n> > Do you want me to add: \"In two places we generate an output that\n> > didn't exist before, but nothing ever reads it.\" ?\n>\n> That would be very friendly to readers who may later wonder why the\n> change was made, yes.\n>\n> In any case, I am not a shell-completion person, so even if I said\n> \"yes that would make the patch perfect\", that would not count as\n> much ;-)\n\nBut it doesn't hurt either.\n\nI'll resend the series only with the obvious fixes, since there\ndoesn't seem to be much interest in the rest.\n\n-- \nFelipe Contreras\n"},{"id":"410773","messageId":"20201125084814.GE8396@szeder.dev","threadId":"54615","inReplyTo":"20201110212136.870769-2-felipe.contreras@gmail.com","subject":"Re: [PATCH v2 01/26] completion: bash: fix prefix detection in branch.*","fromName":"SZEDER Gábor","fromEmail":"szeder.dev@gmail.com","sentAt":"2020-11-25T08:48:14Z","receivedAt":"2020-11-25T08:48:11Z","isPatch":true,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"On Tue, Nov 10, 2020 at 03:21:11PM -0600, Felipe Contreras wrote:\n> Otherwise we are completely ignoring the --cur argument.\n> \n> The issue can be tested with:\n> \n>   git clone --config=branch.<tab>\n> \n> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n> ---\n>  contrib/completion/git-completion.bash | 4 ++--\n>  1 file changed, 2 insertions(+), 2 deletions(-)\n> \n> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n> index 7c81e4ba49..b866b68b3c 100644\n> --- a/contrib/completion/git-completion.bash\n> +++ b/contrib/completion/git-completion.bash\n> @@ -2615,8 +2615,8 @@ __git_complete_config_variable_name ()\n>  \t\treturn\n>  \t\t;;\n>  \tbranch.*)\n> -\t\tlocal pfx=\"${cur%.*}.\"\n> -\t\tcur_=\"${cur#*.}\"\n> +\t\tlocal pfx=\"${cur_%.*}.\"\n> +\t\tcur_=\"${cur_#*.}\"\n\nIndeed, somehow this case was only half-converted in 5af9d5f6c8\n(completion: complete config variables and values for 'git clone\n--config=', 2019-08-13), thanks.\n\n>  \t\t__gitcomp_direct \"$(__git_heads \"$pfx\" \"$cur_\" \".\")\"\n>  \t\t__gitcomp_nl_append $'autoSetupMerge\\nautoSetupRebase\\n' \"$pfx\" \"$cur_\" \"$sfx\"\n>  \t\treturn\n> -- \n> 2.29.2\n> \n"},{"id":"410799","messageId":"xmqqr1ohdvfi.fsf@gitster.c.googlers.com","threadId":"54615","inReplyTo":"20201125084814.GE8396@szeder.dev","subject":"Re: [PATCH v2 01/26] completion: bash: fix prefix detection in branch.*","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-11-25T20:37:53Z","receivedAt":"2020-11-25T20:38:13Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"SZEDER Gábor <szeder.dev@gmail.com> writes:\n\n> On Tue, Nov 10, 2020 at 03:21:11PM -0600, Felipe Contreras wrote:\n>> Otherwise we are completely ignoring the --cur argument.\n>> \n>> The issue can be tested with:\n>> \n>>   git clone --config=branch.<tab>\n>> \n>> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n>> ---\n>>  contrib/completion/git-completion.bash | 4 ++--\n>>  1 file changed, 2 insertions(+), 2 deletions(-)\n>> \n>> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n>> index 7c81e4ba49..b866b68b3c 100644\n>> --- a/contrib/completion/git-completion.bash\n>> +++ b/contrib/completion/git-completion.bash\n>> @@ -2615,8 +2615,8 @@ __git_complete_config_variable_name ()\n>>  \t\treturn\n>>  \t\t;;\n>>  \tbranch.*)\n>> -\t\tlocal pfx=\"${cur%.*}.\"\n>> -\t\tcur_=\"${cur#*.}\"\n>> +\t\tlocal pfx=\"${cur_%.*}.\"\n>> +\t\tcur_=\"${cur_#*.}\"\n>\n> Indeed, somehow this case was only half-converted in 5af9d5f6c8\n> (completion: complete config variables and values for 'git clone\n> --config=', 2019-08-13), thanks.\n\nVery much appreciated a review on this step, and it would be even\nmore appreciated if the whole series gets some review, as we do not\nwant to merge a series that has not been looked at.\n\nThanks.\n\n\n"},{"id":"410807","messageId":"CAMP44s3pSOrOYA+CG5Rd+Bu5UXK-4L=4JsHR0tMb7gV7nmbPEg@mail.gmail.com","threadId":"54615","inReplyTo":"xmqqr1ohdvfi.fsf@gitster.c.googlers.com","subject":"Re: [PATCH v2 01/26] completion: bash: fix prefix detection in branch.*","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2020-11-25T21:46:53Z","receivedAt":"2020-11-25T21:47:07Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Wed, Nov 25, 2020 at 2:37 PM Junio C Hamano <gitster@pobox.com> wrote:\n\n> Very much appreciated a review on this step, and it would be even\n> more appreciated if the whole series gets some review, as we do not\n> want to merge a series that has not been looked at.\n\nYes, but it would be better to review the important ones; the fixes, first.\n\nhttps://lore.kernel.org/git/20201119015209.1155170-1-felipe.contreras@gmail.com/\n\n-- \nFelipe Contreras\n"}]}