git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Stephen Boyd <bebarino@gmail.com>
To: git@vger.kernel.org
Cc: spearce@spearce.org, szeder@ira.uka.de,
	felipe.contreras@gmail.com, jrnieder@gmail.com
Subject: [PATCH 2/2] completion: Use parse-options raw output for simple long options
Date: Wed, 11 Apr 2012 03:29:25 -0700	[thread overview]
Message-ID: <1334140165-24958-3-git-send-email-bebarino@gmail.com> (raw)
In-Reply-To: <1334140165-24958-1-git-send-email-bebarino@gmail.com>

Now that parse-options supports generating lists of long options for any
parse-optified git program we can remove the hand-coded lists in the
completion script. Replace these lists with code to generate the lists
lazily when a user tab completes that specific command. Unforunately,
doing lazy evalution takes more lines than before, but the benefit is we
reduce the amount of trivial patches to update the script for new and/or
removed options. It also mildly encourages the migration of git commands
to the parse-options API.

Signed-off-by: Stephen Boyd <bebarino@gmail.com>
---

Is there some way to compute these lists with some magical function instead
of duplicating that logic over and over?

 contrib/completion/git-completion.bash |  298 +++++++++++++++++++-------------
 1 file changed, 176 insertions(+), 122 deletions(-)

diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 31f714d..69abbe5 100755
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -917,6 +917,11 @@ __git_list_porcelain_commands ()
 	done
 }
 
+__git_list_command_options ()
+{
+	git $@ --dump-raw-long-options
+}
+
 __git_porcelain_commands=
 __git_compute_porcelain_commands ()
 {
@@ -1027,43 +1032,45 @@ _git_am ()
 	COMPREPLY=()
 }
 
+__git_apply_options=
 _git_apply ()
 {
+	test -n "$__git_apply_options" ||
+	__git_apply_options=$(__git_list_command_options apply)
+
 	case "$cur" in
 	--whitespace=*)
 		__gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
 		return
 		;;
 	--*)
-		__gitcomp "
-			--stat --numstat --summary --check --index
-			--cached --index-info --reverse --reject --unidiff-zero
-			--apply --no-add --exclude=
-			--ignore-whitespace --ignore-space-change
-			--whitespace= --inaccurate-eof --verbose
-			"
+		__gitcomp "$__git_apply_options"
 		return
 	esac
 	COMPREPLY=()
 }
 
+__git_add_options=
 _git_add ()
 {
 	__git_has_doubledash && return
+	test -n "$__git_add_options" ||
+	__git_add_options=$(__git_list_command_options add)
 
 	case "$cur" in
 	--*)
-		__gitcomp "
-			--interactive --refresh --patch --update --dry-run
-			--ignore-errors --intent-to-add
-			"
+		__gitcomp "$__git_add_options"
 		return
 	esac
 	COMPREPLY=()
 }
 
+__git_archive_options=
 _git_archive ()
 {
+	test -n "$__git_archive_options" ||
+	__git_archive_options=$(__git_list_command_options archive)
+
 	case "$cur" in
 	--format=*)
 		__gitcomp "$(git archive --list)" "" "${cur##--format=}"
@@ -1074,10 +1081,7 @@ _git_archive ()
 		return
 		;;
 	--*)
-		__gitcomp "
-			--format= --list --verbose
-			--prefix= --remote= --exec=
-			"
+		__gitcomp "$__git_archive_options"
 		return
 		;;
 	esac
@@ -1109,6 +1113,7 @@ _git_bisect ()
 	esac
 }
 
+__git_branch_options=
 _git_branch ()
 {
 	local i c=1 only_local_ref="n" has_r="n"
@@ -1122,13 +1127,12 @@ _git_branch ()
 		((c++))
 	done
 
+	test -n "$__git_branch_options" ||
+	__git_branch_options=$(__git_list_command_options branch)
+
 	case "$cur" in
 	--*)
-		__gitcomp "
-			--color --no-color --verbose --abbrev= --no-abbrev
-			--track --no-track --contains --merged --no-merged
-			--set-upstream --edit-description --list
-			"
+		__gitcomp "$__git_branch_options"
 		;;
 	*)
 		if [ $only_local_ref = "y" -a $has_r = "n" ]; then
@@ -1160,19 +1164,19 @@ _git_bundle ()
 	esac
 }
 
+__git_checkout_options=
 _git_checkout ()
 {
 	__git_has_doubledash && return
+	test -n "$__git_checkout_options" ||
+	__git_checkout_options=$(__git_list_command_options checkout)
 
 	case "$cur" in
 	--conflict=*)
 		__gitcomp "diff3 merge" "" "${cur##--conflict=}"
 		;;
 	--*)
-		__gitcomp "
-			--quiet --ours --theirs --track --no-track --merge
-			--conflict= --orphan --patch
-			"
+		__gitcomp "$__git_checkout_options"
 		;;
 	*)
 		# check if --track, --no-track, or --no-guess was specified
@@ -1191,11 +1195,15 @@ _git_cherry ()
 	__gitcomp "$(__git_refs)"
 }
 
+__git_cherry_pick_options=
 _git_cherry_pick ()
 {
+	test -n "$__git_cherry_pick_options" ||
+	__git_cherry_pick_options=$(__git_list_command_options cherry-pick)
+
 	case "$cur" in
 	--*)
-		__gitcomp "--edit --no-commit"
+		__gitcomp "$__git_cherry_pick_options"
 		;;
 	*)
 		__gitcomp_nl "$(__git_refs)"
@@ -1203,46 +1211,44 @@ _git_cherry_pick ()
 	esac
 }
 
+__git_clean_options=
 _git_clean ()
 {
 	__git_has_doubledash && return
 
+	test -n "$__git_clean_options" ||
+	__git_clean_options=$(__git_list_command_options clean)
+
 	case "$cur" in
 	--*)
-		__gitcomp "--dry-run --quiet"
+		__gitcomp "$__git_clean_options"
 		return
 		;;
 	esac
 	COMPREPLY=()
 }
 
+__git_clone_options=
 _git_clone ()
 {
+	test -n "$__git_clone_options" ||
+	__git_clone_options=$(__git_list_command_options clone)
+
 	case "$cur" in
 	--*)
-		__gitcomp "
-			--local
-			--no-hardlinks
-			--shared
-			--reference
-			--quiet
-			--no-checkout
-			--bare
-			--mirror
-			--origin
-			--upload-pack
-			--template=
-			--depth
-			"
+		__gitcomp "$__git_clone_options"
 		return
 		;;
 	esac
 	COMPREPLY=()
 }
 
+__git_commit_options=
 _git_commit ()
 {
 	__git_has_doubledash && return
+	test -n "$__git_commit_options" ||
+	__git_commit_options=$(__git_list_command_options commit)
 
 	case "$cur" in
 	--cleanup=*)
@@ -1260,27 +1266,21 @@ _git_commit ()
 		return
 		;;
 	--*)
-		__gitcomp "
-			--all --author= --signoff --verify --no-verify
-			--edit --amend --include --only --interactive
-			--dry-run --reuse-message= --reedit-message=
-			--reset-author --file= --message= --template=
-			--cleanup= --untracked-files --untracked-files=
-			--verbose --quiet --fixup= --squash=
-			"
+		__gitcomp "$__git_commit_options"
 		return
 	esac
 	COMPREPLY=()
 }
 
+__git_describe_options=
 _git_describe ()
 {
+	test -n "$__git_describe_options" ||
+	__git_describe_options=$(__git_list_command_options describe)
+
 	case "$cur" in
 	--*)
-		__gitcomp "
-			--all --tags --contains --abbrev= --candidates=
-			--exact-match --debug --long --match --always
-			"
+		__gitcomp "$__git_describe_options"
 		return
 	esac
 	__gitcomp_nl "$(__git_refs)"
@@ -1343,13 +1343,16 @@ _git_difftool ()
 	__git_complete_file
 }
 
-__git_fetch_options="
-	--quiet --verbose --append --upload-pack --force --keep --depth=
-	--tags --no-tags --all --prune --dry-run
-"
+__git_fetch_options=
+__git_compute_fetch_options ()
+{
+	test -n "$__git_fetch_options" ||
+	__git_fetch_options=$(__git_list_command_options fetch)
+}
 
 _git_fetch ()
 {
+	__git_compute_fetch_options
 	case "$cur" in
 	--*)
 		__gitcomp "$__git_fetch_options"
@@ -1359,8 +1362,12 @@ _git_fetch ()
 	__git_complete_remote_or_refspec
 }
 
+__git_format_patch_options=
 _git_format_patch ()
 {
+	test -n "$__git_format_patch_options" ||
+	__git_format_patch_options=$(__git_list_command_options format-patch)
+
 	case "$cur" in
 	--thread=*)
 		__gitcomp "
@@ -1369,46 +1376,37 @@ _git_format_patch ()
 		return
 		;;
 	--*)
-		__gitcomp "
-			--stdout --attach --no-attach --thread --thread=
-			--output-directory
-			--numbered --start-number
-			--numbered-files
-			--keep-subject
-			--signoff --signature --no-signature
-			--in-reply-to= --cc=
-			--full-index --binary
-			--not --all
-			--cover-letter
-			--no-prefix --src-prefix= --dst-prefix=
-			--inline --suffix= --ignore-if-in-upstream
-			--subject-prefix=
-			"
+		__gitcomp "$__git_format_patch_options"
 		return
 		;;
 	esac
 	__git_complete_revlist
 }
 
+__git_fsck_options=
 _git_fsck ()
 {
+	test -n "$__git_fsck_options" ||
+	__git_fsck_options=$(__git_list_command_options fsck)
+
 	case "$cur" in
 	--*)
-		__gitcomp "
-			--tags --root --unreachable --cache --no-reflogs --full
-			--strict --verbose --lost-found
-			"
+		__gitcomp "$__git_fsck_options"
 		return
 		;;
 	esac
 	COMPREPLY=()
 }
 
+__git_gc_options=
 _git_gc ()
 {
+	test -n "$__git_gc_options" ||
+	__git_gc_options=$(__git_list_command_options gc)
+
 	case "$cur" in
 	--*)
-		__gitcomp "--prune --aggressive"
+		__gitcomp "$__git_gc_options"
 		return
 		;;
 	esac
@@ -1424,24 +1422,17 @@ __git_match_ctag() {
 	awk "/^${1////\\/}/ { print \$1 }" "$2"
 }
 
+__git_grep_options=
 _git_grep ()
 {
 	__git_has_doubledash && return
 
+	test -n "$__git_grep_options" ||
+	__git_grep_options=$(__git_list_command_options grep)
+
 	case "$cur" in
 	--*)
-		__gitcomp "
-			--cached
-			--text --ignore-case --word-regexp --invert-match
-			--full-name --line-number
-			--extended-regexp --basic-regexp --fixed-strings
-			--perl-regexp
-			--files-with-matches --name-only
-			--files-without-match
-			--max-depth
-			--count
-			--and --or --not --all-match
-			"
+		__gitcomp "$__git_grep_options"
 		return
 		;;
 	esac
@@ -1458,11 +1449,15 @@ _git_grep ()
 	__gitcomp_nl "$(__git_refs)"
 }
 
+__git_help_options=
 _git_help ()
 {
+	test -n "$__git_help_options" ||
+	__git_help_options=$(__git_list_command_options help)
+
 	case "$cur" in
 	--*)
-		__gitcomp "--all --info --man --web"
+		__gitcomp "$__git_help_options"
 		return
 		;;
 	esac
@@ -1475,8 +1470,12 @@ _git_help ()
 		"
 }
 
+__git_init_options=
 _git_init ()
 {
+	test -n "$__git_init_options" ||
+	__git_init_options=$(__git_list_command_options init)
+
 	case "$cur" in
 	--shared=*)
 		__gitcomp "
@@ -1485,26 +1484,24 @@ _git_init ()
 		return
 		;;
 	--*)
-		__gitcomp "--quiet --bare --template= --shared --shared="
+		__gitcomp "$__git_init_options"
 		return
 		;;
 	esac
 	COMPREPLY=()
 }
 
+__git_ls_files_options=
 _git_ls_files ()
 {
 	__git_has_doubledash && return
 
+	test -n "$__git_ls_files_options" ||
+	__git_ls_files_options=$(__git_list_command_options ls-files)
+
 	case "$cur" in
 	--*)
-		__gitcomp "--cached --deleted --modified --others --ignored
-			--stage --directory --no-empty-directory --unmerged
-			--killed --exclude= --exclude-from=
-			--exclude-per-directory= --exclude-standard
-			--error-unmatch --with-tree= --full-name
-			--abbrev --ignored --exclude-per-directory
-			"
+		__gitcomp "$__git_ls_files_options"
 		return
 		;;
 	esac
@@ -1516,8 +1513,18 @@ _git_ls_remote ()
 	__gitcomp_nl "$(__git_remotes)"
 }
 
+__git_ls_tree_options=
 _git_ls_tree ()
 {
+	test -n "$__git_ls_tree_options" ||
+	__git_ls_tree_options=$(__git_list_command_options ls-tree)
+
+	case "$cur" in
+	--*)
+		__gitcomp "$__git_ls_tree_options"
+		return
+		;;
+	esac
 	__git_complete_file
 }
 
@@ -1595,14 +1602,17 @@ _git_log ()
 	__git_complete_revlist
 }
 
-__git_merge_options="
-	--no-commit --no-stat --log --no-log --squash --strategy
-	--commit --stat --no-squash --ff --no-ff --ff-only --edit --no-edit
-"
+__git_merge_options=
+__git_compute_merge_options ()
+{
+	test -n "$__git_merge_options" ||
+	__git_merge_options=$(__git_list_command_options merge)
+}
 
 _git_merge ()
 {
 	__git_complete_strategy && return
+	__git_compute_merge_options
 
 	case "$cur" in
 	--*)
@@ -1632,30 +1642,50 @@ _git_merge_base ()
 	__gitcomp_nl "$(__git_refs)"
 }
 
+__git_mv_options=
 _git_mv ()
 {
+	test -n "$__git_mv_options" ||
+	__git_mv_options=$(__git_list_command_options mv)
+
 	case "$cur" in
 	--*)
-		__gitcomp "--dry-run"
+		__gitcomp "$__git_mv_options"
 		return
 		;;
 	esac
 	COMPREPLY=()
 }
 
+__git_name_rev_options=
 _git_name_rev ()
 {
-	__gitcomp "--tags --all --stdin"
+	test -n "$__git_name_rev_options" ||
+	__git_name_rev_options=$(__git_list_command_options name-rev)
+
+	case "$cur" in
+	--*)
+		__gitcomp "$__git_name_rev_options"
+		return
+		;;
+	esac
 }
 
+__git_notes_options=
+__git_notes_add_options=
+__git_notes_copy_options=
+__git_notes_prune_options=
 _git_notes ()
 {
 	local subcommands='add append copy edit list prune remove show'
 	local subcommand="$(__git_find_on_cmdline "$subcommands")"
 
+	test -n "$__git_notes_options" ||
+	__git_notes_options=$(__git_list_command_options notes)
+
 	case "$subcommand,$cur" in
 	,--*)
-		__gitcomp '--ref'
+		__gitcomp "$__git_notes_options"
 		;;
 	,*)
 		case "${words[cword-1]}" in
@@ -1672,14 +1702,19 @@ _git_notes ()
 		__gitcomp_nl "$(__git_refs)" "" "${cur#*=}"
 		;;
 	add,--*|append,--*)
-		__gitcomp '--file= --message= --reedit-message=
-				--reuse-message='
+		test -n "$__git_notes_add_options" ||
+		__git_notes_add_options=$(__git_list_command_options notes add)
+		__gitcomp "$__git_notes_add_options"
 		;;
 	copy,--*)
-		__gitcomp '--stdin'
+		test -n "$__git_notes_copy_options" ||
+		__git_notes_copy_options=$(__git_list_command_options notes copy)
+		__gitcomp "$__git_notes_copy_options"
 		;;
 	prune,--*)
-		__gitcomp '--dry-run --verbose'
+		test -n "$__git_notes_prune_options" ||
+		__git_notes_prune_options=$(__git_list_command_options notes prune)
+		__gitcomp "$__git_notes_prune_options"
 		;;
 	prune,*)
 		;;
@@ -1699,6 +1734,9 @@ _git_pull ()
 {
 	__git_complete_strategy && return
 
+	__git_compute_merge_options
+	__git_compute_fetch_options
+
 	case "$cur" in
 	--*)
 		__gitcomp "
@@ -1712,8 +1750,12 @@ _git_pull ()
 	__git_complete_remote_or_refspec
 }
 
+__git_push_options=
 _git_push ()
 {
+	test -n "$__git_push_options" ||
+	__git_push_options=$(__git_list_command_options push)
+
 	case "$prev" in
 	--repo)
 		__gitcomp_nl "$(__git_remotes)"
@@ -1725,10 +1767,7 @@ _git_push ()
 		return
 		;;
 	--*)
-		__gitcomp "
-			--all --mirror --tags --dry-run --force --verbose
-			--receive-pack= --repo= --set-upstream
-		"
+		__gitcomp "$__git_push_options"
 		return
 		;;
 	esac
@@ -2313,37 +2352,49 @@ _git_replace ()
 	__gitcomp_nl "$(__git_refs)"
 }
 
+__git_reset_options=
 _git_reset ()
 {
 	__git_has_doubledash && return
 
+	test -n "$__git_reset_options" ||
+	__git_reset_options=$(__git_list_command_options reset)
+
 	case "$cur" in
 	--*)
-		__gitcomp "--merge --mixed --hard --soft --patch"
+		__gitcomp "$__git_reset_options"
 		return
 		;;
 	esac
 	__gitcomp_nl "$(__git_refs)"
 }
 
+__git_revert_options=
 _git_revert ()
 {
+	test -n "$__git_revert_options" ||
+	__git_revert_options=$(__git_list_command_options revert)
+
 	case "$cur" in
 	--*)
-		__gitcomp "--edit --mainline --no-edit --no-commit --signoff"
+		__gitcomp "$__git_revert_options"
 		return
 		;;
 	esac
 	__gitcomp_nl "$(__git_refs)"
 }
 
+__git_rm_options=
 _git_rm ()
 {
 	__git_has_doubledash && return
 
+	test -n "$__git_rm_options" ||
+	__git_rm_options=$(__git_list_command_options rm)
+
 	case "$cur" in
 	--*)
-		__gitcomp "--cached --dry-run --ignore-unmatch --quiet"
+		__gitcomp "$__git_rm_options"
 		return
 		;;
 	esac
@@ -2367,10 +2418,14 @@ _git_shortlog ()
 	__git_complete_revlist
 }
 
+__git_show_options=
 _git_show ()
 {
 	__git_has_doubledash && return
 
+	test -n "$__git_show_options" ||
+	__git_show_options=$(__git_list_command_options show)
+
 	case "$cur" in
 	--pretty=*|--format=*)
 		__gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases)
@@ -2378,7 +2433,7 @@ _git_show ()
 		return
 		;;
 	--*)
-		__gitcomp "--pretty= --format= --abbrev-commit --oneline
+		__gitcomp "$__git_show_options
 			$__git_diff_common_options
 			"
 		return
@@ -2387,16 +2442,15 @@ _git_show ()
 	__git_complete_file
 }
 
+__git_show_branch_options=
 _git_show_branch ()
 {
+	test -n "$__git_show_branch_options" ||
+	__git_show_branch_options=$(__git_list_command_options show-branch)
+
 	case "$cur" in
 	--*)
-		__gitcomp "
-			--all --remotes --topo-order --current --more=
-			--list --independent --merge-base --no-name
-			--color --no-color
-			--sha1-name --sparse --topics --reflog
-			"
+		__gitcomp "$__git_show_branch_options"
 		return
 		;;
 	esac
-- 
1.7.10.128.g7945c.dirty

  parent reply	other threads:[~2012-04-11 10:29 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-04-11 10:29 [PATCH 0/2] Dynamic long options for bash completion Stephen Boyd
2012-04-11 10:29 ` [PATCH 1/2] parse-options: Add support for dumping out long options Stephen Boyd
2012-04-11 10:51   ` Felipe Contreras
2012-04-12  7:42     ` Stephen Boyd
2012-04-11 12:59   ` Jonathan Nieder
2012-04-12  7:02     ` Stephen Boyd
2012-04-11 14:06   ` SZEDER Gábor
2012-04-12  7:12     ` Stephen Boyd
2012-04-15 12:49       ` SZEDER Gábor
2012-04-15 19:23         ` Junio C Hamano
2012-04-11 10:29 ` Stephen Boyd [this message]
2012-04-11 13:09   ` [PATCH 2/2] completion: Use parse-options raw output for simple " Jonathan Nieder
2012-04-11 13:56   ` SZEDER Gábor
2012-04-17 10:44   ` SZEDER Gábor

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1334140165-24958-3-git-send-email-bebarino@gmail.com \
    --to=bebarino@gmail.com \
    --cc=felipe.contreras@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=jrnieder@gmail.com \
    --cc=spearce@spearce.org \
    --cc=szeder@ira.uka.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).