diff --git a/crates/auto_update/src/auto_update.rs b/crates/auto_update/src/auto_update.rs index 06e445e3de..3b8d1c6e61 100644 --- a/crates/auto_update/src/auto_update.rs +++ b/crates/auto_update/src/auto_update.rs @@ -93,7 +93,9 @@ pub fn init(http_client: Arc, server_url: String, cx: &mut AppCo cx.observe_new_views(|workspace: &mut Workspace, _cx| { workspace.register_action(|_, action: &Check, cx| check(action, cx)); - workspace.register_action(|_, action, cx| view_release_notes(action, cx)); + workspace.register_action(|_, action, cx| { + view_release_notes(action, cx); + }); // @nate - code to trigger update notification on launch // todo!("remove this when Nate is done") @@ -140,24 +142,23 @@ pub fn check(_: &Check, cx: &mut WindowContext) { } } -pub fn view_release_notes(_: &ViewReleaseNotes, cx: &mut AppContext) { - if let Some(auto_updater) = AutoUpdater::get(cx) { +pub fn view_release_notes(_: &ViewReleaseNotes, cx: &mut AppContext) -> Option<()> { + let auto_updater = AutoUpdater::get(cx)?; + let release_channel = cx.try_global::()?; + + if matches!( + release_channel, + ReleaseChannel::Stable | ReleaseChannel::Preview + ) { let auto_updater = auto_updater.read(cx); let server_url = &auto_updater.server_url; + let release_channel = release_channel.dev_name(); let current_version = auto_updater.current_version; - if cx.has_global::() { - match cx.global::() { - ReleaseChannel::Dev => {} - ReleaseChannel::Nightly => {} - ReleaseChannel::Preview => { - cx.open_url(&format!("{server_url}/releases/preview/{current_version}")) - } - ReleaseChannel::Stable => { - cx.open_url(&format!("{server_url}/releases/stable/{current_version}")) - } - } - } + let url = format!("{server_url}/releases/{release_channel}/{current_version}"); + cx.open_url(&url); } + + None } pub fn notify_of_any_new_update(cx: &mut ViewContext) -> Option<()> { @@ -257,11 +258,13 @@ impl AutoUpdater { "{server_url}/api/releases/latest?token={ZED_SECRET_CLIENT_TOKEN}&asset=Zed.dmg" ); cx.update(|cx| { - if cx.has_global::() { - if let Some(param) = cx.global::().release_query_param() { - url_string += "&"; - url_string += param; - } + if let Some(param) = cx + .try_global::() + .map(|release_channel| release_channel.release_query_param()) + .flatten() + { + url_string += "&"; + url_string += param; } })?; @@ -313,8 +316,8 @@ impl AutoUpdater { let (installation_id, release_channel, telemetry) = cx.update(|cx| { let installation_id = cx.global::>().telemetry().installation_id(); let release_channel = cx - .has_global::() - .then(|| cx.global::().display_name()); + .try_global::() + .map(|release_channel| release_channel.display_name()); let telemetry = TelemetrySettings::get_global(cx).metrics; (installation_id, release_channel, telemetry) diff --git a/crates/auto_update/src/update_notification.rs b/crates/auto_update/src/update_notification.rs index 985972da56..1562d90057 100644 --- a/crates/auto_update/src/update_notification.rs +++ b/crates/auto_update/src/update_notification.rs @@ -40,7 +40,9 @@ impl Render for UpdateNotification { .id("notes") .child(Label::new("View the release notes")) .cursor_pointer() - .on_click(|_, cx| crate::view_release_notes(&Default::default(), cx)), + .on_click(|_, cx| { + crate::view_release_notes(&Default::default(), cx); + }), ) } } diff --git a/crates/client/src/telemetry.rs b/crates/client/src/telemetry.rs index 5ee039a8cb..313133ebef 100644 --- a/crates/client/src/telemetry.rs +++ b/crates/client/src/telemetry.rs @@ -150,11 +150,9 @@ const FLUSH_INTERVAL: Duration = Duration::from_secs(60 * 5); impl Telemetry { pub fn new(client: Arc, cx: &mut AppContext) -> Arc { - let release_channel = if cx.has_global::() { - Some(cx.global::().display_name()) - } else { - None - }; + let release_channel = cx + .try_global::() + .map(|release_channel| release_channel.display_name()); TelemetrySettings::register(cx); diff --git a/crates/copilot/src/copilot.rs b/crates/copilot/src/copilot.rs index 89d1086c8e..f36567c6b9 100644 --- a/crates/copilot/src/copilot.rs +++ b/crates/copilot/src/copilot.rs @@ -308,11 +308,7 @@ impl EventEmitter for Copilot {} impl Copilot { pub fn global(cx: &AppContext) -> Option> { - if cx.has_global::>() { - Some(cx.global::>().clone()) - } else { - None - } + cx.try_global::>().map(|model| model.clone()) } fn start( @@ -373,10 +369,11 @@ impl Copilot { #[cfg(any(test, feature = "test-support"))] pub fn fake(cx: &mut gpui::TestAppContext) -> (Model, lsp::FakeLanguageServer) { + use lsp::FakeLanguageServer; use node_runtime::FakeNodeRuntime; let (server, fake_server) = - LanguageServer::fake("copilot".into(), Default::default(), cx.to_async()); + FakeLanguageServer::new("copilot".into(), Default::default(), cx.to_async()); let http = util::http::FakeHttpClient::create(|_| async { unreachable!() }); let node_runtime = FakeNodeRuntime::new(); let this = cx.new_model(|cx| Self { diff --git a/crates/feature_flags/src/feature_flags.rs b/crates/feature_flags/src/feature_flags.rs index ea16ff3f72..907c37ddcd 100644 --- a/crates/feature_flags/src/feature_flags.rs +++ b/crates/feature_flags/src/feature_flags.rs @@ -57,18 +57,14 @@ impl FeatureFlagAppExt for AppContext { } fn has_flag(&self) -> bool { - if self.has_global::() { - self.global::().has_flag(T::NAME) - } else { - false - } + self.try_global::() + .map(|flags| flags.has_flag(T::NAME)) + .unwrap_or(false) } fn is_staff(&self) -> bool { - if self.has_global::() { - return self.global::().staff; - } else { - false - } + self.try_global::() + .map(|flags| flags.staff) + .unwrap_or(false) } } diff --git a/crates/gpui/src/platform.rs b/crates/gpui/src/platform.rs index dfb85104fe..e08d7a8552 100644 --- a/crates/gpui/src/platform.rs +++ b/crates/gpui/src/platform.rs @@ -201,6 +201,7 @@ pub trait PlatformDispatcher: Send + Sync { pub(crate) trait PlatformTextSystem: Send + Sync { fn add_fonts(&self, fonts: &[Arc>]) -> Result<()>; fn all_font_names(&self) -> Vec; + fn all_font_families(&self) -> Vec; fn font_id(&self, descriptor: &Font) -> Result; fn font_metrics(&self, font_id: FontId) -> FontMetrics; fn typographic_bounds(&self, font_id: FontId, glyph_id: GlyphId) -> Result>; @@ -282,8 +283,6 @@ pub(crate) trait PlatformAtlas: Send + Sync { key: &AtlasKey, build: &mut dyn FnMut() -> Result<(Size, Cow<'a, [u8]>)>, ) -> Result; - - fn clear(&self); } #[derive(Clone, Debug, PartialEq, Eq)] diff --git a/crates/gpui/src/platform/mac/metal_atlas.rs b/crates/gpui/src/platform/mac/metal_atlas.rs index 10ca53530e..d3caeba522 100644 --- a/crates/gpui/src/platform/mac/metal_atlas.rs +++ b/crates/gpui/src/platform/mac/metal_atlas.rs @@ -74,20 +74,6 @@ impl PlatformAtlas for MetalAtlas { Ok(tile) } } - - fn clear(&self) { - let mut lock = self.0.lock(); - lock.tiles_by_key.clear(); - for texture in &mut lock.monochrome_textures { - texture.clear(); - } - for texture in &mut lock.polychrome_textures { - texture.clear(); - } - for texture in &mut lock.path_textures { - texture.clear(); - } - } } impl MetalAtlasState { diff --git a/crates/gpui/src/platform/mac/text_system.rs b/crates/gpui/src/platform/mac/text_system.rs index a77741074f..d11efa902a 100644 --- a/crates/gpui/src/platform/mac/text_system.rs +++ b/crates/gpui/src/platform/mac/text_system.rs @@ -85,7 +85,9 @@ impl PlatformTextSystem for MacTextSystem { }; let mut names = BTreeSet::new(); for descriptor in descriptors.into_iter() { - names.insert(descriptor.display_name()); + names.insert(descriptor.font_name()); + names.insert(descriptor.family_name()); + names.insert(descriptor.style_name()); } if let Ok(fonts_in_memory) = self.0.read().memory_source.all_families() { names.extend(fonts_in_memory); @@ -93,6 +95,14 @@ impl PlatformTextSystem for MacTextSystem { names.into_iter().collect() } + fn all_font_families(&self) -> Vec { + self.0 + .read() + .system_source + .all_families() + .expect("core text should never return an error") + } + fn font_id(&self, font: &Font) -> Result { let lock = self.0.upgradable_read(); if let Some(font_id) = lock.font_selections.get(font) { diff --git a/crates/gpui/src/platform/test/window.rs b/crates/gpui/src/platform/test/window.rs index 5c8a3e5a59..2f080bd709 100644 --- a/crates/gpui/src/platform/test/window.rs +++ b/crates/gpui/src/platform/test/window.rs @@ -325,10 +325,4 @@ impl PlatformAtlas for TestAtlas { Ok(state.tiles[key].clone()) } - - fn clear(&self) { - let mut state = self.0.lock(); - state.tiles = HashMap::default(); - state.next_id = 0; - } } diff --git a/crates/gpui/src/text_system.rs b/crates/gpui/src/text_system.rs index 27d216dd50..1c9de5ea04 100644 --- a/crates/gpui/src/text_system.rs +++ b/crates/gpui/src/text_system.rs @@ -13,7 +13,7 @@ use crate::{ SharedString, Size, UnderlineStyle, }; use anyhow::anyhow; -use collections::{FxHashMap, FxHashSet}; +use collections::{BTreeSet, FxHashMap, FxHashSet}; use core::fmt; use itertools::Itertools; use parking_lot::{Mutex, RwLock, RwLockUpgradableReadGuard}; @@ -66,15 +66,18 @@ impl TextSystem { } pub fn all_font_names(&self) -> Vec { - let mut families = self.platform_text_system.all_font_names(); - families.append( - &mut self - .fallback_font_stack + let mut names: BTreeSet<_> = self + .platform_text_system + .all_font_names() + .into_iter() + .collect(); + names.extend(self.platform_text_system.all_font_families().into_iter()); + names.extend( + self.fallback_font_stack .iter() - .map(|font| font.family.to_string()) - .collect(), + .map(|font| font.family.to_string()), ); - families + names.into_iter().collect() } pub fn add_fonts(&self, fonts: &[Arc>]) -> Result<()> { self.platform_text_system.add_fonts(fonts) diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index 366d2b0098..57b76eddad 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -951,7 +951,7 @@ impl LanguageRegistry { if language.fake_adapter.is_some() { let task = cx.spawn(|cx| async move { let (servers_tx, fake_adapter) = language.fake_adapter.as_ref().unwrap(); - let (server, mut fake_server) = lsp::LanguageServer::fake( + let (server, mut fake_server) = lsp::FakeLanguageServer::new( fake_adapter.name.to_string(), fake_adapter.capabilities.clone(), cx.clone(), diff --git a/crates/lsp/src/lsp.rs b/crates/lsp/src/lsp.rs index 80ab6b07d1..a70422008c 100644 --- a/crates/lsp/src/lsp.rs +++ b/crates/lsp/src/lsp.rs @@ -972,30 +972,18 @@ pub struct FakeLanguageServer { } #[cfg(any(test, feature = "test-support"))] -impl LanguageServer { - pub fn full_capabilities() -> ServerCapabilities { - ServerCapabilities { - document_highlight_provider: Some(OneOf::Left(true)), - code_action_provider: Some(CodeActionProviderCapability::Simple(true)), - document_formatting_provider: Some(OneOf::Left(true)), - document_range_formatting_provider: Some(OneOf::Left(true)), - definition_provider: Some(OneOf::Left(true)), - type_definition_provider: Some(TypeDefinitionProviderCapability::Simple(true)), - ..Default::default() - } - } - +impl FakeLanguageServer { /// Construct a fake language server. - pub fn fake( + pub fn new( name: String, capabilities: ServerCapabilities, cx: AsyncAppContext, - ) -> (Self, FakeLanguageServer) { + ) -> (LanguageServer, FakeLanguageServer) { let (stdin_writer, stdin_reader) = async_pipe::pipe(); let (stdout_writer, stdout_reader) = async_pipe::pipe(); let (notifications_tx, notifications_rx) = channel::unbounded(); - let server = Self::new_internal( + let server = LanguageServer::new_internal( LanguageServerId(0), stdin_writer, stdout_reader, @@ -1008,7 +996,7 @@ impl LanguageServer { |_| {}, ); let fake = FakeLanguageServer { - server: Arc::new(Self::new_internal( + server: Arc::new(LanguageServer::new_internal( LanguageServerId(0), stdout_writer, stdin_reader, @@ -1053,6 +1041,21 @@ impl LanguageServer { } } +#[cfg(any(test, feature = "test-support"))] +impl LanguageServer { + pub fn full_capabilities() -> ServerCapabilities { + ServerCapabilities { + document_highlight_provider: Some(OneOf::Left(true)), + code_action_provider: Some(CodeActionProviderCapability::Simple(true)), + document_formatting_provider: Some(OneOf::Left(true)), + document_range_formatting_provider: Some(OneOf::Left(true)), + definition_provider: Some(OneOf::Left(true)), + type_definition_provider: Some(TypeDefinitionProviderCapability::Simple(true)), + ..Default::default() + } + } +} + #[cfg(any(test, feature = "test-support"))] impl FakeLanguageServer { /// See [`LanguageServer::notify`]. @@ -1188,7 +1191,7 @@ mod tests { #[gpui::test] async fn test_fake(cx: &mut TestAppContext) { let (server, mut fake) = - LanguageServer::fake("the-lsp".to_string(), Default::default(), cx.to_async()); + FakeLanguageServer::new("the-lsp".to_string(), Default::default(), cx.to_async()); let (message_tx, message_rx) = channel::unbounded(); let (diagnostics_tx, diagnostics_rx) = channel::unbounded(); diff --git a/crates/project_panel/src/file_associations.rs b/crates/project_panel/src/file_associations.rs index 0ddcfc9285..783fae4c52 100644 --- a/crates/project_panel/src/file_associations.rs +++ b/crates/project_panel/src/file_associations.rs @@ -42,7 +42,7 @@ impl FileAssociations { } pub fn get_icon(path: &Path, cx: &AppContext) -> Option> { - let this = cx.has_global::().then(|| cx.global::())?; + let this = cx.try_global::()?; // FIXME: Associate a type with the languages and have the file's language // override these associations @@ -58,7 +58,7 @@ impl FileAssociations { } pub fn get_folder_icon(expanded: bool, cx: &AppContext) -> Option> { - let this = cx.has_global::().then(|| cx.global::())?; + let this = cx.try_global::()?; let key = if expanded { EXPANDED_DIRECTORY_TYPE @@ -72,7 +72,7 @@ impl FileAssociations { } pub fn get_chevron_icon(expanded: bool, cx: &AppContext) -> Option> { - let this = cx.has_global::().then(|| cx.global::())?; + let this = cx.try_global::()?; let key = if expanded { EXPANDED_CHEVRON_TYPE diff --git a/crates/search/src/buffer_search.rs b/crates/search/src/buffer_search.rs index a1f0d9773b..f4c9f7ef0f 100644 --- a/crates/search/src/buffer_search.rs +++ b/crates/search/src/buffer_search.rs @@ -638,6 +638,12 @@ impl BufferSearchBar { registrar.register_handler(|this, _: &editor::actions::Cancel, cx| { this.dismiss(&Dismiss, cx); }); + + // register deploy buffer search for both search bar states, since we want to focus into the search bar + // when the deploy action is triggered in the buffer. + registrar.register_handler(|this, deploy, cx| { + this.deploy(deploy, cx); + }); registrar.register_handler_for_dismissed_search(|this, deploy, cx| { this.deploy(deploy, cx); }) diff --git a/crates/semantic_index/src/semantic_index.rs b/crates/semantic_index/src/semantic_index.rs index 801f02e600..a556986f9b 100644 --- a/crates/semantic_index/src/semantic_index.rs +++ b/crates/semantic_index/src/semantic_index.rs @@ -275,11 +275,8 @@ pub struct SearchResult { impl SemanticIndex { pub fn global(cx: &mut AppContext) -> Option> { - if cx.has_global::>() { - Some(cx.global::>().clone()) - } else { - None - } + cx.try_global::>() + .map(|semantic_index| semantic_index.clone()) } pub fn authenticate(&mut self, cx: &mut AppContext) -> bool { diff --git a/crates/vim/src/mode_indicator.rs b/crates/vim/src/mode_indicator.rs index b669b16112..423ae0c4e1 100644 --- a/crates/vim/src/mode_indicator.rs +++ b/crates/vim/src/mode_indicator.rs @@ -28,11 +28,10 @@ impl ModeIndicator { fn update_mode(&mut self, cx: &mut ViewContext) { // Vim doesn't exist in some tests - if !cx.has_global::() { + let Some(vim) = cx.try_global::() else { return; - } + }; - let vim = Vim::read(cx); if vim.enabled { self.mode = Some(vim.state().mode); } else { diff --git a/crates/workspace/src/item.rs b/crates/workspace/src/item.rs index 4f696e4a33..79742ee732 100644 --- a/crates/workspace/src/item.rs +++ b/crates/workspace/src/item.rs @@ -586,13 +586,9 @@ impl ItemHandle for View { } fn to_followable_item_handle(&self, cx: &AppContext) -> Option> { - if cx.has_global::() { - let builders = cx.global::(); - let item = self.to_any(); - Some(builders.get(&item.entity_type())?.1(&item)) - } else { - None - } + let builders = cx.try_global::()?; + let item = self.to_any(); + Some(builders.get(&item.entity_type())?.1(&item)) } fn on_release( diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index 3e88469aa8..a9f1676c66 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -195,7 +195,7 @@ struct NavHistoryState { next_timestamp: Arc, } -#[derive(Copy, Clone)] +#[derive(Debug, Copy, Clone)] pub enum NavigationMode { Normal, GoingBack, @@ -1462,7 +1462,7 @@ impl Pane { .icon_size(IconSize::Small) .on_click({ let view = cx.view().clone(); - move |_, cx| view.update(cx, Self::navigate_backward) + move |_, cx| view.update(cx, Self::navigate_forward) }) .disabled(!self.can_navigate_forward()) .tooltip(|cx| Tooltip::for_action("Go Forward", &GoForward, cx)), diff --git a/crates/workspace/src/pane_group.rs b/crates/workspace/src/pane_group.rs index e631cd9c43..476592f374 100644 --- a/crates/workspace/src/pane_group.rs +++ b/crates/workspace/src/pane_group.rs @@ -698,6 +698,7 @@ mod element { workspace .update(cx, |this, cx| this.schedule_serialize(cx)) .log_err(); + cx.stop_propagation(); cx.refresh(); } @@ -754,8 +755,10 @@ mod element { workspace .update(cx, |this, cx| this.schedule_serialize(cx)) .log_err(); + cx.refresh(); } + cx.stop_propagation(); } } }); diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index e8589849f1..20c8bfc94a 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -616,8 +616,8 @@ impl Workspace { let modal_layer = cx.new_view(|_| ModalLayer::new()); let mut active_call = None; - if cx.has_global::>() { - let call = cx.global::>().clone(); + if let Some(call) = cx.try_global::>() { + let call = call.clone(); let mut subscriptions = Vec::new(); subscriptions.push(cx.subscribe(&call, Self::on_active_call_event)); active_call = Some((call, subscriptions)); @@ -3686,11 +3686,8 @@ impl WorkspaceStore { update: proto::update_followers::Variant, cx: &AppContext, ) -> Option<()> { - if !cx.has_global::>() { - return None; - } - - let room_id = ActiveCall::global(cx).read(cx).room()?.read(cx).id(); + let active_call = cx.try_global::>()?; + let room_id = active_call.read(cx).room()?.read(cx).id(); let follower_ids: Vec<_> = self .followers .iter() diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index 82f608a87f..0c9f3d371e 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -102,13 +102,15 @@ fn main() { let open_listener = listener.clone(); app.on_open_urls(move |urls, _| open_listener.open_urls(&urls)); app.on_reopen(move |cx| { - if cx.has_global::>() { - if let Some(app_state) = cx.global::>().upgrade() { - workspace::open_new(&app_state, cx, |workspace, cx| { - Editor::new_file(workspace, &Default::default(), cx) - }) - .detach(); - } + if let Some(app_state) = cx + .try_global::>() + .map(|app_state| app_state.upgrade()) + .flatten() + { + workspace::open_new(&app_state, cx, |workspace, cx| { + Editor::new_file(workspace, &Default::default(), cx) + }) + .detach(); } });