Add Cmd.Shortcuts

pull/97/head v0.12.0
rwxrob 2 years ago
parent c5d6bb50aa
commit c7583b8f82
No known key found for this signature in database
GPG Key ID: 2B9111F33082AE77

@ -89,6 +89,8 @@ type Command interface {
GetName() string
GetTitle() string
GetAliases() []string
GetShortcutsMap() map[string][]string
GetShortcuts() []string
GetSummary() string
GetUsage() string
GetVersion() string

@ -290,6 +290,20 @@ func ArgsOrIn(args []string) string {
return strings.Join(args, " ")
}
// ArgMap is a map keyed to individual arguments that should be
// expanded by being replaced with the slice of strings. Z.Aliases and
// Cmd.Shortcuts are both ArgMaps.
type ArgMap map[string][]string
// Keys returns only the key names.
func (m ArgMap) Keys() []string {
var list []string
for k, _ := range m {
list = append(list, k)
}
return list
}
// Shortcuts allows Bonzai tree developers to create single-word
// shortcuts (similar to shell aliases) that are directly translated
// into arguments to the Bonzai tree executable by overriding the
@ -297,7 +311,7 @@ func ArgsOrIn(args []string) string {
// of strings that will replace the os.Args[2:]. A slice is used
// (instead of a string parsed with strings.Fields) to ensure that
// hard-coded arguments containing whitespace are properly handled.
var Shortcuts = make(map[string][]string)
var Shortcuts = make(ArgMap)
// AllowPanic disables TrapPanic stopping it from cleaning panic errors.
var AllowPanic = false

@ -25,6 +25,7 @@ type Cmd struct {
// main documentation, use Get* for filled template
Name string `json:"name,omitempty"` // plain
Aliases []string `json:"aliases,omitempty"` // plain
Shortcuts ArgMap `json:"shortcuts,omitempty"` // plain
Summary string `json:"summary,omitempty"` // template
Usage string `json:"usage,omitempty"` // template
Version string `json:"version,omitempty"` // template
@ -185,19 +186,19 @@ func (x *Cmd) cacheSections() {
}
}
// Run method resolves aliases and seeks the leaf Cmd. It then calls the
// leaf's first-class Call function passing itself as the first argument
// along with any remaining command line arguments. Run returns nothing
// because it usually exits the program. Normally, Run is called from
// within main() to convert the Cmd into an actual executable program.
// Exiting can be controlled, however, by calling ExitOn or ExitOff
// (primarily for testing). Use Call instead of Run when delegation is
// needed. However, avoid tight-coupling that comes from delegation with
// Call when possible. Also, Call automatically assumes the proper
// number and type of arguments have already been checked (see MinArgs,
// MaxArgs, NumArgs, etc.) which is normally done by Run. Use
// a high-level branch pkg instead (which is idiomatic for good Bonzai
// branch development).
// Run method resolves Shortcuts and Aliases and seeks the leaf Cmd. It
// then calls the leaf's first-class Call function passing itself as the
// first argument along with any remaining command line arguments. Run
// returns nothing because it usually exits the program. Normally, Run
// is called from within main() to convert the Cmd into an actual
// executable program. Exiting can be controlled, however, by calling
// ExitOn or ExitOff (primarily for testing). Use Call instead of Run
// when delegation is needed. However, avoid tight-coupling that comes
// from delegation with Call when possible. Also, Call automatically
// assumes the proper number and type of arguments have already been
// checked (see MinArgs, MaxArgs, NumArgs, etc.) which is normally done
// by Run. Use a high-level branch pkg instead (which is idiomatic for
// good Bonzai branch development).
//
// Handling Completion
//
@ -459,7 +460,8 @@ func (x *Cmd) IsHidden(name string) bool {
// Seek checks the args for command names returning the deepest along
// with the remaining arguments. Typically the args passed are directly
// from the command line.
// from the command line. Seek also sets the Caller on each Cmd found
// during resolution. Cmd.Shortcuts are expanded.
func (x *Cmd) Seek(args []string) (*Cmd, []string) {
if args == nil || x.Commands == nil {
return x, args
@ -474,6 +476,13 @@ func (x *Cmd) Seek(args []string) (*Cmd, []string) {
next.Caller = cur
cur = next
}
if len(cur.Shortcuts) > 0 {
if v, has := cur.Shortcuts[args[n]]; has {
nargs := v
nargs = append(nargs, args[n+1:]...)
return cur.Seek(nargs)
}
}
return cur, args[n:]
}
@ -604,6 +613,14 @@ func (x *Cmd) GetTitle() string { return x.Title() }
// GetAliases fulfills the bonzai.Command interface. No Fill.
func (x *Cmd) GetAliases() []string { return x.Aliases }
// GetShortcutsMap fulfills the bonzai.Command interface. No Fill.
func (x *Cmd) GetShortcutsMap() map[string][]string {
return map[string][]string(x.Shortcuts)
}
// GetShortcuts fulfills the bonzai.Command interface. No Fill.
func (x *Cmd) GetShortcuts() []string { return x.Shortcuts.Keys() }
// GetSummary fulfills the bonzai.Command interface. Uses Fill.
func (x *Cmd) GetSummary() string { return x.Fill(x.Summary) }

Loading…
Cancel
Save