Skip to content

Commit ef56f79

Browse files
Fixing chained parents by flattening the tree on unsplit
1 parent f4d62a4 commit ef56f79

File tree

1 file changed

+49
-0
lines changed

1 file changed

+49
-0
lines changed

internal/views/splits.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,9 +479,58 @@ func (n *Node) Unsplit() bool {
479479
if n.parent.IsLeaf() {
480480
return n.parent.Unsplit()
481481
}
482+
483+
n.parent.flatten()
482484
return true
483485
}
484486

487+
// flattens the tree by removing unnecessary intermediate parents that have only one child
488+
// and handles the side effect of it
489+
func (n *Node) flatten() {
490+
if n.parent == nil {
491+
return
492+
}
493+
494+
ind := 0
495+
for i, c := range n.parent.children {
496+
if c.id == n.id {
497+
ind = i
498+
}
499+
}
500+
501+
if len(n.children) == 1 {
502+
// Replace current node with child node to remove chained parent
503+
n.parent.children[ind] = n.children[0]
504+
n.parent.children[ind].parent = n.parent
505+
if n.children[0].IsLeaf() {
506+
n.parent.children[ind].Kind = n.Kind
507+
} else {
508+
// Flatten the child node that replaced the current node
509+
n.parent.children[ind].flatten()
510+
}
511+
} else if !n.IsLeaf() && n.Kind == n.parent.Kind {
512+
// If we have the same kind as the parent (cuased by previous flattening),
513+
// replace this node with our children.
514+
origsize := len(n.parent.children)
515+
516+
// Let's say we have 5 children and want to replace [2] with its children [a] [b] [c]
517+
// [0] [1] [2] [3] [4] --> [0] [1] [a] [b] [c] [3] [4]
518+
// insertcount will be `3 - 1 = 2` in this case
519+
insertcount := len(n.children) - 1
520+
n.parent.children = append(n.parent.children, make([]*Node, insertcount)...)
521+
if ind != origsize-1 {
522+
copy(n.parent.children[(ind+insertcount+1):], n.children[(ind+1):origsize])
523+
}
524+
for i := 0; i < len(n.children); i++ {
525+
n.parent.children[ind+i] = n.children[i]
526+
n.parent.children[ind].parent = n.parent
527+
}
528+
}
529+
530+
// Update propW and propH since the parent of the children might have been updated
531+
n.parent.markSizes()
532+
}
533+
485534
// String returns the string form of the node and all children (used for debugging)
486535
func (n *Node) String() string {
487536
var strf func(n *Node, ident int) string

0 commit comments

Comments
 (0)