completion.go

 1package bugcmd
 2
 3import (
 4	"strings"
 5
 6	"github.com/spf13/cobra"
 7
 8	"github.com/git-bug/git-bug/cache"
 9	"github.com/git-bug/git-bug/commands/completion"
10	"github.com/git-bug/git-bug/commands/execenv"
11	_select "github.com/git-bug/git-bug/commands/select"
12	"github.com/git-bug/git-bug/entities/common"
13)
14
15// BugCompletion perform bug completion (id, title) on the environment backend
16func BugCompletion(env *execenv.Env) completion.ValidArgsFunction {
17	return func(cmd *cobra.Command, args []string, toComplete string) (completions []string, directives cobra.ShellCompDirective) {
18		if err := execenv.LoadBackend(env)(cmd, args); err != nil {
19			return completion.HandleError(err)
20		}
21		defer func() {
22			_ = env.Backend.Close()
23		}()
24
25		return BugWithBackend(env.Backend, toComplete)
26	}
27}
28
29// BugWithBackend perform bug completion (id, title) on the given backend
30func BugWithBackend(backend *cache.RepoCache, toComplete string) (completions []string, directives cobra.ShellCompDirective) {
31	for _, id := range backend.Bugs().AllIds() {
32		if strings.Contains(id.String(), strings.TrimSpace(toComplete)) {
33			excerpt, err := backend.Bugs().ResolveExcerpt(id)
34			if err != nil {
35				return completion.HandleError(err)
36			}
37			completions = append(completions, id.Human()+"\t"+excerpt.Title)
38		}
39	}
40
41	return completions, cobra.ShellCompDirectiveNoFileComp
42}
43
44// BugAndLabelsCompletion complete either a bug ID or a label if we know about the bug
45func BugAndLabelsCompletion(env *execenv.Env, addOrRemove bool) completion.ValidArgsFunction {
46	return func(cmd *cobra.Command, args []string, toComplete string) (completions []string, directives cobra.ShellCompDirective) {
47		if err := execenv.LoadBackend(env)(cmd, args); err != nil {
48			return completion.HandleError(err)
49		}
50		defer func() {
51			_ = env.Backend.Close()
52		}()
53
54		b, cleanArgs, err := ResolveSelected(env.Backend, args)
55		if _select.IsErrNoValidId(err) {
56			// we need a bug first to complete labels
57			return BugWithBackend(env.Backend, toComplete)
58		}
59		if err != nil {
60			return completion.HandleError(err)
61		}
62
63		snap := b.Snapshot()
64
65		seenLabels := map[common.Label]bool{}
66		for _, label := range cleanArgs {
67			seenLabels[common.Label(label)] = addOrRemove
68		}
69
70		var labels []common.Label
71		if addOrRemove {
72			for _, label := range snap.Labels {
73				seenLabels[label] = true
74			}
75
76			allLabels := env.Backend.Bugs().ValidLabels()
77			labels = make([]common.Label, 0, len(allLabels))
78			for _, label := range allLabels {
79				if !seenLabels[label] {
80					labels = append(labels, label)
81				}
82			}
83		} else {
84			labels = make([]common.Label, 0, len(snap.Labels))
85			for _, label := range snap.Labels {
86				if seenLabels[label] {
87					labels = append(labels, label)
88				}
89			}
90		}
91
92		completions = make([]string, len(labels))
93		for i, label := range labels {
94			completions[i] = string(label) + "\t" + "Label"
95		}
96
97		return completions, cobra.ShellCompDirectiveNoFileComp
98	}
99}