diff --git a/macro.go b/macro.go new file mode 100644 index 0000000..a84e7d9 --- /dev/null +++ b/macro.go @@ -0,0 +1,9 @@ +package spec + +import "github.com/rsteube/carapace" + +var macros = make(map[string]func(string) carapace.Action) + +func AddMacro(s string, f func(string) carapace.Action) { + macros[s] = f +} diff --git a/spec.go b/spec.go index 76cbf1b..2b3ac16 100644 --- a/spec.go +++ b/spec.go @@ -154,7 +154,7 @@ func (f flag) addTo(flagSet *pflag.FlagSet) { func parseAction(cmd *cobra.Command, arr []string) carapace.Action { return carapace.ActionCallback(func(c carapace.Context) carapace.Action { - rMacro := regexp.MustCompile(`^(?P\$[^(]*)(\((?P.*)\))?$`) + rMacro := regexp.MustCompile(`^\$(?P[^(]*)(\((?P.*)\))?$`) listDelimiter := "" nospace := false @@ -166,19 +166,26 @@ func parseAction(cmd *cobra.Command, arr []string) carapace.Action { macro := match["macro"] arg := match["arg"] + if strings.HasPrefix(macro, "_") { // custom macro + if f := macros[strings.TrimPrefix(macro, "_")]; f != nil { + return f(arg) + } + return carapace.ActionMessage(fmt.Sprintf("unknown custom macro: '%v'", elem)) + } + switch macro { - case "$nospace": + case "nospace": nospace = true - case "$list": + case "list": listDelimiter = arg - case "$directories": + case "directories": return carapace.ActionDirectories() - case "$files": + case "files": if arg != "" { batch = append(batch, carapace.ActionFiles(strings.Fields(arg)...)) } batch = append(batch, carapace.ActionFiles()) - case "$": + case "": batch = append(batch, carapace.ActionCallback(func(c carapace.Context) carapace.Action { for index, arg := range c.Args { c.Setenv(fmt.Sprintf("CARAPACE_ARG%v", index), arg)