Skip to content

Commit 3e9a59d

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

File tree

1 file changed

+47
-0
lines changed

1 file changed

+47
-0
lines changed

internal/views/splits.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,9 +479,56 @@ 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 || len(n.children) != 1 {
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+
// Replace current node with its child node to remove chained parent
502+
n.parent.children[ind] = n.children[0]
503+
504+
successor := n.parent.children[ind]
505+
successor.parent = n.parent
506+
if successor.IsLeaf() {
507+
successor.Kind = n.Kind
508+
} else if !successor.IsLeaf() && successor.Kind == n.parent.Kind {
509+
// If we have the same kind as the parent (caused by removing chained parent),
510+
// replace successor node with its children.
511+
origsize := len(n.parent.children)
512+
513+
// Let's say we have 5 children and want to replace [2] with its children [a] [b] [c]
514+
// [0] [1] [2] [3] [4] --> [0] [1] [a] [b] [c] [3] [4]
515+
// insertcount will be `3 - 1 = 2` in this case
516+
insertcount := len(successor.children) - 1
517+
518+
n.parent.children = append(n.parent.children, make([]*Node, insertcount)...)
519+
copy(n.parent.children[ind+insertcount+1:], n.parent.children[ind+1:origsize])
520+
copy(n.parent.children[ind:], successor.children)
521+
522+
for i := 0; i < len(successor.children); i++ {
523+
n.parent.children[ind+i].parent = n.parent
524+
}
525+
}
526+
527+
// Update propW and propH since the parent of the children might have been updated,
528+
// so the children may have new siblings
529+
n.parent.markSizes()
530+
}
531+
485532
// String returns the string form of the node and all children (used for debugging)
486533
func (n *Node) String() string {
487534
var strf func(n *Node, ident int) string

0 commit comments

Comments
 (0)