Documentation ¶
Overview ¶
Package Z (bonzai) provides a rooted node tree of commands and singular parameters making tab completion a breeze and complicated applications much easier to intuit without reading all the docs. Documentation is embedded with each command removing the need for separate man pages and such and can be viewed as text or a locally served web page.
Rooted Node Tree ¶
Commands and parameters are linked to create a rooted node tree of the following types of nodes:
- Leaves with a method and optional parameters
- Branches with leaves, other branches, and a optional method
- Parameters, single words that are passed to a leaf command
Index ¶
- Constants
- Variables
- func ArgsFrom(line string) []string
- func ArgsOrIn(args []string) string
- func Emph[T string | []byte | []rune](buf T) string
- func Emphf(a string, f ...any) string
- func Esc(s string) string
- func EscAll(args []string) []string
- func Exec(args ...string) error
- func Exit()
- func ExitError(err ...interface{})
- func ExitOff()
- func ExitOn()
- func FindPager() string
- func FixPagerEnv()
- func InWrap(in string) string
- func InWrapf(a string, f ...any) string
- func Indent(in string) string
- func Indentf(a string, f ...any) string
- func InferredUsage(cmd bonzai.Command) string
- func Lines(in string) []string
- func Mark(in string) string
- func Markf(a string, f ...any) string
- func Out(args ...string) string
- func Page[T any](buf T) error
- func PageFile(path string) error
- func PrintEmph(a string)
- func PrintEmphf(a string, f ...any)
- func PrintInWrap(a string)
- func PrintInWrapf(a string, f ...any)
- func PrintIndent(a string)
- func PrintIndentf(a string, f ...any)
- func PrintMark(a string)
- func PrintMarkf(a string, f ...any)
- func PrintWrap(a string)
- func PrintWrapf(a string, f ...any)
- func Run()
- func SysExec(args ...string) error
- func UsageGroup(args []string, min, max int) string
- func Wrap(in string) string
- func Wrapf(a string, f ...any) string
- type ArgMap
- type Block
- type Cmd
- func (x *Cmd) Add(name string, aliases ...string) *Cmd
- func (x *Cmd) C(q string) (string, error)
- func (x *Cmd) CmdNames() []string
- func (x *Cmd) Del(key string) error
- func (x *Cmd) Fill(tmpl string) string
- func (x *Cmd) Get(key string) (string, error)
- func (x *Cmd) GetAliases() []string
- func (x *Cmd) GetCaller() bonzai.Command
- func (x *Cmd) GetCommandNames() []string
- func (x *Cmd) GetCommands() []bonzai.Command
- func (x *Cmd) GetComp() bonzai.Completer
- func (x *Cmd) GetCopyright() string
- func (x *Cmd) GetDescription() string
- func (x *Cmd) GetHidden() []string
- func (x *Cmd) GetIssues() string
- func (x *Cmd) GetLegal() string
- func (x *Cmd) GetLicense() string
- func (x *Cmd) GetMaxParm() int
- func (x *Cmd) GetMinArgs() int
- func (x *Cmd) GetMinParm() int
- func (x *Cmd) GetName() string
- func (x *Cmd) GetOther() []bonzai.Section
- func (x *Cmd) GetOtherTitles() []string
- func (x *Cmd) GetParams() []string
- func (x *Cmd) GetShortcuts() []string
- func (x *Cmd) GetShortcutsMap() map[string][]string
- func (x *Cmd) GetSite() string
- func (x *Cmd) GetSource() string
- func (x *Cmd) GetSummary() string
- func (x *Cmd) GetTitle() string
- func (x *Cmd) GetUsage() string
- func (x *Cmd) GetUseConf() bool
- func (x *Cmd) GetUseVars() bool
- func (x *Cmd) GetVersion() string
- func (x *Cmd) IsHidden(name string) bool
- func (x *Cmd) Log(format string, a ...any)
- func (x *Cmd) Names() []string
- func (x *Cmd) OtherTitles() []string
- func (x *Cmd) Param(p string) string
- func (x *Cmd) Path(more ...string) string
- func (x *Cmd) PathCmds() []*Cmd
- func (x *Cmd) PathNames() []string
- func (x *Cmd) Resolve(name string) *Cmd
- func (x *Cmd) Root() *Cmd
- func (x *Cmd) Run()
- func (x *Cmd) Seek(args []string) (*Cmd, []string)
- func (x *Cmd) Set(key, val string) error
- func (x *Cmd) Title() string
- func (x *Cmd) UsageCmdNames() string
- func (x *Cmd) UsageCmdShortcuts() string
- func (x *Cmd) UsageCmdTitles() string
- func (x *Cmd) UsageError() error
- func (x *Cmd) UsageNames() string
- func (x *Cmd) UsageParams() string
- type DefCmdReqCall
- type IncorrectUsage
- type Method
- type MissingConf
- type MissingVar
- type MultiCallCmdArgNotString
- type MultiCallCmdNotCmd
- type MultiCallCmdNotFound
- type NoCallNoCommands
- type NotEnoughArgs
- type Section
- type TooManyArgs
- type UsesConf
- type UsesVars
- type VarVals
- type WrongNumArgs
Examples ¶
- ArgsFrom
- ArgsOrIn (Args_Joined)
- ArgsOrIn (Read_Nil)
- ArgsOrIn (Read_Zero_Args)
- Blocks (Bulleted)
- Blocks (Numbered)
- Blocks (Paragraph)
- Blocks (Verbatim)
- Cmd.CmdNames
- Cmd.GetCommandNames
- Cmd.GetParams
- Cmd.Names
- Cmd.Path
- Cmd.Seek
- Cmd.UsageCmdShortcuts
- Cmd.UsageCmdTitles
- Cmd.UsageError (Commands_with_Aliases)
- Cmd.UsageError (No_Call_nor_Commands)
- Cmd.UsageError (Params_but_No_Call)
- Cmd.UsageNames
- Cmd.UsageParams
- Emph (Basics)
- Emph (Bold)
- Emph (BoldItalic)
- Emph (Code)
- Emph (Italic)
- Emph (Under)
- Emphf
- Esc
- EscAll
- InWrap
- InWrapf
- Indent
- Indentf
- InferredUsage (Commands)
- InferredUsage (Commands_and_Params)
- InferredUsage (Error_No_Call_or_Command)
- InferredUsage (Error_Params_without_Call)
- InferredUsage (Min_3_Param)
- InferredUsage (Min_One_Param)
- InferredUsage (Optional_Param)
- Lines
- Mark
- Mark (Simple)
- Markf
- PrintEmph (Basics)
- PrintEmphf
- PrintInWrap
- PrintInWrapf
- PrintIndentf
- PrintMark
- PrintMarkf
- PrintWrap
- UsageGroup
- Wrap
- Wrapf
Constants ¶
const ( Paragraph = iota + 1 Numbered Bulleted Verbatim )
Variables ¶
var AllowPanic = false
AllowPanic disables TrapPanic stopping it from cleaning panic errors.
var CallDummy = func(_ *Cmd, args ...string) error { return nil }
CallDummy is useful for testing when non-nil Call function needed.
var Columns = int(term.WinSize.Col)
Columns is the number of bytes (not runes) at which Wrap will wrap. By default detects the terminal width (if possible) otherwise keeps 80 standard. Bonzai command tree creator can change this for every composite command imported their application in this one place.
var Commands map[string][]any
Commands contains the Cmds to lookup when executing with Z.Run in "multicall" mode. Each value of the slice keyed to the name must begin with a *Cmd and the rest will be assumed to be string arguments to prepend. This allows the table of Commands to not only associate with a specific Cmd, but to also provide different arguments to that command. The name Commands is similar to Cmd.Commands. See Run.
var Comp = compcmd.New()
Comp may be optionally assigned any implementation of bonzai.Completer and will be used as the default if a Command does not provide its own. Comp is assigned compcmd.Completer by default. This can be overriden by Bonzai tree developers through simple assignment to their own preference. However, for consistency, this default is strongly recommended, at least for all branch commands (as opposed to leafs). See z.Cmd.Run for documentation on completion mode.
var Conf bonzai.Configurer
Conf may be optionally assigned any implementation of a bonzai.Configurer. Once assigned it should not be reassigned at any later time during runtime. Certain Bonzai branches and commands may require Z.Conf to be defined and those that do generally require the same implementation throughout all of runtime. Commands that require Z.Conf should set ReqConf to true. Other than the exceptional case of configuration commands that fulfill bonzai.Configurer (and usually assign themselves to Z.Conf at init() time), commands must never require a specific implementation of bonzai.Configurer. This encourages command creators and Bonzai tree composers to centralize on a single form of configuration without creating brittle dependencies and tight coupling. Configuration persistence can be implemented in any number of ways without a problem and Bonzai trees simply need to be recompiled with a different bonzai.Configurer implementation to switch everything that depends on configuration.
var DoNotExit bool
DoNotExit effectively disables Exit and ExitError allowing the program to continue running, usually for test evaluation.
var Dynamic = template.FuncMap{ "exe": func(a string) string { return term.Under + a + term.Reset }, "pkg": func(a string) string { return term.Bold + a + term.Reset }, "cmd": func(a string) string { return term.Bold + a + term.Reset }, "indent": indent, "pre": func(a string) string { return term.Under + a + term.Reset }, "exepath": exepath, "exename": exename, "execachedir": execachedir, "execonfdir": execonfdir, "cachedir": cachedir, "confdir": confdir, "homedir": homedir, "pathsep": func() string { return string(os.PathSeparator) }, "pathjoin": filepath.Join, }
Dynamic contains the package global default template language which can be supplemented or overridden by Bonzai developers. Note this is in addition to any specific syntax added specifically to a Cmd with Cmd.Dynamic (which takes higher priority). Use Z.Dynamic when a shared template language is to be used across all Cmds within a single Bonzai tree or branch. This allows powerful, template-driven applications to work well with one another.
var EscThese = " \r\t\n|&;()<>![]"
EscThese is set to the default UNIX shell characters which require escaping to be used safely on the terminal. It can be changed to suit the needs of different host shell environments.
var ExeName string
ExeName holds just the base name of the executable without any suffix (ex: .exe) and is set at init() time (see ExePath).
var ExePath string
ExePath holds the full path to the current running process executable which is determined at init() time by calling os.Executable and passing it to path/filepath.EvalSymlinks to ensure it is the actual binary executable file. Errors are reported to stderr, but there should never be an error logged unless something is wrong with the Go runtime environment.
var IndentBy = 7
IndentBy is the number of spaces to indent in Indent. Default is 7. Bonzai command tree creator can change this for every composite command imported their application in this one place.
var NoPager bool
NoPager disables all paging.
var TrapPanic = func() { if !AllowPanic { if r := recover(); r != nil { log.Println(r) os.Exit(1) } } }
TrapPanic recovers from any panic and more gracefully displays the panic by logging it before exiting with a return value of 1.
var UsageFunc = InferredUsage
UsageFunc is the default first-class function called if a Cmd that does not already define its own when usage information is needed (see bonzai.UsageFunc and Cmd.UsageError for more). By default, InferredUsage is assigned.
It is used to return a usage summary. Generally, it should only return a single line (even if that line is very long). Developers are encouraged to refer users to their chosen help command rather than producing usually long usage lines.
var Vars bonzai.Vars
Vars may be optionally assigned any implementation of a bonzai.Vars but this is normally assigned at init() time by a bonzai.Vars driver module. Once assigned it should not be reassigned at any later time during runtime. Certain Bonzai branches and commands may require Z.Vars to be defined and those that do generally require the same implementation throughout all of runtime. Commands that require Z.Vars should set ReqVars to true. Other than the exceptional case of configuration commands that fulfill bonzai.Vars (and usually assign themselves to Z.Vars at init() time), commands must never require a specific implementation of bonzai.Vars. This encourages command creators and Bonzai tree composers to centralize on a single form of caching without creating brittle dependencies and tight coupling. Caching persistence can be implemented in any number of ways without a problem and Bonzai trees simply need to be recompiled with a different bonzai.Vars implementation to switch everything that depends on cached variables.
Functions ¶
func ArgsFrom ¶
ArgsFrom returns a list of field strings split on space with an extra trailing special space item appended if the line has any trailing spaces at all signifying a definite word boundary and not a potential prefix.
Example ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { fmt.Printf("%q\n", Z.ArgsFrom(`greet hi french`)) fmt.Printf("%q\n", Z.ArgsFrom(`greet hi french `)) }
Output: ["greet" "hi" "french"] ["greet" "hi" "french" ""]
func ArgsOrIn ¶
ArgsOrIn takes an slice or nil as argument and if the slice has any length greater than 0 returns all the argument joined together with a single space between them. Otherwise, will read standard input until end of file reached (Cntl-D). Returns empty string if error.
Example (Args_Joined) ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { fmt.Println(Z.ArgsOrIn([]string{"some", "thing"})) }
Output: some thing
Example (Read_Nil) ¶
package main import ( "fmt" "os" Z "github.com/rwxrob/bonzai/z" ) func main() { orig := os.Stdin defer func() { os.Stdin = orig }() os.Stdin, _ = os.Open(`testdata/in`) fmt.Println(Z.ArgsOrIn(nil)) }
Output: some thing input with blank line
Example (Read_Zero_Args) ¶
package main import ( "fmt" "os" Z "github.com/rwxrob/bonzai/z" ) func main() { orig := os.Stdin defer func() { os.Stdin = orig }() os.Stdin, _ = os.Open(`testdata/in`) fmt.Println(Z.ArgsOrIn([]string{})) }
Output: some thing input with blank line
func Emph ¶
Emph renders BonzaiMark emphasis spans specifically for VT100-compatible terminals (which almost all are today):
*Italic* **Bold** ***BoldItalic*** <Under> (keeping brackets) `Code`
See Mark for block formatting and term for terminal rendering.
Example (Basics) ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" "github.com/rwxrob/term" ) func main() { // Emph observes the term escapes // (see package documentation for more) term.Bold = `<bold>` term.BoldItalic = `<bolditalic>` term.Under = `<under>` term.Reset = `<reset>` fmt.Println(Z.Emph("*ITALIC*")) fmt.Println(Z.Emph("**BOLD**")) fmt.Println(Z.Emph("***BOLDITALIC***")) fmt.Println(Z.Emph("<UNDER>")) // keeps brackets }
Output: <italic>ITALIC<reset> <bold>BOLD<reset> <bolditalic>BOLDITALIC<reset> <<under>UNDER<reset>>
Example (Bold) ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" "github.com/rwxrob/term" ) func main() { term.Bold = `<bold>` term.Reset = `<reset>` fmt.Println(Z.Emph("**Bold**")) fmt.Println(Z.Emph("** Bold **")) }
Output: <bold>Bold<reset> ** Bold **
Example (BoldItalic) ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" "github.com/rwxrob/term" ) func main() { term.BoldItalic = `<bolditalic>` term.Reset = `<reset>` fmt.Println(Z.Emph("***BoldItalic***")) }
Output: <bolditalic>BoldItalic<reset>
Example (Code) ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" "github.com/rwxrob/term" ) func main() { term.Under = `<code>` term.Reset = `<reset>` fmt.Println(Z.Emph("`Code`")) fmt.Println(Z.Emph("` Code `")) fmt.Println(Z.Emph("`.git`")) }
Output: <code>Code<reset> ` Code ` <code>.git<reset>
Example (Italic) ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" "github.com/rwxrob/term" ) func main() { term.Italic = `<italic>` term.Reset = `<reset>` fmt.Println(Z.Emph("*Italic*")) fmt.Println(Z.Emph("* Italic *")) }
Output: <italic>Italic<reset> * Italic *
Example (Under) ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" "github.com/rwxrob/term" ) func main() { term.Under = `<under>` term.Reset = `<reset>` fmt.Println(Z.Emph("<UNDER>")) fmt.Println(Z.Emph("< UNDER >")) }
Output: <<under>UNDER<reset>> < UNDER >
func Emphf ¶
Emphf calls fmt.Sprintf on the string before passing it to Emph.
Example ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { fmt.Println(Z.Emphf(`some *%v* thing`, "italic")) }
Output: some <italic>italic<reset> thing
func Esc ¶
Esc returns a shell-escaped version of the string s. The returned value is a string that can safely be used as one token in a shell command line.
Example ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { fmt.Println(Z.Esc("|&;()<>![]")) fmt.Printf("%q", Z.Esc(" \n\r")) }
Output: \|\&\;\(\)\<\>\!\[\] "\\ \\\n\\\r"
func EscAll ¶
EscAll calls Esc on all passed strings.
Example ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { list := []string{"so!me", "<here>", "other&"} fmt.Println(Z.EscAll(list)) }
Output: [so\!me \<here\> other\&]
func Exec ¶
Exec checks for existence of first argument as an executable on the system and then runs it with exec.Command.Run exiting in a way that is supported across all architectures that Go supports. The stdin, stdout, and stderr are connected directly to that of the calling program. Sometimes this is insufficient and the UNIX-specific SysExec is preferred. See exec.Command.Run for more about distinguishing ExitErrors from others.
func Exit ¶
func Exit()
Exit calls os.Exit(0) unless DoNotExit has been set to true. Cmds should never call Exit themselves returning a nil error from their Methods instead.
func ExitError ¶
func ExitError(err ...interface{})
ExitError prints err and exits with 1 return value unless DoNotExit has been set to true. Commands should usually never call ExitError themselves returning an error from their Method instead.
func FindPager ¶ added in v0.20.0
func FindPager() string
FindPager returns a full path to a pager binary if it can find one on the system:
- $PAGER
- pager (in PATH)
If neither is found returns an empty string.
func FixPagerEnv ¶ added in v0.20.2
func FixPagerEnv()
FixPagerEnv sets environment variables for different pagers to get them to support color ANSI escapes. FRX is added to LESS and LV is set to -c. (These are the same fixes used by the git diff command.)
func InWrap ¶
InWrap combines both Wrap and Indent.
Example ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { defer func() { Z.IndentBy = Z.IndentBy }() indent := Z.IndentBy col := Z.Columns Z.Columns = 10 Z.IndentBy = 4 fmt.Printf("%q", Z.InWrap("some\nthat is \n indented")) Z.IndentBy = indent Z.Columns = col }
Output: " some\n that\n is\n indented\n"
func InWrapf ¶
InWrapf calls fmt.Sprintf on the string before passing it to InWrap.
Example ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { in := Z.IndentBy col := Z.Columns Z.IndentBy = 3 Z.Columns = 10 fmt.Println( Z.InWrapf("-----\nindented by %v here and wrapped at %v", Z.IndentBy, Z.Columns, )) Z.IndentBy = in Z.Columns = col // ----- // indented // by 3 // here // and // wrapped // at 10 }
Output:
func Indent ¶
Indent indents the number of spaces set by IndentBy.
Example ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { indent := Z.IndentBy col := Z.Columns Z.Columns = 10 Z.Columns = 10 Z.IndentBy = 4 fmt.Printf("%q", Z.Indent("some\nthat is \n indented")) Z.IndentBy = indent Z.Columns = col }
Output: " some\n that is \n indented\n"
func Indentf ¶
Indentf calls fmt.Sprintf on the string before passing it to Indent.
Example ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { in := Z.IndentBy Z.IndentBy = 3 fmt.Println(Z.Indentf("-----\nindented by %v here", Z.IndentBy)) Z.IndentBy = in }
Output: ----- indented by 3 here
func InferredUsage ¶
InferredUsage returns a single line of text summarizing only the Commands (less any Hidden commands), Params, and Aliases. If a Cmd is currently in an invalid state (Params without Call, no Call and no Commands) a string beginning with ERROR and wrapped in braces ({}) is returned instead. The string depends on the current language (see lang.go). Note that aliases does not include package Z.Aliases.
Example (Commands) ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { x := &Z.Cmd{ Commands: []*Z.Cmd{ &Z.Cmd{Name: "foo", Aliases: []string{"f"}}, &Z.Cmd{Name: "bar"}, }, } fmt.Println(Z.InferredUsage(x)) }
Output: ((f|foo)|bar)
Example (Commands_and_Params) ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { x := &Z.Cmd{ Params: []string{"p1", "p2"}, Commands: []*Z.Cmd{ &Z.Cmd{Name: "foo", Aliases: []string{"f"}}, &Z.Cmd{Name: "bar"}, }, Call: func(_ *Z.Cmd, _ ...string) error { return nil }, } fmt.Println(Z.InferredUsage(x)) }
Output: ((p1|p2)?|((f|foo)|bar))
Example (Error_No_Call_or_Command) ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { x := &Z.Cmd{ Params: []string{"p1", "p2"}, } fmt.Println(Z.InferredUsage(x)) }
Output: {ERROR: neither Call nor Commands defined}
Example (Error_Params_without_Call) ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { x := &Z.Cmd{ Params: []string{"p1", "p2"}, Commands: []*Z.Cmd{ &Z.Cmd{Name: "foo", Aliases: []string{"f"}}, &Z.Cmd{Name: "bar"}, }, } fmt.Println(Z.InferredUsage(x)) }
Output: {ERROR: Params without Call: p1, p2}
Example (Min_3_Param) ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { x := &Z.Cmd{ Params: []string{"p1", "p2"}, MinParm: 3, Call: func(_ *Z.Cmd, _ ...string) error { return nil }, } fmt.Println(Z.InferredUsage(x)) }
Output: (p1|p2){3,}
Example (Min_One_Param) ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { x := &Z.Cmd{ Params: []string{"p1", "p2"}, MinParm: 1, Call: func(_ *Z.Cmd, _ ...string) error { return nil }, } fmt.Println(Z.InferredUsage(x)) }
Output: (p1|p2)+
Example (Optional_Param) ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { x := &Z.Cmd{ Params: []string{"p1", "p2"}, Call: func(_ *Z.Cmd, _ ...string) error { return nil }, } fmt.Println(Z.InferredUsage(x)) }
Output: (p1|p2)?
func Lines ¶
Lines returns the string converted into a slice of lines.
Example ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { fmt.Printf("%q\n", Z.Lines("line one\nline two")) }
Output: ["line one" "line two"]
func Mark ¶
Mark parses the input as a string of BonzaiMark, multiple blocks with optional emphasis (see Blocks and Emph) and applies IndentBy and Columns wrapping to it.
Example ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { in := ` Must have *another* block before verbatim: Now we can start a Verbatim block. Which can have blank lines, even. And back to a paragraph block. * **foo** * bar And a numbered list 1. Something 2. here That's really it. ` fmt.Println("----------------------") fmt.Print(Z.Mark(in)) fmt.Println("----------------------") }
Output: ---------------------- Must have <italic>another<reset> block before verbatim: Now we can start a Verbatim block. Which can have blank lines, even. And back to a paragraph block. * <bold>foo<reset> * bar And a numbered list 1. Something 2. here That's really it. ----------------------
Example (Simple) ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { fmt.Print(Z.Mark(`**foo**`)) }
Output: <bold>foo<reset>
func Markf ¶
Markf calls fmt.Sprintf on the string before passing it to Mark.
Example ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { in := ` Must have *%v* block before verbatim: Now we can start a Verbatim block. Which can have blank lines, even. And back to a %v block. * **foo** * bar And a numbered list 1. Something 2. here That's really it. ` fmt.Println("----------------------") fmt.Print(Z.Markf(in, "another", "paragraph")) fmt.Println("----------------------") }
Output: ---------------------- Must have <italic>another<reset> block before verbatim: Now we can start a Verbatim block. Which can have blank lines, even. And back to a paragraph block. * <bold>foo<reset> * bar And a numbered list 1. Something 2. here That's really it. ----------------------
func Out ¶ added in v0.4.3
Out returns the standard output of the executed command as a string. Errors are logged but not returned.
func Page ¶ added in v0.20.0
Page writes the buf to a temporary file and passes it as first argument to the detected system pager. Anything that to.String accepts can be passed. Just prints output without paging if a pager cannot be found.
func PageFile ¶ added in v0.20.0
PageFile looks up the system pager and passes the first argument as a file argument to it. Just prints file if no pager can be found.
func PrintEmph ¶
func PrintEmph(a string)
PrintEmph passes string to Emph and prints it.
Example (Basics) ¶
package main import ( Z "github.com/rwxrob/bonzai/z" "github.com/rwxrob/term" ) func main() { // Emph observes the term escapes // (see package documentation for more) term.Italic = `<italic>` term.Bold = `<bold>` term.BoldItalic = `<bolditalic>` term.Under = `<under>` term.Reset = `<reset>` Z.PrintEmph("*ITALIC*\n") Z.PrintEmph("**BOLD**\n") Z.PrintEmph("***BOLDITALIC***\n") Z.PrintEmph("<UNDER>\n") // keeps brackets }
Output: <italic>ITALIC<reset> <bold>BOLD<reset> <bolditalic>BOLDITALIC<reset> <<under>UNDER<reset>>
func PrintEmphf ¶
PrintEmphf calls fmt.Sprintf on the string before passing it to Emph and then printing it.
Example ¶
package main import ( Z "github.com/rwxrob/bonzai/z" ) func main() { Z.PrintEmphf(`some *%v* thing`, "italic") }
Output: some <italic>italic<reset> thing
func PrintInWrap ¶
func PrintInWrap(a string)
PrintInWrap passes string to InWrap and prints it.
Example ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { defer func() { Z.IndentBy = Z.IndentBy }() indent := Z.IndentBy col := Z.Columns Z.Columns = 10 Z.IndentBy = 4 fmt.Println("-----") Z.PrintInWrap("some\nthat is \n indented") Z.IndentBy = indent Z.Columns = col }
Output: ----- some that is indented
func PrintInWrapf ¶
PrintInWrapf calls fmt.Sprintf on the string before passing it to InWrap and then printing it.
Example ¶
package main import ( Z "github.com/rwxrob/bonzai/z" ) func main() { in := Z.IndentBy col := Z.Columns Z.IndentBy = 3 Z.Columns = 10 Z.PrintInWrapf("-----\nindented by %v here and wrapped at %v", Z.IndentBy, Z.Columns, ) Z.IndentBy = in Z.Columns = col // ----- // indented // by 3 // here // and // wrapped // at 10 }
Output:
func PrintIndentf ¶
PrintIndentf calls fmt.Sprintf on the string before passing it to Indent and then printing it.
Example ¶
package main import ( Z "github.com/rwxrob/bonzai/z" ) func main() { in := Z.IndentBy Z.IndentBy = 3 Z.PrintIndentf("-----\nindented by %v here", Z.IndentBy) Z.IndentBy = in }
Output: ----- indented by 3 here
func PrintMark ¶
func PrintMark(a string)
PrintMark passes string to Mark and prints it.
Example ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { in := ` Must have *another* block before verbatim: Now we can start a Verbatim block. Which can have blank lines, even. And back to a paragraph block. * **foo** * bar And a numbered list 1. Something 2. here That's really it. ` fmt.Println("----------------------") Z.PrintMark(in) fmt.Println("----------------------") }
Output: ---------------------- Must have <italic>another<reset> block before verbatim: Now we can start a Verbatim block. Which can have blank lines, even. And back to a paragraph block. * <bold>foo<reset> * bar And a numbered list 1. Something 2. here That's really it. ----------------------
func PrintMarkf ¶
PrintMarkf calls fmt.Sprintf on the string before passing it to Mark and then printing it.
Example ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { in := ` Must have *%v* block before verbatim: Now we can start a Verbatim block. Which can have blank lines, even. And back to a %v block. * **foo** * bar And a numbered list 1. Something 2. here That's really it. ` fmt.Println("----------------------") Z.PrintMarkf(in, "another", "paragraph") fmt.Println("----------------------") }
Output: ---------------------- Must have <italic>another<reset> block before verbatim: Now we can start a Verbatim block. Which can have blank lines, even. And back to a paragraph block. * <bold>foo<reset> * bar And a numbered list 1. Something 2. here That's really it. ----------------------
func PrintWrap ¶
func PrintWrap(a string)
PrintWrap passes string to Wrap and prints it.
Example ¶
package main import ( Z "github.com/rwxrob/bonzai/z" ) func main() { col := Z.Columns Z.Columns = 10 Z.PrintWrap(`some thing here that is more than 10 characters`) Z.Columns = col }
Output: some thing here that is more than 10 characters
func PrintWrapf ¶
PrintWrapf calls fmt.Sprintf on the string before passing it to Wrap and then printing it.
func Run ¶
func Run()
Run infers the name of the command to run from the ExeName looked up in the Commands and delegates accordingly, prepending any arguments provided. This allows for BusyBox-like (https://www.busybox.net) multicall binaries to be used for such things as very light-weight Linux distributions when used "FROM SCRATCH" in containers. Although it shares the same name Z.Run should not confused with Cmd.Run. In general, Z.Run is for "multicall" and Cmd.Run is for "monoliths". Run may exit with the following errors:
* MultiCallCmdNotFound * MultiCallCmdNotCmd * MultiCallCmdNotCmd * MultiCallCmdArgNotString
func SysExec ¶
SysExec will check for the existence of the first argument as an executable on the system and then execute it using syscall.Exec(), which replaces the currently running program with the new one in all respects (stdin, stdout, stderr, process ID, signal handling, etc). Generally speaking, this is only available on UNIX variations. This is exceptionally faster and cleaner than calling any of the os/exec variations, but it can make your code far be less compatible with different operating systems.
func UsageGroup ¶
UsageGroup uses Bonzai usage notation, a basic form of regular expressions, to describe the arguments allowed where each argument is a literal string (avoid spaces). The arguments are joined with bars (|) and wrapped with parentheses producing a regex group. The min and max are then applied by adding the following regex decorations after the final parenthesis:
- min=1 max=1 (exactly one) ? - min=0 max=0 (none or many)
- - min=1 max=0 (one or more) {min,} - min>0 max=0 (min, no max) {min,max} - min>0 max>0 (min and max) {,max} - min=0 max>0 (max, no min)
An empty args slice returns an empty string. If only one arg, then that arg is simply returned and min and max are ignored. Arguments that are empty strings are ignored. No transformation is done to the string itself (such as removing white space).
Example ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { fmt.Println(Z.UsageGroup([]string{"", "foo", "", "bar", "with space"}, 1, 1)) fmt.Printf("%q\n", Z.UsageGroup([]string{"", ""}, 1, 1)) fmt.Println(Z.UsageGroup([]string{"one"}, 1, 1)) }
Output: (foo|bar|with space) "" one
func Wrap ¶
Wrap wraps to Columns width.
Example ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { col := Z.Columns Z.Columns = 10 fmt.Println(Z.Wrap(`some thing here that is more than 10 characters`)) Z.Columns = col }
Output: some thing here that is more than 10 characters
Types ¶
type ArgMap ¶ added in v0.12.0
ArgMap is a map keyed to individual arguments that should be expanded by being replaced with the slice of strings. See Cmd.Shortcuts.
type Block ¶
func Blocks ¶
Blocks strips preceding and trailing white space and then checks the first line for indentation (spaces or tabs) and strips that exact indentation string from every line. It then breaks up the input into blocks separated by one or more empty lines and applies basic formatting to each as follows:
If is one of the following leave alone with no wrapping: * Bulleted List - beginning with * * Numbered List - beginning with 1. * Verbatim - beginning with four spaces Everything else is considered a "paragraph" and will be unwrapped into a single long line (which is normally wrapped later).
For now, these blocks are added as is, but plans are to eventually add support for short and long lists much like CommonMark.
If no blocks are parsed returns an empty slice of Block pointers ([] *Block).
Note that because of the nature of Verbatim's block's initial (4 space) token Verbatim blocks must never be first since the entire input buffer is first dedented and the spaces would grouped with the indentation to be stripped. This is never a problem, however, because Verbatim blocks never make sense as the first block in a BonzaiMark document. This simplicity and clarity of 4-space tokens far outweighs the advantages of alternatives (such as fences).
PEGN Specification Grammar <-- Block* Block <-- Bulleted / Numbered / Verbatim / Paragraph Bulleted <-- '* ' (!EOB unipoint)* EOB Numbered <-- '1. ' (!EOB unipoint)* EOB Verbatim <-- ' ' (!EOB unipoint)* EOB Paragraph <-- (!EOB unipoint)* EOB EOB <- LF{2} / EOD EOD <- # end of data stream
Example (Bulleted) ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { in := ` * some thing * another thing * another block * here *boldnotbullet* ` blocks := Z.Blocks(in) //fmt.Println(blocks) fmt.Printf("%q\n", blocks[0]) fmt.Printf("%q\n", blocks[1]) }
Output: "* some thing\n* another thing" "* another block\n* here"
Example (Numbered) ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { in := ` 1. some thing 2. another thing 1. another block 2. here ` blocks := Z.Blocks(in) fmt.Printf("%q\n", blocks[0]) fmt.Printf("%q\n", blocks[1]) }
Output: "1. some thing\n2. another thing" "1. another block\n2. here"
Example (Paragraph) ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { in := ` Simple paragraph here on multiple lines. And another one here with just a bit more. ` blocks := Z.Blocks(in) //fmt.Println(len(blocks)) //fmt.Printf("%v", blocks) fmt.Printf("%q\n", blocks[0]) fmt.Printf("%q\n", blocks[1]) }
Output: "Simple paragraph here on multiple lines." "And another one here with just a bit more."
Example (Verbatim) ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { // Note that the following begins consistently with three tabs so that // dedenting works consistently. There are four spaces before Now and // the verbatim block. Notice that even the blank line within the // verbatim block must have the exact same indentation and spaced // verbatim prefix. (If using Vi/m try set :list to display them.) in := ` * Must have another block type first. Now we can start a Verbatim block. Which can have blank lines, even. * And back to another bulleted list. ` blocks := Z.Blocks(in) //fmt.Println(len(blocks)) //fmt.Println(blocks) fmt.Printf("%q\n", blocks[0]) fmt.Printf("%q\n", blocks[1]) fmt.Printf("%q\n", blocks[2]) }
Output: "* Must have another block type first." "Now we can start\na Verbatim\nblock.\n\nWhich can have blank lines, even." "* And back to another bulleted list."
type Cmd ¶
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 Copyright string `json:"copyright,omitempty"` // template License string `json:"license,omitempty"` // template Description string `json:"description,omitempty"` // template Other []Section `json:"other,omitempty"` // template // for use with text/template for run-time additions to main // documentation and embedded file output (ex: {{ exename }}) Dynamic template.FuncMap `json:"-"` // administrative URLs Site string `json:"site,omitempty"` // template, https:// assumed Source string `json:"source,omitempty"` // template, usually git url Issues string `json:"issues,omitempty"` // template, https:// assumed // descending tree, completable Commands []*Cmd `json:"commands,omitempty"` Params []string `json:"params,omitempty"` Hidden []string `json:"hidden,omitempty"` // default values for Var variables, also for initialization VarDefs VarVals `json:"vardefs,omitempty"` // standard or custom completer, usually of form compfoo.New() Comp bonzai.Completer `json:"-"` // where the work happens Caller *Cmd `json:"-"` Call Method `json:"-"` Init Method `json:"-"` // before Commands/Call, good for validation // pass bulk input efficiently (when args won't do) Input io.Reader // faster than lots of "if" in Call MinArgs int `json:"-"` // minimum number of args required (including parms) MaxArgs int `json:"-"` // maximum number of args required (including parms) NumArgs int `json:"-"` // exact number of args required (including parms) NoArgs bool `json:"-"` // must not have any args MinParm int `json:"-"` // minimum number of params required MaxParm int `json:"-"` // maximum number of params required UseConf bool `json:"-"` // requires Z.Conf be assigned UseVars bool `json:"-"` // requires Z.Var be assigned ConfVars bool `json:"-"` // vars default to conf values before VarDefs // contains filtered or unexported fields }
func (*Cmd) Add ¶
Add creates a new Cmd and sets the name and aliases and adds to Commands returning a reference to the new Cmd. The name must be first.
func (*Cmd) C ¶ added in v0.7.0
C is a shorter version of strings.TrimSpace(Z.Conf.Query(x.Path()+"."+q)) for convenience. The yq YAML/JSON queries unreliably add line returns sometimes and other times not. If a line return is wanted, the caller will need to use fmt.Println. Also see UseConf.
func (*Cmd) CmdNames ¶
CmdNames returns the names of every Command.
Example ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { foo := new(Z.Cmd) foo.Add("bar") foo.Add("blah") foo.Add("other") fmt.Println(foo.CmdNames()) }
Output: [bar blah other]
func (*Cmd) Del ¶ added in v0.13.0
Del is a shorter version of Z.Vars.Del(x.Path()+"."+key.val) for convenience. Logs the error Z.Vars is not defined (see UseVars).
func (*Cmd) Fill ¶ added in v0.4.0
Fill fills out the passed text/template string using the Cmd instance as the data object source for the template. It is called by the Get* family of field accessors but can be called directly as well. Also see markfunc.go for list of predefined template functions.
func (*Cmd) Get ¶ added in v0.7.0
Get is a shorter version of Z.Vars.Get(x.Path()+"."+key) for convenience but also observes VarDefsFromConf if set. Also see UseVars.
func (*Cmd) GetAliases ¶ added in v0.3.0
GetAliases fulfills the bonzai.Command interface. No Fill.
func (*Cmd) GetCommandNames ¶ added in v0.3.0
GetCommandNames fulfills the bonzai.Command interface. No Fill.
Example ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { foo := new(Z.Cmd) foo.Add("bar") foo.Add("blah") foo.Add("other") fmt.Println(foo.GetCommandNames()) }
Output: [bar blah other]
func (*Cmd) GetCommands ¶
GetCommands fulfills the bonzai.Command interface.
func (*Cmd) GetCopyright ¶ added in v0.3.0
GetCopyright fulfills the bonzai.Command interface. Uses Fill.
func (*Cmd) GetDescription ¶ added in v0.3.0
GetDescription fulfills the bonzai.Command interface. Uses Fill.
func (*Cmd) GetLegal ¶ added in v0.6.0
GetLegal returns a single line with the combined values of the Name, Version, Copyright, and License. If Version is empty or nil an empty string is returned instead. GetLegal() is used by the version builtin command to aggregate all the version information into a single output.
func (*Cmd) GetLicense ¶ added in v0.3.0
GetLicense fulfills the bonzai.Command interface. Uses Fill.
func (*Cmd) GetMaxParm ¶ added in v0.3.0
GetMaxParm fulfills the bonzai.Command interface. No Fill.
func (*Cmd) GetMinArgs ¶ added in v0.3.0
GetMinArgs fulfills the bonzai.Command interface. No Fill.
func (*Cmd) GetMinParm ¶ added in v0.3.0
GetMinParm fulfills the bonzai.Command interface. No Fill.
func (*Cmd) GetOtherTitles ¶ added in v0.3.0
GetOtherTitles fulfills the bonzai.Command interface. No Fill.
func (*Cmd) GetParams ¶
GetParams fulfills the bonzai.Command interface.
Example ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { foo := new(Z.Cmd) foo.Params = []string{"box", "bing", "and"} fmt.Println(foo.GetParams()) }
Output: [box bing and]
func (*Cmd) GetShortcuts ¶ added in v0.12.0
GetShortcuts fulfills the bonzai.Command interface. No Fill.
func (*Cmd) GetShortcutsMap ¶ added in v0.12.0
GetShortcutsMap fulfills the bonzai.Command interface. No Fill.
func (*Cmd) GetSummary ¶ added in v0.3.0
GetSummary fulfills the bonzai.Command interface. Uses Fill.
func (*Cmd) GetUsage ¶ added in v0.3.0
GetUsage fulfills the bonzai.Command interface. Uses x.Usage if not empty. Otherwise, calls UsageFunc to get usage, then uses Fill.
func (*Cmd) GetUseConf ¶ added in v0.10.0
GetUseConf fulfills the bonzai.Command interface. No Fill.
func (*Cmd) GetUseVars ¶ added in v0.10.0
GetUseVars fulfills the bonzai.Command interface. No Fill.
func (*Cmd) GetVersion ¶ added in v0.3.0
GetVersion fulfills the bonzai.Command interface. Uses Fill.
func (*Cmd) IsHidden ¶
IsHidden returns true if the specified name is in the list of Hidden commands.
func (*Cmd) Log ¶
Log is currently short for log.Printf() but may be supplemented in the future to have more fine-grained control of logging.
func (*Cmd) Names ¶
Names returns the Name and any Aliases grouped such that the Name is always last. Any alias beginning with anything but a letter (L) is omitted.
Example ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { x := &Z.Cmd{ Name: `foo`, Aliases: []string{"-f", "@f", "f", "FOO"}, } fmt.Println(x.Names()) }
Output: [f FOO foo]
func (*Cmd) OtherTitles ¶
OtherTitles returns just the ordered titles from Other.
func (*Cmd) Path ¶ added in v0.3.0
Path returns a dotted notation of the PathNames including an initial dot (for root). This is compatible yq query expressions and useful for associating configuration and other data specifically with this command. If any arguments are passed then will be added with dots between them.
Example ¶
package main import ( "fmt" "os" Z "github.com/rwxrob/bonzai/z" ) func main() { Z.ExitOff() z := new(Z.Cmd) c := z.Add("some") //fmt.Print(z.Commands[0].Name) c = c.Add("thing") //fmt.Print(z.Commands[0].Commands[0].Name) c = c.Add("deep") //fmt.Print(z.Commands[0].Commands[0].Commands[0].Name) c.Call = func(x *Z.Cmd, _ ...string) error { fmt.Println(x.Path()) fmt.Println(x.Path(`and`, `some`, `more`)) return nil } defer func() { args := os.Args; os.Args = args }() os.Args = []string{"z", "some", "thing", "deep"} // first exe name z.Run() }
Output: .some.thing.deep .some.thing.deep.and.some.more
func (*Cmd) PathCmds ¶ added in v0.8.0
PathCmds returns the path of commands used to arrive at this command. The path is determined by walking backward from current Caller up rather than depending on anything from the command line used to invoke the composing binary. Also see Path, PathNames.
func (*Cmd) PathNames ¶ added in v0.6.0
PathNames returns the path of command names used to arrive at this command. The path is determined by walking backward from current Caller up rather than depending on anything from the command line used to invoke the composing binary. Also see Path.
func (*Cmd) Resolve ¶
Resolve looks up a given Command by name or alias from Aliases (caching a lookup map of aliases in the process).
func (*Cmd) Root ¶
Root returns the root Cmd from the current Path. This must always be calculated every time since any Cmd can change positions and pedigrees at any time at run time. Returns self if no PathCmds found.
func (*Cmd) Run ¶
func (x *Cmd) Run()
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 ¶
Since Run is the main execution entry point for all Bonzai command trees it is also responsible for handling completion (tab or otherwise). Therefore, all Run methods have two modes: delegation and completion (both are executions of the Bonzai binary command tree). Delegation is the default mode. Completion mode is triggered by the detection of the COMP_LINE environment variable.
COMP_LINE
When COMP_LINE is set, Run prints a list of possible completions to standard output by calling its Comp.Complete function (default Z.Comp). Each Cmd therefore manages its own completion and can draw from a rich ecosystem of Completers or assign its own custom one. This enables very powerful completions including dynamic completions that query the network or the local execution environment. Since Go can run on pretty much every device architecture right now, that's a lot of possibilities. Even a line-based calculator can be implemented as a Completer. AI completers are also fully supported by this approach. Intelligent completion eliminates the need for overly complex and error-prone (getopt) argument signatures for all Bonzai commands.
Why COMP_LINE?
Setting COMP_LINE has been a bash shell standard for more than a few decades. (Unfortunately, zsh dubiously chose to not support it for no good reason.) COMP_LINE completion, therefore, is the only planned method of detecting completion context. Enabling it in bash for any command becomes a simple matter of "complete -C foo foo" (rather than forcing users to evaluate thousands of lines of shell code to enable completion for even minimally complex command trees as other "commanders" require). Any code will work that sets COMP_LINE before calling Cmd.Run and receives a list of lines to standard output with completion candidates.
func (*Cmd) Seek ¶
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. Seek also sets the Caller on each Cmd found during resolution. Cmd.Shortcuts are expanded.
Example ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { hello := &Z.Cmd{ Name: `hello`, Params: []string{"there"}, Call: func(_ *Z.Cmd, args ...string) error { if len(args) > 0 { fmt.Printf("hello %v\n", args[0]) return nil } fmt.Println("hello") return nil }, } hi := &Z.Cmd{ Name: `hi`, Params: []string{"there", "ya"}, Call: func(_ *Z.Cmd, args ...string) error { if len(args) > 0 { fmt.Printf("hi %v\n", args[0]) return nil } fmt.Println("hi") return nil }, } yo := &Z.Cmd{ Name: `yo`, Call: func(x *Z.Cmd, args ...string) error { fmt.Println("yo") return nil }, } salut := &Z.Cmd{ Name: `salut`, Params: []string{"la"}, Call: func(_ *Z.Cmd, args ...string) error { if len(args) > 0 { fmt.Printf("salut %v\n", args[0]) return nil } fmt.Println("salut") return nil }, } french := &Z.Cmd{ Name: `french`, Aliases: []string{"fr"}, Commands: []*Z.Cmd{salut}, } greet := &Z.Cmd{ Name: `greet`, Commands: []*Z.Cmd{yo, hi, hello, french}, } cmd, args := greet.Seek(Z.ArgsFrom(`hi there`)) fmt.Printf("%v %q\n", cmd.Name, args) cmd, args = greet.Seek(Z.ArgsFrom(`french salut`)) fmt.Printf("%v %q\n", cmd.Name, args) cmd, args = greet.Seek(Z.ArgsFrom(`french salut `)) fmt.Printf("%v %q\n", cmd.Name, args) }
Output: hi ["there"] salut [] salut [""]
func (*Cmd) Set ¶ added in v0.7.0
Set is a shorter version of Z.Vars.Set(x.Path()+"."+key.val) for convenience. Logs the error Z.Vars is not defined (see UseVars).
func (*Cmd) Title ¶
Title returns a dynamic field of Name and Summary combined (if exists). If the Name field of the commands is not defined will return a "{ERROR}". Fills template for Summary.
func (*Cmd) UsageCmdNames ¶
UsageCmdNames returns the Names for each of its Commands joined, if more than one, with usage regex notation.
func (*Cmd) UsageCmdShortcuts ¶ added in v0.12.1
UsageCmdShortcuts returns a single string with the Shortcuts indented and with a maximum title signature length for justification.
Example ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { x := &Z.Cmd{ Name: `cmd`, Shortcuts: Z.ArgMap{ "foo": {"a", "long", "way", "to", "foo"}, "bar": {"a", "long", "long", "way", "to", "bar"}, }, } fmt.Println(x.UsageCmdShortcuts()) }
Output: foo - a long way to foo bar - a long long way to bar
func (*Cmd) UsageCmdTitles ¶
UsageCmdTitles returns a single string with the titles of each subcommand indented and with a maximum title signature length for justification. Hidden commands are not included. Aliases that begin with anything but a letter (L) are not included. Note that the order of the Commands is preserved (not necessarily alphabetic).
Example ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { x := &Z.Cmd{ Name: `cmd`, Params: []string{"p1", "p2"}, Hidden: []string{"hidden"}, Commands: []*Z.Cmd{ &Z.Cmd{ Name: "foo", Aliases: []string{"f"}, Summary: "foo the things", }, &Z.Cmd{ Name: "bar", Summary: "bar the things", }, &Z.Cmd{ Name: "nosum", }, &Z.Cmd{ Name: "hidden", Summary: "not listed, but works", }, }, } fmt.Println(x.UsageCmdTitles()) }
Output: f|foo - foo the things bar - bar the things nosum
func (*Cmd) UsageError ¶
UsageError returns IncorrectUsage for self.
Example (Commands_with_Aliases) ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { x := &Z.Cmd{ Name: `cmd`, Commands: []*Z.Cmd{ &Z.Cmd{Name: "foo", Aliases: []string{"f"}}, &Z.Cmd{Name: "bar"}, }, } fmt.Println(Z.IncorrectUsage{x}) }
Output: usage: cmd ((f|foo)|bar)
Example (No_Call_nor_Commands) ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { x := &Z.Cmd{ Name: `cmd`, } fmt.Println(Z.IncorrectUsage{x}) }
Output: usage: cmd {ERROR: neither Call nor Commands defined}
Example (Params_but_No_Call) ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { x := &Z.Cmd{ Name: `cmd`, Params: []string{"p1", "p2"}, Commands: []*Z.Cmd{ &Z.Cmd{Name: "foo", Aliases: []string{"f"}}, &Z.Cmd{Name: "bar"}, }, } fmt.Println(Z.IncorrectUsage{x}) }
Output: usage: cmd {ERROR: Params without Call: p1, p2}
func (*Cmd) UsageNames ¶
UsageNames returns single name, joined Names with bar (|) and wrapped in parentheses, or empty string if no names.
Example ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { x := &Z.Cmd{ Name: `foo`, Aliases: []string{"f", "FOO"}, } fmt.Println(x.UsageNames()) }
Output: (f|FOO|foo)
func (*Cmd) UsageParams ¶
UsageParams returns the Params in UsageGroup notation.
Example ¶
package main import ( "fmt" Z "github.com/rwxrob/bonzai/z" ) func main() { x := &Z.Cmd{ Name: `foo`, Params: []string{"p1", "p2"}, } fmt.Println(x.UsageParams()) x.MinParm = 1 fmt.Println(x.UsageParams()) x.MaxParm = 1 fmt.Println(x.UsageParams()) }
Output: (p1|p2)? (p1|p2)+ (p1|p2)
type DefCmdReqCall ¶ added in v0.10.0
type DefCmdReqCall struct {
Cmd *Cmd
}
func (DefCmdReqCall) Error ¶ added in v0.10.0
func (e DefCmdReqCall) Error() string
type IncorrectUsage ¶ added in v0.10.0
type IncorrectUsage struct {
Cmd *Cmd
}
func (IncorrectUsage) Error ¶ added in v0.10.0
func (e IncorrectUsage) Error() string
type Method ¶
Method defines the main code to execute for a command (Cmd). By convention the parameter list should be named "args" if there are args expected and underscore (_) if not. Methods must never write error output to anything but standard error and should almost always use the log package to do so.
type MissingConf ¶ added in v0.10.0
type MissingConf struct {
Path string
}
func (MissingConf) Error ¶ added in v0.10.0
func (e MissingConf) Error() string
type MissingVar ¶ added in v0.15.1
type MissingVar struct {
Path string
}
func (MissingVar) Error ¶ added in v0.15.1
func (e MissingVar) Error() string
type MultiCallCmdArgNotString ¶ added in v0.10.0
func (MultiCallCmdArgNotString) Error ¶ added in v0.10.0
func (e MultiCallCmdArgNotString) Error() string
type MultiCallCmdNotCmd ¶ added in v0.10.0
func (MultiCallCmdNotCmd) Error ¶ added in v0.10.0
func (e MultiCallCmdNotCmd) Error() string
type MultiCallCmdNotFound ¶ added in v0.10.0
type MultiCallCmdNotFound struct {
CmdName string
}
func (MultiCallCmdNotFound) Error ¶ added in v0.10.0
func (e MultiCallCmdNotFound) Error() string
type NoCallNoCommands ¶ added in v0.10.0
type NoCallNoCommands struct {
Cmd *Cmd
}
func (NoCallNoCommands) Error ¶ added in v0.10.0
func (e NoCallNoCommands) Error() string
type NotEnoughArgs ¶ added in v0.10.0
func (NotEnoughArgs) Error ¶ added in v0.10.0
func (e NotEnoughArgs) Error() string
type Section ¶
Section contains the Other sections of a command. Composition notation (without Title and Body) is not only supported but encouraged for clarity when reading the source for documentation.
type TooManyArgs ¶ added in v0.10.0
func (TooManyArgs) Error ¶ added in v0.10.0
func (e TooManyArgs) Error() string
type VarVals ¶ added in v0.15.0
VarVals is a map keyed to individual variable keys from Vars. See Cmd.ConfVars and Cmd.Get.
type WrongNumArgs ¶ added in v0.10.0
func (WrongNumArgs) Error ¶ added in v0.10.0
func (e WrongNumArgs) Error() string