aboutsummaryrefslogtreecommitdiff
path: root/src/layout.rs
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-06-13 01:59:24 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-06-13 01:59:24 +0300
commitd35c642ef36ee5ac2afe7c1b18ad5a717bc807d8 (patch)
tree89f176d076ff65e1cb141f914707a552c17776fc /src/layout.rs
parent469cf9cede389036f5799e2f41483413f1d7e60b (diff)
feat: add pane move api and cli
refs #299
Diffstat (limited to 'src/layout.rs')
-rw-r--r--src/layout.rs40
1 files changed, 40 insertions, 0 deletions
diff --git a/src/layout.rs b/src/layout.rs
index bd7828c6..06426f85 100644
--- a/src/layout.rs
+++ b/src/layout.rs
@@ -132,6 +132,30 @@ impl TileLayout {
new_id
}
+ /// Insert an existing pane id next to a target pane without allocating a new
+ /// pane or spawning a terminal runtime.
+ pub fn insert_pane_near(
+ &mut self,
+ target: PaneId,
+ moved: PaneId,
+ direction: Direction,
+ ratio: f32,
+ ) -> bool {
+ if target == moved {
+ return false;
+ }
+ let ids = self.pane_ids();
+ if !ids.contains(&target) || ids.contains(&moved) {
+ return false;
+ }
+
+ let placeholder = PaneId::from_raw(0);
+ let old = std::mem::replace(&mut self.root, Node::Pane(placeholder));
+ self.root = split_at(old, target, direction, moved, valid_split_ratio(ratio));
+ self.focus = moved;
+ true
+ }
+
/// Close the focused pane. Returns false if it's the last pane.
pub fn close_focused(&mut self) -> bool {
if self.pane_count() <= 1 {
@@ -709,6 +733,22 @@ mod tests {
}
#[test]
+ fn insert_existing_pane_near_target_preserves_existing_ids_and_focuses_moved_pane() {
+ let (mut layout, root) = TileLayout::new();
+ let moved = pane(99);
+
+ assert!(layout.insert_pane_near(root, moved, Direction::Horizontal, 0.25));
+
+ assert_eq!(layout.pane_count(), 2);
+ assert_eq!(layout.pane_ids(), vec![root, moved]);
+ assert_eq!(layout.focused(), moved);
+ let splits = split_snapshot(&layout);
+ assert_eq!(splits, vec![(Direction::Horizontal, 0.25)]);
+ assert_eq!(pane_rect(&layout, root), Rect::new(0, 0, 25, 40));
+ assert_eq!(pane_rect(&layout, moved), Rect::new(25, 0, 75, 40));
+ }
+
+ #[test]
fn split_focused_with_ratio_sets_new_split_ratio() {
let (mut layout, root) = TileLayout::new();
layout.focus_pane(root);