Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 52 additions & 7 deletions internal/views/splits.go
Original file line number Diff line number Diff line change
Expand Up @@ -439,11 +439,12 @@ func (n *Node) VSplit(right bool) uint64 {
}

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

h := n.Kind == STVert
nonrs, numr := n.getResizeInfo(h)
if numr == 0 {
// This means that this was the last child
Expand All @@ -470,18 +471,62 @@ func (n *Node) Unsplit() bool {
ind = i
}
}
if n.parent.Kind == STVert {
n.parent.unsplit(ind, true)
} else {
n.parent.unsplit(ind, false)
}

n.parent.unsplit(ind)
if n.parent.IsLeaf() {
return n.parent.Unsplit()
}

n.parent.flatten()
return true
}

// flattens the tree by removing unnecessary intermediate parents that have only one child
// and handles the side effect of it
func (n *Node) flatten() {
if n.parent == nil || len(n.children) != 1 {
return
}

ind := 0
for i, c := range n.parent.children {
if c.id == n.id {
ind = i
}
}

// Replace current node with its child node to remove chained parent
successor := n.children[0]
n.parent.children[ind] = successor
successor.parent = n.parent

// Maintain the tree in a consistent state: any child node's kind (horiz vs vert)
// should be the opposite of its parent's kind.
if successor.IsLeaf() {
successor.Kind = n.Kind
} else {
// If the successor node has children, that means it is a chained parent as well.
// Therefore it can be replaced by its own children.
origsize := len(n.parent.children)

// Let's say we have 5 children and want to replace [2] with its children [a] [b] [c]
// [0] [1] [2] [3] [4] --> [0] [1] [a] [b] [c] [3] [4]
// insertcount will be `3 - 1 = 2` in this case
insertcount := len(successor.children) - 1

n.parent.children = append(n.parent.children, make([]*Node, insertcount)...)
copy(n.parent.children[ind+insertcount+1:], n.parent.children[ind+1:origsize])
copy(n.parent.children[ind:], successor.children)

for i := 0; i < len(successor.children); i++ {
n.parent.children[ind+i].parent = n.parent
}
}

// Update propW and propH since the parent of the children has been updated,
// so the children have new siblings
n.parent.markSizes()
}

// String returns the string form of the node and all children (used for debugging)
func (n *Node) String() string {
var strf func(n *Node, ident int) string
Expand Down