Skip to content

Commit 74f9b76

Browse files
Merge branch 'ChainedParentsFix' into dev
2 parents 208d090 + 8e70899 commit 74f9b76

File tree

1 file changed

+35
-10
lines changed

1 file changed

+35
-10
lines changed

internal/views/splits.go

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -476,14 +476,14 @@ func (n *Node) Unsplit() bool {
476476
return n.parent.Unsplit()
477477
}
478478

479-
n.parent.simplify()
479+
n.parent.flatten()
480480
return true
481481
}
482482

483-
// Simplify removes unnecessary chained parents
484-
func (n *Node) simplify() {
483+
// flattens the tree by removing unnecessary intermediate parents that have only one child
484+
// and handles the side effect of it
485+
func (n *Node) flatten() {
485486
if n.parent == nil || len(n.children) != 1 {
486-
n.markResize()
487487
return
488488
}
489489

@@ -494,12 +494,37 @@ func (n *Node) simplify() {
494494
}
495495
}
496496

497-
parent := n.parent
498-
kind := n.Kind
499-
parent.children[ind] = n.children[0]
500-
parent.children[ind].parent = parent
501-
parent.children[ind].Kind = kind
502-
parent.simplify()
497+
// Replace current node with its child node to remove chained parent
498+
successor := n.children[0]
499+
n.parent.children[ind] = successor
500+
successor.parent = n.parent
501+
502+
// Maintain the tree in a consistent state: any child node's kind (horiz vs vert)
503+
// should be the opposite of its parent's kind.
504+
if successor.IsLeaf() {
505+
successor.Kind = n.Kind
506+
} else {
507+
// If the successor node has children, that means it is a chained parent as well.
508+
// Therefore it can be replaced by its own children.
509+
origsize := len(n.parent.children)
510+
511+
// Let's say we have 5 children and want to replace [2] with its children [a] [b] [c]
512+
// [0] [1] [2] [3] [4] --> [0] [1] [a] [b] [c] [3] [4]
513+
// insertcount will be `3 - 1 = 2` in this case
514+
insertcount := len(successor.children) - 1
515+
516+
n.parent.children = append(n.parent.children, make([]*Node, insertcount)...)
517+
copy(n.parent.children[ind+insertcount+1:], n.parent.children[ind+1:origsize])
518+
copy(n.parent.children[ind:], successor.children)
519+
520+
for i := 0; i < len(successor.children); i++ {
521+
n.parent.children[ind+i].parent = n.parent
522+
}
523+
}
524+
525+
// Update propW and propH since the parent of the children has been updated,
526+
// so the children have new siblings
527+
n.parent.markSizes()
503528
}
504529

505530
// String returns the string form of the node and all children (used for debugging)

0 commit comments

Comments
 (0)