1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-01-10 04:07:18 +02:00
lazygit/pkg/gui/filetree/inode.go

207 lines
3.9 KiB
Go
Raw Normal View History

2021-03-30 14:56:59 +02:00
package filetree
2022-03-19 06:36:46 +02:00
import "github.com/jesseduffield/generics/slices"
2021-03-30 14:56:59 +02:00
type INode interface {
2022-01-21 15:13:51 +02:00
IsNil() bool
2021-03-30 14:56:59 +02: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
}
2022-03-19 06:36:46 +02:00
sortedChildren := slices.Clone(node.GetChildren())
2021-03-30 14:56:59 +02:00
2022-03-19 06:36:46 +02:00
slices.SortFunc(sortedChildren, func(a, b INode) bool {
if !a.IsLeaf() && b.IsLeaf() {
2021-03-30 14:56:59 +02:00
return true
}
2022-03-19 06:36:46 +02:00
if a.IsLeaf() && !b.IsLeaf() {
2021-03-30 14:56:59 +02:00
return false
}
2022-03-19 06:36:46 +02:00
return a.GetPath() < b.GetPath()
2021-03-30 14:56:59 +02:00
})
// 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 13:39:55 +02: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 03:26:30 +02:00
func flatten(node INode, collapsedPaths *CollapsedPaths) []INode {
2021-03-30 14:56:59 +02:00
result := []INode{}
result = append(result, node)
2022-03-19 03:26:30 +02:00
if !collapsedPaths.IsCollapsed(node.GetPath()) {
2021-03-30 14:56:59 +02:00
for _, child := range node.GetChildren() {
result = append(result, flatten(child, collapsedPaths)...)
}
}
return result
}
2022-03-19 03:26:30 +02:00
func getNodeAtIndex(node INode, index int, collapsedPaths *CollapsedPaths) INode {
2021-03-30 14:56:59 +02:00
foundNode, _ := getNodeAtIndexAux(node, index, collapsedPaths)
return foundNode
}
2022-03-19 03:26:30 +02:00
func getNodeAtIndexAux(node INode, index int, collapsedPaths *CollapsedPaths) (INode, int) {
2021-03-30 14:56:59 +02:00
offset := 1
if index == 0 {
return node, offset
}
2022-03-19 03:26:30 +02:00
if !collapsedPaths.IsCollapsed(node.GetPath()) {
2021-03-30 14:56:59 +02: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 03:26:30 +02:00
func getIndexForPath(node INode, path string, collapsedPaths *CollapsedPaths) (int, bool) {
2021-03-30 14:56:59 +02:00
offset := 0
if node.GetPath() == path {
return offset, true
}
2022-03-19 03:26:30 +02:00
if !collapsedPaths.IsCollapsed(node.GetPath()) {
2021-03-30 14:56:59 +02: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 03:26:30 +02:00
func size(node INode, collapsedPaths *CollapsedPaths) int {
2021-03-30 14:56:59 +02:00
output := 1
2022-03-19 03:26:30 +02:00
if !collapsedPaths.IsCollapsed(node.GetPath()) {
2021-03-30 14:56:59 +02: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 13:00:33 +02:00
for len(grandchildren) == 1 && !grandchildren[0].IsLeaf() {
2021-03-30 14:56:59 +02: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}
}
return slices.FlatMap(node.GetChildren(), func(child INode) []INode {
return getLeaves(child)
})
2021-03-30 14:56:59 +02:00
}