diff --git a/crates/ely_browser_core/src/navigation.rs b/crates/ely_browser_core/src/navigation.rs index f14a9b1..fcd5d8c 100644 --- a/crates/ely_browser_core/src/navigation.rs +++ b/crates/ely_browser_core/src/navigation.rs @@ -19,6 +19,9 @@ fn internal_page_title(url: &str) -> Option<&'static str> { "ely://downloads" => Some("Downloads"), "ely://history" => Some("History"), "ely://settings" => Some("Settings"), + "ely://settings/plugins" => Some("Plugin Settings"), + "ely://settings/profiles" => Some("Profile Settings"), + "ely://settings/sync" => Some("Sync Settings"), _ => None, } } @@ -82,6 +85,29 @@ pub(crate) fn settings_url() -> Result { internal_page_url("ely://settings") } +pub(crate) fn settings_page_url(query: &str) -> Result, CoreError> { + let normalized_query = query.trim().to_ascii_lowercase(); + let Some(url) = settings_page_route(&normalized_query) else { + return Ok(None); + }; + + internal_page_url(url).map(Some) +} + +fn settings_page_route(query: &str) -> Option<&'static str> { + match query { + "settings" | "general" | "browser" => Some("ely://settings"), + "sync" | "sync settings" => Some("ely://settings/sync"), + "profile" | "profiles" | "profile settings" | "profiles settings" => { + Some("ely://settings/profiles") + } + "plugin" | "plugins" | "plugin settings" | "plugins settings" => { + Some("ely://settings/plugins") + } + _ => None, + } +} + fn internal_page_url(value: &str) -> Result { UrlText::parse(value).map_err(CoreError::from) } diff --git a/crates/ely_browser_core/src/state/commands.rs b/crates/ely_browser_core/src/state/commands.rs index 1a5a164..20d7875 100644 --- a/crates/ely_browser_core/src/state/commands.rs +++ b/crates/ely_browser_core/src/state/commands.rs @@ -4,7 +4,7 @@ use crate::{ CoreError, navigation::{ downloads_url, history_url, move_tab_space_name, new_profile_name, new_space_name, - search_url, settings_url, space_icon, switch_profile_name, + search_url, settings_page_url, settings_url, space_icon, switch_profile_name, }, }; @@ -44,6 +44,12 @@ impl BrowserCore { self.command_query.clear(); } } + CommandIntent::ScopedSearch { scope: CommandScope::Settings, query } => { + if let Some(url) = settings_page_url(query)? { + self.open_tab(url); + self.command_query.clear(); + } + } CommandIntent::ScopedSearch { scope: CommandScope::Archive, query } if self.restore_archived_tab_match(query)?.is_some() => { diff --git a/crates/ely_browser_core/tests/commands.rs b/crates/ely_browser_core/tests/commands.rs index 9f739ea..73fa059 100644 --- a/crates/ely_browser_core/tests/commands.rs +++ b/crates/ely_browser_core/tests/commands.rs @@ -96,6 +96,48 @@ fn open_settings_command_opens_settings_page() -> Result<(), Box> { Ok(()) } +#[test] +fn settings_scoped_search_opens_matching_settings_page() -> Result<(), Box> { + let mut core = BrowserCore::new(InitialBrowserConfig::ely_defaults()?)?; + + core.set_command_query("@settings sync"); + let intent = core.submit_command()?; + let active_tab = core.active_tab()?; + + assert_eq!( + intent, + Some(CommandIntent::ScopedSearch { + scope: CommandScope::Settings, + query: "sync".to_string() + }) + ); + assert_eq!(active_tab.title(), "Sync Settings"); + assert_eq!(active_tab.url().as_str(), "ely://settings/sync"); + assert_eq!(core.snapshot()?.command_query, ""); + Ok(()) +} + +#[test] +fn settings_scoped_search_preserves_query_without_match() -> Result<(), Box> { + let mut core = BrowserCore::new(InitialBrowserConfig::ely_defaults()?)?; + let active_tab_id = core.active_tab()?.id().clone(); + + core.set_command_query("@settings absent"); + let intent = core.submit_command()?; + let snapshot = core.snapshot()?; + + assert_eq!( + intent, + Some(CommandIntent::ScopedSearch { + scope: CommandScope::Settings, + query: "absent".to_string() + }) + ); + assert_eq!(snapshot.active_tab_id, active_tab_id); + assert_eq!(snapshot.command_query, "@settings absent"); + Ok(()) +} + #[test] fn new_space_command_creates_and_selects_named_space() -> Result<(), Box> { let mut core = BrowserCore::new(InitialBrowserConfig::ely_defaults()?)?;