Move active tabs between spaces
This commit is contained in:
@@ -30,6 +30,17 @@ pub(crate) fn new_space_name(command: &str) -> Option<&str> {
|
||||
None
|
||||
}
|
||||
|
||||
pub(crate) fn move_tab_space_name(command: &str) -> Option<&str> {
|
||||
let normalized_command = command.to_ascii_lowercase();
|
||||
for prefix in ["move-tab ", "move tab ", "move-tab-to-space ", "move tab to space "] {
|
||||
if normalized_command.starts_with(prefix) {
|
||||
let name = command[prefix.len()..].trim();
|
||||
return (!name.is_empty()).then_some(name);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub(crate) fn space_icon(name: &str) -> String {
|
||||
name.chars().next().map_or_else(String::new, |value| value.to_string())
|
||||
}
|
||||
|
||||
@@ -162,6 +162,38 @@ impl BrowserCore {
|
||||
Ok(tab_id)
|
||||
}
|
||||
|
||||
pub fn move_active_tab_to_space(&mut self, space_id: &SpaceId) -> Result<TabId, CoreError> {
|
||||
if !self.spaces.iter().any(|space| space.id() == space_id) {
|
||||
return Err(CoreError::SpaceNotFound { id: space_id.clone() });
|
||||
}
|
||||
|
||||
let tab_index = self.active_tab_index()?;
|
||||
let tab_id = self.active_tab_id.clone();
|
||||
let source_space_id = self.tabs[tab_index].space_id().clone();
|
||||
if &source_space_id == space_id {
|
||||
return Ok(tab_id);
|
||||
}
|
||||
|
||||
self.tabs[tab_index].move_to_space(space_id.clone());
|
||||
self.active_tabs_by_space.insert(space_id.clone(), tab_id.clone());
|
||||
|
||||
if let Some(next_tab_id) = self.nearest_tab_in_space(&source_space_id, tab_index) {
|
||||
self.active_tabs_by_space.insert(source_space_id, next_tab_id);
|
||||
} else {
|
||||
let tab = self.build_tab_for(
|
||||
source_space_id.clone(),
|
||||
self.active_profile_id.clone(),
|
||||
self.new_tab_url.clone(),
|
||||
);
|
||||
let replacement_id = tab.id().clone();
|
||||
self.tabs.insert(tab_index, tab);
|
||||
self.active_tabs_by_space.insert(source_space_id, replacement_id);
|
||||
}
|
||||
|
||||
self.select_tab(&tab_id)?;
|
||||
Ok(tab_id)
|
||||
}
|
||||
|
||||
pub fn close_active_tab(&mut self) -> Result<TabId, CoreError> {
|
||||
let tab_id = self.active_tab_id.clone();
|
||||
self.close_tab(&tab_id)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use ely_domain::{CommandIntent, CommandScope};
|
||||
use ely_domain::{CommandIntent, CommandScope, SpaceId};
|
||||
|
||||
use crate::{
|
||||
CoreError,
|
||||
navigation::{new_space_name, search_url, space_icon},
|
||||
navigation::{move_tab_space_name, new_space_name, search_url, space_icon},
|
||||
};
|
||||
|
||||
use super::BrowserCore;
|
||||
@@ -36,12 +36,7 @@ impl BrowserCore {
|
||||
}
|
||||
}
|
||||
CommandIntent::ScopedSearch { scope: CommandScope::Spaces, query } => {
|
||||
let query = query.trim().to_lowercase();
|
||||
if let Some(space_id) = self.spaces.iter().find_map(|space| {
|
||||
(space.name().to_lowercase().contains(&query)
|
||||
|| space.icon().to_lowercase().contains(&query))
|
||||
.then(|| space.id().clone())
|
||||
}) {
|
||||
if let Some(space_id) = self.find_space_match(query) {
|
||||
self.select_space(&space_id)?;
|
||||
self.command_query.clear();
|
||||
}
|
||||
@@ -63,6 +58,13 @@ impl BrowserCore {
|
||||
self.create_space(name.to_string(), space_icon(name), 0xf54e00)?;
|
||||
return Ok(true);
|
||||
}
|
||||
if let Some(name) = move_tab_space_name(command) {
|
||||
let Some(space_id) = self.find_space_match(name) else {
|
||||
return Ok(false);
|
||||
};
|
||||
self.move_active_tab_to_space(&space_id)?;
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
match command.to_ascii_lowercase().as_str() {
|
||||
"new-tab" => {
|
||||
@@ -88,4 +90,13 @@ impl BrowserCore {
|
||||
_ => Ok(false),
|
||||
}
|
||||
}
|
||||
|
||||
fn find_space_match(&self, query: &str) -> Option<SpaceId> {
|
||||
let query = query.trim().to_lowercase();
|
||||
self.spaces.iter().find_map(|space| {
|
||||
(space.name().to_lowercase().contains(&query)
|
||||
|| space.icon().to_lowercase().contains(&query))
|
||||
.then(|| space.id().clone())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user