diff --git a/z/cmd.go b/z/cmd.go index 95f540d..d547cff 100644 --- a/z/cmd.go +++ b/z/cmd.go @@ -277,6 +277,17 @@ func (x *Cmd) Run() { Exit() } +// 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 (x *Cmd) Root() *Cmd { + cmds := x.PathCmds() + if len(cmds) > 0 { + return cmds[0].Caller + } + return x.Caller +} + // UsageError returns an error with a single-line usage string. func (x *Cmd) UsageError() error { return fmt.Errorf("usage: %v %v", x.Name, UsageFunc(x)) @@ -429,6 +440,20 @@ func (x *Cmd) Seek(args []string) (*Cmd, []string) { return cur, args[n:] } +// 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 (x *Cmd) PathCmds() []*Cmd { + path := qstack.New[*Cmd]() + path.Unshift(x) + for p := x.Caller; p != nil; p = p.Caller { + path.Unshift(p) + } + path.Shift() + return path.Items() +} + // 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 diff --git a/z/markfunc.go b/z/markfunc.go index 276ff5c..05e5dcb 100644 --- a/z/markfunc.go +++ b/z/markfunc.go @@ -5,6 +5,7 @@ import ( "path/filepath" "text/template" + "github.com/rwxrob/term" "github.com/rwxrob/to" ) @@ -13,7 +14,17 @@ import ( // allowed. var markFuncMap = template.FuncMap{ - "indent": indent, + + // semantic + "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 }, + + // stylistic + "indent": indent, + "pre": func(a string) string { return term.Under + a + term.Reset }, + + // host system information "exepath": exepath, "exename": exename, "execachedir": execachedir,