@@ -11,6 +11,7 @@ import (
1111 "github.com/carapace-sh/carapace-bin/cmd/carapace/cmd/completers"
1212 carapacebin "github.com/carapace-sh/carapace-bin/pkg/actions/tools/carapace"
1313 "github.com/carapace-sh/carapace-bridge/pkg/actions/bridge"
14+ spec "github.com/carapace-sh/carapace-spec"
1415 "github.com/carapace-sh/carapace/pkg/uid"
1516 "github.com/spf13/cobra"
1617)
@@ -24,122 +25,6 @@ var invokeCmd = &cobra.Command{
2425 },
2526}
2627
27- // func invoke(cmd *cobra.Command, args []string) {
28- // if overlayPath, err := overlayPath(args[0]); err == nil && len(args) > 2 { // and arg[1] is a known shell
29- // cmd := &cobra.Command{
30- // DisableFlagParsing: true,
31- // CompletionOptions: cobra.CompletionOptions{
32- // DisableDefaultCmd: true,
33- // },
34- // }
35-
36- // // TODO yuck
37- // command := args[0]
38- // shell := args[1]
39- // args[0] = "_carapace"
40- // args[1] = "export"
41- // os.Args[1] = "_carapace"
42- // os.Args[2] = "export"
43- // os.Setenv("CARAPACE_LENIENT", "1")
44-
45- // carapace.Gen(cmd).PositionalAnyCompletion(
46- // carapace.ActionCallback(func(c carapace.Context) carapace.Action {
47- // batch := carapace.Batch()
48- // specPath, err := completers.SpecPath(command)
49- // if err != nil {
50- // batch = append(batch, carapace.ActionImport([]byte(invokeCompleter(command))))
51- // } else {
52- // out, err := specCompletion(specPath, args[1:]...)
53- // if err != nil {
54- // return carapace.ActionMessage(err.Error())
55- // }
56-
57- // batch = append(batch, carapace.ActionImport([]byte(out)))
58- // }
59-
60- // batch = append(batch, overlayCompletion(overlayPath, args[1:]...))
61- // return batch.ToA()
62- // }),
63- // )
64-
65- // cmd.SetArgs(append([]string{"_carapace", shell}, args[2:]...))
66- // cmd.Execute()
67- // } else {
68- // if specPath, err := completers.SpecPath(args[0]); err == nil {
69- // out, err := specCompletion(specPath, args[1:]...)
70- // if err != nil {
71- // fmt.Fprintln(cmd.ErrOrStderr(), err.Error())
72- // return
73- // }
74-
75- // // TODO revert the patching from specCompletion to use the integrated version for overlay to work (should move this somewhere else - best in specCompletion)
76- // // TODO only patch completion script
77- // // TODO this isn't correct anymore
78- // out = strings.ReplaceAll(out, fmt.Sprintf("--spec '%v'", specPath), args[0])
79- // out = func() string {
80- // var (
81- // s, old, new string = out, fmt.Sprintf("'--spec', '%v'", specPath), fmt.Sprintf("'%v'", args[0])
82- // n int = -1
83- // )
84- // if old == new || n == 0 {
85- // return s
86- // }
87- // if m := strings.Count(s, old); m == 0 {
88- // return s
89- // } else if n < 0 || m < n {
90- // n = m
91- // }
92- // var b strings. // Apply replacements to buffer.
93- // Builder
94- // b.Grow(len(s) + n*(len(new)-len(old)))
95- // start := 0
96- // if len(old) > 0 {
97- // for range n {
98- // j := start + strings.Index(s[start:], old)
99- // b.WriteString(s[start:j])
100- // b.WriteString(new)
101- // start = j + len(old)
102- // }
103- // } else {
104- // b.WriteString(new)
105- // for range n - 1 {
106- // _, wid := utf8.DecodeRuneInString(s[start:])
107- // j := start + wid
108- // b.WriteString(s[start:j])
109- // b.WriteString(new)
110- // start = j
111- // }
112- // }
113- // b.WriteString(s[start:])
114- // return b.String()
115- // }() // xonsh callback
116- // fmt.Fprint(cmd.OutOrStdout(), out)
117- // } else if _, err := completers.Lookup(args[0]); err == nil {
118- // fmt.Print(invokeCompleter(args[0]))
119- // } else {
120- // if _, ok := bridges.Bridges()[args[0]]; ok {
121- // _bridgeCmd := &cobra.Command{
122- // Use: args[0],
123- // DisableFlagParsing: true,
124- // }
125-
126- // carapace.Gen(_bridgeCmd).PositionalAnyCompletion(
127- // bridge.ActionBridges(args[0]),
128- // )
129- // carapace.Gen(_bridgeCmd).Standalone()
130-
131- // out, err := cmdCompletion(_bridgeCmd, args[1:]...)
132- // if err != nil {
133- // fmt.Fprintln(cmd.ErrOrStderr(), err.Error())
134- // return
135- // }
136- // fmt.Fprint(cmd.OutOrStdout(), out)
137- // }
138- // return
139- // }
140- // }
141- // }
142-
14328func init () {
14429 carapace .Gen (invokeCmd ).Standalone ()
14530 invokeCmd .Flags ().SetInterspersed (false )
@@ -230,15 +115,32 @@ func wrap(f func()) string { // TODO get rid of this
230115func invokeCompleter (nameVariant string ) string {
231116 var out string
232117 if completer , err := completers .Lookup (nameVariant ); err == nil { // TODO handle error
233- switch completer . Execute {
234- case nil :
118+ switch {
119+ case completer . Execute == nil :
235120 carapace .LOG .Printf ("Completer.Execute of %q is nil" , nameVariant )
236- default :
121+ case completer .Overlay != "" && len (os .Args ) > 2 :
122+ // TODO yuck
123+ shell := os .Args [2 ]
124+
125+ os .Setenv ("CARAPACE_LENIENT" , "1" )
126+ os .Args [2 ] = "export"
237127 out = wrap (func () {
238128 os .Args [1 ] = "_carapace"
239- // TODO merge with overlay
240129 completer .Execute () // TODO Execute should handle the stdout wrapping
241130 })
131+
132+ os .Args [2 ] = shell
133+ out = wrap (func () {
134+ complete (completer .Name , carapace .Batch (
135+ carapace .ActionImport ([]byte (out )),
136+ spec .ActionSpec (completer .Overlay ),
137+ ).ToA ())() // TODO handle error
138+ })
139+ default :
140+ out = wrap (func () {
141+ os .Args [1 ] = "_carapace"
142+ completer .Execute () // TODO handle error
143+ })
242144 }
243145 }
244146
@@ -248,36 +150,16 @@ func invokeCompleter(nameVariant string) string {
248150 return patched
249151}
250152
251- // TODO use specCompletion and extract common code with invokeCompleter
252- // func cmdCompletion(cmd *cobra.Command, args ...string) (string, error) {
253- // old := os.Stdout
254- // r, w, _ := os.Pipe()
255- // os.Stdout = w
256-
257- // outC := make(chan string)
258- // // copy the output in a separate goroutine so printing can't block indefinitely
259- // go func() {
260- // var buf bytes.Buffer
261- // io.Copy(&buf, r)
262- // outC <- buf.String()
263- // }()
264-
265- // a := []string{"_carapace"}
266- // a = append(a, args...)
267- // cmd.SetArgs(a)
268- // cmd.Execute()
269-
270- // w.Close()
271- // out := <-outC
272- // os.Stdout = old
273-
274- // executable, err := os.Executable()
275- // if err != nil {
276- // return "", err
277- // }
278-
279- // executableName := filepath.Base(executable)
280- // patched := strings.ReplaceAll(string(out), fmt.Sprintf("%v _carapace", executableName), fmt.Sprintf("%v %v", executableName, cmd.Name())) // general callback
281- // patched = strings.ReplaceAll(patched, fmt.Sprintf("'%v', '_carapace'", executableName), fmt.Sprintf("'%v', '%v'", executableName, cmd.Name())) // xonsh callback
282- // return patched, nil
283- // }
153+ func complete (name string , action carapace.Action ) func () error {
154+ return func () error {
155+ cmd := & cobra.Command {
156+ Use : name ,
157+ DisableFlagParsing : true ,
158+ }
159+ carapace .Gen (cmd ).Standalone ()
160+ carapace .Gen (cmd ).PositionalAnyCompletion (
161+ action ,
162+ )
163+ return cmd .Execute ()
164+ }
165+ }
0 commit comments