Skip to content

Commit

Permalink
expose custom macros
Browse files Browse the repository at this point in the history
  • Loading branch information
rsteube committed Dec 19, 2023
1 parent 8a179a3 commit 4830d37
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 8 deletions.
45 changes: 41 additions & 4 deletions action.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package spec
import (
"fmt"
"os"
"path/filepath"
"regexp"
"sort"
"strings"
Expand Down Expand Up @@ -47,14 +48,50 @@ func (value) JSONSchema() *jsonschema.Schema {
}
}

func executable() string {
s, err := os.Executable()
if err != nil {
panic(err.Error()) // TODO handle error, eval symlink, how to handle "go test"
}

return filepath.Base(s)
}

// ActionMacro completes given macro
func ActionMacro(s string) carapace.Action {
return carapace.ActionCallback(func(c carapace.Context) carapace.Action {
m, err := macros.Lookup(s)
if err != nil {
return carapace.ActionMessage(err.Error())
r := regexp.MustCompile(`^\$(?P<macro>[^(]*)(\((?P<arg>.*)\))?$`)
matches := r.FindStringSubmatch(s)
if matches == nil {
return carapace.ActionMessage("malformed macro: %#v", s)
}
if strings.HasPrefix(matches[1], "_") && !strings.HasPrefix(matches[1], "_.") {
return carapace.ActionMessage(`"$_" deprecated: replace %#v with %#v`, "$"+matches[1], "$carapace."+strings.TrimPrefix(matches[1], "_"))
}
prefix := fmt.Sprintf("$%v.", executable())

switch {
case !strings.HasPrefix(matches[1], "_.") && strings.Contains(matches[1], ".") && !strings.HasPrefix(s, prefix):
splitted := strings.SplitN(strings.TrimPrefix(s, "$"), ".", 2)
args := []string{"_carapace", "macro"}
args = append(args, splitted[1])
args = append(args, c.Args...)
args = append(args, c.Value)
carapace.LOG.Printf("%#v", args)
return carapace.ActionExecCommand(splitted[0], args...)(func(output []byte) carapace.Action {
return carapace.ActionImport(output)
})

default:
if strings.HasPrefix(s, prefix) {
s = "$_." + strings.TrimPrefix(s, prefix)
}
m, err := macros.Lookup(s)
if err != nil {
return carapace.ActionMessage(err.Error())
}
return m.Parse(s)
}
return m.Parse(s)
})
}

Expand Down
4 changes: 4 additions & 0 deletions cmd/carapace-spec/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,11 @@ func init() {
default:
cmd.Flags().Parse(args[:1]) // TODO unnecessary
}

})

spec.AddMacro("Spec", spec.MacroI(spec.ActionSpec))
spec.Register(rootCmd)
}

func bridgeCompletion(cmd *cobra.Command, spec string, args ...string) {
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.18

require (
github.com/invopop/jsonschema v0.12.0
github.com/rsteube/carapace v0.47.0
github.com/rsteube/carapace v0.47.3
github.com/spf13/cobra v1.8.0
github.com/spf13/pflag v1.0.5
gopkg.in/yaml.v3 v3.0.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFF
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/rsteube/carapace v0.47.0 h1:2mt1sGsNcqvh+XzG070FGSG8EXMIRGdgYt0SOo/DaWQ=
github.com/rsteube/carapace v0.47.0/go.mod h1:4ZC5bulItu9t9sZ5yPcHgPREd8rPf274Q732n+wfl/o=
github.com/rsteube/carapace v0.47.3 h1:g+R4mKPzuV6aPcztQR+kpZlLAqRFvUSG2aM/9JaOIUw=
github.com/rsteube/carapace v0.47.3/go.mod h1:4ZC5bulItu9t9sZ5yPcHgPREd8rPf274Q732n+wfl/o=
github.com/rsteube/carapace-shlex v0.1.1 h1:fRQEBBKyYKm4TXUabm4tzH904iFWSmXJl3UZhMfQNYU=
github.com/rsteube/carapace-shlex v0.1.1/go.mod h1:zPw1dOFwvLPKStUy9g2BYKanI6bsQMATzDMYQQybo3o=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
Expand Down
2 changes: 1 addition & 1 deletion macro.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func addCoreMacro(s string, m Macro) {

// AddMacro adds a custom macro
func AddMacro(s string, m Macro) {
macros["_"+s] = m
macros["_."+s] = m
}

func MacroN(f func() carapace.Action) Macro {
Expand Down
82 changes: 82 additions & 0 deletions register.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package spec

import (
"fmt"
"sort"
"strings"

"github.com/rsteube/carapace"
"github.com/spf13/cobra"
)

func Register(cmd *cobra.Command) {
carapace.Gen(cmd)

carapaceCmd, _, err := cmd.Find([]string{"_carapace"}) // TODO provide access to it using `carapace.Gen`
if err != nil {
carapace.LOG.Println(err.Error())
return // should never happen
}

macroCmd := &cobra.Command{
Use: "macro",
RunE: func(cmd *cobra.Command, args []string) error {
switch len(args) {
case 0:
keys := make([]string, 0, len(macros))
for k := range macros {
keys = append(keys, k)
}
sort.Strings(keys)

for _, key := range keys {
if strings.HasPrefix(key, "_") {
fmt.Fprintln(cmd.OutOrStdout(), strings.TrimPrefix(key, "_"))
}
}
case 1:
m, ok := macros["_."+args[0]]
if !ok {
return fmt.Errorf("unknown macro: %v", args[0])
}
fmt.Fprintln(cmd.OutOrStdout(), m.Signature())
default:
mCmd := &cobra.Command{
DisableFlagParsing: true,
}
carapace.Gen(mCmd).Standalone()
carapace.Gen(mCmd).PositionalAnyCompletion(
ActionMacro("$_." + args[0]),
)
carapace.LOG.Printf("%#v", args)
mCmd.SetArgs(append([]string{"_carapace", "export", ""}, args[1:]...))
mCmd.SetOut(cmd.OutOrStdout())
mCmd.SetErr(cmd.ErrOrStderr())
return mCmd.Execute()
}
return nil
},
}

macroCmd.Flags().SetInterspersed(false)

carapaceCmd.AddCommand(macroCmd)

carapace.Gen(macroCmd).PositionalCompletion(
carapace.ActionCallback(func(c carapace.Context) carapace.Action {
vals := make([]string, 0, len(macros))
for key := range macros {
if strings.HasPrefix(key, "_.") {
vals = append(vals, strings.TrimPrefix(key, "_."))
}
}
return carapace.ActionValues(vals...).MultiParts(".")
}),
)

carapace.Gen(macroCmd).PositionalAnyCompletion(
carapace.ActionCallback(func(c carapace.Context) carapace.Action {
return ActionMacro("$_." + c.Args[0]).Shift(1)
}),
)
}

0 comments on commit 4830d37

Please sign in to comment.