Add active tab reorder commands

This commit is contained in:
2026-05-09 00:16:12 -04:00
parent 79d9646ab8
commit 97a06d7b52
3 changed files with 143 additions and 1 deletions
@@ -167,6 +167,10 @@ impl BrowserCore {
self.open_new_tab()?;
Ok(true)
}
"move-tab-up" | "move tab up" | "tab-up" | "tab up" => self.move_active_tab_up(),
"move-tab-down" | "move tab down" | "tab-down" | "tab down" => {
self.move_active_tab_down()
}
"split-right" | "split right" => {
self.split_active_tab_right()?;
Ok(true)
+63 -1
View File
@@ -1,8 +1,16 @@
use ely_domain::{BrowserTab, SpaceId};
use ely_domain::{BrowserTab, SpaceId, TabId};
use super::BrowserCore;
impl BrowserCore {
pub fn move_active_tab_up(&mut self) -> Result<bool, crate::CoreError> {
self.move_active_tab_by(TabMoveDirection::Up)
}
pub fn move_active_tab_down(&mut self) -> Result<bool, crate::CoreError> {
self.move_active_tab_by(TabMoveDirection::Down)
}
pub(super) fn next_tab_sort_key(&self, space_id: &SpaceId) -> u64 {
self.tabs
.iter()
@@ -34,6 +42,45 @@ impl BrowserCore {
self.tabs[index] = tab;
}
}
fn move_active_tab_by(
&mut self,
direction: TabMoveDirection,
) -> Result<bool, crate::CoreError> {
let active_tab = self.active_tab()?.clone();
let space_id = active_tab.space_id().clone();
let mut tab_ids = sorted_tabs(self.tabs.iter().filter(|tab| tab.space_id() == &space_id))
.into_iter()
.map(|tab| tab.id().clone())
.collect::<Vec<_>>();
let Some(active_index) = tab_ids.iter().position(|tab_id| tab_id == active_tab.id()) else {
return Err(crate::CoreError::MissingActiveTab);
};
let Some(target_index) = direction.target_index(active_index, tab_ids.len()) else {
return Ok(false);
};
tab_ids.swap(active_index, target_index);
self.apply_tab_order(&space_id, &tab_ids)?;
Ok(true)
}
fn apply_tab_order(
&mut self,
space_id: &SpaceId,
tab_ids: &[TabId],
) -> Result<(), crate::CoreError> {
for (sort_key, tab_id) in tab_ids.iter().enumerate() {
let tab = self
.tabs
.iter_mut()
.find(|tab| tab.id() == tab_id && tab.space_id() == space_id)
.ok_or_else(|| crate::CoreError::TabNotFound { id: tab_id.clone() })?;
tab.set_sort_key(sort_key as u64);
}
self.sort_tabs_within_space(space_id);
Ok(())
}
}
pub(super) fn sorted_tabs<'a>(tabs: impl Iterator<Item = &'a BrowserTab>) -> Vec<BrowserTab> {
@@ -45,3 +92,18 @@ pub(super) fn sorted_tabs<'a>(tabs: impl Iterator<Item = &'a BrowserTab>) -> Vec
fn compare_tabs(left: &BrowserTab, right: &BrowserTab) -> std::cmp::Ordering {
left.sort_key().cmp(&right.sort_key()).then_with(|| left.id().cmp(right.id()))
}
#[derive(Clone, Copy)]
enum TabMoveDirection {
Up,
Down,
}
impl TabMoveDirection {
fn target_index(self, active_index: usize, tab_count: usize) -> Option<usize> {
match self {
Self::Up => active_index.checked_sub(1),
Self::Down => (active_index + 1 < tab_count).then_some(active_index + 1),
}
}
}