mirror of
https://github.com/zyedidia/micro.git
synced 2025-06-18 14:55:38 -04:00
Fixing chained parents by flattening the tree on unsplit
This commit is contained in:
parent
f4d62a498b
commit
080d216ffd
@ -479,9 +479,58 @@ func (n *Node) Unsplit() bool {
|
|||||||
if n.parent.IsLeaf() {
|
if n.parent.IsLeaf() {
|
||||||
return n.parent.Unsplit()
|
return n.parent.Unsplit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
n.parent.flatten()
|
||||||
return true
|
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)
|
// String returns the string form of the node and all children (used for debugging)
|
||||||
func (n *Node) String() string {
|
func (n *Node) String() string {
|
||||||
var strf func(n *Node, ident int) string
|
var strf func(n *Node, ident int) string
|
||||||
|
Loading…
Reference in New Issue
Block a user