From 94e71bc9093ac85af45310d6863037924f86e247 Mon Sep 17 00:00:00 2001 From: rsteube Date: Tue, 24 Dec 2024 13:46:49 +0100 Subject: [PATCH] argcomplete: re-added legacy version for gcloud --- pkg/actions/bridge/argcomplete_legacy.go | 84 ++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 pkg/actions/bridge/argcomplete_legacy.go diff --git a/pkg/actions/bridge/argcomplete_legacy.go b/pkg/actions/bridge/argcomplete_legacy.go new file mode 100644 index 0000000..aef7468 --- /dev/null +++ b/pkg/actions/bridge/argcomplete_legacy.go @@ -0,0 +1,84 @@ +package bridge + +import ( + "os/exec" + "strconv" + "strings" + + "github.com/carapace-sh/carapace" +) + +// Deprecated: Old version which uses fd 8/9, which aren't available on powershell/windows. +func ActionArgcompleteLegacy(command ...string) carapace.Action { + return actionCommand(command...)(func(command ...string) carapace.Action { + return carapace.ActionCallback(func(c carapace.Context) carapace.Action { + if _, err := exec.LookPath(command[0]); err != nil { + return carapace.ActionMessage(err.Error()) + } + + args := append(command[1:], c.Args...) + current := c.Value + + prefix := "" + if strings.HasPrefix(current, "--") { + if strings.Contains(current, "=") { // optarg flag which is handled as normal arg by the completer + splitted := strings.SplitN(current, "=", 2) + prefix = splitted[0] + "=" + args = append(args, splitted[0]) // add flag as arg + current = "" // seem partial optarg value isn't completed + + } else { + current = "--" // seems partial flag names aren't completed so get all + } + } else { + current = "" // seems partial positional arguments aren't completed as well + } + + compLine := command[0] + " " + strings.Join(append(args, current), " ") // TODO escape/quote special characters + c.Setenv("_ARGCOMPLETE", "1") + c.Setenv("_ARGCOMPLETE_DFS", "\t") + c.Setenv("_ARGCOMPLETE_IFS", "\n") + c.Setenv("_ARGCOMPLETE_SHELL", "fish") + c.Setenv("_ARGCOMPLETE_SUPPRESS_SPACE", "1") // TODO needed? relevant for nospace detection? + // c.Setenv("_ARGCOMPLETE_COMP_WORDBREAKS", " ") // TODO set to space-only for multiparts? + c.Setenv("_ARGCOMPLETE", "1") + c.Setenv("COMP_LINE", compLine) + c.Setenv("COMP_POINT", strconv.Itoa(len(compLine))) + nospace := false + a := carapace.ActionExecCommand("sh", "-c", command[0]+" 8>&1 9>&2 1>/dev/null 2>/dev/null")(func(output []byte) carapace.Action { + lines := strings.Split(string(output), "\n") + vals := make([]string, 0) + isFlag := strings.HasPrefix(c.Value, "-") + for _, line := range lines[:len(lines)-1] { + if !isFlag && strings.HasPrefix(line, "-") { + continue + } + if strings.HasSuffix(line, "=") || + strings.HasSuffix(line, "/") || + strings.HasSuffix(line, ",") { + nospace = true + } + if splitted := strings.SplitN(line, "\t", 2); splitted[0] != "" { + vals = append(vals, splitted...) + if len(splitted) < 2 { + vals = append(vals, "") + } + } + } + + if len(vals) == 0 { + // fallback to file completions when no values returned + if index := strings.Index(c.Value, "="); index > -1 { + return carapace.ActionFiles().Invoke(carapace.Context{Value: c.Value[index+1:]}).ToA() + } + return carapace.ActionFiles() + } + return carapace.ActionValuesDescribed(vals...) + }).Invoke(c).Prefix(prefix).ToA() // re-add optarg prefix + if nospace { + return a.NoSpace() + } + return a + }) + }) +}