1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-01-24 05:36:19 +02:00
lazygit/pkg/gui/filetree/inode.go

214 lines
4.0 KiB
Go
Raw Normal View History

2021-03-30 23:56:59 +11:00
package filetree
2021-03-31 22:08:55 +11:00
import (
"sort"
)
2021-03-30 23:56:59 +11:00
type INode interface {
2022-01-22 00:13:51 +11:00
IsNil() bool
2021-03-30 23:56:59 +11:00
IsLeaf() bool
GetPath() string
GetChildren() []INode
SetChildren([]INode)
GetCompressionLevel() int
SetCompressionLevel(int)
}
func sortNode(node INode) {
sortChildren(node)
for _, child := range node.GetChildren() {
sortNode(child)
}
}
func sortChildren(node INode) {
if node.IsLeaf() {
return
}
children := node.GetChildren()
sortedChildren := make([]INode, len(children))
copy(sortedChildren, children)
sort.Slice(sortedChildren, func(i, j int) bool {
if !sortedChildren[i].IsLeaf() && sortedChildren[j].IsLeaf() {
return true
}
if sortedChildren[i].IsLeaf() && !sortedChildren[j].IsLeaf() {
return false
}
return sortedChildren[i].GetPath() < sortedChildren[j].GetPath()
})
// TODO: think about making this in-place
node.SetChildren(sortedChildren)
}
func forEachLeaf(node INode, cb func(INode) error) error {
if node.IsLeaf() {
if err := cb(node); err != nil {
return err
}
}
for _, child := range node.GetChildren() {
if err := forEachLeaf(child, cb); err != nil {
return err
}
}
return nil
}
func any(node INode, test func(INode) bool) bool {
if test(node) {
return true
}
for _, child := range node.GetChildren() {
if any(child, test) {
return true
}
}
return false
}
2021-03-31 22:39:55 +11:00
func every(node INode, test func(INode) bool) bool {
if !test(node) {
return false
}
for _, child := range node.GetChildren() {
if !every(child, test) {
return false
}
}
return true
}
2022-03-19 12:26:30 +11:00
func flatten(node INode, collapsedPaths *CollapsedPaths) []INode {
2021-03-30 23:56:59 +11:00
result := []INode{}
result = append(result, node)
2022-03-19 12:26:30 +11:00
if !collapsedPaths.IsCollapsed(node.GetPath()) {
2021-03-30 23:56:59 +11:00
for _, child := range node.GetChildren() {
result = append(result, flatten(child, collapsedPaths)...)
}
}
return result
}
2022-03-19 12:26:30 +11:00
func getNodeAtIndex(node INode, index int, collapsedPaths *CollapsedPaths) INode {
2021-03-30 23:56:59 +11:00
foundNode, _ := getNodeAtIndexAux(node, index, collapsedPaths)
return foundNode
}
2022-03-19 12:26:30 +11:00
func getNodeAtIndexAux(node INode, index int, collapsedPaths *CollapsedPaths) (INode, int) {
2021-03-30 23:56:59 +11:00
offset := 1
if index == 0 {
return node, offset
}
2022-03-19 12:26:30 +11:00
if !collapsedPaths.IsCollapsed(node.GetPath()) {
2021-03-30 23:56:59 +11:00
for _, child := range node.GetChildren() {
foundNode, offsetChange := getNodeAtIndexAux(child, index-offset, collapsedPaths)
offset += offsetChange
if foundNode != nil {
return foundNode, offset
}
}
}
return nil, offset
}
2022-03-19 12:26:30 +11:00
func getIndexForPath(node INode, path string, collapsedPaths *CollapsedPaths) (int, bool) {
2021-03-30 23:56:59 +11:00
offset := 0
if node.GetPath() == path {
return offset, true
}
2022-03-19 12:26:30 +11:00
if !collapsedPaths.IsCollapsed(node.GetPath()) {
2021-03-30 23:56:59 +11:00
for _, child := range node.GetChildren() {
offsetChange, found := getIndexForPath(child, path, collapsedPaths)
offset += offsetChange + 1
if found {
return offset, true
}
}
}
return offset, false
}
2022-03-19 12:26:30 +11:00
func size(node INode, collapsedPaths *CollapsedPaths) int {
2021-03-30 23:56:59 +11:00
output := 1
2022-03-19 12:26:30 +11:00
if !collapsedPaths.IsCollapsed(node.GetPath()) {
2021-03-30 23:56:59 +11:00
for _, child := range node.GetChildren() {
output += size(child, collapsedPaths)
}
}
return output
}
func compressAux(node INode) INode {
if node.IsLeaf() {
return node
}
children := node.GetChildren()
for i := range children {
grandchildren := children[i].GetChildren()
2021-07-27 21:00:33 +10:00
for len(grandchildren) == 1 && !grandchildren[0].IsLeaf() {
2021-03-30 23:56:59 +11:00
grandchildren[0].SetCompressionLevel(children[i].GetCompressionLevel() + 1)
children[i] = grandchildren[0]
grandchildren = children[i].GetChildren()
}
}
for i := range children {
children[i] = compressAux(children[i])
}
node.SetChildren(children)
return node
}
func getPathsMatching(node INode, test func(INode) bool) []string {
paths := []string{}
if test(node) {
paths = append(paths, node.GetPath())
}
for _, child := range node.GetChildren() {
paths = append(paths, getPathsMatching(child, test)...)
}
return paths
}
func getLeaves(node INode) []INode {
if node.IsLeaf() {
return []INode{node}
}
output := []INode{}
for _, child := range node.GetChildren() {
output = append(output, getLeaves(child)...)
}
return output
}