* [PATCH 0/2] Dynamic long options for bash completion @ 2012-04-11 10:29 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:29 ` [PATCH 2/2] completion: Use parse-options raw output for simple " Stephen Boyd 0 siblings, 2 replies; 14+ messages in thread From: Stephen Boyd @ 2012-04-11 10:29 UTC (permalink / raw) To: git; +Cc: spearce, szeder, felipe.contreras, jrnieder I've been meaning to do this for a while. I realize we gain some more lines but it seems better to just generate these lists automatically instead of managing them by hand. Stephen Boyd (2): parse-options: Add support for dumping out long options completion: Use parse-options raw output for simple long options contrib/completion/git-completion.bash | 298 +++++++++++++++++++------------- parse-options.c | 41 +++++ 2 files changed, 217 insertions(+), 122 deletions(-) -- 1.7.10.128.g7945c.dirty ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 1/2] parse-options: Add support for dumping out long options 2012-04-11 10:29 [PATCH 0/2] Dynamic long options for bash completion Stephen Boyd @ 2012-04-11 10:29 ` Stephen Boyd 2012-04-11 10:51 ` Felipe Contreras ` (2 more replies) 2012-04-11 10:29 ` [PATCH 2/2] completion: Use parse-options raw output for simple " Stephen Boyd 1 sibling, 3 replies; 14+ messages in thread From: Stephen Boyd @ 2012-04-11 10:29 UTC (permalink / raw) To: git; +Cc: spearce, szeder, felipe.contreras, jrnieder The bash completion script wants to know what the long options are for a certain command at runtime. Add a magical long option that nobody could possibly ever use (--dump-raw-long-options) to get this information. Some example output: $ git clone --dump-raw-long-options --no-verbose --no-quiet --progress --no-progress --no-checkout --checkout --bare --no-bare --mirror --no-mirror --local --no-local --no-hardlinks --hardlinks --shared --no-shared --recursive --no-recursive --recurse-submodules --no-recurse-submodules --template= --no-template --reference= --no-reference --origin= --no-origin --branch= --no-branch --upload-pack= --no-upload-pack --depth= --no-depth --single-branch --no-single-branch --separate-git-dir= --no-separate-git-dir --config= --no-config Signed-off-by: Stephen Boyd <bebarino@gmail.com> --- The name can be anything. This seemed sufficiently obscure. parse-options.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/parse-options.c b/parse-options.c index 850cfa7..6c37497 100644 --- a/parse-options.c +++ b/parse-options.c @@ -364,6 +364,45 @@ static int usage_with_options_internal(struct parse_opt_ctx_t *, const char * const *, const struct option *, int, int); +static int parse_options_raw(const struct option *opts) +{ + for (; opts->type != OPTION_END; opts++) { + if (opts->flags & PARSE_OPT_HIDDEN) + continue; + if (!opts->long_name) + continue; + switch (opts->type) { + case OPTION_BIT: + case OPTION_NEGBIT: + case OPTION_COUNTUP: + case OPTION_SET_INT: + case OPTION_SET_PTR: + fprintf(stdout, "--%s ", opts->long_name); + break; + case OPTION_LOWLEVEL_CALLBACK: + case OPTION_STRING: + case OPTION_FILENAME: + case OPTION_INTEGER: + case OPTION_CALLBACK: + if (opts->flags & PARSE_OPT_OPTARG) + fprintf(stdout, "--%s ", opts->long_name); + else if (!(opts->flags & PARSE_OPT_NOARG)) + fprintf(stdout, "--%s= ", opts->long_name); + break; + default: + continue; + } + if (!(opts->flags & PARSE_OPT_NONEG)) { + if (!prefixcmp(opts->long_name, "no-")) + fprintf(stdout, "--%s ", opts->long_name + 3); + else + fprintf(stdout, "--no-%s ", opts->long_name); + } + } + + return PARSE_OPT_HELP; +} + int parse_options_step(struct parse_opt_ctx_t *ctx, const struct option *options, const char * const usagestr[]) @@ -431,6 +470,8 @@ int parse_options_step(struct parse_opt_ctx_t *ctx, return usage_with_options_internal(ctx, usagestr, options, 1, 0); if (internal_help && !strcmp(arg + 2, "help")) return parse_options_usage(ctx, usagestr, options, 0); + if (!strcmp(arg + 2, "dump-raw-long-options")) + return parse_options_raw(options); switch (parse_long_opt(ctx, arg + 2, options)) { case -1: return parse_options_usage(ctx, usagestr, options, 1); -- 1.7.10.128.g7945c.dirty ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] parse-options: Add support for dumping out long options 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-11 14:06 ` SZEDER Gábor 2 siblings, 1 reply; 14+ messages in thread From: Felipe Contreras @ 2012-04-11 10:51 UTC (permalink / raw) To: Stephen Boyd; +Cc: git, spearce, szeder, jrnieder On Wed, Apr 11, 2012 at 1:29 PM, Stephen Boyd <bebarino@gmail.com> wrote: > The bash completion script wants to know what the long options are for a > certain command at runtime. Add a magical long option that nobody could > possibly ever use (--dump-raw-long-options) to get this information. I thought about doing this, but I would like more than just dumping the options. In zsh one can show more than just the options; each option can have a description. I was thinking on something like 'git help --raw'. We also need something like that to list all the plumbing commands, and options for certain options, like merge strategies, and so on. Perhaps it would even make sense to have a new 'git raw-help' command. Cheers. -- Felipe Contreras ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] parse-options: Add support for dumping out long options 2012-04-11 10:51 ` Felipe Contreras @ 2012-04-12 7:42 ` Stephen Boyd 0 siblings, 0 replies; 14+ messages in thread From: Stephen Boyd @ 2012-04-12 7:42 UTC (permalink / raw) To: Felipe Contreras; +Cc: git, spearce, szeder, jrnieder On 04/11/2012 03:51 AM, Felipe Contreras wrote: > On Wed, Apr 11, 2012 at 1:29 PM, Stephen Boyd <bebarino@gmail.com> wrote: >> The bash completion script wants to know what the long options are for a >> certain command at runtime. Add a magical long option that nobody could >> possibly ever use (--dump-raw-long-options) to get this information. > > I thought about doing this, but I would like more than just dumping > the options. In zsh one can show more than just the options; each > option can have a description. Cool. I don't use zsh but it sounds interesting. Perhaps the magical long option should grow an optional argument? i.e. --dump-raw-long-option=zsh which would dump the options in a format that zsh would like? Alternatively, we can make a tiny option description grammar that's easily parsed. I probably won't have time for this any time soon though. > > I was thinking on something like 'git help --raw'. We also need > something like that to list all the plumbing commands, and options for > certain options, like merge strategies, and so on. Perhaps it would > even make sense to have a new 'git raw-help' command. > I'd like to avoid tying the long option stuff to git help so that other users of parse-options besides git (perhaps perf?) get the dumping support for free. Actually it works well for 'git notes <subcommand>' right now so it probably has to stay tied to each git command. Plus I think we've covered merge strategies and command lists already so I don't know how useful 'git help --raw' would be. I have been pondering ways to get all the possible config keys dynamically. That would remove a huge list (~2000 lines) in the completion script that always needs updating. Doing that would probably require some sort of grep over all the source files and a special key comparison function to look for (#define CONFIG_MATCH strcmp might work). Even then I don't know how we would handle color.branch.* and similar things. Maybe we would just do those by hand. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] parse-options: Add support for dumping out long options 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-11 12:59 ` Jonathan Nieder 2012-04-12 7:02 ` Stephen Boyd 2012-04-11 14:06 ` SZEDER Gábor 2 siblings, 1 reply; 14+ messages in thread From: Jonathan Nieder @ 2012-04-11 12:59 UTC (permalink / raw) To: Stephen Boyd; +Cc: git, spearce, szeder, felipe.contreras Stephen Boyd wrote: > The bash completion script wants to know what the long options are for a > certain command at runtime. Add a magical long option that nobody could > possibly ever use (--dump-raw-long-options) to get this information. Neat. Probably should be documented: diff --git i/Documentation/gitcli.txt w/Documentation/gitcli.txt index f734f97b..0de074ec 100644 --- i/Documentation/gitcli.txt +++ w/Documentation/gitcli.txt @@ -96,6 +96,11 @@ usage: git describe [options] <committish>* are deprecated, and such options are hidden from the default usage. This option gives the full list of options. +--dump-raw-long-options:: + prints a space-separated list of supported options, including + negated `--no-<foo>` forms. Long options taking an argument are + printed with a trailing equal sign, as in "`--depth=`". + Negating options ~~~~~~~~~~~~~~~~ ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] parse-options: Add support for dumping out long options 2012-04-11 12:59 ` Jonathan Nieder @ 2012-04-12 7:02 ` Stephen Boyd 0 siblings, 0 replies; 14+ messages in thread From: Stephen Boyd @ 2012-04-12 7:02 UTC (permalink / raw) To: Jonathan Nieder; +Cc: git, spearce, szeder, felipe.contreras On 04/11/2012 05:59 AM, Jonathan Nieder wrote: > Stephen Boyd wrote: > >> The bash completion script wants to know what the long options are for a >> certain command at runtime. Add a magical long option that nobody could >> possibly ever use (--dump-raw-long-options) to get this information. > > Neat. Probably should be documented: > > diff --git i/Documentation/gitcli.txt w/Documentation/gitcli.txt > index f734f97b..0de074ec 100644 > --- i/Documentation/gitcli.txt > +++ w/Documentation/gitcli.txt > @@ -96,6 +96,11 @@ usage: git describe [options] <committish>* > are deprecated, and such options are hidden from the default usage. This > option gives the full list of options. > > +--dump-raw-long-options:: > + prints a space-separated list of supported options, including > + negated `--no-<foo>` forms. Long options taking an argument are > + printed with a trailing equal sign, as in "`--depth=`". > + > > Negating options > ~~~~~~~~~~~~~~~~ Thanks. Squashed in. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] parse-options: Add support for dumping out long options 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-11 12:59 ` Jonathan Nieder @ 2012-04-11 14:06 ` SZEDER Gábor 2012-04-12 7:12 ` Stephen Boyd 2 siblings, 1 reply; 14+ messages in thread From: SZEDER Gábor @ 2012-04-11 14:06 UTC (permalink / raw) To: Stephen Boyd; +Cc: git, spearce, felipe.contreras, jrnieder Hi, On Wed, Apr 11, 2012 at 03:29:24AM -0700, Stephen Boyd wrote: > The bash completion script wants to know what the long options are for a > certain command at runtime. Add a magical long option that nobody could > possibly ever use (--dump-raw-long-options) to get this information. > > Some example output: > > $ git clone --dump-raw-long-options > --no-verbose --no-quiet --progress --no-progress --no-checkout > --checkout --bare --no-bare --mirror --no-mirror --local --no-local > --no-hardlinks --hardlinks --shared --no-shared --recursive > --no-recursive --recurse-submodules --no-recurse-submodules --template= > --no-template --reference= --no-reference --origin= --no-origin > --branch= --no-branch --upload-pack= --no-upload-pack --depth= > --no-depth --single-branch --no-single-branch --separate-git-dir= > --no-separate-git-dir --config= --no-config > I think this is a good idea; there are many completion functions that fell behind and lack an option or two. However, in the completion script we deliberately miss options like '--force', but with your series such options will be offered, too. Best, Gábor ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] parse-options: Add support for dumping out long options 2012-04-11 14:06 ` SZEDER Gábor @ 2012-04-12 7:12 ` Stephen Boyd 2012-04-15 12:49 ` SZEDER Gábor 0 siblings, 1 reply; 14+ messages in thread From: Stephen Boyd @ 2012-04-12 7:12 UTC (permalink / raw) To: SZEDER Gábor; +Cc: git, spearce, felipe.contreras, jrnieder On 04/11/2012 07:06 AM, SZEDER Gábor wrote: > On Wed, Apr 11, 2012 at 03:29:24AM -0700, Stephen Boyd wrote: >> The bash completion script wants to know what the long options are for a >> certain command at runtime. Add a magical long option that nobody could >> possibly ever use (--dump-raw-long-options) to get this information. >> >> Some example output: >> >> $ git clone --dump-raw-long-options >> --no-verbose --no-quiet --progress --no-progress --no-checkout >> --checkout --bare --no-bare --mirror --no-mirror --local --no-local >> --no-hardlinks --hardlinks --shared --no-shared --recursive >> --no-recursive --recurse-submodules --no-recurse-submodules --template= >> --no-template --reference= --no-reference --origin= --no-origin >> --branch= --no-branch --upload-pack= --no-upload-pack --depth= >> --no-depth --single-branch --no-single-branch --separate-git-dir= >> --no-separate-git-dir --config= --no-config >> > > I think this is a good idea; there are many completion functions that > fell behind and lack an option or two. > > However, in the completion script we deliberately miss options like > '--force', but with your series such options will be offered, too. > Hm.. I meant to say something about that in the commit text. I'm willing to live with wading through some more options when I tab complete if it means the script never falls out of date with my git installation. I can envision us putting more smarts into the parse options code to hide certain options from the raw dump but I'm not sure how useful that is. Do we need that? ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] parse-options: Add support for dumping out long options 2012-04-12 7:12 ` Stephen Boyd @ 2012-04-15 12:49 ` SZEDER Gábor 2012-04-15 19:23 ` Junio C Hamano 0 siblings, 1 reply; 14+ messages in thread From: SZEDER Gábor @ 2012-04-15 12:49 UTC (permalink / raw) To: Stephen Boyd; +Cc: git, spearce, felipe.contreras, jrnieder Hi, On Thu, Apr 12, 2012 at 12:12:32AM -0700, Stephen Boyd wrote: > On 04/11/2012 07:06 AM, SZEDER Gábor wrote: > > On Wed, Apr 11, 2012 at 03:29:24AM -0700, Stephen Boyd wrote: > >> The bash completion script wants to know what the long options are for a > >> certain command at runtime. Add a magical long option that nobody could > >> possibly ever use (--dump-raw-long-options) to get this information. > >> > >> Some example output: > >> > >> $ git clone --dump-raw-long-options > >> --no-verbose --no-quiet --progress --no-progress --no-checkout > >> --checkout --bare --no-bare --mirror --no-mirror --local --no-local > >> --no-hardlinks --hardlinks --shared --no-shared --recursive > >> --no-recursive --recurse-submodules --no-recurse-submodules --template= > >> --no-template --reference= --no-reference --origin= --no-origin > >> --branch= --no-branch --upload-pack= --no-upload-pack --depth= > >> --no-depth --single-branch --no-single-branch --separate-git-dir= > >> --no-separate-git-dir --config= --no-config > >> > > > > I think this is a good idea; there are many completion functions that > > fell behind and lack an option or two. > > > > However, in the completion script we deliberately miss options like > > '--force', but with your series such options will be offered, too. > > > > Hm.. I meant to say something about that in the commit text. I'm willing > to live with wading through some more options when I tab complete if it > means the script never falls out of date with my git installation. > > I can envision us putting more smarts into the parse options code to > hide certain options from the raw dump but I'm not sure how useful that > is. Do we need that? It's not just about wading through some more options. Parse options already has the PARSE_OPT_HIDDEN flag to omit an option from the default usage. Your patch already respects that option, so e.g. 'git commit --<TAB>' won't offer '--allow-empty', which is meant for foreign SCM interface scripts. This is good. However, '--force' is different, because it should be shown in the default usage, but since it's a "dangerous" option it should be use with great care. That's the reason the completion script doesn't offer it for any of the commands. I'm not sure whether there are any such options besides '--force', though. If that is the only one, then maybe this is all we need: diff --git a/parse-options.c b/parse-options.c index 6c37497c..1a2b0328 100644 --- a/parse-options.c +++ b/parse-options.c @@ -371,6 +371,8 @@ static int parse_options_raw(const struct option *opts) continue; if (!opts->long_name) continue; + if (!strcmp(opts->long_name, "force")) + continue; switch (opts->type) { case OPTION_BIT: case OPTION_NEGBIT: Best, Gábor ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 1/2] parse-options: Add support for dumping out long options 2012-04-15 12:49 ` SZEDER Gábor @ 2012-04-15 19:23 ` Junio C Hamano 0 siblings, 0 replies; 14+ messages in thread From: Junio C Hamano @ 2012-04-15 19:23 UTC (permalink / raw) To: SZEDER Gábor; +Cc: Stephen Boyd, git, spearce, felipe.contreras, jrnieder SZEDER Gábor <szeder@ira.uka.de> writes: > Parse options already has the PARSE_OPT_HIDDEN flag to omit an option > from the default usage. Your patch already respects that option, so > e.g. 'git commit --<TAB>' won't offer '--allow-empty', which is meant > for foreign SCM interface scripts. This is good. > > However, '--force' is different,... Don't we have enough bits in PARSE_OPT_* namespace so that we can spare one for PARSE_OPT_OMIT_FROM_COMPLETION? ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 2/2] completion: Use parse-options raw output for simple long options 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:29 ` Stephen Boyd 2012-04-11 13:09 ` Jonathan Nieder ` (2 more replies) 1 sibling, 3 replies; 14+ messages in thread From: Stephen Boyd @ 2012-04-11 10:29 UTC (permalink / raw) To: git; +Cc: spearce, szeder, felipe.contreras, jrnieder 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 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 2/2] completion: Use parse-options raw output for simple long options 2012-04-11 10:29 ` [PATCH 2/2] completion: Use parse-options raw output for simple " Stephen Boyd @ 2012-04-11 13:09 ` Jonathan Nieder 2012-04-11 13:56 ` SZEDER Gábor 2012-04-17 10:44 ` SZEDER Gábor 2 siblings, 0 replies; 14+ messages in thread From: Jonathan Nieder @ 2012-04-11 13:09 UTC (permalink / raw) To: Stephen Boyd; +Cc: git, spearce, szeder, felipe.contreras Stephen Boyd wrote: > Is there some way to compute these lists with some magical function instead > of duplicating that logic over and over? Maybe roughly like this. for command in $porcelain do eval "__git_${command//-/_}_options=" done __git_complete_for_command () { local options local options_var="__git_${command//-/_}_options" eval "options=\$$options_var" if test -z "$options" then eval "$options_var=\$(__git_list_command_options \$command)" eval "options=\$$options_var" fi ... } _git () { ... __git_complete_for_command "$command" } Jonathan ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/2] completion: Use parse-options raw output for simple long options 2012-04-11 10:29 ` [PATCH 2/2] completion: Use parse-options raw output for simple " Stephen Boyd 2012-04-11 13:09 ` Jonathan Nieder @ 2012-04-11 13:56 ` SZEDER Gábor 2012-04-17 10:44 ` SZEDER Gábor 2 siblings, 0 replies; 14+ messages in thread From: SZEDER Gábor @ 2012-04-11 13:56 UTC (permalink / raw) To: Stephen Boyd; +Cc: git, spearce, szeder, felipe.contreras, jrnieder Hi, On Wed, Apr 11, 2012 at 03:29:25AM -0700, Stephen Boyd wrote: > 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? Maybe a function like this: __git_compute_command_options () { local varname="__git_${@//[ -]/_}_options" eval "test -n \"\$$varname\" || $varname=\"$(git $@ --dump-raw-long-options)\"" } And then in each completion function just need to call this function with the command (and possibly subcommand) as parameter: __git_compute_command_options add Best, Gábor ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/2] completion: Use parse-options raw output for simple long options 2012-04-11 10:29 ` [PATCH 2/2] completion: Use parse-options raw output for simple " Stephen Boyd 2012-04-11 13:09 ` Jonathan Nieder 2012-04-11 13:56 ` SZEDER Gábor @ 2012-04-17 10:44 ` SZEDER Gábor 2 siblings, 0 replies; 14+ messages in thread From: SZEDER Gábor @ 2012-04-17 10:44 UTC (permalink / raw) To: Stephen Boyd; +Cc: git, spearce, felipe.contreras, jrnieder Hi Stephen, On Wed, Apr 11, 2012 at 03:29:25AM -0700, Stephen Boyd wrote: > 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. > +__git_list_command_options () > +{ > + git $@ --dump-raw-long-options > +} Attempting option completion for the first time for commands requiring a repository to work (e.g. 'add', 'branch', 'checkout', etc.) outside of a git repository produces a 'fatal: not a git repository' error. These commands require a repository for '--dump-raw-long-options', too, otherwise they error out in __git_list_command_options(). So at least we'll need git $@ --dump-raw-long-options 2> /dev/null to silence that error, but even then the user won't get any options. Now, I don't think that getting a list of options is that useful at that point, because the command will error out anyway (except when the user explicitly specifies the paths to the repo and work tree), but it's a side effect nonetheless, because it worked before. Computing the long options for commands not requiring a repository (e.g. 'clone', 'archive', 'help', etc.) works properly even for the first time and outside of a repository. Best, Gábor ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2012-04-17 10:44 UTC | newest] Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 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 ` [PATCH 2/2] completion: Use parse-options raw output for simple " Stephen Boyd 2012-04-11 13:09 ` Jonathan Nieder 2012-04-11 13:56 ` SZEDER Gábor 2012-04-17 10:44 ` SZEDER Gábor
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.