diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-06-13 01:59:24 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-06-13 01:59:24 +0300 |
| commit | d35c642ef36ee5ac2afe7c1b18ad5a717bc807d8 (patch) | |
| tree | 89f176d076ff65e1cb141f914707a552c17776fc /src/workspace | |
| parent | 469cf9cede389036f5799e2f41483413f1d7e60b (diff) | |
feat: add pane move api and cli
refs #299
Diffstat (limited to 'src/workspace')
| -rw-r--r-- | src/workspace/tab.rs | 80 |
1 files changed, 79 insertions, 1 deletions
diff --git a/src/workspace/tab.rs b/src/workspace/tab.rs index 4363e05c..0d9e6fdb 100644 --- a/src/workspace/tab.rs +++ b/src/workspace/tab.rs @@ -7,12 +7,17 @@ use ratatui::layout::Direction; use tokio::sync::{mpsc, Notify}; use crate::events::AppEvent; -use crate::layout::{PaneId, TileLayout}; +use crate::layout::{Node, PaneId, TileLayout}; use crate::pane::PaneState; use crate::terminal::{TerminalId, TerminalRuntime, TerminalRuntimeRegistry, TerminalState}; pub(crate) type DetachedPane = (PaneId, TerminalId); +pub(crate) struct MovedPane { + pub pane_id: PaneId, + pub pane_state: PaneState, +} + pub struct NewPane { pub pane_id: PaneId, pub terminal: TerminalState, @@ -401,6 +406,79 @@ impl Tab { self.detach_pane(pane_id) } + pub(crate) fn from_existing_pane( + number: usize, + custom_name: Option<String>, + moved: MovedPane, + events: mpsc::Sender<AppEvent>, + render_notify: Arc<Notify>, + render_dirty: Arc<AtomicBool>, + ) -> Self { + let mut panes = HashMap::new(); + let pane_id = moved.pane_id; + panes.insert(pane_id, moved.pane_state); + Self { + custom_name, + number, + root_pane: pane_id, + layout: TileLayout::from_saved(Node::Pane(pane_id), pane_id), + panes, + #[cfg(test)] + runtimes: HashMap::new(), + zoomed: false, + events, + render_notify, + render_dirty, + } + } + + pub(crate) fn take_pane_for_move(&mut self, pane_id: PaneId) -> Option<MovedPane> { + if !self.panes.contains_key(&pane_id) { + return None; + } + + if self.layout.pane_count() > 1 { + let next_root = self.promoted_root_if_needed(pane_id); + if self.layout.focused() == pane_id { + self.layout.close_focused(); + } else { + let prev_focus = self.layout.focused(); + self.layout.focus_pane(pane_id); + self.layout.close_focused(); + self.layout.focus_pane(prev_focus); + } + if let Some(next_root) = next_root { + self.root_pane = next_root; + } + } + + let pane_state = self.panes.remove(&pane_id)?; + self.zoomed = false; + Some(MovedPane { + pane_id, + pane_state, + }) + } + + pub(crate) fn insert_existing_pane( + &mut self, + target_pane_id: PaneId, + moved: MovedPane, + direction: Direction, + ratio: f32, + ) -> Result<PaneId, MovedPane> { + if !self + .layout + .insert_pane_near(target_pane_id, moved.pane_id, direction, ratio) + { + return Err(moved); + } + let pane_id = moved.pane_id; + self.panes.insert(pane_id, moved.pane_state); + self.zoomed = false; + Ok(pane_id) + } + fn detach_pane(&mut self, pane_id: PaneId) -> Option<DetachedPane> { if self.layout.pane_count() <= 1 { return None; |
