package ffmd import ( "fmt" "sort" "strings" "github.com/peterbourgon/ff/v3/ffcli" ) // Tree returns a tree-representation of a ffcli.Command func Tree(cmd *ffcli.Command) string { t := tree{cmd.Name: commandTree(cmd)} s := t.String(true, "") return strings.TrimSpace(s) } type tree map[string]tree func commandTree(cmd *ffcli.Command) tree { t := tree{} for _, sub := range cmd.Subcommands { t[sub.Name] = commandTree(sub) } return t } func (t tree) keys() []string { k := make([]string, 0, len(t)) for key, _ := range t { k = append(k, key) } sort.Strings(k) return k } func (t tree) String(root bool, padding string) string { var s strings.Builder index := 0 for _, k := range t.keys() { v := t[k] p := pipe(index, len(t)) s.WriteString(fmt.Sprintf("%s%s\n", padding+pipePad(root, p), k)) op := outerPipe(index, len(t)) s.WriteString(v.String(false, padding+pipePad(root, op))) index++ } return s.String() } func pipe(index int, len int) string { switch { case index+1 > len: return " " case index+1 == len: return "└─" default: return "├─" } } func outerPipe(index int, len int) string { switch { case index+1 == len: return " " default: return "│ " } } func pipePad(root bool, box string) string { if root { return "" } return box + " " }