Repository: zyedidia/micro
File: internal/views/splits.go (Go)

Code before:
	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
	n.parent.children[ind] = n.children[0]

	successor := n.parent.children[ind]
	successor.parent = n.parent
	if successor.IsLeaf() {
		successor.Kind = n.Kind
	} else if !successor.IsLeaf() && successor.Kind == n.parent.Kind {
		// If we have the same kind as the parent (caused by removing chained parent),
		// replace successor node with its 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 might have been updated,
	// so the children may have new siblings
	n.parent.markSizes()

Review comment (suggestion):
Maybe add a comment above this line: "Make sure the tree remains in a consistent state: any child node's kind (horizontal vs vertical) is the opposite of its parent's kind"?

Also why not rearrange the lines like this:
```go
--- a/internal/views/splits.go
+++ b/internal/views/splits.go
@@ -495,10 +495,12 @@ func (n *Node) flatten() {
 	}
 
 	// Replace current node with its child node to remove chained parent
-	n.parent.children[ind] = n.children[0]
-
-	successor := n.parent.children[ind]
+	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 !successor.IsLeaf() && successor.Kind == n.parent.Kind {
```

Code after:
	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()
}