mirror of
https://github.com/zyedidia/micro.git
synced 2026-02-05 22:50:21 +09:00
208 lines
4.2 KiB
Go
208 lines
4.2 KiB
Go
package main
|
|
|
|
type SplitType bool
|
|
|
|
const (
|
|
VerticalSplit = false
|
|
HorizontalSplit = true
|
|
)
|
|
|
|
type Node interface {
|
|
VSplit(buf *Buffer)
|
|
HSplit(buf *Buffer)
|
|
String() string
|
|
}
|
|
|
|
type LeafNode struct {
|
|
view *View
|
|
|
|
parent *SplitTree
|
|
}
|
|
|
|
func NewLeafNode(v *View, parent *SplitTree) *LeafNode {
|
|
n := new(LeafNode)
|
|
n.view = v
|
|
n.view.splitNode = n
|
|
n.parent = parent
|
|
return n
|
|
}
|
|
|
|
type SplitTree struct {
|
|
kind SplitType
|
|
|
|
parent *SplitTree
|
|
children []Node
|
|
|
|
x int
|
|
y int
|
|
|
|
width int
|
|
height int
|
|
|
|
tabNum int
|
|
}
|
|
|
|
func (l *LeafNode) VSplit(buf *Buffer) {
|
|
tab := tabs[l.parent.tabNum]
|
|
if l.parent.kind == VerticalSplit {
|
|
newView := NewView(buf)
|
|
newView.TabNum = l.parent.tabNum
|
|
newView.Num = len(tab.views)
|
|
l.parent.children = append(l.parent.children, NewLeafNode(newView, l.parent))
|
|
|
|
tab.curView++
|
|
tab.views = append(tab.views, newView)
|
|
} else {
|
|
s := new(SplitTree)
|
|
s.kind = VerticalSplit
|
|
s.parent = l.parent
|
|
newView := NewView(buf)
|
|
newView.TabNum = l.parent.tabNum
|
|
newView.Num = len(tab.views)
|
|
s.children = []Node{l, NewLeafNode(newView, s)}
|
|
l.parent.children[search(l.parent.children, l)] = s
|
|
l.parent = s
|
|
|
|
tab.curView++
|
|
tab.views = append(tab.views, newView)
|
|
}
|
|
}
|
|
|
|
func (l *LeafNode) HSplit(buf *Buffer) {
|
|
tab := tabs[l.parent.tabNum]
|
|
if l.parent.kind == HorizontalSplit {
|
|
newView := NewView(buf)
|
|
newView.TabNum = l.parent.tabNum
|
|
newView.Num = len(tab.views)
|
|
l.parent.children = append(l.parent.children, NewLeafNode(newView, l.parent))
|
|
|
|
tab.curView++
|
|
tab.views = append(tab.views, newView)
|
|
} else {
|
|
s := new(SplitTree)
|
|
s.kind = HorizontalSplit
|
|
s.parent = l.parent
|
|
newView := NewView(buf)
|
|
newView.TabNum = l.parent.tabNum
|
|
newView.Num = len(tab.views)
|
|
s.children = []Node{l, NewLeafNode(newView, s)}
|
|
l.parent.children[search(l.parent.children, l)] = s
|
|
l.parent = s
|
|
|
|
tab.curView++
|
|
tab.views = append(tab.views, newView)
|
|
}
|
|
}
|
|
|
|
func (l *LeafNode) Delete() {
|
|
i := search(l.parent.children, l)
|
|
|
|
copy(l.parent.children[i:], l.parent.children[i+1:])
|
|
l.parent.children[len(l.parent.children)-1] = nil
|
|
l.parent.children = l.parent.children[:len(l.parent.children)-1]
|
|
|
|
tab := tabs[l.parent.tabNum]
|
|
j := findView(tab.views, l.view)
|
|
copy(tab.views[j:], tab.views[j+1:])
|
|
tab.views[len(tab.views)-1] = nil // or the zero value of T
|
|
tab.views = tab.views[:len(tab.views)-1]
|
|
|
|
for i, v := range tab.views {
|
|
v.Num = i
|
|
}
|
|
if tab.curView > 0 {
|
|
tab.curView--
|
|
}
|
|
}
|
|
|
|
func (s *SplitTree) Cleanup() {
|
|
for i, node := range s.children {
|
|
if n, ok := node.(*SplitTree); ok {
|
|
if len(n.children) == 1 {
|
|
if child, ok := n.children[0].(*LeafNode); ok {
|
|
s.children[i] = child
|
|
child.parent = s
|
|
continue
|
|
}
|
|
}
|
|
n.Cleanup()
|
|
}
|
|
}
|
|
}
|
|
|
|
func (s *SplitTree) ResizeSplits() {
|
|
for i, node := range s.children {
|
|
if n, ok := node.(*LeafNode); ok {
|
|
if s.kind == VerticalSplit {
|
|
n.view.width = s.width / len(s.children)
|
|
n.view.height = s.height
|
|
|
|
n.view.x = s.x + n.view.width*i
|
|
n.view.y = s.y
|
|
} else {
|
|
n.view.height = s.height / len(s.children)
|
|
n.view.width = s.width
|
|
|
|
n.view.y = s.y + n.view.height*i
|
|
n.view.x = s.x
|
|
}
|
|
// n.view.ToggleStatusLine()
|
|
_, screenH := screen.Size()
|
|
if settings["statusline"].(bool) || (n.view.y+n.view.height) != screenH-1 {
|
|
n.view.height--
|
|
}
|
|
|
|
n.view.ToggleTabbar()
|
|
n.view.matches = Match(n.view)
|
|
} else if n, ok := node.(*SplitTree); ok {
|
|
if s.kind == VerticalSplit {
|
|
n.width = s.width / len(s.children)
|
|
n.height = s.height
|
|
|
|
n.x = s.x + n.width*i
|
|
n.y = s.y
|
|
} else {
|
|
n.height = s.height / len(s.children)
|
|
n.width = s.width
|
|
|
|
n.y = s.y + n.height*i
|
|
n.x = s.x
|
|
}
|
|
n.ResizeSplits()
|
|
}
|
|
}
|
|
}
|
|
|
|
func (l *LeafNode) String() string {
|
|
return l.view.Buf.Name
|
|
}
|
|
|
|
func search(haystack []Node, needle Node) int {
|
|
for i, x := range haystack {
|
|
if x == needle {
|
|
return i
|
|
}
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func findView(haystack []*View, needle *View) int {
|
|
for i, x := range haystack {
|
|
if x == needle {
|
|
return i
|
|
}
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func (s *SplitTree) VSplit(buf *Buffer) {}
|
|
func (s *SplitTree) HSplit(buf *Buffer) {}
|
|
|
|
func (s *SplitTree) String() string {
|
|
str := "["
|
|
for _, child := range s.children {
|
|
str += child.String() + ", "
|
|
}
|
|
return str + "]"
|
|
}
|