From 4e7c01c3c80b78044443b3e2275c0f385d1e884f Mon Sep 17 00:00:00 2001 From: Massimo Mund Date: Wed, 6 Aug 2025 20:51:56 +0200 Subject: [PATCH 1/2] `vResizeSplit` and `hResizeSplit` cannot change the size of the last split in a group of siblings. The general strategy for changing the size of a split is to set the size of the selected split and adjust the size of the split to its right according to the remaining space. This calculation works for all cases except the last split. Instead of directly setting the size of the selected (last) split, the existing strategy is to calculate the necessary size of the split to its left based on the available space and thus indirectly adjust the size of the selected split. However, the necessary adjustment of the new size is missing. --- internal/views/splits.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/views/splits.go b/internal/views/splits.go index b2a20873f9..101ae196b6 100644 --- a/internal/views/splits.go +++ b/internal/views/splits.go @@ -147,6 +147,7 @@ func (n *Node) vResizeSplit(i int, size int) bool { var c1, c2 *Node if i == len(n.children)-1 { c1, c2 = n.children[i-1], n.children[i] + size = c1.H + c2.H - size } else { c1, c2 = n.children[i], n.children[i+1] } @@ -168,6 +169,7 @@ func (n *Node) hResizeSplit(i int, size int) bool { var c1, c2 *Node if i == len(n.children)-1 { c1, c2 = n.children[i-1], n.children[i] + size = c1.W + c2.W - size } else { c1, c2 = n.children[i], n.children[i+1] } From 230d5d5fd572ad5a737d97f9c0bc117c4a5325de Mon Sep 17 00:00:00 2001 From: Massimo Mund Date: Wed, 6 Aug 2025 21:18:52 +0200 Subject: [PATCH 2/2] Change the design of `vResizeSplit` and `hResizeSplit` The entire design of the function is somewhat peculiar. Resizing to the right/bottom works well. However you cannot choose the direction in which you wish to resize, and therefore must deal with additional logic to achieve resizing to the left/top. --- internal/action/bufpane.go | 10 +++++-- internal/action/tab.go | 2 +- internal/views/splits.go | 56 +++++++++++++++++++++++++---------- internal/views/splits_test.go | 2 +- 4 files changed, 49 insertions(+), 21 deletions(-) diff --git a/internal/action/bufpane.go b/internal/action/bufpane.go index b4030a956f..fff5ac2067 100644 --- a/internal/action/bufpane.go +++ b/internal/action/bufpane.go @@ -314,10 +314,14 @@ func (h *BufPane) Tab() *Tab { return h.tab } -func (h *BufPane) ResizePane(size int) { +// ResizePane resizes the pane to a given size in the specified direction +func (h *BufPane) ResizePane(size int, right_or_bottom bool) bool { n := h.tab.GetNode(h.splitID) - n.ResizeSplit(size) - h.tab.Resize() + r := n.ResizeSplit(size, right_or_bottom) + if r { + h.tab.Resize() + } + return r } // PluginCB calls all plugin callbacks with a certain name and displays an diff --git a/internal/action/tab.go b/internal/action/tab.go index 076df5f801..24f9cc63ed 100644 --- a/internal/action/tab.go +++ b/internal/action/tab.go @@ -292,7 +292,7 @@ func (t *Tab) HandleEvent(event tcell.Event) { } else { size = my - t.resizing.Y + 1 } - t.resizing.ResizeSplit(size) + t.resizing.ResizeSplit(size, true) t.Resize() return } diff --git a/internal/views/splits.go b/internal/views/splits.go index 101ae196b6..1005b56ece 100644 --- a/internal/views/splits.go +++ b/internal/views/splits.go @@ -117,6 +117,11 @@ func (n *Node) SetPropScale(b bool) { n.propScale = b } +// Parent returns this node's parent +func (n *Node) Parent() *Node { + return n.parent +} + // Children returns this node's children func (n *Node) Children() []*Node { return n.children @@ -140,16 +145,26 @@ func (n *Node) GetNode(id uint64) *Node { return nil } -func (n *Node) vResizeSplit(i int, size int) bool { +// vResizeSplit resizes a node vertically on the given side +func (n *Node) vResizeSplit(i int, size int, bottom bool) bool { if i < 0 || i >= len(n.children) { return false } var c1, c2 *Node - if i == len(n.children)-1 { + if bottom { + if i == len(n.children)-1 { + return false + } + c1, c2 = n.children[i], n.children[i+1] + } else { + if i == 0 { + return false + } c1, c2 = n.children[i-1], n.children[i] size = c1.H + c2.H - size - } else { - c1, c2 = n.children[i], n.children[i+1] + } + if size <= 0 || size >= n.H { + return false } toth := c1.H + c2.H if size >= toth { @@ -162,16 +177,27 @@ func (n *Node) vResizeSplit(i int, size int) bool { n.alignSizes(n.W, n.H) return true } -func (n *Node) hResizeSplit(i int, size int) bool { + +// hResizeSplit resizes a node horizontally on the given side +func (n *Node) hResizeSplit(i int, size int, right bool) bool { if i < 0 || i >= len(n.children) { return false } var c1, c2 *Node - if i == len(n.children)-1 { + if right { + if i == len(n.children)-1 { + return false + } + c1, c2 = n.children[i], n.children[i+1] + } else { + if i == 0 { + return false + } c1, c2 = n.children[i-1], n.children[i] size = c1.W + c2.W - size - } else { - c1, c2 = n.children[i], n.children[i+1] + } + if size <= 0 || size >= n.W { + return false } totw := c1.W + c2.W if size >= totw { @@ -185,12 +211,8 @@ func (n *Node) hResizeSplit(i int, size int) bool { return true } -// ResizeSplit resizes a certain split to a given size -func (n *Node) ResizeSplit(size int) bool { - // TODO: `size < 0` does not work for some reason - if size <= 0 { - return false - } +// ResizeSplit resizes a node to a given size in the specified direction +func (n *Node) ResizeSplit(size int, right_or_bottom bool) bool { if len(n.parent.children) <= 1 { // cannot resize a lone node return false @@ -202,9 +224,11 @@ func (n *Node) ResizeSplit(size int) bool { } } if n.parent.Kind == STVert { - return n.parent.vResizeSplit(ind, size) + return n.parent.vResizeSplit(ind, size, right_or_bottom) + } else if n.parent.Kind == STHoriz { + return n.parent.hResizeSplit(ind, size, right_or_bottom) } - return n.parent.hResizeSplit(ind, size) + return false } // Resize sets this node's size and resizes all children accordingly diff --git a/internal/views/splits_test.go b/internal/views/splits_test.go index 94f8a2b97a..4bbe04d0ba 100644 --- a/internal/views/splits_test.go +++ b/internal/views/splits_test.go @@ -9,7 +9,7 @@ func TestHSplit(t *testing.T) { root := NewRoot(0, 0, 80, 80) n1 := root.VSplit(true) root.GetNode(n1).VSplit(true) - root.GetNode(root.id).ResizeSplit(7) + root.GetNode(root.id).ResizeSplit(7, true) root.Resize(120, 120) fmt.Println(root.String())