diff options
author | Johannes Altmanninger <aclopte@gmail.com> | 2021-01-24 14:05:40 +0100 |
---|---|---|
committer | Michael Muré <batolettre@gmail.com> | 2022-05-01 10:54:13 +0200 |
commit | bc6ba02bd84fc3bd86c61e89c16c400dfef01623 (patch) | |
tree | d6a88de7569493795544eedeb962a1dc859b8e71 | |
parent | 8ee333582ff82d0df971309e94946f2f6e69475b (diff) | |
download | git-bug-bc6ba02bd84fc3bd86c61e89c16c400dfef01623.tar.gz |
Add command-specific argument completions
Complete bug IDs, bridges, users, labels where appropriate.
This works in bash and fish. ZSH is not yet supported by Cobra.
In fish, descriptions (the part of a completion after the "\t") are shown
as completion label, and can be searched with Ctrl+S.
Reproduce with
fish -C 'source misc/fish_completion/git-bug'
git bug select ^I
(tested with fish version 3.3.1)
Also works with bash, but only for "git-bug" (with the dash)
bash --rcfile <(echo source misc/bash_completion/git-bug)
git-bug select ^I
Closes #493
-rw-r--r-- | commands/bridge_auth_addtoken.go | 2 | ||||
-rw-r--r-- | commands/bridge_auth_rm.go | 3 | ||||
-rw-r--r-- | commands/bridge_auth_show.go | 3 | ||||
-rw-r--r-- | commands/bridge_configure.go | 1 | ||||
-rw-r--r-- | commands/bridge_pull.go | 3 | ||||
-rw-r--r-- | commands/bridge_push.go | 3 | ||||
-rw-r--r-- | commands/bridge_rm.go | 3 | ||||
-rw-r--r-- | commands/comment.go | 1 | ||||
-rw-r--r-- | commands/comment_add.go | 1 | ||||
-rw-r--r-- | commands/helper_completion.go | 350 | ||||
-rw-r--r-- | commands/label.go | 1 | ||||
-rw-r--r-- | commands/label_add.go | 1 | ||||
-rw-r--r-- | commands/label_rm.go | 1 | ||||
-rw-r--r-- | commands/ls.go | 11 | ||||
-rw-r--r-- | commands/pull.go | 1 | ||||
-rw-r--r-- | commands/push.go | 1 | ||||
-rw-r--r-- | commands/rm.go | 1 | ||||
-rw-r--r-- | commands/select.go | 1 | ||||
-rw-r--r-- | commands/show.go | 6 | ||||
-rw-r--r-- | commands/status.go | 1 | ||||
-rw-r--r-- | commands/title.go | 1 | ||||
-rw-r--r-- | commands/title_edit.go | 1 | ||||
-rw-r--r-- | commands/user.go | 6 | ||||
-rw-r--r-- | commands/user_adopt.go | 1 | ||||
-rw-r--r-- | commands/user_ls.go | 1 | ||||
-rw-r--r-- | misc/bash_completion/git-bug | 77 |
26 files changed, 475 insertions, 7 deletions
diff --git a/commands/bridge_auth_addtoken.go b/commands/bridge_auth_addtoken.go index c0458fda..dfdc66b6 100644 --- a/commands/bridge_auth_addtoken.go +++ b/commands/bridge_auth_addtoken.go @@ -41,10 +41,12 @@ func newBridgeAuthAddTokenCommand() *cobra.Command { flags.StringVarP(&options.target, "target", "t", "", fmt.Sprintf("The target of the bridge. Valid values are [%s]", strings.Join(bridge.Targets(), ","))) + cmd.RegisterFlagCompletionFunc("target", completeFrom(bridge.Targets())) flags.StringVarP(&options.login, "login", "l", "", "The login in the remote bug-tracker") flags.StringVarP(&options.user, "user", "u", "", "The user to add the token to. Default is the current user") + cmd.RegisterFlagCompletionFunc("user", completeUser(env)) return cmd } diff --git a/commands/bridge_auth_rm.go b/commands/bridge_auth_rm.go index fa73ad11..a28057de 100644 --- a/commands/bridge_auth_rm.go +++ b/commands/bridge_auth_rm.go @@ -16,7 +16,8 @@ func newBridgeAuthRm() *cobra.Command { RunE: func(cmd *cobra.Command, args []string) error { return runBridgeAuthRm(env, args) }, - Args: cobra.ExactArgs(1), + Args: cobra.ExactArgs(1), + ValidArgsFunction: completeBridgeAuth(env), } return cmd diff --git a/commands/bridge_auth_show.go b/commands/bridge_auth_show.go index f174cdb7..7233bb51 100644 --- a/commands/bridge_auth_show.go +++ b/commands/bridge_auth_show.go @@ -21,7 +21,8 @@ func newBridgeAuthShow() *cobra.Command { RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error { return runBridgeAuthShow(env, args) }), - Args: cobra.ExactArgs(1), + Args: cobra.ExactArgs(1), + ValidArgsFunction: completeBridgeAuth(env), } return cmd diff --git a/commands/bridge_configure.go b/commands/bridge_configure.go index 6533e497..bbfc13be 100644 --- a/commands/bridge_configure.go +++ b/commands/bridge_configure.go @@ -97,6 +97,7 @@ git bug bridge configure \ flags.StringVarP(&options.name, "name", "n", "", "A distinctive name to identify the bridge") flags.StringVarP(&options.target, "target", "t", "", fmt.Sprintf("The target of the bridge. Valid values are [%s]", strings.Join(bridge.Targets(), ","))) + cmd.RegisterFlagCompletionFunc("target", completeFrom(bridge.Targets())) flags.StringVarP(&options.params.URL, "url", "u", "", "The URL of the remote repository") flags.StringVarP(&options.params.BaseURL, "base-url", "b", "", "The base URL of your remote issue tracker") flags.StringVarP(&options.params.Login, "login", "l", "", "The login on your remote issue tracker") diff --git a/commands/bridge_pull.go b/commands/bridge_pull.go index 3155ebf4..9370e088 100644 --- a/commands/bridge_pull.go +++ b/commands/bridge_pull.go @@ -32,7 +32,8 @@ func newBridgePullCommand() *cobra.Command { RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error { return runBridgePull(env, options, args) }), - Args: cobra.MaximumNArgs(1), + Args: cobra.MaximumNArgs(1), + ValidArgsFunction: completeBridge(env), } flags := cmd.Flags() diff --git a/commands/bridge_push.go b/commands/bridge_push.go index a232f0f0..ef1f2d3e 100644 --- a/commands/bridge_push.go +++ b/commands/bridge_push.go @@ -23,7 +23,8 @@ func newBridgePushCommand() *cobra.Command { RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error { return runBridgePush(env, args) }), - Args: cobra.MaximumNArgs(1), + Args: cobra.MaximumNArgs(1), + ValidArgsFunction: completeBridge(env), } return cmd diff --git a/commands/bridge_rm.go b/commands/bridge_rm.go index 121a35ad..0306944e 100644 --- a/commands/bridge_rm.go +++ b/commands/bridge_rm.go @@ -16,7 +16,8 @@ func newBridgeRm() *cobra.Command { RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error { return runBridgeRm(env, args) }), - Args: cobra.ExactArgs(1), + Args: cobra.ExactArgs(1), + ValidArgsFunction: completeBridge(env), } return cmd diff --git a/commands/comment.go b/commands/comment.go index 90657e4a..b4b4628b 100644 --- a/commands/comment.go +++ b/commands/comment.go @@ -18,6 +18,7 @@ func newCommentCommand() *cobra.Command { RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error { return runComment(env, args) }), + ValidArgsFunction: completeBug(env), } cmd.AddCommand(newCommentAddCommand()) diff --git a/commands/comment_add.go b/commands/comment_add.go index 11ba5ad3..f308428c 100644 --- a/commands/comment_add.go +++ b/commands/comment_add.go @@ -25,6 +25,7 @@ func newCommentAddCommand() *cobra.Command { RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error { return runCommentAdd(env, options, args) }), + ValidArgsFunction: completeBug(env), } flags := cmd.Flags() diff --git a/commands/helper_completion.go b/commands/helper_completion.go new file mode 100644 index 00000000..a23e810f --- /dev/null +++ b/commands/helper_completion.go @@ -0,0 +1,350 @@ +package commands + +import ( + "sort" + "strings" + + "github.com/spf13/cobra" + + "github.com/MichaelMure/git-bug/bridge" + "github.com/MichaelMure/git-bug/bridge/core/auth" + "github.com/MichaelMure/git-bug/bug" + "github.com/MichaelMure/git-bug/cache" + _select "github.com/MichaelMure/git-bug/commands/select" +) + +type validArgsFunction func(cmd *cobra.Command, args []string, toComplete string) (completions []string, directives cobra.ShellCompDirective) + +func completionHandlerError(err error) (completions []string, directives cobra.ShellCompDirective) { + return nil, cobra.ShellCompDirectiveError +} + +func completeBridge(env *Env) validArgsFunction { + return func(cmd *cobra.Command, args []string, toComplete string) (completions []string, directives cobra.ShellCompDirective) { + if len(args) > 0 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + if err := loadBackend(env)(cmd, args); err != nil { + return completionHandlerError(err) + } + defer func() { + _ = env.backend.Close() + }() + + bridges, err := bridge.ConfiguredBridges(env.backend) + if err != nil { + return completionHandlerError(err) + } + + completions = make([]string, len(bridges)) + for i, bridge := range bridges { + completions[i] = bridge + "\t" + "Bridge" + } + + return completions, cobra.ShellCompDirectiveDefault + } +} + +func completeBridgeAuth(env *Env) validArgsFunction { + return func(cmd *cobra.Command, args []string, toComplete string) (completions []string, directives cobra.ShellCompDirective) { + if len(args) > 0 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + if err := loadBackend(env)(cmd, args); err != nil { + return completionHandlerError(err) + } + defer func() { + _ = env.backend.Close() + }() + + creds, err := auth.List(env.backend) + if err != nil { + return completionHandlerError(err) + } + + completions = make([]string, len(creds)) + for i, cred := range creds { + meta := make([]string, 0, len(cred.Metadata())) + for k, v := range cred.Metadata() { + meta = append(meta, k+":"+v) + } + sort.Strings(meta) + metaFmt := strings.Join(meta, ",") + + completions[i] = cred.ID().Human() + "\t" + cred.Target() + " " + string(cred.Kind()) + " " + metaFmt + } + + return completions, cobra.ShellCompDirectiveDefault + } +} + +func completeBug(env *Env) validArgsFunction { + return func(cmd *cobra.Command, args []string, toComplete string) (completions []string, directives cobra.ShellCompDirective) { + if len(args) > 0 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + if err := loadBackend(env)(cmd, args); err != nil { + return completionHandlerError(err) + } + defer func() { + _ = env.backend.Close() + }() + + allIds := env.backend.AllBugsIds() + bugExcerpt := make([]*cache.BugExcerpt, len(allIds)) + for i, id := range allIds { + var err error + bugExcerpt[i], err = env.backend.ResolveBugExcerpt(id) + if err != nil { + return completionHandlerError(err) + } + } + + completions = make([]string, len(allIds)) + for i, id := range allIds { + completions[i] = id.Human() + "\t" + bugExcerpt[i].Title + } + return completions, cobra.ShellCompDirectiveDefault + } +} + +func completeBugAndLabels(env *Env, addOrRemove bool) validArgsFunction { + return func(cmd *cobra.Command, args []string, toComplete string) (completions []string, directives cobra.ShellCompDirective) { + if len(args) == 0 { + return completeBug(env)(cmd, args, toComplete) + } + + if err := loadBackend(env)(cmd, args); err != nil { + return completionHandlerError(err) + } + defer func() { + _ = env.backend.Close() + }() + + b, args, err := _select.ResolveBug(env.backend, args) + if err != nil { + return completionHandlerError(err) + } + + snap := b.Snapshot() + + seenLabels := map[bug.Label]bool{} + for _, label := range args { + seenLabels[bug.Label(label)] = addOrRemove + } + + var labels []bug.Label + if addOrRemove { + for _, label := range snap.Labels { + seenLabels[label] = true + } + + allLabels := env.backend.ValidLabels() + labels = make([]bug.Label, 0, len(allLabels)) + for _, label := range allLabels { + if !seenLabels[label] { + labels = append(labels, label) + } + } + } else { + labels = make([]bug.Label, 0, len(snap.Labels)) + for _, label := range snap.Labels { + if seenLabels[label] { + labels = append(labels, label) + } + } + } + + completions = make([]string, len(labels)) + for i, label := range labels { + completions[i] = string(label) + "\t" + "Label" + } + + return completions, cobra.ShellCompDirectiveDefault + } +} + +func completeFrom(choices []string) validArgsFunction { + return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return choices, cobra.ShellCompDirectiveDefault + } +} + +func completeGitRemote(env *Env) validArgsFunction { + return func(cmd *cobra.Command, args []string, toComplete string) (completions []string, directives cobra.ShellCompDirective) { + if len(args) > 0 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + if err := loadBackend(env)(cmd, args); err != nil { + return completionHandlerError(err) + } + defer func() { + _ = env.backend.Close() + }() + + remoteMap, err := env.backend.GetRemotes() + if err != nil { + return completionHandlerError(err) + } + completions = make([]string, 0, len(remoteMap)) + for remote, url := range remoteMap { + completions = append(completions, remote+"\t"+"Remote: "+url) + } + sort.Strings(completions) + return completions, cobra.ShellCompDirectiveDefault + } +} + +func completeLabel(env *Env) validArgsFunction { + return func(cmd *cobra.Command, args []string, toComplete string) (completions []string, directives cobra.ShellCompDirective) { + if len(args) > 0 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + if err := loadBackend(env)(cmd, args); err != nil { + return completionHandlerError(err) + } + defer func() { + _ = env.backend.Close() + }() + + labels := env.backend.ValidLabels() + completions = make([]string, len(labels)) + for i, label := range labels { + completions[i] = string(label) + "\t" + "Label" + } + return completions, cobra.ShellCompDirectiveDefault + } +} + +func completeLs(env *Env) validArgsFunction { + return func(cmd *cobra.Command, args []string, toComplete string) (completions []string, directives cobra.ShellCompDirective) { + if strings.HasPrefix(toComplete, "status:") { + completions = append(completions, "status:open\tOpen bugs") + completions = append(completions, "status:closed\tClosed bugs") + return completions, cobra.ShellCompDirectiveDefault + } + + byPerson := []string{"author:", "participant:", "actor:"} + byLabel := []string{"label:", "no:"} + needBackend := false + for _, key := range append(byPerson, byLabel...) { + if strings.HasPrefix(toComplete, key) { + needBackend = true + } + } + + if needBackend { + if err := loadBackend(env)(cmd, args); err != nil { + return completionHandlerError(err) + } + defer func() { + _ = env.backend.Close() + }() + } + + for _, key := range byPerson { + if !strings.HasPrefix(toComplete, key) { + continue + } + ids := env.backend.AllIdentityIds() + completions = make([]string, len(ids)) + for i, id := range ids { + user, err := env.backend.ResolveIdentityExcerpt(id) + if err != nil { + return completionHandlerError(err) + } + var handle string + if user.Login != "" { + handle = user.Login + } else { + // "author:John Doe" does not work yet, so use the first name. + handle = strings.Split(user.Name, " ")[0] + } + completions[i] = key + handle + "\t" + user.DisplayName() + } + return completions, cobra.ShellCompDirectiveDefault + } + + for _, key := range byLabel { + if !strings.HasPrefix(toComplete, key) { + continue + } + labels := env.backend.ValidLabels() + completions = make([]string, len(labels)) + for i, label := range labels { + completions[i] = key + string(label) + } + return completions, cobra.ShellCompDirectiveDefault + } + + completions = []string{ + "actor:\tFilter by actor", + "author:\tFilter by author", + "label:\tFilter by label", + "no:\tExclude bugs by label", + "participant:\tFilter by participant", + "status:\tFilter by open/close status", + "title:\tFilter by title", + } + return completions, cobra.ShellCompDirectiveNoSpace + } +} + +func completeUser(env *Env) validArgsFunction { + return func(cmd *cobra.Command, args []string, toComplete string) (completions []string, directives cobra.ShellCompDirective) { + if len(args) > 0 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + + if err := loadBackend(env)(cmd, args); err != nil { + return completionHandlerError(err) + } + defer func() { + _ = env.backend.Close() + }() + + ids := env.backend.AllIdentityIds() + completions = make([]string, len(ids)) + for i, id := range ids { + user, err := env.backend.ResolveIdentityExcerpt(id) + if err != nil { + return completionHandlerError(err) + } + completions[i] = user.Id.Human() + "\t" + user.DisplayName() + } + return completions, cobra.ShellCompDirectiveDefault + } +} + +func completeUserForQuery(env *Env) validArgsFunction { + return func(cmd *cobra.Command, args []string, toComplete string) (completions []string, directives cobra.ShellCompDirective) { + if len(args) > 0 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + + if err := loadBackend(env)(cmd, args); err != nil { + return completionHandlerError(err) + } + defer func() { + _ = env.backend.Close() + }() + + ids := env.backend.AllIdentityIds() + completions = make([]string, len(ids)) + for i, id := range ids { + user, err := env.backend.ResolveIdentityExcerpt(id) + if err != nil { + return completionHandlerError(err) + } + var handle string + if user.Login != "" { + handle = user.Login + } else { + // "author:John Doe" does not work yet, so use the first name. + handle = strings.Split(user.Name, " ")[0] + } + completions[i] = handle + "\t" + user.DisplayName() + } + return completions, cobra.ShellCompDirectiveDefault + } +} diff --git a/commands/label.go b/commands/label.go index d108b089..906974a5 100644 --- a/commands/label.go +++ b/commands/label.go @@ -16,6 +16,7 @@ func newLabelCommand() *cobra.Command { RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error { return runLabel(env, args) }), + ValidArgsFunction: completeBug(env), } cmd.AddCommand(newLabelAddCommand()) diff --git a/commands/label_add.go b/commands/label_add.go index c60ecfeb..65439a4a 100644 --- a/commands/label_add.go +++ b/commands/label_add.go @@ -17,6 +17,7 @@ func newLabelAddCommand() *cobra.Command { RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error { return runLabelAdd(env, args) }), + ValidArgsFunction: completeBugAndLabels(env, true), } return cmd diff --git a/commands/label_rm.go b/commands/label_rm.go index 1cdcd248..3f4e1958 100644 --- a/commands/label_rm.go +++ b/commands/label_rm.go @@ -17,6 +17,7 @@ func newLabelRmCommand() *cobra.Command { RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error { return runLabelRm(env, args) }), + ValidArgsFunction: completeBugAndLabels(env, false), } return cmd diff --git a/commands/ls.go b/commands/ls.go index db4145d0..909e25a8 100644 --- a/commands/ls.go +++ b/commands/ls.go @@ -56,6 +56,7 @@ git bug ls status:open --by creation "foo bar" baz RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error { return runLs(env, options, args) }), + ValidArgsFunction: completeLs(env), } flags := cmd.Flags() @@ -63,26 +64,36 @@ git bug ls status:open --by creation "foo bar" baz flags.StringSliceVarP(&options.statusQuery, "status", "s", nil, "Filter by status. Valid values are [open,closed]") + cmd.RegisterFlagCompletionFunc("status", completeFrom([]string{"open", "closed"})) flags.StringSliceVarP(&options.authorQuery, "author", "a", nil, "Filter by author") flags.StringSliceVarP(&options.metadataQuery, "metadata", "m", nil, "Filter by metadata. Example: github-url=URL") + cmd.RegisterFlagCompletionFunc("author", completeUserForQuery(env)) flags.StringSliceVarP(&options.participantQuery, "participant", "p", nil, "Filter by participant") + cmd.RegisterFlagCompletionFunc("participant", completeUserForQuery(env)) flags.StringSliceVarP(&options.actorQuery, "actor", "A", nil, "Filter by actor") + cmd.RegisterFlagCompletionFunc("actor", completeUserForQuery(env)) flags.StringSliceVarP(&options.labelQuery, "label", "l", nil, "Filter by label") + cmd.RegisterFlagCompletionFunc("label", completeLabel(env)) flags.StringSliceVarP(&options.titleQuery, "title", "t", nil, "Filter by title") flags.StringSliceVarP(&options.noQuery, "no", "n", nil, "Filter by absence of something. Valid values are [label]") + cmd.RegisterFlagCompletionFunc("no", completeLabel(env)) flags.StringVarP(&options.sortBy, "by", "b", "creation", "Sort the results by a characteristic. Valid values are [id,creation,edit]") + cmd.RegisterFlagCompletionFunc("by", completeFrom([]string{"id", "creation", "edit"})) flags.StringVarP(&options.sortDirection, "direction", "d", "asc", "Select the sorting direction. Valid values are [asc,desc]") + cmd.RegisterFlagCompletionFunc("direction", completeFrom([]string{"asc", "desc"})) flags.StringVarP(&options.outputFormat, "format", "f", "default", "Select the output formatting style. Valid values are [default,plain,json,org-mode]") + cmd.RegisterFlagCompletionFunc("format", + completeFrom([]string{"default", "plain", "json", "org-mode"})) return cmd } diff --git a/commands/pull.go b/commands/pull.go index f3a31414..29c9f034 100644 --- a/commands/pull.go +++ b/commands/pull.go @@ -18,6 +18,7 @@ func newPullCommand() *cobra.Command { RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error { return runPull(env, args) }), + ValidArgsFunction: completeGitRemote(env), } return cmd diff --git a/commands/push.go b/commands/push.go index 9d6ca7df..adba6bef 100644 --- a/commands/push.go +++ b/commands/push.go @@ -16,6 +16,7 @@ func newPushCommand() *cobra.Command { RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error { return runPush(env, args) }), + ValidArgsFunction: completeGitRemote(env), } return cmd diff --git a/commands/rm.go b/commands/rm.go index 8205c128..2e1d924d 100644 --- a/commands/rm.go +++ b/commands/rm.go @@ -17,6 +17,7 @@ func newRmCommand() *cobra.Command { RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error { return runRm(env, args) }), + ValidArgsFunction: completeBug(env), } flags := cmd.Flags() diff --git a/commands/select.go b/commands/select.go index 34d00a32..f9e6ece7 100644 --- a/commands/select.go +++ b/commands/select.go @@ -31,6 +31,7 @@ The complementary command is "git bug deselect" performing the opposite operatio RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error { return runSelect(env, args) }), + ValidArgsFunction: completeBug(env), } return cmd diff --git a/commands/show.go b/commands/show.go index 55140357..16747214 100644 --- a/commands/show.go +++ b/commands/show.go @@ -29,13 +29,17 @@ func newShowCommand() *cobra.Command { RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error { return runShow(env, options, args) }), + ValidArgsFunction: completeBug(env), } flags := cmd.Flags() flags.SortFlags = false + fields := []string{"author", "authorEmail", "createTime", "lastEdit", "humanId", + "id", "labels", "shortId", "status", "title", "actors", "participants"} flags.StringVarP(&options.fields, "field", "", "", - "Select field to display. Valid values are [author,authorEmail,createTime,lastEdit,humanId,id,labels,shortId,status,title,actors,participants]") + "Select field to display. Valid values are ["+strings.Join(fields, ",")+"]") + cmd.RegisterFlagCompletionFunc("by", completeFrom(fields)) flags.StringVarP(&options.format, "format", "f", "default", "Select the output formatting style. Valid values are [default,json,org-mode]") diff --git a/commands/status.go b/commands/status.go index c1e45c5f..c3e860b6 100644 --- a/commands/status.go +++ b/commands/status.go @@ -15,6 +15,7 @@ func newStatusCommand() *cobra.Command { RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error { return runStatus(env, args) }), + ValidArgsFunction: completeBug(env), } cmd.AddCommand(newStatusCloseCommand()) diff --git a/commands/title.go b/commands/title.go index c4293530..f99c6eff 100644 --- a/commands/title.go +++ b/commands/title.go @@ -15,6 +15,7 @@ func newTitleCommand() *cobra.Command { RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error { return runTitle(env, args) }), + ValidArgsFunction: completeBug(env), } cmd.AddCommand(newTitleEditCommand()) diff --git a/commands/title_edit.go b/commands/title_edit.go index 810c5e62..a9e7fe4b 100644 --- a/commands/title_edit.go +++ b/commands/title_edit.go @@ -24,6 +24,7 @@ func newTitleEditCommand() *cobra.Command { RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error { return runTitleEdit(env, options, args) }), + ValidArgsFunction: completeBug(env), } flags := cmd.Flags() diff --git a/commands/user.go b/commands/user.go index b6a2e485..0fe3be4d 100644 --- a/commands/user.go +++ b/commands/user.go @@ -3,6 +3,7 @@ package commands import ( "errors" "fmt" + "strings" "github.com/spf13/cobra" @@ -24,6 +25,7 @@ func newUserCommand() *cobra.Command { RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error { return runUser(env, options, args) }), + ValidArgsFunction: completeUser(env), } cmd.AddCommand(newUserAdoptCommand()) @@ -33,8 +35,10 @@ func newUserCommand() *cobra.Command { flags := cmd.Flags() flags.SortFlags = false + fields := []string{"email", "humanId", "id", "lastModification", "lastModificationLamports", "login", "metadata", "name"} flags.StringVarP(&options.fields, "field", "f", "", - "Select field to display. Valid values are [email,humanId,id,lastModification,lastModificationLamports,login,metadata,name]") + "Select field to display. Valid values are ["+strings.Join(fields, ",")+"]") + cmd.RegisterFlagCompletionFunc("field", completeFrom(fields)) return cmd } diff --git a/commands/user_adopt.go b/commands/user_adopt.go index 166063ae..afef94ea 100644 --- a/commands/user_adopt.go +++ b/commands/user_adopt.go @@ -15,6 +15,7 @@ func newUserAdoptCommand() *cobra.Command { RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error { return runUserAdopt(env, args) }), + ValidArgsFunction: completeUser(env), } return cmd diff --git a/commands/user_ls.go b/commands/user_ls.go index 98800b87..341f0dc1 100644 --- a/commands/user_ls.go +++ b/commands/user_ls.go @@ -32,6 +32,7 @@ func newUserLsCommand() *cobra.Command { flags.StringVarP(&options.format, "format", "f", "default", "Select the output formatting style. Valid values are [default,json]") + cmd.RegisterFlagCompletionFunc("format", completeFrom([]string{"default", "json"})) return cmd } diff --git a/misc/bash_completion/git-bug b/misc/bash_completion/git-bug index 2320c1c0..ab023c71 100644 --- a/misc/bash_completion/git-bug +++ b/misc/bash_completion/git-bug @@ -420,7 +420,11 @@ _git-bug_bridge_auth_add-token() flags+=("--target=") two_word_flags+=("--target") + flags_with_completion+=("--target") + flags_completion+=("__git-bug_handle_go_custom_completion") two_word_flags+=("-t") + flags_with_completion+=("-t") + flags_completion+=("__git-bug_handle_go_custom_completion") local_nonpersistent_flags+=("--target") local_nonpersistent_flags+=("--target=") local_nonpersistent_flags+=("-t") @@ -432,7 +436,11 @@ _git-bug_bridge_auth_add-token() local_nonpersistent_flags+=("-l") flags+=("--user=") two_word_flags+=("--user") + flags_with_completion+=("--user") + flags_completion+=("__git-bug_handle_go_custom_completion") two_word_flags+=("-u") + flags_with_completion+=("-u") + flags_completion+=("__git-bug_handle_go_custom_completion") local_nonpersistent_flags+=("--user") local_nonpersistent_flags+=("--user=") local_nonpersistent_flags+=("-u") @@ -459,6 +467,7 @@ _git-bug_bridge_auth_rm() must_have_one_flag=() must_have_one_noun=() + has_completion_function=1 noun_aliases=() } @@ -479,6 +488,7 @@ _git-bug_bridge_auth_show() must_have_one_flag=() must_have_one_noun=() + has_completion_function=1 noun_aliases=() } @@ -527,7 +537,11 @@ _git-bug_bridge_configure() local_nonpersistent_flags+=("-n") flags+=("--target=") two_word_flags+=("--target") + flags_with_completion+=("--target") + flags_completion+=("__git-bug_handle_go_custom_completion") two_word_flags+=("-t") + flags_with_completion+=("-t") + flags_completion+=("__git-bug_handle_go_custom_completion") local_nonpersistent_flags+=("--target") local_nonpersistent_flags+=("--target=") local_nonpersistent_flags+=("-t") @@ -608,6 +622,7 @@ _git-bug_bridge_pull() must_have_one_flag=() must_have_one_noun=() + has_completion_function=1 noun_aliases=() } @@ -628,6 +643,7 @@ _git-bug_bridge_push() must_have_one_flag=() must_have_one_noun=() + has_completion_function=1 noun_aliases=() } @@ -648,6 +664,7 @@ _git-bug_bridge_rm() must_have_one_flag=() must_have_one_noun=() + has_completion_function=1 noun_aliases=() } @@ -731,6 +748,7 @@ _git-bug_comment_add() must_have_one_flag=() must_have_one_noun=() + has_completion_function=1 noun_aliases=() } @@ -787,6 +805,7 @@ _git-bug_comment() must_have_one_flag=() must_have_one_noun=() + has_completion_function=1 noun_aliases=() } @@ -827,6 +846,7 @@ _git-bug_label_add() must_have_one_flag=() must_have_one_noun=() + has_completion_function=1 noun_aliases=() } @@ -847,6 +867,7 @@ _git-bug_label_rm() must_have_one_flag=() must_have_one_noun=() + has_completion_function=1 noun_aliases=() } @@ -869,6 +890,7 @@ _git-bug_label() must_have_one_flag=() must_have_one_noun=() + has_completion_function=1 noun_aliases=() } @@ -888,13 +910,21 @@ _git-bug_ls() flags+=("--status=") two_word_flags+=("--status") + flags_with_completion+=("--status") + flags_completion+=("__git-bug_handle_go_custom_completion") two_word_flags+=("-s") + flags_with_completion+=("-s") + flags_completion+=("__git-bug_handle_go_custom_completion") local_nonpersistent_flags+=("--status") local_nonpersistent_flags+=("--status=") local_nonpersistent_flags+=("-s") flags+=("--author=") two_word_flags+=("--author") + flags_with_completion+=("--author") + flags_completion+=("__git-bug_handle_go_custom_completion") two_word_flags+=("-a") + flags_with_completion+=("-a") + flags_completion+=("__git-bug_handle_go_custom_completion") local_nonpersistent_flags+=("--author") local_nonpersistent_flags+=("--author=") local_nonpersistent_flags+=("-a") @@ -906,19 +936,31 @@ _git-bug_ls() local_nonpersistent_flags+=("-m") flags+=("--participant=") two_word_flags+=("--participant") + flags_with_completion+=("--participant") + flags_completion+=("__git-bug_handle_go_custom_completion") two_word_flags+=("-p") + flags_with_completion+=("-p") + flags_completion+=("__git-bug_handle_go_custom_completion") local_nonpersistent_flags+=("--participant") local_nonpersistent_flags+=("--participant=") local_nonpersistent_flags+=("-p") flags+=("--actor=") two_word_flags+=("--actor") + flags_with_completion+=("--actor") + flags_completion+=("__git-bug_handle_go_custom_completion") two_word_flags+=("-A") + flags_with_completion+=("-A") + flags_completion+=("__git-bug_handle_go_custom_completion") local_nonpersistent_flags+=("--actor") local_nonpersistent_flags+=("--actor=") local_nonpersistent_flags+=("-A") flags+=("--label=") two_word_flags+=("--label") + flags_with_completion+=("--label") + flags_completion+=("__git-bug_handle_go_custom_completion") two_word_flags+=("-l") + flags_with_completion+=("-l") + flags_completion+=("__git-bug_handle_go_custom_completion") local_nonpersistent_flags+=("--label") local_nonpersistent_flags+=("--label=") local_nonpersistent_flags+=("-l") @@ -930,31 +972,48 @@ _git-bug_ls() local_nonpersistent_flags+=("-t") flags+=("--no=") two_word_flags+=("--no") + flags_with_completion+=("--no") + flags_completion+=("__git-bug_handle_go_custom_completion") two_word_flags+=("-n") + flags_with_completion+=("-n") + flags_completion+=("__git-bug_handle_go_custom_completion") local_nonpersistent_flags+=("--no") local_nonpersistent_flags+=("--no=") local_nonpersistent_flags+=("-n") flags+=("--by=") two_word_flags+=("--by") + flags_with_completion+=("--by") + flags_completion+=("__git-bug_handle_go_custom_completion") two_word_flags+=("-b") + flags_with_completion+=("-b") + flags_completion+=("__git-bug_handle_go_custom_completion") local_nonpersistent_flags+=("--by") local_nonpersistent_flags+=("--by=") local_nonpersistent_flags+=("-b") flags+=("--direction=") two_word_flags+=("--direction") + flags_with_completion+=("--direction") + flags_completion+=("__git-bug_handle_go_custom_completion") two_word_flags+=("-d") + flags_with_completion+=("-d") + flags_completion+=("__git-bug_handle_go_custom_completion") local_nonpersistent_flags+=("--direction") local_nonpersistent_flags+=("--direction=") local_nonpersistent_flags+=("-d") flags+=("--format=") two_word_flags+=("--format") + flags_with_completion+=("--format") + flags_completion+=("__git-bug_handle_go_custom_completion") two_word_flags+=("-f") + flags_with_completion+=("-f") + flags_completion+=("__git-bug_handle_go_custom_completion") local_nonpersistent_flags+=("--format") local_nonpersistent_flags+=("--format=") local_nonpersistent_flags+=("-f") must_have_one_flag=() must_have_one_noun=() + has_completion_function=1 noun_aliases=() } @@ -1015,6 +1074,7 @@ _git-bug_pull() must_have_one_flag=() must_have_one_noun=() + has_completion_function=1 noun_aliases=() } @@ -1035,6 +1095,7 @@ _git-bug_push() must_have_one_flag=() must_have_one_noun=() + has_completion_function=1 noun_aliases=() } @@ -1055,6 +1116,7 @@ _git-bug_rm() must_have_one_flag=() must_have_one_noun=() + has_completion_function=1 noun_aliases=() } @@ -1075,6 +1137,7 @@ _git-bug_select() must_have_one_flag=() must_have_one_noun=() + has_completion_function=1 noun_aliases=() } @@ -1105,6 +1168,7 @@ _git-bug_show() must_have_one_flag=() must_have_one_noun=() + has_completion_function=1 noun_aliases=() } @@ -1167,6 +1231,7 @@ _git-bug_status() must_have_one_flag=() must_have_one_noun=() + has_completion_function=1 noun_aliases=() } @@ -1215,6 +1280,7 @@ _git-bug_title_edit() must_have_one_flag=() must_have_one_noun=() + has_completion_function=1 noun_aliases=() } @@ -1236,6 +1302,7 @@ _git-bug_title() must_have_one_flag=() must_have_one_noun=() + has_completion_function=1 noun_aliases=() } @@ -1256,6 +1323,7 @@ _git-bug_user_adopt() must_have_one_flag=() must_have_one_noun=() + has_completion_function=1 noun_aliases=() } @@ -1315,7 +1383,11 @@ _git-bug_user_ls() flags+=("--format=") two_word_flags+=("--format") + flags_with_completion+=("--format") + flags_completion+=("__git-bug_handle_go_custom_completion") two_word_flags+=("-f") + flags_with_completion+=("-f") + flags_completion+=("__git-bug_handle_go_custom_completion") local_nonpersistent_flags+=("--format") local_nonpersistent_flags+=("--format=") local_nonpersistent_flags+=("-f") @@ -1344,13 +1416,18 @@ _git-bug_user() flags+=("--field=") two_word_flags+=("--field") + flags_with_completion+=("--field") + flags_completion+=("__git-bug_handle_go_custom_completion") two_word_flags+=("-f") + flags_with_completion+=("-f") + flags_completion+=("__git-bug_handle_go_custom_completion") local_nonpersistent_flags+=("--field") local_nonpersistent_flags+=("--field=") local_nonpersistent_flags+=("-f") must_have_one_flag=() must_have_one_noun=() + has_completion_function=1 noun_aliases=() } |