completions.go

 1package cmd
 2
 3import (
 4	"strings"
 5
 6	"github.com/spf13/cobra"
 7
 8	"git.secluded.site/keld/internal/config"
 9)
10
11// completePreset offers completions for the root --preset flag.
12func completePreset(_ *cobra.Command, _ []string, toComplete string) ([]string, cobra.ShellCompDirective) {
13	if strings.Contains(toComplete, "@") {
14		return completeSuffix(toComplete), cobra.ShellCompDirectiveNoFileComp
15	}
16
17	prefixes := config.Prefixes()
18	presets := config.Presets()
19
20	seen := make(map[string]struct{}, len(prefixes)+len(presets))
21	out := make([]string, 0, len(prefixes)+len(presets))
22
23	add := func(s string) {
24		if !strings.HasPrefix(s, toComplete) {
25			return
26		}
27		if _, ok := seen[s]; ok {
28			return
29		}
30		seen[s] = struct{}{}
31		out = append(out, s)
32	}
33
34	for _, p := range prefixes {
35		add(p)
36	}
37	for _, p := range presets {
38		add(p)
39	}
40
41	return out, cobra.ShellCompDirectiveNoFileComp
42}
43
44// completeSuffix generates completions when the user has typed a prefix
45// containing "@". For example, typing "home@" offers "home@cloud",
46// "home@nas", etc. by combining the typed prefix with known suffixes.
47func completeSuffix(typed string) []string {
48	idx := strings.Index(typed, "@")
49	if idx < 0 {
50		return nil
51	}
52
53	prefix := typed[:idx+1] // e.g. "home@"
54	suffixes := config.Suffixes()
55
56	out := make([]string, 0, len(suffixes))
57	for _, sfx := range suffixes {
58		// sfx is e.g. "@cloud"; combine as "home@cloud".
59		combo := prefix[:len(prefix)-1] + sfx
60		if strings.HasPrefix(combo, typed) {
61			out = append(out, combo)
62		}
63	}
64	return out
65}