]> git.lizzy.rs Git - micro.git/blobdiff - cmd/micro/split_tree.go
Merge pull request #1200 from Calinou/add-systemd-timer-section
[micro.git] / cmd / micro / split_tree.go
index 78a6928b1dfd9904e63e5034a5e6e71ca9652d9f..e34c37f1335865b1d146557afd922c1a61da94b2 100644 (file)
@@ -1,6 +1,6 @@
 package main
 
-// SpltType specifies whether a split is horizontal or vertical
+// SplitType specifies whether a split is horizontal or vertical
 type SplitType bool
 
 const (
@@ -12,8 +12,8 @@ const (
 
 // A Node on the split tree
 type Node interface {
-       VSplit(buf *Buffer)
-       HSplit(buf *Buffer)
+       VSplit(buf *Buffer, splitIndex int)
+       HSplit(buf *Buffer, splitIndex int)
        String() string
 }
 
@@ -43,66 +43,119 @@ type SplitTree struct {
        x int
        y int
 
-       width  int
-       height int
+       width      int
+       height     int
+       lockWidth  bool
+       lockHeight bool
 
        tabNum int
 }
 
 // VSplit creates a vertical split
-func (l *LeafNode) VSplit(buf *Buffer) {
+func (l *LeafNode) VSplit(buf *Buffer, splitIndex int) {
+       if splitIndex < 0 {
+               splitIndex = 0
+       }
+
        tab := tabs[l.parent.tabNum]
        if l.parent.kind == VerticalSplit {
+               if splitIndex > len(l.parent.children) {
+                       splitIndex = len(l.parent.children)
+               }
+
                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)
+               l.parent.children = append(l.parent.children, nil)
+               copy(l.parent.children[splitIndex+1:], l.parent.children[splitIndex:])
+               l.parent.children[splitIndex] = NewLeafNode(newView, l.parent)
+
+               tab.Views = append(tab.Views, nil)
+               copy(tab.Views[splitIndex+1:], tab.Views[splitIndex:])
+               tab.Views[splitIndex] = newView
+
+               tab.CurView = splitIndex
        } else {
+               if splitIndex > 1 {
+                       splitIndex = 1
+               }
+
                s := new(SplitTree)
                s.kind = VerticalSplit
                s.parent = l.parent
                s.tabNum = l.parent.tabNum
                newView := NewView(buf)
                newView.TabNum = l.parent.tabNum
-               newView.Num = len(tab.views)
-               s.children = []Node{l, NewLeafNode(newView, s)}
+               if splitIndex == 1 {
+                       s.children = []Node{l, NewLeafNode(newView, s)}
+               } else {
+                       s.children = []Node{NewLeafNode(newView, s), l}
+               }
                l.parent.children[search(l.parent.children, l)] = s
                l.parent = s
 
-               tab.curView++
-               tab.views = append(tab.views, newView)
+               tab.Views = append(tab.Views, nil)
+               copy(tab.Views[splitIndex+1:], tab.Views[splitIndex:])
+               tab.Views[splitIndex] = newView
+
+               tab.CurView = splitIndex
        }
+
+       tab.Resize()
 }
 
 // HSplit creates a horizontal split
-func (l *LeafNode) HSplit(buf *Buffer) {
+func (l *LeafNode) HSplit(buf *Buffer, splitIndex int) {
+       if splitIndex < 0 {
+               splitIndex = 0
+       }
+
        tab := tabs[l.parent.tabNum]
        if l.parent.kind == HorizontalSplit {
+               if splitIndex > len(l.parent.children) {
+                       splitIndex = len(l.parent.children)
+               }
+
                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)
+               l.parent.children = append(l.parent.children, nil)
+               copy(l.parent.children[splitIndex+1:], l.parent.children[splitIndex:])
+               l.parent.children[splitIndex] = NewLeafNode(newView, l.parent)
+
+               tab.Views = append(tab.Views, nil)
+               copy(tab.Views[splitIndex+1:], tab.Views[splitIndex:])
+               tab.Views[splitIndex] = newView
+
+               tab.CurView = splitIndex
        } else {
+               if splitIndex > 1 {
+                       splitIndex = 1
+               }
+
                s := new(SplitTree)
                s.kind = HorizontalSplit
                s.tabNum = l.parent.tabNum
                s.parent = l.parent
                newView := NewView(buf)
                newView.TabNum = l.parent.tabNum
-               newView.Num = len(tab.views)
-               s.children = []Node{l, NewLeafNode(newView, s)}
+               newView.Num = len(tab.Views)
+               if splitIndex == 1 {
+                       s.children = []Node{l, NewLeafNode(newView, s)}
+               } else {
+                       s.children = []Node{NewLeafNode(newView, s), l}
+               }
                l.parent.children[search(l.parent.children, l)] = s
                l.parent = s
 
-               tab.curView++
-               tab.views = append(tab.views, newView)
+               tab.Views = append(tab.Views, nil)
+               copy(tab.Views[splitIndex+1:], tab.Views[splitIndex:])
+               tab.Views[splitIndex] = newView
+
+               tab.CurView = splitIndex
        }
+
+       tab.Resize()
 }
 
 // Delete deletes a split
@@ -114,16 +167,16 @@ func (l *LeafNode) Delete() {
        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]
+       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 {
+       for i, v := range tab.Views {
                v.Num = i
        }
-       if tab.curView > 0 {
-               tab.curView--
+       if tab.CurView > 0 {
+               tab.CurView--
        }
 }
 
@@ -145,40 +198,82 @@ func (s *SplitTree) Cleanup() {
 
 // ResizeSplits resizes all the splits correctly
 func (s *SplitTree) ResizeSplits() {
-       for i, node := range s.children {
+       lockedWidth := 0
+       lockedHeight := 0
+       lockedChildren := 0
+       for _, node := range s.children {
+               if n, ok := node.(*LeafNode); ok {
+                       if s.kind == VerticalSplit {
+                               if n.view.LockWidth {
+                                       lockedWidth += n.view.Width
+                                       lockedChildren++
+                               }
+                       } else {
+                               if n.view.LockHeight {
+                                       lockedHeight += n.view.Height
+                                       lockedChildren++
+                               }
+                       }
+               } else if n, ok := node.(*SplitTree); ok {
+                       if s.kind == VerticalSplit {
+                               if n.lockWidth {
+                                       lockedWidth += n.width
+                                       lockedChildren++
+                               }
+                       } else {
+                               if n.lockHeight {
+                                       lockedHeight += n.height
+                                       lockedChildren++
+                               }
+                       }
+               }
+       }
+       x, y := 0, 0
+       for _, 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
+                               if !n.view.LockWidth {
+                                       n.view.Width = (s.width - lockedWidth) / (len(s.children) - lockedChildren)
+                               }
+                               n.view.Height = s.height
 
-                               n.view.x = s.x + n.view.width*i
+                               n.view.x = s.x + x
                                n.view.y = s.y
+                               x += n.view.Width
                        } else {
-                               n.view.height = s.height / len(s.children)
-                               n.view.width = s.width
+                               if !n.view.LockHeight {
+                                       n.view.Height = (s.height - lockedHeight) / (len(s.children) - lockedChildren)
+                               }
+                               n.view.Width = s.width
 
-                               n.view.y = s.y + n.view.height*i
+                               n.view.y = s.y + y
                                n.view.x = s.x
+                               y += n.view.Height
                        }
                        if n.view.Buf.Settings["statusline"].(bool) {
-                               n.view.height--
+                               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)
+                               if !n.lockWidth {
+                                       n.width = (s.width - lockedWidth) / (len(s.children) - lockedChildren)
+                               }
                                n.height = s.height
 
-                               n.x = s.x + n.width*i
+                               n.x = s.x + x
                                n.y = s.y
+                               x += n.width
                        } else {
-                               n.height = s.height / len(s.children)
+                               if !n.lockHeight {
+                                       n.height = (s.height - lockedHeight) / (len(s.children) - lockedChildren)
+                               }
                                n.width = s.width
 
-                               n.y = s.y + n.height*i
+                               n.y = s.y + y
                                n.x = s.x
+                               y += n.height
                        }
                        n.ResizeSplits()
                }
@@ -186,7 +281,7 @@ func (s *SplitTree) ResizeSplits() {
 }
 
 func (l *LeafNode) String() string {
-       return l.view.Buf.Name
+       return l.view.Buf.GetName()
 }
 
 func search(haystack []Node, needle Node) int {
@@ -208,10 +303,10 @@ func findView(haystack []*View, needle *View) int {
 }
 
 // VSplit is here just to make SplitTree fit the Node interface
-func (s *SplitTree) VSplit(buf *Buffer) {}
+func (s *SplitTree) VSplit(buf *Buffer, splitIndex int) {}
 
 // HSplit is here just to make SplitTree fit the Node interface
-func (s *SplitTree) HSplit(buf *Buffer) {}
+func (s *SplitTree) HSplit(buf *Buffer, splitIndex int) {}
 
 func (s *SplitTree) String() string {
        str := "["