Commit 8776470
completion: repair config completion for Zsh
Commit 1e0ee40 (completion: add and use
__git_compute_first_level_config_vars_for_section, 2024-02-10) uses an
indirect variable syntax that is only valid for Bash, but the Zsh
completion code relies on the Bash completion code to function. Zsh
supports a different indirect variable expansion using ${(P)var}, but in
`emulate ksh` mode does not support Bash's ${!var}.
This manifests as completing strange config options like
"__git_first_level_config_vars_for_section_remote" as a choice for the
command line
git config set remote.
Using Zsh's C-x ? _complete_debug widget with the cursor at the end of
that command line captures a trace, in which we see (some details
elided):
+__git_complete_config_variable_name:7> __git_compute_first_level_config_vars_for_section remote
+__git_compute_first_level_config_vars_for_section:7> local section=remote
+__git_compute_first_level_config_vars_for_section:7> __git_compute_config_vars
+__git_compute_config_vars:7> test -n $'add.ignoreErrors\nadvice.addEmbeddedRepo\nadvice.addEmptyPathspec\nadvice.addIgnoredFile[…]'
+__git_compute_first_level_config_vars_for_section:7> local this_section=__git_first_level_config_vars_for_section_remote
+__git_compute_first_level_config_vars_for_section:7> test -n __git_first_level_config_vars_for_section_remote
+__git_complete_config_variable_name:7> local this_section=__git_first_level_config_vars_for_section_remote
+__git_complete_config_variable_name:7> __gitcomp_nl_append __git_first_level_config_vars_for_section_remote remote. '' ' '
+__gitcomp_nl_append:7> __gitcomp_nl __git_first_level_config_vars_for_section_remote remote. '' ' '
+__gitcomp_nl:7> emulate -L zsh
+__gitcomp_nl:7> compset -P '*[=:]'
+__gitcomp_nl:7> compadd -Q -S ' ' -p remote. -- __git_first_level_config_vars_for_section_remote
We perform the test for __git_compute_config_vars correctly, but the
${!this_section} references are not expanded as expected.
Instead, portably expand indirect references through the new
__git_indirect. Contrary to some versions you might find online [1],
this version avoids echo non-portabilities [2] [3] and correctly quotes
the indirect expansion after eval (so that the result is not split or
globbed before being handed to printf).
[1]: https://unix.stackexchange.com/a/41409/301073
[2]: https://askubuntu.com/questions/715765/mysterious-behavior-of-echo-command#comment1056038_715769
[3]: https://mywiki.wooledge.org/CatEchoLs
The following demo program demonstrates how this works:
b=1
indirect() {
eval printf '%s' "\"\$$1\""
}
f() {
# Comment this out to see that it works for globals, too. Or, use
# a value with spaces like '2 3 4' to see how it handles those.
local b=2
local a=b
test -n "$(indirect $a)" && echo nice
}
f
When placed in a file "demo", then both
bash -x demo
and
zsh -xc 'emulate ksh -c ". ./demo"' |& tail
provide traces showing that "$(indirect $a)" produces 2 (or 1, with the
global, or "2 3 4" as a single string, etc.).
Signed-off-by: D. Ben Knoble <[email protected]>
Acked-by: Philippe Blain <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>1 parent c2b3f2b commit 8776470
1 file changed
+11
-6
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2723 | 2723 | | |
2724 | 2724 | | |
2725 | 2725 | | |
| 2726 | + | |
| 2727 | + | |
| 2728 | + | |
| 2729 | + | |
| 2730 | + | |
2726 | 2731 | | |
2727 | 2732 | | |
2728 | 2733 | | |
2729 | 2734 | | |
2730 | 2735 | | |
2731 | | - | |
| 2736 | + | |
2732 | 2737 | | |
2733 | 2738 | | |
2734 | 2739 | | |
| |||
2738 | 2743 | | |
2739 | 2744 | | |
2740 | 2745 | | |
2741 | | - | |
| 2746 | + | |
2742 | 2747 | | |
2743 | 2748 | | |
2744 | 2749 | | |
| |||
2893 | 2898 | | |
2894 | 2899 | | |
2895 | 2900 | | |
2896 | | - | |
| 2901 | + | |
2897 | 2902 | | |
2898 | 2903 | | |
2899 | 2904 | | |
| |||
2903 | 2908 | | |
2904 | 2909 | | |
2905 | 2910 | | |
2906 | | - | |
| 2911 | + | |
2907 | 2912 | | |
2908 | 2913 | | |
2909 | 2914 | | |
| |||
2920 | 2925 | | |
2921 | 2926 | | |
2922 | 2927 | | |
2923 | | - | |
| 2928 | + | |
2924 | 2929 | | |
2925 | 2930 | | |
2926 | 2931 | | |
| |||
2930 | 2935 | | |
2931 | 2936 | | |
2932 | 2937 | | |
2933 | | - | |
| 2938 | + | |
2934 | 2939 | | |
2935 | 2940 | | |
2936 | 2941 | | |
| |||
0 commit comments