diff --git a/cmd/carapace/cmd/invoke.go b/cmd/carapace/cmd/invoke.go new file mode 100644 index 0000000000..5f680d0bb0 --- /dev/null +++ b/cmd/carapace/cmd/invoke.go @@ -0,0 +1,80 @@ +package cmd + +import ( + "fmt" + "os" + "strings" + + "github.com/rsteube/carapace" + "github.com/rsteube/carapace-bin/cmd/carapace/cmd/completers" + "github.com/spf13/cobra" +) + +var invokeCmd = &cobra.Command{ + Use: "invoke", + Short: "", + Args: cobra.MinimumNArgs(1), + Run: func(cmd *cobra.Command, args []string) { + if overlayPath, err := overlayPath(args[0]); err == nil && len(args) > 2 { // and arg[1] is a known shell + cmd := &cobra.Command{ + DisableFlagParsing: true, + CompletionOptions: cobra.CompletionOptions{ + DisableDefaultCmd: true, + }, + } + + // TODO yuck + command := args[0] + shell := args[1] + args[0] = "_carapace" + args[1] = "export" + os.Args[1] = "_carapace" + os.Args[2] = "export" + os.Setenv("CARAPACE_LENIENT", "1") + + carapace.Gen(cmd).PositionalAnyCompletion( + carapace.ActionCallback(func(c carapace.Context) carapace.Action { + batch := carapace.Batch() + specPath, err := completers.SpecPath(command) + if err != nil { + batch = append(batch, carapace.ActionImport([]byte(invokeCompleter(command)))) + } else { + out, err := specCompletion(specPath, args[1:]...) + if err != nil { + return carapace.ActionMessage(err.Error()) + } + + batch = append(batch, carapace.ActionImport([]byte(out))) + } + + batch = append(batch, overlayCompletion(overlayPath, args[1:]...)) + return batch.ToA() + }), + ) + + cmd.SetArgs(append([]string{"_carapace", shell}, args[2:]...)) + cmd.Execute() + } else { + if specPath, err := completers.SpecPath(args[0]); err == nil { + out, err := specCompletion(specPath, args[1:]...) + if err != nil { + fmt.Fprintln(cmd.ErrOrStderr(), err.Error()) + return + } + + // TODO revert the patching from specCompletion to use the integrated version for overlay to work (should move this somewhere else - best in specCompletion) + // TODO only patch completion script + out = strings.Replace(out, fmt.Sprintf("--spec '%v'", specPath), args[0], -1) + out = strings.Replace(out, fmt.Sprintf("'--spec', '%v'", specPath), fmt.Sprintf("'%v'", args[0]), -1) // xonsh callback + fmt.Fprint(cmd.OutOrStdout(), out) + } else { + fmt.Print(invokeCompleter(args[0])) + } + } + }, +} + +func init() { + carapace.Gen(invokeCmd).Standalone() + +} diff --git a/cmd/carapace/cmd/list.go b/cmd/carapace/cmd/list.go index fb54bed627..89b82a654e 100644 --- a/cmd/carapace/cmd/list.go +++ b/cmd/carapace/cmd/list.go @@ -1,7 +1,11 @@ package cmd import ( + "fmt" + "strconv" + "github.com/rsteube/carapace" + "github.com/rsteube/carapace-bin/cmd/carapace/cmd/completers" "github.com/spf13/cobra" ) @@ -21,3 +25,15 @@ func init() { carapace.Gen(listCmd).Standalone() } +func printCompleters() { + maxlen := 0 + for _, name := range completers.Names() { + if len := len(name); len > maxlen { + maxlen = len + } + } + + for _, name := range completers.Names() { + fmt.Printf("%-"+strconv.Itoa(maxlen)+"v %v\n", name, completers.Description(name)) + } +} diff --git a/cmd/carapace/cmd/root.go b/cmd/carapace/cmd/root.go index 4fd5c908a9..55dc70e250 100644 --- a/cmd/carapace/cmd/root.go +++ b/cmd/carapace/cmd/root.go @@ -22,7 +22,6 @@ import ( "github.com/rsteube/carapace-bin/pkg/actions" spec "github.com/rsteube/carapace-spec" "github.com/rsteube/carapace/pkg/ps" - "github.com/rsteube/carapace/pkg/style" "github.com/rsteube/carapace/pkg/xdg" "github.com/spf13/cobra" ) @@ -89,64 +88,9 @@ var rootCmd = &cobra.Command{ styleCmd.SetArgs(args[1:]) styleCmd.Execute() default: - if overlayPath, err := overlayPath(args[0]); err == nil && len(args) > 2 { // and arg[1] is a known shell - cmd := &cobra.Command{ - DisableFlagParsing: true, - CompletionOptions: cobra.CompletionOptions{ - DisableDefaultCmd: true, - }, - } - - // TODO yuck - command := args[0] - shell := args[1] - args[0] = "_carapace" - args[1] = "export" - os.Args[1] = "_carapace" - os.Args[2] = "export" - os.Setenv("CARAPACE_LENIENT", "1") - - carapace.Gen(cmd).PositionalAnyCompletion( - carapace.ActionCallback(func(c carapace.Context) carapace.Action { - batch := carapace.Batch() - specPath, err := completers.SpecPath(command) - if err != nil { - batch = append(batch, carapace.ActionImport([]byte(invokeCompleter(command)))) - } else { - out, err := specCompletion(specPath, args[1:]...) - if err != nil { - return carapace.ActionMessage(err.Error()) - } - - batch = append(batch, carapace.ActionImport([]byte(out))) - } - - batch = append(batch, overlayCompletion(overlayPath, args[1:]...)) - return batch.ToA() - }), - ) - - cmd.SetArgs(append([]string{"_carapace", shell}, args[2:]...)) - cmd.Execute() - } else { - if specPath, err := completers.SpecPath(args[0]); err == nil { - out, err := specCompletion(specPath, args[1:]...) - if err != nil { - fmt.Fprintln(cmd.ErrOrStderr(), err.Error()) - return - } - - // TODO revert the patching from specCompletion to use the integrated version for overlay to work (should move this somewhere else - best in specCompletion) - // TODO only patch completion script - out = strings.Replace(out, fmt.Sprintf("--spec '%v'", specPath), args[0], -1) - out = strings.Replace(out, fmt.Sprintf("'--spec', '%v'", specPath), fmt.Sprintf("'%v'", args[0]), -1) // xonsh callback - fmt.Fprint(cmd.OutOrStdout(), out) - } else { - fmt.Print(invokeCompleter(args[0])) - } - } + invokeCmd.SetArgs(args) + invokeCmd.Execute() } - }, DisableFlagParsing: true, FParseErrWhitelist: cobra.FParseErrWhitelist{ @@ -159,19 +103,6 @@ var rootCmd = &cobra.Command{ func suppressErr(f func() (string, error)) string { s, _ := f(); return s } -func printCompleters() { - maxlen := 0 - for _, name := range completers.Names() { - if len := len(name); len > maxlen { - maxlen = len - } - } - - for _, name := range completers.Names() { - fmt.Printf("%-"+strconv.Itoa(maxlen)+"v %v\n", name, completers.Description(name)) - } -} - func createOverlayDir() error { configDir, err := xdg.UserConfigDir() if err != nil { @@ -291,13 +222,6 @@ func invokeCompleter(completer string) string { } -func setStyle(s string) error { - if splitted := strings.SplitN(s, "=", 2); len(splitted) == 2 { - return style.Set(splitted[0], splitted[1]) - } - return fmt.Errorf("invalid format: '%v'", s) -} - func updateSchema() error { confDir, err := xdg.UserConfigDir() if err != nil { diff --git a/cmd/carapace/cmd/style.go b/cmd/carapace/cmd/style.go index db979f91ec..c11a1e2263 100644 --- a/cmd/carapace/cmd/style.go +++ b/cmd/carapace/cmd/style.go @@ -2,8 +2,10 @@ package cmd import ( "fmt" + "strings" "github.com/rsteube/carapace" + "github.com/rsteube/carapace/pkg/style" "github.com/spf13/cobra" ) @@ -22,3 +24,10 @@ func init() { carapace.Gen(styleCmd).Standalone() } + +func setStyle(s string) error { + if splitted := strings.SplitN(s, "=", 2); len(splitted) == 2 { + return style.Set(splitted[0], splitted[1]) + } + return fmt.Errorf("invalid format: '%v'", s) +}