Add tab group rename command

This commit is contained in:
2026-05-08 11:05:54 -04:00
parent fb33771c8f
commit 5588237a1f
5 changed files with 96 additions and 3 deletions
@@ -105,6 +105,13 @@ pub(crate) fn tab_group_name(command: &str) -> Option<&str> {
command_argument(command, &["group-tab ", "group tab ", "tab-group ", "tab group "]) command_argument(command, &["group-tab ", "group tab ", "tab-group ", "tab group "])
} }
pub(crate) fn rename_tab_group_name(command: &str) -> Option<&str> {
command_argument(
command,
&["rename-tab-group ", "rename tab group ", "rename-group ", "rename group "],
)
}
pub(crate) fn split_group_name(command: &str) -> Option<&str> { pub(crate) fn split_group_name(command: &str) -> Option<&str> {
command_argument( command_argument(
command, command,
@@ -10,9 +10,9 @@ use crate::{
about_url, archive_idle_days, archive_url, bookmarks_url, downloads_url, history_url, about_url, archive_idle_days, archive_url, bookmarks_url, downloads_url, history_url,
move_tab_space_name, new_private_profile_name, new_profile_name, new_space_name, note_body, move_tab_space_name, new_private_profile_name, new_profile_name, new_space_name, note_body,
notes_url, plugin_detail_url, plugins_url, reading_list_url, reading_progress_percent, notes_url, plugin_detail_url, plugins_url, reading_list_url, reading_progress_percent,
search_url, settings_page_url, settings_url, shortcut_settings_url, space_icon, rename_tab_group_name, search_url, settings_page_url, settings_url, shortcut_settings_url,
split_group_name, switch_profile_name, sync_status_url, tab_group_name, tab_note_body, space_icon, split_group_name, switch_profile_name, sync_status_url, tab_group_name,
task_manager_url, tab_note_body, task_manager_url,
}, },
}; };
@@ -146,6 +146,9 @@ impl BrowserCore {
self.group_active_tab(name)?; self.group_active_tab(name)?;
return Ok(true); return Ok(true);
} }
if let Some(name) = rename_tab_group_name(command) {
return Ok(self.rename_active_tab_group(name)?.is_some());
}
if let Some(body) = tab_note_body(command) { if let Some(body) = tab_note_body(command) {
self.save_active_tab_note(body)?; self.save_active_tab_note(body)?;
return Ok(true); return Ok(true);
@@ -80,6 +80,26 @@ impl BrowserCore {
Ok(true) Ok(true)
} }
pub fn rename_active_tab_group(
&mut self,
name: impl Into<String>,
) -> Result<Option<TabGroupId>, CoreError> {
let Some(group_id) = self.active_tab_group_id()? else {
return Ok(None);
};
self.rename_tab_group(&group_id, name)?;
Ok(Some(group_id))
}
pub fn rename_tab_group(
&mut self,
group_id: &TabGroupId,
name: impl Into<String>,
) -> Result<(), CoreError> {
let group = self.tab_group_mut(group_id)?;
group.rename(name).map_err(CoreError::from)
}
pub fn discard_active_tab_group(&mut self) -> Result<Option<usize>, CoreError> { pub fn discard_active_tab_group(&mut self) -> Result<Option<usize>, CoreError> {
let Some(group_id) = self.active_tab_group_id()? else { let Some(group_id) = self.active_tab_group_id()? else {
return Ok(None); return Ok(None);
@@ -0,0 +1,47 @@
use std::error::Error;
use ely_browser_core::{BrowserCore, InitialBrowserConfig};
use ely_domain::{CommandIntent, TabGroupId, UrlText};
#[test]
fn rename_tab_group_command_updates_active_group_name() -> Result<(), Box<dyn Error>> {
let mut core = BrowserCore::new(InitialBrowserConfig::ely_defaults()?)?;
let first_tab_id = core.open_tab(UrlText::parse("https://example.com/a")?);
core.group_active_tab("Docs")?;
let second_tab_id = core.open_tab(UrlText::parse("https://example.com/b")?);
core.group_active_tab("Docs")?;
core.set_command_query(">rename-tab-group Research");
let intent = core.submit_command()?;
let snapshot = core.snapshot()?;
let group = snapshot.tab_groups.first().ok_or("missing tab group")?;
assert_eq!(intent, Some(CommandIntent::Command("rename-tab-group Research".to_string())));
assert_eq!(snapshot.command_query, "");
assert_eq!(snapshot.tab_groups.len(), 1);
assert_eq!(group.name(), "Research");
assert_eq!(tab_group_id(&snapshot, &first_tab_id), Some(group.id()));
assert_eq!(tab_group_id(&snapshot, &second_tab_id), Some(group.id()));
Ok(())
}
#[test]
fn rename_tab_group_command_preserves_query_without_active_group() -> Result<(), Box<dyn Error>> {
let mut core = BrowserCore::new(InitialBrowserConfig::ely_defaults()?)?;
core.set_command_query(">rename-tab-group Research");
let intent = core.submit_command()?;
let snapshot = core.snapshot()?;
assert_eq!(intent, Some(CommandIntent::Command("rename-tab-group Research".to_string())));
assert_eq!(snapshot.command_query, ">rename-tab-group Research");
assert!(snapshot.tab_groups.is_empty());
Ok(())
}
fn tab_group_id<'a>(
snapshot: &'a ely_browser_core::BrowserSnapshot,
tab_id: &ely_domain::TabId,
) -> Option<&'a TabGroupId> {
snapshot.tabs.iter().find(|tab| tab.id() == tab_id).and_then(|tab| tab.group_id())
}
+16
View File
@@ -87,6 +87,22 @@ Domain auto grouping keeps manual groups intact and groups matching ungrouped ho
└──────────────────────────────┴───────────────────────────────────────────────┘ └──────────────────────────────┴───────────────────────────────────────────────┘
``` ```
Group rename updates the active group row in place:
```text
┌──────────────────────────────────────────────────────────────────────────────┐
│ ELY Browser [ >rename-tab-group Research................. ] [pin] [*] [+] │
├──────────────────────────────┬───────────────────────────────────────────────┤
│ Tabs │ example.com │
│ [folder] Research │ https://example.com/b │
│ 2 tabs - Expanded │ │
│ example.com │ Group Research │
│ example.com │ │
│ example.com │ │
│ example.com │ │
└──────────────────────────────┴───────────────────────────────────────────────┘
```
Group sleep applies the sleeping state to every tab in the active group: Group sleep applies the sleeping state to every tab in the active group:
```text ```text