diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-04-10 14:15:23 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-04-10 14:16:25 +0300 |
| commit | 831bb66c0cda103f79b2418389cd6528c03ade56 (patch) | |
| tree | 0ae176496c492a035f3eb6fb9f8eab13bd397ca1 /src/workspace.rs | |
| parent | e20be7bdae5c46ff922ee442b4fbd5d79c46cf99 (diff) | |
feat(tabs): add overflow scrolling and drag reorder
Diffstat (limited to 'src/workspace.rs')
| -rw-r--r-- | src/workspace.rs | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/src/workspace.rs b/src/workspace.rs index 5fabe47f..09fa382d 100644 --- a/src/workspace.rs +++ b/src/workspace.rs @@ -399,6 +399,32 @@ impl Workspace { true } + pub fn move_tab(&mut self, source_idx: usize, insert_idx: usize) -> bool { + if source_idx >= self.tabs.len() || insert_idx > self.tabs.len() { + return false; + } + + let target_idx = if source_idx < insert_idx { + insert_idx.saturating_sub(1) + } else { + insert_idx + } + .min(self.tabs.len().saturating_sub(1)); + + if source_idx == target_idx { + return false; + } + + let active_root_pane = self.tabs.get(self.active_tab).map(|tab| tab.root_pane); + let tab = self.tabs.remove(source_idx); + self.tabs.insert(target_idx, tab); + self.renumber_tabs(); + self.active_tab = active_root_pane + .and_then(|root_pane| self.tabs.iter().position(|tab| tab.root_pane == root_pane)) + .unwrap_or(target_idx); + true + } + pub fn close_active_tab(&mut self) -> bool { self.close_tab(self.active_tab) } @@ -963,6 +989,26 @@ mod tests { } #[test] + fn moving_tab_keeps_active_identity_and_renumbers_auto_tabs() { + let mut ws = Workspace::test_new("test"); + let moved_root = ws.tabs[0].root_pane; + ws.test_add_tab(Some("foo")); + let final_auto_idx = ws.test_add_tab(None); + let active_root = ws.tabs[final_auto_idx].root_pane; + ws.switch_tab(final_auto_idx); + + assert!(ws.move_tab(0, ws.tabs.len())); + + let labels: Vec<_> = ws.tabs.iter().map(|tab| tab.display_name()).collect(); + assert_eq!(labels, vec!["foo", "2", "3"]); + assert_eq!(ws.tabs[0].custom_name.as_deref(), Some("foo")); + assert!(ws.tabs[1].custom_name.is_none()); + assert!(ws.tabs[2].custom_name.is_none()); + assert_eq!(ws.tabs[2].root_pane, moved_root); + assert_eq!(ws.tabs[ws.active_tab].root_pane, active_root); + } + + #[test] fn pane_details_include_tab_context_when_workspace_has_multiple_tabs() { let mut ws = Workspace::test_new("test"); ws.tabs[0].set_custom_name("main".into()); |
