package dirtree import "strings" // FlattenTree returns []*Node consistent with each node's `Expanded` state func FlattenTree(node *Node, expandAll bool) []*Node { lines := make([]*Node, 0) var flatten func(n *Node) flatten = func(node *Node) { lines = append(lines, node) if node.isDir && (node.Expanded || expandAll) { for _, child := range node.children { flatten(child) } } } flatten(node) return lines } type TreeFormat struct { Space string Span string Node string NodeLast string } var ( Standard = TreeFormat{ Space: " ", Span: "│ ", Node: "├── ", NodeLast: "└── ", } Compact = TreeFormat{ Space: " ", Span: "│ ", Node: "├ ", NodeLast: "└ ", } ) func RenderNodes(displayNodes []*Node, format TreeFormat, cursor int, renderNode func(*Node) string) string { var sb strings.Builder levelIsLast := make(map[int]bool) for i, node := range displayNodes { // Cursor indicator if cursor >= 0 { if i == cursor { sb.WriteString("> ") } else { sb.WriteString(" ") } } // Tree structure if node.depth > 0 { for d := 1; d < node.depth; d++ { if levelIsLast[d] { sb.WriteString(format.Space) } else { sb.WriteString(format.Span) } } // Find if this node is the last among its siblings isLast := node.parent.children[len(node.parent.children)-1] == node levelIsLast[node.depth] = isLast if isLast { sb.WriteString(format.NodeLast) } else { sb.WriteString(format.Node) } } // Render the node sb.WriteString(renderNode(node)) sb.WriteString("\n") } return sb.String() }