Install shell completion as an optional command
This commit is contained in:
@@ -9,6 +9,9 @@ import (
|
||||
spfcobra "github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// CompletionQueryToken is the hidden request understood by generated scripts.
|
||||
const CompletionQueryToken = spfcobra.ShellCompRequestCmd
|
||||
|
||||
// CompletionScript generates a shell script for the installed executable.
|
||||
func CompletionScript(w io.Writer, executable, shell string) error {
|
||||
root := &spfcobra.Command{Use: executable}
|
||||
@@ -56,6 +59,11 @@ func replaceCompletionText(script, old, replacement string) (string, error) {
|
||||
|
||||
func adjustFishCompletion(script, name string) (string, error) {
|
||||
var err error
|
||||
cobraName := strings.NewReplacer("-", "_", ":", "_").Replace(name)
|
||||
variableName := strings.ReplaceAll(cobraName, ".", "_")
|
||||
if cobraName != variableName {
|
||||
script = strings.ReplaceAll(script, "__"+cobraName+"_", "__"+variableName+"_")
|
||||
}
|
||||
script, err = replaceCompletionText(script,
|
||||
`set -l lastArg (string escape -- (commandline -ct))`,
|
||||
"set -l lastArg (string unescape -- (commandline -ct))\n set -q lastArg[1]; or set lastArg \"\"")
|
||||
@@ -72,7 +80,7 @@ func adjustFishCompletion(script, name string) (string, error) {
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
variable := "__" + strings.NewReplacer("-", "_", ":", "_").Replace(name) + "_comp_results"
|
||||
variable := "__" + variableName + "_comp_results"
|
||||
directories := fmt.Sprintf(`if test $dirfilter -eq 1
|
||||
set -l flagPrefix (string match -r -- '^-[^=]*=' (commandline -ct))
|
||||
set --global %[1]s
|
||||
|
||||
@@ -52,6 +52,9 @@ sys.stdout.write(os.environ['PROBE_REPLY'])
|
||||
if err := os.WriteFile(filepath.Join(dir, "probe"), []byte(fixture), 0o755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.WriteFile(filepath.Join(dir, "probe.app"), []byte(fixture), 0o755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.Mkdir(filepath.Join(dir, "partial dir"), 0o755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -114,6 +117,28 @@ sys.stdout.write(os.environ['PROBE_REPLY'])
|
||||
}
|
||||
})
|
||||
}
|
||||
t.Run(shell+"/dotted executable", func(t *testing.T) {
|
||||
var generated bytes.Buffer
|
||||
if err := CompletionScript(&generated, "probe.app", shell); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.WriteFile(script, generated.Bytes(), 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
log := filepath.Join(dir, "log")
|
||||
if err := os.WriteFile(log, nil, 0o600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cmd := exec.Command("python3", "testdata/completion_terminal.py", shell, script, "probe.app --config=./par")
|
||||
cmd.Env = append(os.Environ(), "PATH="+dir+string(os.PathListSeparator)+os.Getenv("PATH"), "HOME="+dir, "TERM=xterm", "PROBE_LOG="+log, "PROBE_REPLY="+reply("./partial file\tdescription\n", spfcobra.ShellCompDirectiveNoFileComp), "PROBE_DIR="+dir)
|
||||
if out, err := cmd.CombinedOutput(); err != nil {
|
||||
t.Fatalf("shell completion: %v\n%s", err, out)
|
||||
}
|
||||
contents, err := os.ReadFile(log)
|
||||
if err != nil || !strings.Contains(string(contents), `["__complete", "--config=./par"]`) || !strings.Contains(string(contents), `["--config=./partial file"]`) {
|
||||
t.Fatalf("query and edited line: %q; read error: %v", contents, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user