git-completion.bash: introduce __gitcomp_builtin

This is a __gitcomp wrapper that will execute git ... --git-completion-helper to get the list of completable options. The call will be made only once and cached to avoid performance issues, especially on Windows. __gitcomp_builtin() allows callers to change its output a bit by adding some more options, or removing some. - Current --git-completion-helper for example does not output --no-foo form, this has to be added manually by __gitcomp_builtin() callers when necessary - Some options from --git-completion-helper should only be available in certain conditions (e.g. --continue and friends). __gitcomp_builtin() callers can remove them if the conditions are not met. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nguyễn Thái Ngọc Duy committed Feb 9, 2018 at 18:01 UTC d401f3debc5807092d68c95a89b363b65bbc8947
1 file changed +33
contrib/completion/git-completion.bash
+33
@@ -280,6 +280,39 @@ __gitcomp ()
280 esac
281 }
282
283 +# This function is equivalent to
284 +#
285 +# __gitcomp "$(git xxx --git-completion-helper) ..."
286 +#
287 +# except that the output is cached. Accept 1-3 arguments:
288 +# 1: the git command to execute, this is also the cache key
289 +# 2: extra options to be added on top (e.g. negative forms)
290 +# 3: options to be excluded
291 +__gitcomp_builtin ()
292 +{
293 + # spaces must be replaced with underscore for multi-word
294 + # commands, e.g. "git remote add" becomes remote_add.
295 + local cmd="$1"
296 + local incl="$2"
297 + local excl="$3"
298 +
299 + local var=__gitcomp_builtin_"${cmd/-/_}"
300 + local options
301 + eval "options=\$$var"
302 +
303 + if [ -z "$options" ]; then
304 + # leading and trailing spaces are significant to make
305 + # option removal work correctly.
306 + options=" $(__git ${cmd/_/ } --git-completion-helper) $incl "
307 + for i in $excl; do
308 + options="${options/ $i / }"
309 + done
310 + eval "$var=\"$options\""
311 + fi
312 +
313 + __gitcomp "$options"
314 +}
315 +
316 # Variation of __gitcomp_nl () that appends to the existing list of
317 # completion candidates, COMPREPLY.
318 __gitcomp_nl_append ()