Skip to content

Commit

Permalink
Merge pull request #1076 from rsteube/spec-completion
Browse files Browse the repository at this point in the history
added spec completion
  • Loading branch information
rsteube authored May 1, 2022
2 parents 30b61d7 + dab567b commit 4148558
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 1 deletion.
18 changes: 17 additions & 1 deletion cmd/carapace/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (
)

var rootCmd = &cobra.Command{
Use: "carapace [flags] [COMPLETER] [bash|elvish|fish|oil|powershell|tcsh|xonsh|zsh]",
Use: "carapace [flags] [COMPLETER] [bash|elvish|fish|nushell|oil|powershell|tcsh|xonsh|zsh]",
Long: "multi-shell multi-command argument completer",
Example: fmt.Sprintf(` Single completer:
bash: source <(carapace chmod bash)
Expand Down Expand Up @@ -45,11 +45,23 @@ var rootCmd = &cobra.Command{
bash: source <(carapace --bridge vault/posener)
elvish: eval (carapace --bridge vault/posener|slurp)
fish: carapace --bridge vault/posener | source
nushell: carapace --bridge vault/posener | save vault.nu ; nu -c 'source vault.nu'
oil: source <(carapace --bridge vault/posener)
powershell: carapace --bridge vault/posener | Out-String | Invoke-Expression
tcsh: eval `+"`"+`carapace --bridge vault/posener`+"`"+`
xonsh: exec($(carapace --bridge vault/posener))
zsh: source <(carapace --bridge vault/posener)
Spec completion:
bash: source <(carapace --spec example.yaml)
elvish: eval (carapace --spec example.yaml|slurp)
fish: carapace --spec example.yaml | source
oil: source <(carapace --spec example.yaml)
nushell: carapace --spec example.yaml | save example.nu ; nu -c 'source example.nu'
powershell: carapace --spec example.yaml | Out-String | Invoke-Expression
tcsh: eval `+"`"+`carapace --spec example.yaml`+"`"+`
xonsh: exec($(carapace --spec example.yaml))
zsh: source <(carapace --spec example.yaml)
Style:
set: carapace --style 'carapace.Value=bold,magenta'
Expand All @@ -71,6 +83,10 @@ var rootCmd = &cobra.Command{
bridgeCompletion(splitted[0], splitted[1], args[2:]...)
}
}
case "--spec":
if len(args) > 1 {
specCompletion(args[1], args[2:]...)
}
case "-h":
cmd.Help()
case "--help":
Expand Down
70 changes: 70 additions & 0 deletions cmd/carapace/cmd/spec.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package cmd

import (
"bytes"
"fmt"
"github.com/rsteube/carapace-spec"
"github.com/spf13/cobra"
"gopkg.in/yaml.v3"
"io"
"os"
"path/filepath"
"strings"
)

func loadSpec(path string) (string, *cobra.Command, error) {
abs, err := filepath.Abs(path)
if err != nil {
return "", nil, err
}

content, err := os.ReadFile(abs)
if err != nil {
return "", nil, err
}

var specCmd spec.Command
if err := yaml.Unmarshal(content, &specCmd); err != nil {
return "", nil, err
}
return abs, specCmd.ToCobra(), nil
}

func specCompletion(path string, args ...string) {
old := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w

outC := make(chan string)
// copy the output in a separate goroutine so printing can't block indefinitely
go func() {
var buf bytes.Buffer
io.Copy(&buf, r)
outC <- buf.String()
}()

abs, cmd, err := loadSpec(path)
if err != nil {
return /// TODO handle error
}

a := []string{"_carapace"}
a = append(a, args...)
cmd.SetArgs(a)
cmd.Execute()

w.Close()
out := <-outC
os.Stdout = old

executable, err := os.Executable()
if err != nil {
panic(err.Error()) // TODO exit with error message
}

executableName := filepath.Base(executable)
patched := strings.Replace(string(out), fmt.Sprintf("%v _carapace", executableName), fmt.Sprintf("%v --spec %v", executableName, abs), -1) // general callback
patched = strings.Replace(patched, fmt.Sprintf("'%v', '_carapace'", executableName), fmt.Sprintf("'%v', '--spec', '%v'", executableName, abs), -1) // xonsh callback
fmt.Print(patched)

}
2 changes: 2 additions & 0 deletions completers/carapace_completer/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ func flagCmd() *cobra.Command {
cmd.Flags().String("bridge", "", "generic completion bridge")
cmd.Flags().BoolP("help", "h", false, "help for carapace")
cmd.Flags().Bool("list", false, "list completers")
cmd.Flags().String("spec", "", "spec completion")
cmd.Flags().StringSlice("style", []string{}, "set style")
cmd.Flags().BoolP("version", "v", false, "version for carapace")

Expand All @@ -53,6 +54,7 @@ func flagCmd() *cobra.Command {
return carapace.ActionValues()
}
}),
"spec": carapace.ActionFiles(".yaml"),
"style": carapace.ActionStyleConfig(),
})
return cmd
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
github.com/mitchellh/go-ps v1.0.0
github.com/pelletier/go-toml v1.9.5
github.com/rsteube/carapace v0.20.1
github.com/rsteube/carapace-spec v0.0.4
github.com/spf13/cobra v1.4.0
github.com/spf13/pflag v1.0.5
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rsteube/carapace v0.20.1 h1:ZnPtEZQGi4vSoco7yLexTvmx9X82jUaOcDScpl3v14M=
github.com/rsteube/carapace v0.20.1/go.mod h1:GgiwpPVhucHNOv0AmtIkxhiEFkCMP5BBRauyQLP0mFY=
github.com/rsteube/carapace-spec v0.0.4 h1:ZXqtUGw+Qp+hu3RVIXrp2Xv7hmZa6nxFZnfkyzxeC3k=
github.com/rsteube/carapace-spec v0.0.4/go.mod h1:u6Qe+U4w4/yD1MWRV9k83WuCkqq4Z/rAjzj8gz7zS9M=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q=
github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g=
Expand Down

0 comments on commit 4148558

Please sign in to comment.