Skip to content

Commit 06fe85c

Browse files
authored
Merge pull request zyedidia#3708 from Neko-Box-Coder/ChainedParentsFix
Fix unable to perform proportional resize caused by chained parents after quiting a nested VSplit inside a HSplit
2 parents ca32ffb + 8e70899 commit 06fe85c

File tree

1 file changed

+52
-7
lines changed

1 file changed

+52
-7
lines changed

internal/views/splits.go

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -439,11 +439,12 @@ func (n *Node) VSplit(right bool) uint64 {
439439
}
440440

441441
// unsplits the child of a split
442-
func (n *Node) unsplit(i int, h bool) {
442+
func (n *Node) unsplit(i int) {
443443
copy(n.children[i:], n.children[i+1:])
444444
n.children[len(n.children)-1] = nil
445445
n.children = n.children[:len(n.children)-1]
446446

447+
h := n.Kind == STVert
447448
nonrs, numr := n.getResizeInfo(h)
448449
if numr == 0 {
449450
// This means that this was the last child
@@ -470,18 +471,62 @@ func (n *Node) Unsplit() bool {
470471
ind = i
471472
}
472473
}
473-
if n.parent.Kind == STVert {
474-
n.parent.unsplit(ind, true)
475-
} else {
476-
n.parent.unsplit(ind, false)
477-
}
478-
474+
n.parent.unsplit(ind)
479475
if n.parent.IsLeaf() {
480476
return n.parent.Unsplit()
481477
}
478+
479+
n.parent.flatten()
482480
return true
483481
}
484482

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() {
486+
if n.parent == nil || len(n.children) != 1 {
487+
return
488+
}
489+
490+
ind := 0
491+
for i, c := range n.parent.children {
492+
if c.id == n.id {
493+
ind = i
494+
}
495+
}
496+
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()
528+
}
529+
485530
// String returns the string form of the node and all children (used for debugging)
486531
func (n *Node) String() string {
487532
var strf func(n *Node, ident int) string

0 commit comments

Comments
 (0)