From 1c8eeb01c9ff7417a5039c6b3855baea79d445d8 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 5 Aug 2022 16:34:26 +0200 Subject: [PATCH 01/27] Make project panel more compact This ensures more deeply-nested entries can be displayed without needing to show scrollbars. Adding scrollbars introduces UX issues when creating/renaming files because there are two scroll layers: the outer project panel AND the editor. Sublime Text and Atom dodged this issue by not displaying an inline editor and showing it as a modal instead. VS Code shows the editor inline but has a much more compact visualization. I think we should copy VS Code. --- styles/src/styleTree/projectPanel.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/styles/src/styleTree/projectPanel.ts b/styles/src/styleTree/projectPanel.ts index 26f88c6784111bcf1a0b2f33aa44a4d07baaf71a..7add861fa64fcabf8956b9949b988ab72823600d 100644 --- a/styles/src/styleTree/projectPanel.ts +++ b/styles/src/styleTree/projectPanel.ts @@ -6,7 +6,7 @@ export default function projectPanel(theme: Theme) { return { ...panel, padding: { left: 12, right: 12, top: 6, bottom: 6 }, - indentWidth: 20, + indentWidth: 8, entry: { height: 24, iconColor: iconColor(theme, "muted"), From ffce2cb0845f12808974ccb2b22f51a5740c440c Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Fri, 5 Aug 2022 12:44:34 -0400 Subject: [PATCH 02/27] Use One Dark as the default theme. --- assets/settings/default.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/settings/default.json b/assets/settings/default.json index 505e8dd4ebb6111d7799142da7358d8664ee75ef..33eb64e2019992ffca8cc94242ff12b5dcec19b6 100644 --- a/assets/settings/default.json +++ b/assets/settings/default.json @@ -1,6 +1,6 @@ { // The name of the Zed theme to use for the UI - "theme": "cave-dark", + "theme": "one-dark", // The name of a font to use for rendering text in the editor "buffer_font_family": "Zed Mono", // The default font size for text in the editor From db52593d9bf11be7c1991e47b755df7742a1f2c0 Mon Sep 17 00:00:00 2001 From: ForLoveOfCats Date: Mon, 8 Aug 2022 13:17:19 -0400 Subject: [PATCH 03/27] Automatically trigger project search to occur when deploying --- crates/search/src/project_search.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index ab130c135081f4b88225b2dbfc9e1409fb1baa46..39415b383272399b6806efa1126a5fcf13309777 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -477,6 +477,7 @@ impl ProjectSearchView { search.update(cx, |search, cx| { if let Some(query) = query { search.set_query(&query, cx); + search.search(cx); } search.focus_query_editor(cx) }); From a47a6f2f22b04b3d02630ec951fea88b34993bb1 Mon Sep 17 00:00:00 2001 From: ForLoveOfCats Date: Mon, 8 Aug 2022 15:59:33 -0400 Subject: [PATCH 04/27] Handle Cmd/Shift + Click go-to action on mouse-up instead of mouse-down --- crates/editor/src/editor.rs | 8 ++++ crates/editor/src/element.rs | 75 +++++++++++++++++++----------------- 2 files changed, 47 insertions(+), 36 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 7c2d560a41a123eb7024dc1e7ccf152d395182de..f7d9c9be79fce450682c0a3ec29023983d10c5f8 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -1787,6 +1787,14 @@ impl Editor { cx.notify(); } + pub fn are_selections_empty(&self) -> bool { + let pending_empty = match self.selections.pending_anchor() { + Some(Selection { start, end, .. }) => start == end, + None => true, + }; + pending_empty && self.columnar_selection_tail.is_none() + } + pub fn is_selecting(&self) -> bool { self.selections.pending_anchor().is_some() || self.columnar_selection_tail.is_some() } diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 95d760846f147ed7eff1bd388f38c8e473f37d91..25a71b93dc0d6099135f18c6c2c39c6eb60b333f 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -113,7 +113,6 @@ impl EditorElement { fn mouse_down( &self, position: Vector2F, - cmd: bool, alt: bool, shift: bool, mut click_count: usize, @@ -121,20 +120,6 @@ impl EditorElement { paint: &mut PaintState, cx: &mut EventContext, ) -> bool { - if cmd && paint.text_bounds.contains_point(position) { - let (point, target_point) = - paint.point_for_position(&self.snapshot(cx), layout, position); - if point == target_point { - if shift { - cx.dispatch_action(GoToFetchedTypeDefinition { point }); - } else { - cx.dispatch_action(GoToFetchedDefinition { point }); - } - - return true; - } - } - if paint.gutter_bounds.contains_point(position) { click_count = 3; // Simulate triple-click when clicking the gutter to select lines } else if !paint.text_bounds.contains_point(position) { @@ -183,13 +168,39 @@ impl EditorElement { true } - fn mouse_up(&self, _position: Vector2F, cx: &mut EventContext) -> bool { - if self.view(cx.app.as_ref()).is_selecting() { + fn mouse_up( + &self, + position: Vector2F, + cmd: bool, + shift: bool, + layout: &mut LayoutState, + paint: &mut PaintState, + cx: &mut EventContext, + ) -> bool { + let view = self.view(cx.app.as_ref()); + let end_selection = view.is_selecting(); + let selections_empty = view.are_selections_empty(); + + if end_selection { cx.dispatch_action(Select(SelectPhase::End)); - true - } else { - false } + + if selections_empty && cmd && paint.text_bounds.contains_point(position) { + let (point, target_point) = + paint.point_for_position(&self.snapshot(cx), layout, position); + + if point == target_point { + if shift { + cx.dispatch_action(GoToFetchedTypeDefinition { point }); + } else { + cx.dispatch_action(GoToFetchedDefinition { point }); + } + + return true; + } + } + + end_selection } fn mouse_dragged( @@ -1533,36 +1544,28 @@ impl Element for EditorElement { } match event { - Event::MouseDown(MouseButtonEvent { + &Event::MouseDown(MouseButtonEvent { button: MouseButton::Left, position, - cmd, alt, shift, click_count, .. - }) => self.mouse_down( - *position, - *cmd, - *alt, - *shift, - *click_count, - layout, - paint, - cx, - ), + }) => self.mouse_down(position, alt, shift, click_count, layout, paint, cx), - Event::MouseDown(MouseButtonEvent { + &Event::MouseDown(MouseButtonEvent { button: MouseButton::Right, position, .. - }) => self.mouse_right_down(*position, layout, paint, cx), + }) => self.mouse_right_down(position, layout, paint, cx), - Event::MouseUp(MouseButtonEvent { + &Event::MouseUp(MouseButtonEvent { button: MouseButton::Left, position, + cmd, + shift, .. - }) => self.mouse_up(*position, cx), + }) => self.mouse_up(position, cmd, shift, layout, paint, cx), Event::MouseMoved(MouseMovedEvent { pressed_button: Some(MouseButton::Left), From ab760493cfc4f75bc6a3bbf2c578efa643017afd Mon Sep 17 00:00:00 2001 From: ForLoveOfCats Date: Tue, 9 Aug 2022 15:34:57 -0400 Subject: [PATCH 05/27] Route whether or not a window is fullscreen down into GPUI This still needs to be able to invalidate things to be useful but it's a good first cut at just making the information available to platform-agnostic code Co-authored-by: Mikayla --- crates/gpui/src/app.rs | 91 +++++++++++++++++++++++++- crates/gpui/src/platform.rs | 1 + crates/gpui/src/platform/mac/window.rs | 32 +++++++++ crates/gpui/src/platform/test.rs | 6 ++ 4 files changed, 128 insertions(+), 2 deletions(-) diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 8285fda2132af5d318c2716c91e0658579158543..532f59f008f051752f38b96b47d7c060e3da878f 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -1248,6 +1248,13 @@ impl MutableAppContext { .map_or(false, |window| window.is_active) } + pub fn window_is_fullscreen(&self, window_id: usize) -> bool { + self.cx + .windows + .get(&window_id) + .map_or(false, |window| window.is_fullscreen) + } + pub fn render_view(&mut self, params: RenderParams) -> Result { let window_id = params.window_id; let view_id = params.view_id; @@ -1934,6 +1941,7 @@ impl MutableAppContext { focused_view_id: Some(root_view.id()), is_active: false, invalidation: None, + is_fullscreen: false, }, ); root_view.update(this, |view, cx| view.on_focus(cx)); @@ -2010,6 +2018,13 @@ impl MutableAppContext { })); } + { + let mut app = self.upgrade(); + window.on_fullscreen(Box::new(move |is_fullscreen| { + app.update(|cx| cx.window_was_fullscreen_changed(window_id, is_fullscreen)) + })); + } + { let mut app = self.upgrade(); window.on_close(Box::new(move || { @@ -2151,7 +2166,9 @@ impl MutableAppContext { subscription_id, callback, } => self.handle_subscription_effect(entity_id, subscription_id, callback), + Effect::Event { entity_id, payload } => self.emit_event(entity_id, payload), + Effect::GlobalSubscription { type_id, subscription_id, @@ -2161,21 +2178,27 @@ impl MutableAppContext { subscription_id, callback, ), + Effect::GlobalEvent { payload } => self.emit_global_event(payload), + Effect::Observation { entity_id, subscription_id, callback, } => self.handle_observation_effect(entity_id, subscription_id, callback), + Effect::ModelNotification { model_id } => { self.handle_model_notification_effect(model_id) } + Effect::ViewNotification { window_id, view_id } => { self.handle_view_notification_effect(window_id, view_id) } + Effect::GlobalNotification { type_id } => { self.handle_global_notification_effect(type_id) } + Effect::Deferred { callback, after_window_update, @@ -2186,15 +2209,19 @@ impl MutableAppContext { callback(self) } } + Effect::ModelRelease { model_id, model } => { self.handle_entity_release_effect(model_id, model.as_any()) } + Effect::ViewRelease { view_id, view } => { self.handle_entity_release_effect(view_id, view.as_any()) } + Effect::Focus { window_id, view_id } => { self.handle_focus_effect(window_id, view_id); } + Effect::FocusObservation { view_id, subscription_id, @@ -2202,6 +2229,7 @@ impl MutableAppContext { } => { self.handle_focus_observation_effect(view_id, subscription_id, callback) } + Effect::ResizeWindow { window_id } => { if let Some(window) = self.cx.windows.get_mut(&window_id) { window @@ -2209,6 +2237,7 @@ impl MutableAppContext { .get_or_insert(WindowInvalidation::default()); } } + Effect::WindowActivationObservation { window_id, subscription_id, @@ -2218,10 +2247,17 @@ impl MutableAppContext { subscription_id, callback, ), + Effect::ActivateWindow { window_id, is_active, } => self.handle_window_activation_effect(window_id, is_active), + + Effect::FullscreenWindow { + window_id, + is_fullscreen, + } => self.handle_fullscreen_effect(window_id, is_fullscreen), + Effect::RefreshWindows => { refreshing = true; } @@ -2294,6 +2330,13 @@ impl MutableAppContext { .push_back(Effect::ResizeWindow { window_id }); } + fn window_was_fullscreen_changed(&mut self, window_id: usize, is_fullscreen: bool) { + self.pending_effects.push_back(Effect::FullscreenWindow { + window_id, + is_fullscreen, + }); + } + fn window_changed_active_status(&mut self, window_id: usize, is_active: bool) { self.pending_effects.push_back(Effect::ActivateWindow { window_id, @@ -2608,13 +2651,36 @@ impl MutableAppContext { } } + fn handle_fullscreen_effect(&mut self, window_id: usize, is_fullscreen: bool) { + //Short circuit evaluation if we're already g2g + if self + .cx + .windows + .get(&window_id) + .map(|w| w.is_fullscreen == is_fullscreen) + .unwrap_or(false) + { + return; + } + + self.update(|this| { + let window = this.cx.windows.get_mut(&window_id)?; + window.is_fullscreen = is_fullscreen; + + // self.emit_event(entity_id, payload); + + Some(()) + }); + } + fn handle_window_activation_effect(&mut self, window_id: usize, active: bool) { + //Short circuit evaluation if we're already g2g if self .cx .windows .get(&window_id) - .map(|w| w.is_active) - .map_or(false, |cur_active| cur_active == active) + .map(|w| w.is_active == active) + .unwrap_or(false) { return; } @@ -2622,6 +2688,8 @@ impl MutableAppContext { self.update(|this| { let window = this.cx.windows.get_mut(&window_id)?; window.is_active = active; + + //Handle focus let view_id = window.focused_view_id?; if let Some(mut view) = this.cx.views.remove(&(window_id, view_id)) { if active { @@ -2632,6 +2700,7 @@ impl MutableAppContext { this.cx.views.insert((window_id, view_id), view); } + //Deliver events let callbacks = this .window_activation_observations .lock() @@ -2640,6 +2709,7 @@ impl MutableAppContext { for (id, callback) in callbacks { if let Some(mut callback) = callback { let alive = callback(active, this); + //Put entry back if alive { match this .window_activation_observations @@ -3072,6 +3142,7 @@ struct Window { root_view: AnyViewHandle, focused_view_id: Option, is_active: bool, + is_fullscreen: bool, invalidation: Option, } @@ -3138,6 +3209,10 @@ pub enum Effect { ResizeWindow { window_id: usize, }, + FullscreenWindow { + window_id: usize, + is_fullscreen: bool, + }, ActivateWindow { window_id: usize, is_active: bool, @@ -3256,6 +3331,14 @@ impl Debug for Effect { .field("window_id", window_id) .field("is_active", is_active) .finish(), + Effect::FullscreenWindow { + window_id, + is_fullscreen, + } => f + .debug_struct("Effect::FullscreenWindow") + .field("window_id", window_id) + .field("is_fullscreen", is_fullscreen) + .finish(), Effect::RefreshWindows => f.debug_struct("Effect::FullViewRefresh").finish(), Effect::WindowShouldCloseSubscription { window_id, .. } => f .debug_struct("Effect::WindowShouldCloseSubscription") @@ -4032,6 +4115,10 @@ impl<'a, V: View> RenderContext<'a, V> { WeakViewHandle::new(self.window_id, self.view_id) } + pub fn window_id(&self) -> usize { + self.window_id + } + pub fn view_id(&self) -> usize { self.view_id } diff --git a/crates/gpui/src/platform.rs b/crates/gpui/src/platform.rs index 833912587c0f99e99583f0b2c1e67d91b2c5a5f4..df7727ee89ee47a463bbdb5dbe37732707553a21 100644 --- a/crates/gpui/src/platform.rs +++ b/crates/gpui/src/platform.rs @@ -112,6 +112,7 @@ pub trait Window: WindowContext { fn on_event(&mut self, callback: Box bool>); fn on_active_status_change(&mut self, callback: Box); fn on_resize(&mut self, callback: Box); + fn on_fullscreen(&mut self, callback: Box); fn on_should_close(&mut self, callback: Box bool>); fn on_close(&mut self, callback: Box); fn set_input_handler(&mut self, input_handler: Box); diff --git a/crates/gpui/src/platform/mac/window.rs b/crates/gpui/src/platform/mac/window.rs index 908efd451cf1fa79765e1ccd2c7f98730e8b044f..2168b07ffed6f4b546c0fca13ea57f48aa01109f 100644 --- a/crates/gpui/src/platform/mac/window.rs +++ b/crates/gpui/src/platform/mac/window.rs @@ -128,6 +128,14 @@ unsafe fn build_classes() { sel!(windowDidResize:), window_did_resize as extern "C" fn(&Object, Sel, id), ); + decl.add_method( + sel!(windowDidEnterFullScreen:), + window_did_enter_fullscreen as extern "C" fn(&Object, Sel, id), + ); + decl.add_method( + sel!(windowDidExitFullScreen:), + window_did_exit_fullscreen as extern "C" fn(&Object, Sel, id), + ); decl.add_method( sel!(windowDidBecomeKey:), window_did_change_key_status as extern "C" fn(&Object, Sel, id), @@ -276,6 +284,7 @@ struct WindowState { event_callback: Option bool>>, activate_callback: Option>, resize_callback: Option>, + fullscreen_callback: Option>, should_close_callback: Option bool>>, close_callback: Option>, input_handler: Option>, @@ -368,6 +377,7 @@ impl Window { should_close_callback: None, close_callback: None, activate_callback: None, + fullscreen_callback: None, input_handler: None, pending_key_down: None, performed_key_equivalent: false, @@ -467,6 +477,10 @@ impl platform::Window for Window { self.0.as_ref().borrow_mut().resize_callback = Some(callback); } + fn on_fullscreen(&mut self, callback: Box) { + self.0.as_ref().borrow_mut().fullscreen_callback = Some(callback); + } + fn on_should_close(&mut self, callback: Box bool>) { self.0.as_ref().borrow_mut().should_close_callback = Some(callback); } @@ -908,6 +922,24 @@ extern "C" fn window_did_resize(this: &Object, _: Sel, _: id) { window_state.as_ref().borrow().move_traffic_light(); } +extern "C" fn window_did_enter_fullscreen(this: &Object, _: Sel, _: id) { + window_fullscreen_changed(this, true); +} + +extern "C" fn window_did_exit_fullscreen(this: &Object, _: Sel, _: id) { + window_fullscreen_changed(this, false); +} + +fn window_fullscreen_changed(this: &Object, is_fullscreen: bool) { + let window_state = unsafe { get_window_state(this) }; + let mut window_state_borrow = window_state.as_ref().borrow_mut(); + if let Some(mut callback) = window_state_borrow.fullscreen_callback.take() { + drop(window_state_borrow); + callback(is_fullscreen); + window_state.borrow_mut().fullscreen_callback = Some(callback); + } +} + extern "C" fn window_did_change_key_status(this: &Object, selector: Sel, _: id) { let is_active = if selector == sel!(windowDidBecomeKey:) { true diff --git a/crates/gpui/src/platform/test.rs b/crates/gpui/src/platform/test.rs index 8ea55b5e0d3d71c077c201909c2622eb3bb310bb..3eb9b1e88efa354799b30af66eda18343b27d871 100644 --- a/crates/gpui/src/platform/test.rs +++ b/crates/gpui/src/platform/test.rs @@ -37,6 +37,7 @@ pub struct Window { event_handlers: Vec bool>>, resize_handlers: Vec>, close_handlers: Vec>, + fullscreen_handlers: Vec>, pub(crate) active_status_change_handlers: Vec>, pub(crate) should_close_handler: Option bool>>, pub(crate) title: Option, @@ -199,6 +200,7 @@ impl Window { close_handlers: Default::default(), should_close_handler: Default::default(), active_status_change_handlers: Default::default(), + fullscreen_handlers: Default::default(), scale_factor: 1.0, current_scene: None, title: None, @@ -253,6 +255,10 @@ impl super::Window for Window { self.active_status_change_handlers.push(callback); } + fn on_fullscreen(&mut self, callback: Box) { + self.fullscreen_handlers.push(callback) + } + fn on_resize(&mut self, callback: Box) { self.resize_handlers.push(callback); } From 46fef69b1a7423caa7278a79d25550a6cffd342c Mon Sep 17 00:00:00 2001 From: ForLoveOfCats Date: Tue, 9 Aug 2022 18:10:30 -0400 Subject: [PATCH 06/27] Refactor notification/observation callback pattern in MutableAppContext Pull out duplicate code and clarify some misc behavior. Some of this existing API feels like it's probably incorrect but that needs more thorough investigation Co-authored-by: Mikayla --- crates/gpui/src/app.rs | 531 +++++++++++++---------------------------- 1 file changed, 164 insertions(+), 367 deletions(-) diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 532f59f008f051752f38b96b47d7c060e3da878f..a9467c99962f74b73655aec949827f2b9be636f1 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -962,6 +962,92 @@ type WindowActivationCallback = Box b type DeserializeActionCallback = fn(json: &str) -> anyhow::Result>; type WindowShouldCloseSubscriptionCallback = Box bool>; +// type SubscriptionMappings = Arc>>>>; +struct SubscriptionMappings { + internal: Arc>>>>, +} + +impl Default for SubscriptionMappings { + fn default() -> Self { + SubscriptionMappings { + internal: Arc::new(Mutex::new(HashMap::new())), + } + } +} + +impl SubscriptionMappings { + fn clone_ref(&self) -> Self { + Self { + internal: self.internal.clone(), + } + } + + fn add_callback(&mut self, id: K, subscription_id: usize, callback: F) { + self.internal + .lock() + .entry(id) + .or_default() + .insert(subscription_id, Some(callback)); + } + + fn remove(&mut self, id: K) { + self.internal.lock().remove(&id); + } + + fn add_or_remove_callback(&mut self, id: K, subscription_id: usize, callback: F) { + match self + .internal + .lock() + .entry(id) + .or_default() + .entry(subscription_id) + { + btree_map::Entry::Vacant(entry) => { + entry.insert(Some(callback)); + } + + btree_map::Entry::Occupied(entry) => { + // TODO: This seems like it should never be called because no code + // should ever attempt to remove an existing callback + debug_assert!(entry.get().is_none()); + entry.remove(); + } + } + } + + fn emit_and_cleanup bool>( + &mut self, + id: K, + cx: &mut MutableAppContext, + mut call_callback: C, + ) { + let callbacks = self.internal.lock().remove(&id); + if let Some(callbacks) = callbacks { + for (subscription_id, callback) in callbacks { + if let Some(mut callback) = callback { + let alive = call_callback(&mut callback, cx); + if alive { + match self + .internal + .lock() + .entry(id) + .or_default() + .entry(subscription_id) + { + btree_map::Entry::Vacant(entry) => { + entry.insert(Some(callback)); + } + btree_map::Entry::Occupied(entry) => { + entry.remove(); + } + } + } + } + } + } + } +} + pub struct MutableAppContext { weak_self: Option>>, foreground_platform: Rc, @@ -976,18 +1062,17 @@ pub struct MutableAppContext { next_window_id: usize, next_subscription_id: usize, frame_count: usize, - subscriptions: Arc>>>>, - global_subscriptions: - Arc>>>>, - observations: Arc>>>>, - focus_observations: - Arc>>>>, - global_observations: - Arc>>>>, + + focus_observations: SubscriptionMappings, + global_subscriptions: SubscriptionMappings, + global_observations: SubscriptionMappings, + subscriptions: SubscriptionMappings, + observations: SubscriptionMappings, + window_activation_observations: SubscriptionMappings, + release_observations: Arc>>>, - window_activation_observations: - Arc>>>>, action_dispatch_observations: Arc>>, + presenters_and_platform_windows: HashMap>, Box)>, foreground: Rc, @@ -1395,7 +1480,7 @@ impl MutableAppContext { Subscription::GlobalSubscription { id: subscription_id, type_id, - subscriptions: Some(Arc::downgrade(&self.global_subscriptions)), + subscriptions: Some(Arc::downgrade(&self.global_subscriptions.internal)), } } @@ -1436,7 +1521,7 @@ impl MutableAppContext { Subscription::Subscription { id: subscription_id, entity_id: handle.id(), - subscriptions: Some(Arc::downgrade(&self.subscriptions)), + subscriptions: Some(Arc::downgrade(&self.subscriptions.internal)), } } @@ -1464,7 +1549,7 @@ impl MutableAppContext { Subscription::Observation { id: subscription_id, entity_id, - observations: Some(Arc::downgrade(&self.observations)), + observations: Some(Arc::downgrade(&self.observations.internal)), } } @@ -1476,6 +1561,7 @@ impl MutableAppContext { let subscription_id = post_inc(&mut self.next_subscription_id); let observed = handle.downgrade(); let view_id = handle.id(); + self.pending_effects.push_back(Effect::FocusObservation { view_id, subscription_id, @@ -1487,10 +1573,11 @@ impl MutableAppContext { } }), }); + Subscription::FocusObservation { id: subscription_id, view_id, - observations: Some(Arc::downgrade(&self.focus_observations)), + observations: Some(Arc::downgrade(&self.focus_observations.internal)), } } @@ -1502,20 +1589,16 @@ impl MutableAppContext { let type_id = TypeId::of::(); let id = post_inc(&mut self.next_subscription_id); - self.global_observations - .lock() - .entry(type_id) - .or_default() - .insert( - id, - Some(Box::new(move |cx: &mut MutableAppContext| observe(cx)) - as GlobalObservationCallback), - ); + self.global_observations.add_callback( + type_id, + id, + Box::new(move |cx: &mut MutableAppContext| observe(cx)), + ); Subscription::GlobalObservation { id, type_id, - observations: Some(Arc::downgrade(&self.global_observations)), + observations: Some(Arc::downgrade(&self.global_observations.internal)), } } @@ -1573,7 +1656,9 @@ impl MutableAppContext { Subscription::WindowActivationObservation { id: subscription_id, window_id, - observations: Some(Arc::downgrade(&self.window_activation_observations)), + observations: Some(Arc::downgrade( + &self.window_activation_observations.internal, + )), } } @@ -2107,8 +2192,8 @@ impl MutableAppContext { } for model_id in dropped_models { - self.subscriptions.lock().remove(&model_id); - self.observations.lock().remove(&model_id); + self.subscriptions.remove(model_id); + self.observations.remove(model_id); let mut model = self.cx.models.remove(&model_id).unwrap(); model.release(self); self.pending_effects @@ -2116,8 +2201,8 @@ impl MutableAppContext { } for (window_id, view_id) in dropped_views { - self.subscriptions.lock().remove(&view_id); - self.observations.lock().remove(&view_id); + self.subscriptions.remove(view_id); + self.observations.remove(view_id); let mut view = self.cx.views.remove(&(window_id, view_id)).unwrap(); view.release(self); let change_focus_to = self.cx.windows.get_mut(&window_id).and_then(|window| { @@ -2165,15 +2250,24 @@ impl MutableAppContext { entity_id, subscription_id, callback, - } => self.handle_subscription_effect(entity_id, subscription_id, callback), + } => self.subscriptions.add_or_remove_callback( + entity_id, + subscription_id, + callback, + ), - Effect::Event { entity_id, payload } => self.emit_event(entity_id, payload), + Effect::Event { entity_id, payload } => { + let mut subscriptions = self.subscriptions.clone_ref(); + subscriptions.emit_and_cleanup(entity_id, self, |callback, this| { + callback(payload.as_ref(), this) + }) + } Effect::GlobalSubscription { type_id, subscription_id, callback, - } => self.handle_global_subscription_effect( + } => self.global_subscriptions.add_or_remove_callback( type_id, subscription_id, callback, @@ -2185,10 +2279,16 @@ impl MutableAppContext { entity_id, subscription_id, callback, - } => self.handle_observation_effect(entity_id, subscription_id, callback), + } => self.observations.add_or_remove_callback( + entity_id, + subscription_id, + callback, + ), Effect::ModelNotification { model_id } => { - self.handle_model_notification_effect(model_id) + let mut observations = self.observations.clone_ref(); + observations + .emit_and_cleanup(model_id, self, |callback, this| callback(this)); } Effect::ViewNotification { window_id, view_id } => { @@ -2196,7 +2296,11 @@ impl MutableAppContext { } Effect::GlobalNotification { type_id } => { - self.handle_global_notification_effect(type_id) + let mut subscriptions = self.global_observations.clone_ref(); + subscriptions.emit_and_cleanup(type_id, self, |callback, this| { + callback(this); + true + }); } Effect::Deferred { @@ -2227,7 +2331,11 @@ impl MutableAppContext { subscription_id, callback, } => { - self.handle_focus_observation_effect(view_id, subscription_id, callback) + self.focus_observations.add_or_remove_callback( + view_id, + subscription_id, + callback, + ); } Effect::ResizeWindow { window_id } => { @@ -2242,7 +2350,7 @@ impl MutableAppContext { window_id, subscription_id, callback, - } => self.handle_window_activation_observation_effect( + } => self.window_activation_observations.add_or_remove_callback( window_id, subscription_id, callback, @@ -2369,182 +2477,14 @@ impl MutableAppContext { self.presenters_and_platform_windows = presenters; } - fn handle_subscription_effect( - &mut self, - entity_id: usize, - subscription_id: usize, - callback: SubscriptionCallback, - ) { - match self - .subscriptions - .lock() - .entry(entity_id) - .or_default() - .entry(subscription_id) - { - btree_map::Entry::Vacant(entry) => { - entry.insert(Some(callback)); - } - // Subscription was dropped before effect was processed - btree_map::Entry::Occupied(entry) => { - debug_assert!(entry.get().is_none()); - entry.remove(); - } - } - } - - fn emit_event(&mut self, entity_id: usize, payload: Box) { - let callbacks = self.subscriptions.lock().remove(&entity_id); - if let Some(callbacks) = callbacks { - for (id, callback) in callbacks { - if let Some(mut callback) = callback { - let alive = callback(payload.as_ref(), self); - if alive { - match self - .subscriptions - .lock() - .entry(entity_id) - .or_default() - .entry(id) - { - btree_map::Entry::Vacant(entry) => { - entry.insert(Some(callback)); - } - btree_map::Entry::Occupied(entry) => { - entry.remove(); - } - } - } - } - } - } - } - - fn handle_global_subscription_effect( - &mut self, - type_id: TypeId, - subscription_id: usize, - callback: GlobalSubscriptionCallback, - ) { - match self - .global_subscriptions - .lock() - .entry(type_id) - .or_default() - .entry(subscription_id) - { - btree_map::Entry::Vacant(entry) => { - entry.insert(Some(callback)); - } - // Subscription was dropped before effect was processed - btree_map::Entry::Occupied(entry) => { - debug_assert!(entry.get().is_none()); - entry.remove(); - } - } - } - fn emit_global_event(&mut self, payload: Box) { let type_id = (&*payload).type_id(); - let callbacks = self.global_subscriptions.lock().remove(&type_id); - if let Some(callbacks) = callbacks { - for (id, callback) in callbacks { - if let Some(mut callback) = callback { - callback(payload.as_ref(), self); - match self - .global_subscriptions - .lock() - .entry(type_id) - .or_default() - .entry(id) - { - btree_map::Entry::Vacant(entry) => { - entry.insert(Some(callback)); - } - btree_map::Entry::Occupied(entry) => { - entry.remove(); - } - } - } - } - } - } - fn handle_observation_effect( - &mut self, - entity_id: usize, - subscription_id: usize, - callback: ObservationCallback, - ) { - match self - .observations - .lock() - .entry(entity_id) - .or_default() - .entry(subscription_id) - { - btree_map::Entry::Vacant(entry) => { - entry.insert(Some(callback)); - } - // Observation was dropped before effect was processed - btree_map::Entry::Occupied(entry) => { - debug_assert!(entry.get().is_none()); - entry.remove(); - } - } - } - - fn handle_focus_observation_effect( - &mut self, - view_id: usize, - subscription_id: usize, - callback: FocusObservationCallback, - ) { - match self - .focus_observations - .lock() - .entry(view_id) - .or_default() - .entry(subscription_id) - { - btree_map::Entry::Vacant(entry) => { - entry.insert(Some(callback)); - } - // Observation was dropped before effect was processed - btree_map::Entry::Occupied(entry) => { - debug_assert!(entry.get().is_none()); - entry.remove(); - } - } - } - - fn handle_model_notification_effect(&mut self, observed_id: usize) { - let callbacks = self.observations.lock().remove(&observed_id); - if let Some(callbacks) = callbacks { - if self.cx.models.contains_key(&observed_id) { - for (id, callback) in callbacks { - if let Some(mut callback) = callback { - let alive = callback(self); - if alive { - match self - .observations - .lock() - .entry(observed_id) - .or_default() - .entry(id) - { - btree_map::Entry::Vacant(entry) => { - entry.insert(Some(callback)); - } - btree_map::Entry::Occupied(entry) => { - entry.remove(); - } - } - } - } - } - } - } + let mut subscriptions = self.global_subscriptions.clone_ref(); + subscriptions.emit_and_cleanup(type_id, self, |callback, this| { + callback(payload.as_ref(), this); + true //Always alive + }); } fn handle_view_notification_effect( @@ -2552,8 +2492,6 @@ impl MutableAppContext { observed_window_id: usize, observed_view_id: usize, ) { - let callbacks = self.observations.lock().remove(&observed_view_id); - if self .cx .views @@ -2567,54 +2505,8 @@ impl MutableAppContext { .insert(observed_view_id); } - if let Some(callbacks) = callbacks { - for (id, callback) in callbacks { - if let Some(mut callback) = callback { - let alive = callback(self); - if alive { - match self - .observations - .lock() - .entry(observed_view_id) - .or_default() - .entry(id) - { - btree_map::Entry::Vacant(entry) => { - entry.insert(Some(callback)); - } - btree_map::Entry::Occupied(entry) => { - entry.remove(); - } - } - } - } - } - } - } - } - - fn handle_global_notification_effect(&mut self, observed_type_id: TypeId) { - let callbacks = self.global_observations.lock().remove(&observed_type_id); - if let Some(callbacks) = callbacks { - for (id, callback) in callbacks { - if let Some(mut callback) = callback { - callback(self); - match self - .global_observations - .lock() - .entry(observed_type_id) - .or_default() - .entry(id) - { - collections::btree_map::Entry::Vacant(entry) => { - entry.insert(Some(callback)); - } - collections::btree_map::Entry::Occupied(entry) => { - entry.remove(); - } - } - } - } + let mut observations = self.observations.clone_ref(); + observations.emit_and_cleanup(observed_view_id, self, |callback, this| callback(this)); } } @@ -2627,30 +2519,6 @@ impl MutableAppContext { } } - fn handle_window_activation_observation_effect( - &mut self, - window_id: usize, - subscription_id: usize, - callback: WindowActivationCallback, - ) { - match self - .window_activation_observations - .lock() - .entry(window_id) - .or_default() - .entry(subscription_id) - { - btree_map::Entry::Vacant(entry) => { - entry.insert(Some(callback)); - } - // Observation was dropped before effect was processed - btree_map::Entry::Occupied(entry) => { - debug_assert!(entry.get().is_none()); - entry.remove(); - } - } - } - fn handle_fullscreen_effect(&mut self, window_id: usize, is_fullscreen: bool) { //Short circuit evaluation if we're already g2g if self @@ -2667,8 +2535,6 @@ impl MutableAppContext { let window = this.cx.windows.get_mut(&window_id)?; window.is_fullscreen = is_fullscreen; - // self.emit_event(entity_id, payload); - Some(()) }); } @@ -2700,35 +2566,8 @@ impl MutableAppContext { this.cx.views.insert((window_id, view_id), view); } - //Deliver events - let callbacks = this - .window_activation_observations - .lock() - .remove(&window_id); - if let Some(callbacks) = callbacks { - for (id, callback) in callbacks { - if let Some(mut callback) = callback { - let alive = callback(active, this); - //Put entry back - if alive { - match this - .window_activation_observations - .lock() - .entry(window_id) - .or_default() - .entry(id) - { - btree_map::Entry::Vacant(entry) => { - entry.insert(Some(callback)); - } - btree_map::Entry::Occupied(entry) => { - entry.remove(); - } - } - } - } - } - } + let mut observations = this.window_activation_observations.clone_ref(); + observations.emit_and_cleanup(window_id, this, |callback, this| callback(active, this)); Some(()) }); @@ -2759,30 +2598,9 @@ impl MutableAppContext { blurred_view.on_blur(this, window_id, blurred_id); this.cx.views.insert((window_id, blurred_id), blurred_view); - let callbacks = this.focus_observations.lock().remove(&blurred_id); - if let Some(callbacks) = callbacks { - for (id, callback) in callbacks { - if let Some(mut callback) = callback { - let alive = callback(false, this); - if alive { - match this - .focus_observations - .lock() - .entry(blurred_id) - .or_default() - .entry(id) - { - btree_map::Entry::Vacant(entry) => { - entry.insert(Some(callback)); - } - btree_map::Entry::Occupied(entry) => { - entry.remove(); - } - } - } - } - } - } + let mut subscriptions = this.focus_observations.clone_ref(); + subscriptions + .emit_and_cleanup(blurred_id, this, |callback, this| callback(false, this)); } } @@ -2791,30 +2609,9 @@ impl MutableAppContext { focused_view.on_focus(this, window_id, focused_id); this.cx.views.insert((window_id, focused_id), focused_view); - let callbacks = this.focus_observations.lock().remove(&focused_id); - if let Some(callbacks) = callbacks { - for (id, callback) in callbacks { - if let Some(mut callback) = callback { - let alive = callback(true, this); - if alive { - match this - .focus_observations - .lock() - .entry(focused_id) - .or_default() - .entry(id) - { - btree_map::Entry::Vacant(entry) => { - entry.insert(Some(callback)); - } - btree_map::Entry::Occupied(entry) => { - entry.remove(); - } - } - } - } - } - } + let mut subscriptions = this.focus_observations.clone_ref(); + subscriptions + .emit_and_cleanup(focused_id, this, |callback, this| callback(true, this)); } } }) @@ -5768,8 +5565,8 @@ mod tests { }); assert_eq!(cx.cx.models.len(), 1); - assert!(cx.subscriptions.lock().is_empty()); - assert!(cx.observations.lock().is_empty()); + assert!(cx.subscriptions.internal.lock().is_empty()); + assert!(cx.observations.internal.lock().is_empty()); } #[crate::test(self)] @@ -6019,8 +5816,8 @@ mod tests { }); assert_eq!(cx.cx.views.len(), 2); - assert!(cx.subscriptions.lock().is_empty()); - assert!(cx.observations.lock().is_empty()); + assert!(cx.subscriptions.internal.lock().is_empty()); + assert!(cx.observations.internal.lock().is_empty()); } #[crate::test(self)] From 43b9f3beb3be382f63e3a10112320e4478c44fcc Mon Sep 17 00:00:00 2001 From: ForLoveOfCats Date: Tue, 9 Aug 2022 18:52:25 -0400 Subject: [PATCH 07/27] Invalidate view when entering/exiting fullscreen This is required for `render_titlebar` to eventually adapt to fullscreen status to affect the size of left padding on workspace name to account for the traffic lights presence/absence Co-authored-by: Mikayla --- crates/gpui/src/app.rs | 102 +++++++++++++++++++++++++++++- crates/workspace/src/workspace.rs | 2 + 2 files changed, 103 insertions(+), 1 deletion(-) diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index a9467c99962f74b73655aec949827f2b9be636f1..480a9a1bdf211ce356c2ca1f8873250833ca601a 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -959,6 +959,7 @@ type GlobalObservationCallback = Box; type ReleaseObservationCallback = Box; type ActionObservationCallback = Box; type WindowActivationCallback = Box bool>; +type WindowFullscreenCallback = Box bool>; type DeserializeActionCallback = fn(json: &str) -> anyhow::Result>; type WindowShouldCloseSubscriptionCallback = Box bool>; @@ -1069,7 +1070,8 @@ pub struct MutableAppContext { subscriptions: SubscriptionMappings, observations: SubscriptionMappings, window_activation_observations: SubscriptionMappings, - + window_fullscreen_observations: SubscriptionMappings, + release_observations: Arc>>>, action_dispatch_observations: Arc>>, @@ -1126,6 +1128,7 @@ impl MutableAppContext { release_observations: Default::default(), global_observations: Default::default(), window_activation_observations: Default::default(), + window_fullscreen_observations: Default::default(), action_dispatch_observations: Default::default(), presenters_and_platform_windows: HashMap::new(), foreground, @@ -1662,6 +1665,26 @@ impl MutableAppContext { } } + fn observe_fullscreen(&mut self, window_id: usize, callback: F) -> Subscription + where + F: 'static + FnMut(bool, &mut MutableAppContext) -> bool, + { + let subscription_id = post_inc(&mut self.next_subscription_id); + self.pending_effects + .push_back(Effect::WindowFullscreenObservation { + window_id, + subscription_id, + callback: Box::new(callback), + }); + Subscription::WindowFullscreenObservation { + id: subscription_id, + window_id, + observations: Some(Arc::downgrade( + &self.window_activation_observations.internal, + )), + } + } + pub fn defer(&mut self, callback: impl 'static + FnOnce(&mut MutableAppContext)) { self.pending_effects.push_back(Effect::Deferred { callback: Box::new(callback), @@ -2361,6 +2384,16 @@ impl MutableAppContext { is_active, } => self.handle_window_activation_effect(window_id, is_active), + Effect::WindowFullscreenObservation { + window_id, + subscription_id, + callback, + } => self.window_fullscreen_observations.add_or_remove_callback( + window_id, + subscription_id, + callback, + ), + Effect::FullscreenWindow { window_id, is_fullscreen, @@ -2535,6 +2568,11 @@ impl MutableAppContext { let window = this.cx.windows.get_mut(&window_id)?; window.is_fullscreen = is_fullscreen; + let mut observations = this.window_fullscreen_observations.clone_ref(); + observations.emit_and_cleanup(window_id, this, |callback, this| { + callback(is_fullscreen, this) + }); + Some(()) }); } @@ -3019,6 +3057,11 @@ pub enum Effect { subscription_id: usize, callback: WindowActivationCallback, }, + WindowFullscreenObservation { + window_id: usize, + subscription_id: usize, + callback: WindowFullscreenCallback, + }, RefreshWindows, ActionDispatchNotification { action_id: TypeId, @@ -3136,6 +3179,15 @@ impl Debug for Effect { .field("window_id", window_id) .field("is_fullscreen", is_fullscreen) .finish(), + Effect::WindowFullscreenObservation { + window_id, + subscription_id, + callback: _, + } => f + .debug_struct("Effect::WindowFullscreenObservation") + .field("window_id", window_id) + .field("subscription_id", subscription_id) + .finish(), Effect::RefreshWindows => f.debug_struct("Effect::FullViewRefresh").finish(), Effect::WindowShouldCloseSubscription { window_id, .. } => f .debug_struct("Effect::WindowShouldCloseSubscription") @@ -3807,6 +3859,24 @@ impl<'a, T: View> ViewContext<'a, T> { }) } + pub fn observe_fullscreen(&mut self, mut callback: F) -> Subscription + where + F: 'static + FnMut(&mut T, bool, &mut ViewContext), + { + let observer = self.weak_handle(); + self.app + .observe_fullscreen(self.window_id(), move |active, cx| { + if let Some(observer) = observer.upgrade(cx) { + observer.update(cx, |observer, cx| { + callback(observer, active, cx); + }); + true + } else { + false + } + }) + } + pub fn emit(&mut self, payload: T::Event) { self.app.pending_effects.push_back(Effect::Event { entity_id: self.view_id, @@ -5128,6 +5198,12 @@ pub enum Subscription { observations: Option>>>>>, }, + WindowFullscreenObservation { + id: usize, + window_id: usize, + observations: + Option>>>>>, + }, } impl Subscription { @@ -5157,6 +5233,9 @@ impl Subscription { Subscription::WindowActivationObservation { observations, .. } => { observations.take(); } + Subscription::WindowFullscreenObservation { observations, .. } => { + observations.take(); + } } } } @@ -5291,6 +5370,27 @@ impl Drop for Subscription { } } } + Subscription::WindowFullscreenObservation { + id, + window_id, + observations, + } => { + if let Some(observations) = observations.as_ref().and_then(Weak::upgrade) { + match observations + .lock() + .entry(*window_id) + .or_default() + .entry(*id) + { + btree_map::Entry::Vacant(entry) => { + entry.insert(None); + } + btree_map::Entry::Occupied(entry) => { + entry.remove(); + } + } + } + } } } } diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 045e9c6f90de3cc5ed54411607519391a76fea6b..302ebd65ee227bba2cdb0b675752b69bab1c40ce 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -823,6 +823,8 @@ enum FollowerItem { impl Workspace { pub fn new(project: ModelHandle, cx: &mut ViewContext) -> Self { + cx.observe_fullscreen(|_, _, cx| cx.notify()).detach(); + cx.observe_window_activation(Self::on_window_activation_changed) .detach(); cx.observe(&project, |_, _, cx| cx.notify()).detach(); From 3d9821b430dde5ab583b2f571c86fadf992afcf4 Mon Sep 17 00:00:00 2001 From: ForLoveOfCats Date: Tue, 9 Aug 2022 19:03:03 -0400 Subject: [PATCH 08/27] Jankily adjust left padding on workspace title in fullscreen This could seriously be done better Co-authored-by: Mikayla --- crates/gpui/src/platform/mac/window.rs | 12 ++++++------ crates/workspace/src/workspace.rs | 13 ++++++++++++- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/crates/gpui/src/platform/mac/window.rs b/crates/gpui/src/platform/mac/window.rs index 2168b07ffed6f4b546c0fca13ea57f48aa01109f..568356e93825ff51877091d6d77abe81dc8eebb2 100644 --- a/crates/gpui/src/platform/mac/window.rs +++ b/crates/gpui/src/platform/mac/window.rs @@ -129,12 +129,12 @@ unsafe fn build_classes() { window_did_resize as extern "C" fn(&Object, Sel, id), ); decl.add_method( - sel!(windowDidEnterFullScreen:), - window_did_enter_fullscreen as extern "C" fn(&Object, Sel, id), + sel!(windowWillEnterFullScreen:), + window_will_enter_fullscreen as extern "C" fn(&Object, Sel, id), ); decl.add_method( - sel!(windowDidExitFullScreen:), - window_did_exit_fullscreen as extern "C" fn(&Object, Sel, id), + sel!(windowWillExitFullScreen:), + window_will_exit_fullscreen as extern "C" fn(&Object, Sel, id), ); decl.add_method( sel!(windowDidBecomeKey:), @@ -922,11 +922,11 @@ extern "C" fn window_did_resize(this: &Object, _: Sel, _: id) { window_state.as_ref().borrow().move_traffic_light(); } -extern "C" fn window_did_enter_fullscreen(this: &Object, _: Sel, _: id) { +extern "C" fn window_will_enter_fullscreen(this: &Object, _: Sel, _: id) { window_fullscreen_changed(this, true); } -extern "C" fn window_did_exit_fullscreen(this: &Object, _: Sel, _: id) { +extern "C" fn window_will_exit_fullscreen(this: &Object, _: Sel, _: id) { window_fullscreen_changed(this, false); } diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 302ebd65ee227bba2cdb0b675752b69bab1c40ce..a27754aa1308c89ec5823ab703e496d842cf901b 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -1858,6 +1858,17 @@ impl Workspace { worktree_root_names.push_str(name); } + // TODO: There should be a better system in place for this + // (https://github.com/zed-industries/zed/issues/1290) + let is_fullscreen = cx.window_is_fullscreen(cx.window_id()); + let container_theme = if is_fullscreen { + let mut container_theme = theme.workspace.titlebar.container; + container_theme.padding.left = container_theme.padding.right; + container_theme + } else { + theme.workspace.titlebar.container + }; + ConstrainedBox::new( Container::new( Stack::new() @@ -1885,7 +1896,7 @@ impl Workspace { ) .boxed(), ) - .with_style(theme.workspace.titlebar.container) + .with_style(container_theme) .boxed(), ) .with_height(theme.workspace.titlebar.height) From 45c0539de0becaa9e68f07e92d16ac424ccfff31 Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Tue, 9 Aug 2022 16:59:13 -0700 Subject: [PATCH 09/27] changed name of subscription mapping and moved out to file Co-authored-by: Keith --- crates/gpui/src/app.rs | 208 ++++++--------------- crates/gpui/src/app/callback_collection.rs | 106 +++++++++++ crates/gpui/src/presenter.rs | 4 +- 3 files changed, 165 insertions(+), 153 deletions(-) create mode 100644 crates/gpui/src/app/callback_collection.rs diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 480a9a1bdf211ce356c2ca1f8873250833ca601a..cc4c1191f618cf9a92e8dc521cfe6f6b3b14c5e6 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -1,4 +1,5 @@ pub mod action; +mod callback_collection; use crate::{ elements::ElementBox, @@ -13,7 +14,8 @@ use crate::{ }; pub use action::*; use anyhow::{anyhow, Context, Result}; -use collections::btree_map; +use callback_collection::CallbackCollection; +use collections::{btree_map, hash_map::Entry, BTreeMap, HashMap, HashSet, VecDeque}; use keymap::MatchResult; use lazy_static::lazy_static; use parking_lot::Mutex; @@ -24,7 +26,6 @@ use smol::prelude::*; use std::{ any::{type_name, Any, TypeId}, cell::RefCell, - collections::{hash_map::Entry, BTreeMap, HashMap, HashSet, VecDeque}, fmt::{self, Debug}, hash::{Hash, Hasher}, marker::PhantomData, @@ -37,6 +38,8 @@ use std::{ time::Duration, }; +use self::callback_collection::Mapping; + pub trait Entity: 'static { type Event; @@ -963,92 +966,6 @@ type WindowFullscreenCallback = Box b type DeserializeActionCallback = fn(json: &str) -> anyhow::Result>; type WindowShouldCloseSubscriptionCallback = Box bool>; -// type SubscriptionMappings = Arc>>>>; -struct SubscriptionMappings { - internal: Arc>>>>, -} - -impl Default for SubscriptionMappings { - fn default() -> Self { - SubscriptionMappings { - internal: Arc::new(Mutex::new(HashMap::new())), - } - } -} - -impl SubscriptionMappings { - fn clone_ref(&self) -> Self { - Self { - internal: self.internal.clone(), - } - } - - fn add_callback(&mut self, id: K, subscription_id: usize, callback: F) { - self.internal - .lock() - .entry(id) - .or_default() - .insert(subscription_id, Some(callback)); - } - - fn remove(&mut self, id: K) { - self.internal.lock().remove(&id); - } - - fn add_or_remove_callback(&mut self, id: K, subscription_id: usize, callback: F) { - match self - .internal - .lock() - .entry(id) - .or_default() - .entry(subscription_id) - { - btree_map::Entry::Vacant(entry) => { - entry.insert(Some(callback)); - } - - btree_map::Entry::Occupied(entry) => { - // TODO: This seems like it should never be called because no code - // should ever attempt to remove an existing callback - debug_assert!(entry.get().is_none()); - entry.remove(); - } - } - } - - fn emit_and_cleanup bool>( - &mut self, - id: K, - cx: &mut MutableAppContext, - mut call_callback: C, - ) { - let callbacks = self.internal.lock().remove(&id); - if let Some(callbacks) = callbacks { - for (subscription_id, callback) in callbacks { - if let Some(mut callback) = callback { - let alive = call_callback(&mut callback, cx); - if alive { - match self - .internal - .lock() - .entry(id) - .or_default() - .entry(subscription_id) - { - btree_map::Entry::Vacant(entry) => { - entry.insert(Some(callback)); - } - btree_map::Entry::Occupied(entry) => { - entry.remove(); - } - } - } - } - } - } - } -} - pub struct MutableAppContext { weak_self: Option>>, foreground_platform: Rc, @@ -1064,13 +981,13 @@ pub struct MutableAppContext { next_subscription_id: usize, frame_count: usize, - focus_observations: SubscriptionMappings, - global_subscriptions: SubscriptionMappings, - global_observations: SubscriptionMappings, - subscriptions: SubscriptionMappings, - observations: SubscriptionMappings, - window_activation_observations: SubscriptionMappings, - window_fullscreen_observations: SubscriptionMappings, + focus_observations: CallbackCollection, + global_subscriptions: CallbackCollection, + global_observations: CallbackCollection, + subscriptions: CallbackCollection, + observations: CallbackCollection, + window_activation_observations: CallbackCollection, + window_fullscreen_observations: CallbackCollection, release_observations: Arc>>>, action_dispatch_observations: Arc>>, @@ -1112,10 +1029,10 @@ impl MutableAppContext { font_cache, platform, }, - action_deserializers: HashMap::new(), - capture_actions: HashMap::new(), - actions: HashMap::new(), - global_actions: HashMap::new(), + action_deserializers: Default::default(), + capture_actions: Default::default(), + actions: Default::default(), + global_actions: Default::default(), keystroke_matcher: keymap::Matcher::default(), next_entity_id: 0, next_window_id: 0, @@ -1130,12 +1047,12 @@ impl MutableAppContext { window_activation_observations: Default::default(), window_fullscreen_observations: Default::default(), action_dispatch_observations: Default::default(), - presenters_and_platform_windows: HashMap::new(), + presenters_and_platform_windows: Default::default(), foreground, pending_effects: VecDeque::new(), pending_focus_index: None, - pending_notifications: HashSet::new(), - pending_global_notifications: HashSet::new(), + pending_notifications: Default::default(), + pending_global_notifications: Default::default(), pending_flushes: 0, flushing_effects: false, halt_action_dispatch: false, @@ -1480,10 +1397,11 @@ impl MutableAppContext { callback(payload, cx) }), }); + Subscription::GlobalSubscription { id: subscription_id, type_id, - subscriptions: Some(Arc::downgrade(&self.global_subscriptions.internal)), + subscriptions: Some(self.global_subscriptions.downgrade()), } } @@ -1524,7 +1442,7 @@ impl MutableAppContext { Subscription::Subscription { id: subscription_id, entity_id: handle.id(), - subscriptions: Some(Arc::downgrade(&self.subscriptions.internal)), + subscriptions: Some(self.subscriptions.downgrade()), } } @@ -1552,7 +1470,7 @@ impl MutableAppContext { Subscription::Observation { id: subscription_id, entity_id, - observations: Some(Arc::downgrade(&self.observations.internal)), + observations: Some(self.observations.downgrade()), } } @@ -1580,7 +1498,7 @@ impl MutableAppContext { Subscription::FocusObservation { id: subscription_id, view_id, - observations: Some(Arc::downgrade(&self.focus_observations.internal)), + observations: Some(self.focus_observations.downgrade()), } } @@ -1601,7 +1519,7 @@ impl MutableAppContext { Subscription::GlobalObservation { id, type_id, - observations: Some(Arc::downgrade(&self.global_observations.internal)), + observations: Some(self.global_observations.downgrade()), } } @@ -1659,9 +1577,7 @@ impl MutableAppContext { Subscription::WindowActivationObservation { id: subscription_id, window_id, - observations: Some(Arc::downgrade( - &self.window_activation_observations.internal, - )), + observations: Some(self.window_activation_observations.downgrade()), } } @@ -1679,9 +1595,7 @@ impl MutableAppContext { Subscription::WindowFullscreenObservation { id: subscription_id, window_id, - observations: Some(Arc::downgrade( - &self.window_activation_observations.internal, - )), + observations: Some(self.window_activation_observations.downgrade()), } } @@ -2280,7 +2194,7 @@ impl MutableAppContext { ), Effect::Event { entity_id, payload } => { - let mut subscriptions = self.subscriptions.clone_ref(); + let mut subscriptions = self.subscriptions.clone(); subscriptions.emit_and_cleanup(entity_id, self, |callback, this| { callback(payload.as_ref(), this) }) @@ -2309,7 +2223,7 @@ impl MutableAppContext { ), Effect::ModelNotification { model_id } => { - let mut observations = self.observations.clone_ref(); + let mut observations = self.observations.clone(); observations .emit_and_cleanup(model_id, self, |callback, this| callback(this)); } @@ -2319,7 +2233,7 @@ impl MutableAppContext { } Effect::GlobalNotification { type_id } => { - let mut subscriptions = self.global_observations.clone_ref(); + let mut subscriptions = self.global_observations.clone(); subscriptions.emit_and_cleanup(type_id, self, |callback, this| { callback(this); true @@ -2442,7 +2356,7 @@ impl MutableAppContext { } fn update_windows(&mut self) { - let mut invalidations = HashMap::new(); + let mut invalidations: HashMap<_, _> = Default::default(); for (window_id, window) in &mut self.cx.windows { if let Some(invalidation) = window.invalidation.take() { invalidations.insert(*window_id, invalidation); @@ -2513,7 +2427,7 @@ impl MutableAppContext { fn emit_global_event(&mut self, payload: Box) { let type_id = (&*payload).type_id(); - let mut subscriptions = self.global_subscriptions.clone_ref(); + let mut subscriptions = self.global_subscriptions.clone(); subscriptions.emit_and_cleanup(type_id, self, |callback, this| { callback(payload.as_ref(), this); true //Always alive @@ -2538,7 +2452,7 @@ impl MutableAppContext { .insert(observed_view_id); } - let mut observations = self.observations.clone_ref(); + let mut observations = self.observations.clone(); observations.emit_and_cleanup(observed_view_id, self, |callback, this| callback(this)); } } @@ -2568,7 +2482,7 @@ impl MutableAppContext { let window = this.cx.windows.get_mut(&window_id)?; window.is_fullscreen = is_fullscreen; - let mut observations = this.window_fullscreen_observations.clone_ref(); + let mut observations = this.window_fullscreen_observations.clone(); observations.emit_and_cleanup(window_id, this, |callback, this| { callback(is_fullscreen, this) }); @@ -2604,7 +2518,7 @@ impl MutableAppContext { this.cx.views.insert((window_id, view_id), view); } - let mut observations = this.window_activation_observations.clone_ref(); + let mut observations = this.window_activation_observations.clone(); observations.emit_and_cleanup(window_id, this, |callback, this| callback(active, this)); Some(()) @@ -2636,7 +2550,7 @@ impl MutableAppContext { blurred_view.on_blur(this, window_id, blurred_id); this.cx.views.insert((window_id, blurred_id), blurred_view); - let mut subscriptions = this.focus_observations.clone_ref(); + let mut subscriptions = this.focus_observations.clone(); subscriptions .emit_and_cleanup(blurred_id, this, |callback, this| callback(false, this)); } @@ -2647,7 +2561,7 @@ impl MutableAppContext { focused_view.on_focus(this, window_id, focused_id); this.cx.views.insert((window_id, focused_id), focused_view); - let mut subscriptions = this.focus_observations.clone_ref(); + let mut subscriptions = this.focus_observations.clone(); subscriptions .emit_and_cleanup(focused_id, this, |callback, this| callback(true, this)); } @@ -5153,35 +5067,39 @@ pub enum Subscription { Subscription { id: usize, entity_id: usize, - subscriptions: - Option>>>>>, + subscriptions: Option>>, }, GlobalSubscription { id: usize, type_id: TypeId, - subscriptions: Option< - Weak>>>>, - >, + subscriptions: Option>>, }, Observation { id: usize, entity_id: usize, - observations: - Option>>>>>, + observations: Option>>, }, GlobalObservation { id: usize, type_id: TypeId, - observations: Option< - Weak>>>>, - >, + observations: Option>>, }, FocusObservation { id: usize, view_id: usize, - observations: - Option>>>>>, + observations: Option>>, + }, + WindowActivationObservation { + id: usize, + window_id: usize, + observations: Option>>, + }, + WindowFullscreenObservation { + id: usize, + window_id: usize, + observations: Option>>, }, + ReleaseObservation { id: usize, entity_id: usize, @@ -5192,18 +5110,6 @@ pub enum Subscription { id: usize, observations: Option>>>, }, - WindowActivationObservation { - id: usize, - window_id: usize, - observations: - Option>>>>>, - }, - WindowFullscreenObservation { - id: usize, - window_id: usize, - observations: - Option>>>>>, - }, } impl Subscription { @@ -5665,8 +5571,8 @@ mod tests { }); assert_eq!(cx.cx.models.len(), 1); - assert!(cx.subscriptions.internal.lock().is_empty()); - assert!(cx.observations.internal.lock().is_empty()); + assert!(cx.subscriptions.is_empty()); + assert!(cx.observations.is_empty()); } #[crate::test(self)] @@ -5916,8 +5822,8 @@ mod tests { }); assert_eq!(cx.cx.views.len(), 2); - assert!(cx.subscriptions.internal.lock().is_empty()); - assert!(cx.observations.internal.lock().is_empty()); + assert!(cx.subscriptions.is_empty()); + assert!(cx.observations.is_empty()); } #[crate::test(self)] diff --git a/crates/gpui/src/app/callback_collection.rs b/crates/gpui/src/app/callback_collection.rs new file mode 100644 index 0000000000000000000000000000000000000000..4ec90fbac0b4962520945f2c3914bd3a324f2e1b --- /dev/null +++ b/crates/gpui/src/app/callback_collection.rs @@ -0,0 +1,106 @@ +use std::sync::Arc; +use std::{hash::Hash, sync::Weak}; + +use parking_lot::Mutex; + +use collections::{btree_map, BTreeMap, HashMap}; + +use crate::MutableAppContext; + +pub type Mapping = Mutex>>>; + +pub struct CallbackCollection { + internal: Arc>, +} + +impl Clone for CallbackCollection { + fn clone(&self) -> Self { + Self { + internal: self.internal.clone(), + } + } +} + +impl Default for CallbackCollection { + fn default() -> Self { + CallbackCollection { + internal: Arc::new(Mutex::new(Default::default())), + } + } +} + +impl CallbackCollection { + pub fn downgrade(&self) -> Weak> { + Arc::downgrade(&self.internal) + } + + #[cfg(test)] + pub fn is_empty(&self) -> bool { + self.internal.lock().is_empty() + } + + pub fn add_callback(&mut self, id: K, subscription_id: usize, callback: F) { + self.internal + .lock() + .entry(id) + .or_default() + .insert(subscription_id, Some(callback)); + } + + pub fn remove(&mut self, id: K) { + self.internal.lock().remove(&id); + } + + pub fn add_or_remove_callback(&mut self, id: K, subscription_id: usize, callback: F) { + match self + .internal + .lock() + .entry(id) + .or_default() + .entry(subscription_id) + { + btree_map::Entry::Vacant(entry) => { + entry.insert(Some(callback)); + } + + btree_map::Entry::Occupied(entry) => { + // TODO: This seems like it should never be called because no code + // should ever attempt to remove an existing callback + debug_assert!(entry.get().is_none()); + entry.remove(); + } + } + } + + pub fn emit_and_cleanup bool>( + &mut self, + id: K, + cx: &mut MutableAppContext, + mut call_callback: C, + ) { + let callbacks = self.internal.lock().remove(&id); + if let Some(callbacks) = callbacks { + for (subscription_id, callback) in callbacks { + if let Some(mut callback) = callback { + let alive = call_callback(&mut callback, cx); + if alive { + match self + .internal + .lock() + .entry(id) + .or_default() + .entry(subscription_id) + { + btree_map::Entry::Vacant(entry) => { + entry.insert(Some(callback)); + } + btree_map::Entry::Occupied(entry) => { + entry.remove(); + } + } + } + } + } + } + } +} diff --git a/crates/gpui/src/presenter.rs b/crates/gpui/src/presenter.rs index d0af2473a6aeb03ea13c7fe2954a2f0ff2820466..a8aefad6e9afc94eda4e5d9162e28780d1110920 100644 --- a/crates/gpui/src/presenter.rs +++ b/crates/gpui/src/presenter.rs @@ -13,11 +13,11 @@ use crate::{ ReadModel, ReadView, RenderContext, RenderParams, Scene, UpgradeModelHandle, UpgradeViewHandle, View, ViewHandle, WeakModelHandle, WeakViewHandle, }; +use collections::{HashMap, HashSet}; use pathfinder_geometry::vector::{vec2f, Vector2F}; use serde_json::json; use smallvec::SmallVec; use std::{ - collections::{HashMap, HashSet}, marker::PhantomData, ops::{Deref, DerefMut, Range}, sync::Arc, @@ -52,7 +52,7 @@ impl Presenter { Self { window_id, rendered_views: cx.render_views(window_id, titlebar_height), - parents: HashMap::new(), + parents: Default::default(), cursor_regions: Default::default(), mouse_regions: Default::default(), font_cache, From 4271eb36241b97aee562df9f1d3da44cfed5755c Mon Sep 17 00:00:00 2001 From: K Simmons Date: Thu, 4 Aug 2022 20:55:10 -0700 Subject: [PATCH 10/27] Event dispatch moved to MutableAppContext. No longer dispatches from presenter. Not currently handling key presses properly --- crates/collab/src/integration_tests.rs | 29 +- crates/command_palette/src/command_palette.rs | 10 +- crates/contacts_panel/src/contacts_panel.rs | 4 +- crates/context_menu/src/context_menu.rs | 4 +- crates/diagnostics/src/diagnostics.rs | 4 +- crates/editor/src/editor.rs | 4 +- crates/editor/src/items.rs | 4 +- crates/gpui/src/app.rs | 523 ++++++++++-------- crates/gpui/src/presenter.rs | 64 +-- crates/gpui/src/test.rs | 20 +- crates/search/src/buffer_search.rs | 8 +- crates/search/src/project_search.rs | 7 +- crates/workspace/src/pane.rs | 4 +- crates/workspace/src/workspace.rs | 45 +- 14 files changed, 393 insertions(+), 337 deletions(-) diff --git a/crates/collab/src/integration_tests.rs b/crates/collab/src/integration_tests.rs index 2a68c2056e523c7965d7cdeb090a3cdf55337f61..4118e5963cdd7d706095ff4968b5f12b10d163ee 100644 --- a/crates/collab/src/integration_tests.rs +++ b/crates/collab/src/integration_tests.rs @@ -18,6 +18,7 @@ use futures::{channel::mpsc, Future, StreamExt as _}; use gpui::{ executor::{self, Deterministic}, geometry::vector::vec2f, + test::EmptyView, ModelHandle, Task, TestAppContext, ViewHandle, }; use language::{ @@ -67,7 +68,7 @@ async fn test_share_project( cx_b2: &mut TestAppContext, ) { cx_a.foreground().forbid_parking(); - let (window_b, _) = cx_b.add_window(|_| EmptyView); + let (_, window_b) = cx_b.add_window(|_| EmptyView); let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await; let client_a = server.create_client(cx_a, "user_a").await; let client_b = server.create_client(cx_b, "user_b").await; @@ -145,7 +146,7 @@ async fn test_share_project( .await .unwrap(); - let editor_b = cx_b.add_view(window_b, |cx| Editor::for_buffer(buffer_b, None, cx)); + let editor_b = cx_b.add_view(&window_b, |cx| Editor::for_buffer(buffer_b, None, cx)); // TODO // // Create a selection set as client B and see that selection set as client A. @@ -1736,8 +1737,8 @@ async fn test_collaborating_with_completion(cx_a: &mut TestAppContext, cx_b: &mu .update(cx_b, |p, cx| p.open_buffer((worktree_id, "main.rs"), cx)) .await .unwrap(); - let (window_b, _) = cx_b.add_window(|_| EmptyView); - let editor_b = cx_b.add_view(window_b, |cx| { + let (_, window_b) = cx_b.add_window(|_| EmptyView); + let editor_b = cx_b.add_view(&window_b, |cx| { Editor::for_buffer(buffer_b.clone(), Some(project_b.clone()), cx) }); @@ -5387,8 +5388,8 @@ impl TestClient { project: &ModelHandle, cx: &mut TestAppContext, ) -> ViewHandle { - let (window_id, _) = cx.add_window(|_| EmptyView); - cx.add_view(window_id, |cx| Workspace::new(project.clone(), cx)) + let (_, root_view) = cx.add_window(|_| EmptyView); + cx.add_view(&root_view, |cx| Workspace::new(project.clone(), cx)) } async fn simulate_host( @@ -5901,19 +5902,3 @@ fn channel_messages(channel: &Channel) -> Vec<(String, String, bool)> { }) .collect() } - -struct EmptyView; - -impl gpui::Entity for EmptyView { - type Event = (); -} - -impl gpui::View for EmptyView { - fn ui_name() -> &'static str { - "empty view" - } - - fn render(&mut self, _: &mut gpui::RenderContext) -> gpui::ElementBox { - gpui::Element::boxed(gpui::elements::Empty::new()) - } -} diff --git a/crates/command_palette/src/command_palette.rs b/crates/command_palette/src/command_palette.rs index 5f438057ee96440c7cce45e105cbb1e7f7d457c0..5f213284e8f10779eb903df2d850c5a49af39b10 100644 --- a/crates/command_palette/src/command_palette.rs +++ b/crates/command_palette/src/command_palette.rs @@ -85,8 +85,8 @@ impl CommandPalette { let focused_view_id = cx.focused_view_id(window_id).unwrap_or(workspace.id()); cx.as_mut().defer(move |cx| { - let this = cx.add_view(window_id, |cx| Self::new(focused_view_id, cx)); workspace.update(cx, |workspace, cx| { + let this = cx.add_view(|cx| Self::new(focused_view_id, cx)); workspace.toggle_modal(cx, |_, cx| { cx.subscribe(&this, Self::on_event).detach(); this @@ -110,10 +110,10 @@ impl CommandPalette { } => { let window_id = *window_id; let focused_view_id = *focused_view_id; - let action = (*action).boxed_clone(); + let action = action.boxed_clone(); workspace.dismiss_modal(cx); cx.as_mut() - .defer(move |cx| cx.dispatch_action_at(window_id, focused_view_id, &*action)) + .defer(move |cx| cx.dispatch_any_action_at(window_id, focused_view_id, action)) } } } @@ -345,8 +345,8 @@ mod tests { }); let project = Project::test(app_state.fs.clone(), [], cx).await; - let (window_id, workspace) = cx.add_window(|cx| Workspace::new(project, cx)); - let editor = cx.add_view(window_id, |cx| { + let (_, workspace) = cx.add_window(|cx| Workspace::new(project, cx)); + let editor = cx.add_view(&workspace, |cx| { let mut editor = Editor::single_line(None, cx); editor.set_text("abc", cx); editor diff --git a/crates/contacts_panel/src/contacts_panel.rs b/crates/contacts_panel/src/contacts_panel.rs index aef90378791a9f49f6e08dddd647324ae0ee361c..4aff5b1a74fe61d2522b456e0d80fc13b726cd87 100644 --- a/crates/contacts_panel/src/contacts_panel.rs +++ b/crates/contacts_panel/src/contacts_panel.rs @@ -1248,8 +1248,8 @@ mod tests { .0 .read_with(cx, |worktree, _| worktree.id().to_proto()); - let workspace = cx.add_view(0, |cx| Workspace::new(project.clone(), cx)); - let panel = cx.add_view(0, |cx| { + let (_, workspace) = cx.add_window(|cx| Workspace::new(project.clone(), cx)); + let panel = cx.add_view(&workspace, |cx| { ContactsPanel::new( user_store.clone(), project_store.clone(), diff --git a/crates/context_menu/src/context_menu.rs b/crates/context_menu/src/context_menu.rs index d49f817de64a2fd0d9817e101a37f124f4d75d91..b17718577ffc39908f0b29cd0041eb866d73f53a 100644 --- a/crates/context_menu/src/context_menu.rs +++ b/crates/context_menu/src/context_menu.rs @@ -156,9 +156,7 @@ impl ContextMenu { fn confirm(&mut self, _: &Confirm, cx: &mut ViewContext) { if let Some(ix) = self.selected_index { if let Some(ContextMenuItem::Item { action, .. }) = self.items.get(ix) { - let window_id = cx.window_id(); - let view_id = cx.view_id(); - cx.dispatch_action_at(window_id, view_id, action.as_ref()); + cx.dispatch_any_action(action.boxed_clone()); self.reset(cx); } } diff --git a/crates/diagnostics/src/diagnostics.rs b/crates/diagnostics/src/diagnostics.rs index 8d5746f8fb2a2ae933b5398692ca45eea89402b6..e9692c5493641944274aaa3bca46feab551e67b7 100644 --- a/crates/diagnostics/src/diagnostics.rs +++ b/crates/diagnostics/src/diagnostics.rs @@ -786,7 +786,7 @@ mod tests { .await; let project = Project::test(app_state.fs.clone(), ["/test".as_ref()], cx).await; - let workspace = cx.add_view(0, |cx| Workspace::new(project.clone(), cx)); + let (_, workspace) = cx.add_window(|cx| Workspace::new(project.clone(), cx)); // Create some diagnostics project.update(cx, |project, cx| { @@ -873,7 +873,7 @@ mod tests { }); // Open the project diagnostics view while there are already diagnostics. - let view = cx.add_view(0, |cx| { + let view = cx.add_view(&workspace, |cx| { ProjectDiagnosticsEditor::new(project.clone(), workspace.downgrade(), cx) }); diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 7c2d560a41a123eb7024dc1e7ccf152d395182de..e4ff272440ab114a61333cd2a658f48c9d571517 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -7099,10 +7099,10 @@ mod tests { fn test_navigation_history(cx: &mut gpui::MutableAppContext) { cx.set_global(Settings::test(cx)); use workspace::Item; - let pane = cx.add_view(Default::default(), |cx| Pane::new(cx)); + let (_, pane) = cx.add_window(Default::default(), |cx| Pane::new(cx)); let buffer = MultiBuffer::build_simple(&sample_text(300, 5, 'a'), cx); - cx.add_window(Default::default(), |cx| { + cx.add_view(&pane, |cx| { let mut editor = build_editor(buffer.clone(), cx); let handle = cx.handle(); editor.set_nav_history(Some(pane.read(cx).nav_history_for_item(&handle))); diff --git a/crates/editor/src/items.rs b/crates/editor/src/items.rs index 5bb8d4d0b2f0bc105608d0f672a7ee74be1fde17..9837c5070f53f2b9aa0e9093c5fddeec84843391 100644 --- a/crates/editor/src/items.rs +++ b/crates/editor/src/items.rs @@ -54,8 +54,8 @@ impl FollowableItem for Editor { }) }) .unwrap_or_else(|| { - cx.add_view(pane.window_id(), |cx| { - Editor::for_buffer(buffer, Some(project), cx) + pane.update(&mut cx, |_, cx| { + cx.add_view(|cx| Editor::for_buffer(buffer, Some(project), cx)) }) }); editor.update(&mut cx, |editor, cx| { diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index cc4c1191f618cf9a92e8dc521cfe6f6b3b14c5e6..a1b782039a618d2bf756d8dd66c42eaea5fefc2a 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -229,18 +229,12 @@ impl App { move |action| { let mut cx = cx.borrow_mut(); if let Some(key_window_id) = cx.cx.platform.key_window_id() { - if let Some((presenter, _)) = - cx.presenters_and_platform_windows.get(&key_window_id) - { - let presenter = presenter.clone(); - let path = presenter.borrow().dispatch_path(cx.as_ref()); - cx.dispatch_action_any(key_window_id, &path, action); - } else { - cx.dispatch_global_action_any(action); + if let Some(view_id) = cx.focused_view_id(key_window_id) { + cx.handle_dispatch_action_any_effect(key_window_id, Some(view_id), action); + return; } - } else { - cx.dispatch_global_action_any(action); } + cx.dispatch_global_action_any(action); } })); @@ -462,15 +456,9 @@ impl TestAppContext { pub fn dispatch_action(&self, window_id: usize, action: A) { let mut cx = self.cx.borrow_mut(); - let dispatch_path = cx - .presenters_and_platform_windows - .get(&window_id) - .unwrap() - .0 - .borrow() - .dispatch_path(cx.as_ref()); - - cx.dispatch_action_any(window_id, &dispatch_path, &action); + if let Some(view_id) = cx.focused_view_id(window_id) { + cx.handle_dispatch_action_any_effect(window_id, Some(view_id), &action); + } } pub fn dispatch_global_action(&self, action: A) { @@ -485,9 +473,8 @@ impl TestAppContext { .unwrap() .0 .clone(); - let dispatch_path = presenter.borrow().dispatch_path(cx.as_ref()); - if cx.dispatch_keystroke(window_id, dispatch_path, &keystroke) { + if cx.dispatch_keystroke(window_id, &keystroke) { return true; } if presenter.borrow_mut().dispatch_event( @@ -533,32 +520,24 @@ impl TestAppContext { (window_id, view) } - pub fn window_ids(&self) -> Vec { - self.cx.borrow().window_ids().collect() - } - - pub fn root_view(&self, window_id: usize) -> Option> { - self.cx.borrow().root_view(window_id) - } - - pub fn add_view(&mut self, window_id: usize, build_view: F) -> ViewHandle + pub fn add_view( + &mut self, + parent_handle: impl Into, + build_view: F, + ) -> ViewHandle where T: View, F: FnOnce(&mut ViewContext) -> T, { - self.cx.borrow_mut().add_view(window_id, build_view) + self.cx.borrow_mut().add_view(parent_handle, build_view) } - pub fn add_option_view( - &mut self, - window_id: usize, - build_view: F, - ) -> Option> - where - T: View, - F: FnOnce(&mut ViewContext) -> Option, - { - self.cx.borrow_mut().add_option_view(window_id, build_view) + pub fn window_ids(&self) -> Vec { + self.cx.borrow().window_ids().collect() + } + + pub fn root_view(&self, window_id: usize) -> Option> { + self.cx.borrow().root_view(window_id) } pub fn read T>(&self, callback: F) -> T { @@ -786,14 +765,6 @@ impl AsyncAppContext { self.update(|cx| cx.add_model(build_model)) } - pub fn add_view(&mut self, window_id: usize, build_view: F) -> ViewHandle - where - T: View, - F: FnOnce(&mut ViewContext) -> T, - { - self.update(|cx| cx.add_view(window_id, build_view)) - } - pub fn add_window( &mut self, window_options: WindowOptions, @@ -1021,6 +992,7 @@ impl MutableAppContext { cx: AppContext { models: Default::default(), views: Default::default(), + parents: Default::default(), windows: Default::default(), globals: Default::default(), element_states: Default::default(), @@ -1645,17 +1617,7 @@ impl MutableAppContext { ) -> impl Iterator, SmallVec<[&Binding; 1]>)> { let mut action_types: HashSet<_> = self.global_actions.keys().copied().collect(); - let presenter = self - .presenters_and_platform_windows - .get(&window_id) - .unwrap() - .0 - .clone(); - let mut dispatch_path = Vec::new(); - presenter - .borrow() - .compute_dispatch_path_from(view_id, &mut dispatch_path); - for view_id in dispatch_path { + for view_id in self.parents(window_id, view_id) { if let Some(view) = self.views.get(&(window_id, view_id)) { let view_type = view.as_any().type_id(); if let Some(actions) = self.actions.get(&view_type) { @@ -1684,9 +1646,8 @@ impl MutableAppContext { pub fn is_action_available(&self, action: &dyn Action) -> bool { let action_type = action.as_any().type_id(); if let Some(window_id) = self.cx.platform.key_window_id() { - if let Some((presenter, _)) = self.presenters_and_platform_windows.get(&window_id) { - let dispatch_path = presenter.borrow().dispatch_path(&self.cx); - for view_id in dispatch_path { + if let Some(focused_view_id) = self.focused_view_id(window_id) { + for view_id in self.parents(window_id, focused_view_id) { if let Some(view) = self.views.get(&(window_id, view_id)) { let view_type = view.as_any().type_id(); if let Some(actions) = self.actions.get(&view_type) { @@ -1724,83 +1685,76 @@ impl MutableAppContext { None } - pub fn dispatch_action_at(&mut self, window_id: usize, view_id: usize, action: &dyn Action) { - let presenter = self - .presenters_and_platform_windows - .get(&window_id) - .unwrap() - .0 - .clone(); - let mut dispatch_path = Vec::new(); - presenter - .borrow() - .compute_dispatch_path_from(view_id, &mut dispatch_path); - self.dispatch_action_any(window_id, &dispatch_path, action); - } - - pub fn dispatch_action( - &mut self, - window_id: usize, - dispatch_path: Vec, - action: &A, - ) { - self.dispatch_action_any(window_id, &dispatch_path, action); - } - - pub(crate) fn dispatch_action_any( + // pub fn dispatch_action_at(&mut self, window_id: usize, view_id: usize, action: &dyn Action) { + // let presenter = self + // .presenters_and_platform_windows + // .get(&window_id) + // .unwrap() + // .0 + // .clone(); + // let mut dispatch_path = Vec::new(); + // presenter + // .borrow() + // .compute_dispatch_path_from(view_id, &mut dispatch_path); + // self.dispatch_action_any(window_id, &dispatch_path, action); + // } + + // pub fn dispatch_action( + // &mut self, + // window_id: usize, + // dispatch_path: Vec, + // action: &A, + // ) { + // self.dispatch_action_any(window_id, &dispatch_path, action); + // } + + // Traverses the parent tree. Walks down the tree toward the passed + // view calling visit with true. Then walks back up the tree calling visit with false. + // If `visit` returns false this function will immediately return. + // Returns a bool indicating if the traversal was completed early. + fn visit_dispatch_path( &mut self, window_id: usize, - path: &[usize], - action: &dyn Action, + view_id: usize, + mut visit: impl FnMut(usize, bool, &mut MutableAppContext) -> bool, ) -> bool { - self.update(|this| { - this.halt_action_dispatch = false; - for (capture_phase, view_id) in path - .iter() - .map(|view_id| (true, *view_id)) - .chain(path.iter().rev().map(|view_id| (false, *view_id))) - { - if let Some(mut view) = this.cx.views.remove(&(window_id, view_id)) { - let type_id = view.as_any().type_id(); - - if let Some((name, mut handlers)) = this - .actions_mut(capture_phase) - .get_mut(&type_id) - .and_then(|h| h.remove_entry(&action.id())) - { - for handler in handlers.iter_mut().rev() { - this.halt_action_dispatch = true; - handler(view.as_mut(), action, this, window_id, view_id); - if this.halt_action_dispatch { - break; - } - } - this.actions_mut(capture_phase) - .get_mut(&type_id) - .unwrap() - .insert(name, handlers); - } - - this.cx.views.insert((window_id, view_id), view); + // List of view ids from the leaf to the root of the window + let mut path = vec![view_id]; + let mut current_view = view_id; + while let Some(ParentId::View(parent_id)) = self.parents.get(&(window_id, current_view)) { + current_view = *parent_id; + path.push(current_view); + } - if this.halt_action_dispatch { - break; - } - } + // Walk down from the root to the leaf calling visit with capture_phase = true + for view_id in path.iter().rev() { + if !visit(*view_id, true, self) { + return false; } + } - if !this.halt_action_dispatch { - this.halt_action_dispatch = this.dispatch_global_action_any(action); + // Walk up from the leaf to the root calling visit with capture_phase = false + for view_id in path.iter() { + if !visit(*view_id, false, self) { + return false; } + } - this.pending_effects - .push_back(Effect::ActionDispatchNotification { - action_id: action.id(), - }); - this.halt_action_dispatch - }) + true } + // Returns an iterator over all of the view ids from the passed view up to the root of the window + // Includes the passed view itself + fn parents(&self, window_id: usize, mut view_id: usize) -> impl Iterator + '_ { + std::iter::from_fn(move || { + if let Some(ParentId::View(parent_id)) = self.parents.get(&(window_id, view_id)) { + view_id = *parent_id; + Some(view_id) + } else { + None + } + }) + } fn actions_mut( &mut self, capture_phase: bool, @@ -1836,34 +1790,34 @@ impl MutableAppContext { self.keystroke_matcher.clear_bindings(); } - pub fn dispatch_keystroke( - &mut self, - window_id: usize, - dispatch_path: Vec, - keystroke: &Keystroke, - ) -> bool { - let mut context_chain = Vec::new(); - for view_id in &dispatch_path { - let view = self - .cx - .views - .get(&(window_id, *view_id)) - .expect("view in responder chain does not exist"); - context_chain.push(view.keymap_context(self.as_ref())); - } - + pub fn dispatch_keystroke(&mut self, window_id: usize, keystroke: &Keystroke) -> bool { let mut pending = false; - for (i, cx) in context_chain.iter().enumerate().rev() { - match self - .keystroke_matcher - .push_keystroke(keystroke.clone(), dispatch_path[i], cx) - { - MatchResult::None => {} - MatchResult::Pending => pending = true, - MatchResult::Action(action) => { - if self.dispatch_action_any(window_id, &dispatch_path[0..=i], action.as_ref()) { - self.keystroke_matcher.clear_pending(); - return true; + + if let Some(view_id) = self.focused_view_id(window_id) { + for view_id in self.parents(window_id, view_id).collect::>() { + let keymap_context = self + .cx + .views + .get(&(window_id, view_id)) + .expect("View passed to visit does not exist") + .keymap_context(self.as_ref()); + + match self.keystroke_matcher.push_keystroke( + keystroke.clone(), + view_id, + &keymap_context, + ) { + MatchResult::None => {} + MatchResult::Pending => pending = true, + MatchResult::Action(action) => { + if self.handle_dispatch_action_any_effect( + window_id, + Some(view_id), + action.as_ref(), + ) { + self.keystroke_matcher.clear_pending(); + return true; + } } } } @@ -1917,15 +1871,14 @@ impl MutableAppContext { { self.update(|this| { let type_id = TypeId::of::(); - let mut state = this - .cx - .globals - .remove(&type_id) - .expect("no global has been added for this type"); - let result = update(state.downcast_mut().unwrap(), this); - this.cx.globals.insert(type_id, state); - this.notify_global(type_id); - result + if let Some(mut state) = this.cx.globals.remove(&type_id) { + let result = update(state.downcast_mut().unwrap(), this); + this.cx.globals.insert(type_id, state); + this.notify_global(type_id); + result + } else { + panic!("No global added for {}", std::any::type_name::()); + } }) } @@ -1955,7 +1908,9 @@ impl MutableAppContext { { self.update(|this| { let window_id = post_inc(&mut this.next_window_id); - let root_view = this.add_view(window_id, build_root_view); + let root_view = this + .build_and_insert_view(window_id, ParentId::Root, |cx| Some(build_root_view(cx))) + .unwrap(); this.cx.windows.insert( window_id, Window { @@ -1979,7 +1934,9 @@ impl MutableAppContext { F: FnOnce(&mut ViewContext) -> T, { self.update(|this| { - let root_view = this.add_view(window_id, build_root_view); + let root_view = this + .build_and_insert_view(window_id, ParentId::Root, |cx| Some(build_root_view(cx))) + .unwrap(); let window = this.cx.windows.get_mut(&window_id).unwrap(); window.root_view = root_view.clone().into(); window.focused_view_id = Some(root_view.id()); @@ -2009,11 +1966,7 @@ impl MutableAppContext { app.update(|cx| { if let Some(presenter) = presenter.upgrade() { if let Event::KeyDown(KeyDownEvent { keystroke, .. }) = &event { - if cx.dispatch_keystroke( - window_id, - presenter.borrow().dispatch_path(cx.as_ref()), - keystroke, - ) { + if cx.dispatch_keystroke(window_id, keystroke) { return true; } } @@ -2079,18 +2032,45 @@ impl MutableAppContext { ) } - pub fn add_view(&mut self, window_id: usize, build_view: F) -> ViewHandle + pub fn add_view( + &mut self, + parent_handle: impl Into, + build_view: F, + ) -> ViewHandle where T: View, F: FnOnce(&mut ViewContext) -> T, { - self.add_option_view(window_id, |cx| Some(build_view(cx))) - .unwrap() + let parent_handle = parent_handle.into(); + self.build_and_insert_view( + parent_handle.window_id, + ParentId::View(parent_handle.view_id), + |cx| Some(build_view(cx)), + ) + .unwrap() } pub fn add_option_view( + &mut self, + parent_handle: impl Into, + build_view: F, + ) -> Option> + where + T: View, + F: FnOnce(&mut ViewContext) -> Option, + { + let parent_handle = parent_handle.into(); + self.build_and_insert_view( + parent_handle.window_id, + ParentId::View(parent_handle.view_id), + build_view, + ) + } + + pub(crate) fn build_and_insert_view( &mut self, window_id: usize, + parent_id: ParentId, build_view: F, ) -> Option> where @@ -2102,6 +2082,7 @@ impl MutableAppContext { let mut cx = ViewContext::new(this, window_id, view_id); let handle = if let Some(view) = build_view(&mut cx) { this.cx.views.insert((window_id, view_id), Box::new(view)); + this.cx.parents.insert((window_id, view_id), parent_id); if let Some(window) = this.cx.windows.get_mut(&window_id) { window .invalidation @@ -2154,6 +2135,7 @@ impl MutableAppContext { None } }); + self.cx.parents.remove(&(window_id, view_id)); if let Some(view_id) = change_focus_to { self.handle_focus_effect(window_id, Some(view_id)); @@ -2316,6 +2298,17 @@ impl MutableAppContext { Effect::RefreshWindows => { refreshing = true; } + Effect::DispatchActionFrom { + window_id, + view_id, + action, + } => { + self.handle_dispatch_action_any_effect( + window_id, + Some(view_id), + action.as_ref(), + ); + } Effect::ActionDispatchNotification { action_id } => { self.handle_action_dispatch_notification_effect(action_id) } @@ -2403,6 +2396,23 @@ impl MutableAppContext { self.pending_effects.push_back(Effect::RefreshWindows); } + pub fn dispatch_action_at(&mut self, window_id: usize, view_id: usize, action: impl Action) { + self.dispatch_any_action_at(window_id, view_id, Box::new(action)); + } + + pub fn dispatch_any_action_at( + &mut self, + window_id: usize, + view_id: usize, + action: Box, + ) { + self.pending_effects.push_back(Effect::DispatchActionFrom { + window_id, + view_id, + action, + }); + } + fn perform_window_refresh(&mut self) { let mut presenters = mem::take(&mut self.presenters_and_platform_windows); for (window_id, (presenter, window)) in &mut presenters { @@ -2569,6 +2579,55 @@ impl MutableAppContext { }) } + fn handle_dispatch_action_any_effect( + &mut self, + window_id: usize, + view_id: Option, + action: &dyn Action, + ) -> bool { + self.update(|this| { + if let Some(view_id) = view_id { + this.visit_dispatch_path(window_id, view_id, |view_id, capture_phase, this| { + if let Some(mut view) = this.cx.views.remove(&(window_id, view_id)) { + let type_id = view.as_any().type_id(); + + if let Some((name, mut handlers)) = this + .actions_mut(capture_phase) + .get_mut(&type_id) + .and_then(|h| h.remove_entry(&action.id())) + { + for handler in handlers.iter_mut().rev() { + this.halt_action_dispatch = true; + handler(view.as_mut(), action, this, window_id, view_id); + if this.halt_action_dispatch { + break; + } + } + this.actions_mut(capture_phase) + .get_mut(&type_id) + .unwrap() + .insert(name, handlers); + } + + this.cx.views.insert((window_id, view_id), view); + } + + !this.halt_action_dispatch + }); + } + + if !this.halt_action_dispatch { + this.halt_action_dispatch = this.dispatch_global_action_any(action); + } + + this.pending_effects + .push_back(Effect::ActionDispatchNotification { + action_id: action.id(), + }); + this.halt_action_dispatch + }) + } + fn handle_action_dispatch_notification_effect(&mut self, action_id: TypeId) { let mut callbacks = mem::take(&mut *self.action_dispatch_observations.lock()); for (_, callback) in &mut callbacks { @@ -2750,9 +2809,15 @@ impl Deref for MutableAppContext { } } +pub enum ParentId { + View(usize), + Root, +} + pub struct AppContext { models: HashMap>, views: HashMap<(usize, usize), Box>, + parents: HashMap<(usize, usize), ParentId>, windows: HashMap, globals: HashMap>, element_states: HashMap>, @@ -2977,6 +3042,11 @@ pub enum Effect { callback: WindowFullscreenCallback, }, RefreshWindows, + DispatchActionFrom { + window_id: usize, + view_id: usize, + action: Box, + }, ActionDispatchNotification { action_id: TypeId, }, @@ -3060,6 +3130,13 @@ impl Debug for Effect { .field("view_id", view_id) .field("subscription_id", subscription_id) .finish(), + Effect::DispatchActionFrom { + window_id, view_id, .. + } => f + .debug_struct("Effect::DispatchActionFrom") + .field("window_id", window_id) + .field("view_id", view_id) + .finish(), Effect::ActionDispatchNotification { action_id, .. } => f .debug_struct("Effect::ActionDispatchNotification") .field("action_id", action_id) @@ -3640,7 +3717,11 @@ impl<'a, T: View> ViewContext<'a, T> { S: View, F: FnOnce(&mut ViewContext) -> S, { - self.app.add_view(self.window_id, build_view) + self.app + .build_and_insert_view(self.window_id, ParentId::View(self.view_id), |cx| { + Some(build_view(cx)) + }) + .unwrap() } pub fn add_option_view(&mut self, build_view: F) -> Option> @@ -3648,7 +3729,8 @@ impl<'a, T: View> ViewContext<'a, T> { S: View, F: FnOnce(&mut ViewContext) -> Option, { - self.app.add_option_view(self.window_id, build_view) + self.app + .build_and_insert_view(self.window_id, ParentId::View(self.view_id), build_view) } pub fn replace_root_view(&mut self, build_root_view: F) -> ViewHandle @@ -3658,7 +3740,9 @@ impl<'a, T: View> ViewContext<'a, T> { { let window_id = self.window_id; self.update(|this| { - let root_view = this.add_view(window_id, build_root_view); + let root_view = this + .build_and_insert_view(window_id, ParentId::Root, |cx| Some(build_root_view(cx))) + .unwrap(); let window = this.cx.windows.get_mut(&window_id).unwrap(); window.root_view = root_view.clone().into(); window.focused_view_id = Some(root_view.id()); @@ -3802,6 +3886,11 @@ impl<'a, T: View> ViewContext<'a, T> { self.app.notify_view(self.window_id, self.view_id); } + pub fn dispatch_any_action(&mut self, action: Box) { + self.app + .dispatch_any_action_at(self.window_id, self.view_id, action) + } + pub fn defer(&mut self, callback: impl 'static + FnOnce(&mut T, &mut ViewContext)) { let handle = self.handle(); self.app.defer(move |cx| { @@ -5797,9 +5886,9 @@ mod tests { } } - let (window_id, _) = cx.add_window(Default::default(), |cx| View::new(None, cx)); - let handle_1 = cx.add_view(window_id, |cx| View::new(None, cx)); - let handle_2 = cx.add_view(window_id, |cx| View::new(Some(handle_1.clone()), cx)); + let (_, root_view) = cx.add_window(Default::default(), |cx| View::new(None, cx)); + let handle_1 = cx.add_view(&root_view, |cx| View::new(None, cx)); + let handle_2 = cx.add_view(&root_view, |cx| View::new(Some(handle_1.clone()), cx)); assert_eq!(cx.cx.views.len(), 3); handle_1.update(cx, |view, cx| { @@ -5973,8 +6062,8 @@ mod tests { type Event = usize; } - let (window_id, handle_1) = cx.add_window(Default::default(), |_| View::default()); - let handle_2 = cx.add_view(window_id, |_| View::default()); + let (_, handle_1) = cx.add_window(Default::default(), |_| View::default()); + let handle_2 = cx.add_view(&handle_1, |_| View::default()); let handle_3 = cx.add_model(|_| Model); handle_1.update(cx, |_, cx| { @@ -6214,9 +6303,9 @@ mod tests { type Event = (); } - let (window_id, _) = cx.add_window(Default::default(), |_| View); - let observing_view = cx.add_view(window_id, |_| View); - let emitting_view = cx.add_view(window_id, |_| View); + let (_, root_view) = cx.add_window(Default::default(), |_| View); + let observing_view = cx.add_view(&root_view, |_| View); + let emitting_view = cx.add_view(&root_view, |_| View); let observing_model = cx.add_model(|_| Model); let observed_model = cx.add_model(|_| Model); @@ -6390,8 +6479,8 @@ mod tests { type Event = (); } - let (window_id, _) = cx.add_window(Default::default(), |_| View); - let observing_view = cx.add_view(window_id, |_| View); + let (_, root_view) = cx.add_window(Default::default(), |_| View); + let observing_view = cx.add_view(root_view, |_| View); let observing_model = cx.add_model(|_| Model); let observed_model = cx.add_model(|_| Model); @@ -6513,9 +6602,9 @@ mod tests { } } - let (window_id, _) = cx.add_window(Default::default(), |_| View); - let observing_view = cx.add_view(window_id, |_| View); - let observed_view = cx.add_view(window_id, |_| View); + let (_, root_view) = cx.add_window(Default::default(), |_| View); + let observing_view = cx.add_view(&root_view, |_| View); + let observed_view = cx.add_view(&root_view, |_| View); let observation_count = Rc::new(RefCell::new(0)); observing_view.update(cx, |_, cx| { @@ -6587,11 +6676,11 @@ mod tests { } let view_events: Arc>> = Default::default(); - let (window_id, view_1) = cx.add_window(Default::default(), |_| View { + let (_, view_1) = cx.add_window(Default::default(), |_| View { events: view_events.clone(), name: "view 1".to_string(), }); - let view_2 = cx.add_view(window_id, |_| View { + let view_2 = cx.add_view(&view_1, |_| View { events: view_events.clone(), name: "view 2".to_string(), }); @@ -6813,11 +6902,6 @@ mod tests { } }); - let (window_id, view_1) = cx.add_window(Default::default(), |_| ViewA { id: 1 }); - let view_2 = cx.add_view(window_id, |_| ViewB { id: 2 }); - let view_3 = cx.add_view(window_id, |_| ViewA { id: 3 }); - let view_4 = cx.add_view(window_id, |_| ViewB { id: 4 }); - let observed_actions = Rc::new(RefCell::new(Vec::new())); cx.observe_actions({ let observed_actions = observed_actions.clone(); @@ -6825,9 +6909,14 @@ mod tests { }) .detach(); - cx.dispatch_action( + let (window_id, view_1) = cx.add_window(Default::default(), |_| ViewA { id: 1 }); + let view_2 = cx.add_view(&view_1, |_| ViewB { id: 2 }); + let view_3 = cx.add_view(&view_2, |_| ViewA { id: 3 }); + let view_4 = cx.add_view(&view_3, |_| ViewB { id: 4 }); + + cx.handle_dispatch_action_any_effect( window_id, - vec![view_1.id(), view_2.id(), view_3.id(), view_4.id()], + Some(view_4.id()), &Action("bar".to_string()), ); @@ -6848,10 +6937,15 @@ mod tests { assert_eq!(*observed_actions.borrow(), [Action::default().id()]); // Remove view_1, which doesn't propagate the action + + let (window_id, view_2) = cx.add_window(Default::default(), |_| ViewA { id: 1 }); + let view_3 = cx.add_view(&view_2, |_| ViewA { id: 3 }); + let view_4 = cx.add_view(&view_3, |_| ViewB { id: 4 }); + actions.borrow_mut().clear(); - cx.dispatch_action( + cx.handle_dispatch_action_any_effect( window_id, - vec![view_2.id(), view_3.id(), view_4.id()], + Some(view_4.id()), &Action("bar".to_string()), ); @@ -6924,8 +7018,9 @@ mod tests { view_3.keymap_context.set.insert("c".into()); let (window_id, view_1) = cx.add_window(Default::default(), |_| view_1); - let view_2 = cx.add_view(window_id, |_| view_2); - let view_3 = cx.add_view(window_id, |_| view_3); + let view_2 = cx.add_view(&view_1, |_| view_2); + let view_3 = cx.add_view(&view_2, |_| view_3); + cx.focus(window_id, Some(view_3.id())); // This keymap's only binding dispatches an action on view 2 because that view will have // "a" and "b" in its context, but not "c". @@ -6963,20 +7058,12 @@ mod tests { } }); - cx.dispatch_keystroke( - window_id, - vec![view_1.id(), view_2.id(), view_3.id()], - &Keystroke::parse("a").unwrap(), - ); + cx.dispatch_keystroke(window_id, &Keystroke::parse("a").unwrap()); assert_eq!(&*actions.borrow(), &["2 a"]); actions.borrow_mut().clear(); - cx.dispatch_keystroke( - window_id, - vec![view_1.id(), view_2.id(), view_3.id()], - &Keystroke::parse("b").unwrap(), - ); + cx.dispatch_keystroke(window_id, &Keystroke::parse("b").unwrap()); assert_eq!(&*actions.borrow(), &["3 b", "2 b", "1 b", "global b"]); } @@ -7130,8 +7217,8 @@ mod tests { } } - let window_id = cx.add_window(|_| View).0; - let view = cx.add_view(window_id, |_| View); + let (_, root_view) = cx.add_window(|_| View); + let view = cx.add_view(&root_view, |_| View); let condition = view.condition(&cx, |_, _| false); cx.update(|_| drop(view)); @@ -7164,7 +7251,7 @@ mod tests { Some("render count: 0") ); - let view = cx.add_view(window_id, |cx| { + let view = cx.add_view(&root_view, |cx| { cx.refresh_windows(); View(0) }); diff --git a/crates/gpui/src/presenter.rs b/crates/gpui/src/presenter.rs index a8aefad6e9afc94eda4e5d9162e28780d1110920..57d3a1a3fda11addf7d4f9aff392a29cbc53af70 100644 --- a/crates/gpui/src/presenter.rs +++ b/crates/gpui/src/presenter.rs @@ -26,7 +26,6 @@ use std::{ pub struct Presenter { window_id: usize, pub(crate) rendered_views: HashMap, - parents: HashMap, cursor_regions: Vec, mouse_regions: Vec<(MouseRegion, usize)>, font_cache: Arc, @@ -52,7 +51,6 @@ impl Presenter { Self { window_id, rendered_views: cx.render_views(window_id, titlebar_height), - parents: Default::default(), cursor_regions: Default::default(), mouse_regions: Default::default(), font_cache, @@ -67,22 +65,22 @@ impl Presenter { } } - pub fn dispatch_path(&self, app: &AppContext) -> Vec { - let mut path = Vec::new(); - if let Some(view_id) = app.focused_view_id(self.window_id) { - self.compute_dispatch_path_from(view_id, &mut path) - } - path - } + // pub fn dispatch_path(&self, app: &AppContext) -> Vec { + // let mut path = Vec::new(); + // if let Some(view_id) = app.focused_view_id(self.window_id) { + // self.compute_dispatch_path_from(view_id, &mut path) + // } + // path + // } - pub(crate) fn compute_dispatch_path_from(&self, mut view_id: usize, path: &mut Vec) { - path.push(view_id); - while let Some(parent_id) = self.parents.get(&view_id).copied() { - path.push(parent_id); - view_id = parent_id; - } - path.reverse(); - } + // pub(crate) fn compute_dispatch_path_from(&self, mut view_id: usize, path: &mut Vec) { + // path.push(view_id); + // while let Some(parent_id) = self.parents.get(&view_id).copied() { + // path.push(parent_id); + // view_id = parent_id; + // } + // path.reverse(); + // } pub fn invalidate( &mut self, @@ -93,7 +91,6 @@ impl Presenter { for view_id in &invalidation.removed { invalidation.updated.remove(&view_id); self.rendered_views.remove(&view_id); - self.parents.remove(&view_id); } for view_id in &invalidation.updated { self.rendered_views.insert( @@ -191,7 +188,6 @@ impl Presenter { LayoutContext { window_id: self.window_id, rendered_views: &mut self.rendered_views, - parents: &mut self.parents, font_cache: &self.font_cache, font_system: cx.platform().fonts(), text_layout_cache: &self.text_layout_cache, @@ -344,21 +340,11 @@ impl Presenter { } invalidated_views.extend(event_cx.invalidated_views); - let dispatch_directives = event_cx.dispatched_actions; for view_id in invalidated_views { cx.notify_view(self.window_id, view_id); } - let mut dispatch_path = Vec::new(); - for directive in dispatch_directives { - dispatch_path.clear(); - if let Some(view_id) = directive.dispatcher_view_id { - self.compute_dispatch_path_from(view_id, &mut dispatch_path); - } - cx.dispatch_action_any(self.window_id, &dispatch_path, directive.action.as_ref()); - } - handled } else { false @@ -372,9 +358,6 @@ impl Presenter { cx: &'a mut MutableAppContext, ) -> (bool, EventContext<'a>) { let mut hover_regions = Vec::new(); - // let mut unhovered_regions = Vec::new(); - // let mut hovered_regions = Vec::new(); - if let Event::MouseMoved( e @ MouseMovedEvent { position, @@ -446,7 +429,6 @@ impl Presenter { ) -> EventContext<'a> { EventContext { rendered_views: &mut self.rendered_views, - dispatched_actions: Default::default(), font_cache: &self.font_cache, text_layout_cache: &self.text_layout_cache, view_stack: Default::default(), @@ -473,15 +455,9 @@ impl Presenter { } } -pub struct DispatchDirective { - pub dispatcher_view_id: Option, - pub action: Box, -} - pub struct LayoutContext<'a> { window_id: usize, rendered_views: &'a mut HashMap, - parents: &'a mut HashMap, view_stack: Vec, pub font_cache: &'a Arc, pub font_system: Arc, @@ -506,9 +482,6 @@ impl<'a> LayoutContext<'a> { } fn layout(&mut self, view_id: usize, constraint: SizeConstraint) -> Vector2F { - if let Some(parent_id) = self.view_stack.last() { - self.parents.insert(view_id, *parent_id); - } self.view_stack.push(view_id); let mut rendered_view = self.rendered_views.remove(&view_id).unwrap(); let size = rendered_view.layout(constraint, self); @@ -637,7 +610,6 @@ impl<'a> Deref for PaintContext<'a> { pub struct EventContext<'a> { rendered_views: &'a mut HashMap, - dispatched_actions: Vec, pub font_cache: &'a FontCache, pub text_layout_cache: &'a TextLayoutCache, pub app: &'a mut MutableAppContext, @@ -692,10 +664,8 @@ impl<'a> EventContext<'a> { } pub fn dispatch_any_action(&mut self, action: Box) { - self.dispatched_actions.push(DispatchDirective { - dispatcher_view_id: self.view_stack.last().copied(), - action, - }); + self.app + .dispatch_any_action_at(self.window_id, *self.view_stack.last().unwrap(), action) } pub fn dispatch_action(&mut self, action: A) { diff --git a/crates/gpui/src/test.rs b/crates/gpui/src/test.rs index c8a69c4e7d7b0ee46caac66b041e4fa769ef3e5a..4122ad09b7480adcd647db98821a6bb3c533aa1f 100644 --- a/crates/gpui/src/test.rs +++ b/crates/gpui/src/test.rs @@ -1,6 +1,6 @@ use crate::{ - executor, platform, Entity, FontCache, Handle, LeakDetector, MutableAppContext, Platform, - Subscription, TestAppContext, + elements::Empty, executor, platform, Element, ElementBox, Entity, FontCache, Handle, + LeakDetector, MutableAppContext, Platform, RenderContext, Subscription, TestAppContext, View, }; use futures::StreamExt; use parking_lot::Mutex; @@ -162,3 +162,19 @@ where Observation { rx, _subscription } } + +pub struct EmptyView; + +impl Entity for EmptyView { + type Event = (); +} + +impl View for EmptyView { + fn ui_name() -> &'static str { + "empty view" + } + + fn render(&mut self, _: &mut RenderContext) -> ElementBox { + Element::boxed(Empty::new()) + } +} diff --git a/crates/search/src/buffer_search.rs b/crates/search/src/buffer_search.rs index 52631e71b4b71827e6ad03ede931034e1f021b68..ada785f85415898799dcb810752d74d478b6918b 100644 --- a/crates/search/src/buffer_search.rs +++ b/crates/search/src/buffer_search.rs @@ -600,7 +600,7 @@ impl BufferSearchBar { mod tests { use super::*; use editor::{DisplayPoint, Editor}; - use gpui::{color::Color, TestAppContext}; + use gpui::{color::Color, test::EmptyView, TestAppContext}; use language::Buffer; use std::sync::Arc; use unindent::Unindent as _; @@ -629,11 +629,13 @@ mod tests { cx, ) }); - let editor = cx.add_view(Default::default(), |cx| { + let (_, root_view) = cx.add_window(|_| EmptyView); + + let editor = cx.add_view(&root_view, |cx| { Editor::for_buffer(buffer.clone(), None, cx) }); - let search_bar = cx.add_view(Default::default(), |cx| { + let search_bar = cx.add_view(&root_view, |cx| { let mut search_bar = BufferSearchBar::new(cx); search_bar.set_active_pane_item(Some(&editor), cx); search_bar.show(false, true, cx); diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 39415b383272399b6806efa1126a5fcf13309777..6cbd4c7e2dcf1aa8ef57cf60091b9a8dd61c9894 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -933,7 +933,8 @@ mod tests { cx.update(|cx| { let mut settings = Settings::test(cx); settings.theme = Arc::new(theme); - cx.set_global(settings) + cx.set_global(settings); + cx.set_global(ActiveSearches::default()); }); let fs = FakeFs::new(cx.background()); @@ -949,9 +950,7 @@ mod tests { .await; let project = Project::test(fs.clone(), ["/dir".as_ref()], cx).await; let search = cx.add_model(|cx| ProjectSearch::new(project, cx)); - let search_view = cx.add_view(Default::default(), |cx| { - ProjectSearchView::new(search.clone(), cx) - }); + let (_, search_view) = cx.add_window(|cx| ProjectSearchView::new(search.clone(), cx)); search_view.update(cx, |search_view, cx| { search_view diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index a05b9ac1a822b34e36701b226085c95d287ce98c..354331974ff370784cceee5d888b23f113755800 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -386,7 +386,7 @@ impl Pane { project_entry_id: ProjectEntryId, focus_item: bool, cx: &mut ViewContext, - build_item: impl FnOnce(&mut MutableAppContext) -> Box, + build_item: impl FnOnce(&mut ViewContext) -> Box, ) -> Box { let existing_item = pane.update(cx, |pane, cx| { for (ix, item) in pane.items.iter().enumerate() { @@ -403,7 +403,7 @@ impl Pane { if let Some(existing_item) = existing_item { existing_item } else { - let item = build_item(cx); + let item = pane.update(cx, |_, cx| build_item(cx)); Self::add_item(workspace, pane, item.boxed_clone(), true, focus_item, cx); item } diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index a27754aa1308c89ec5823ab703e496d842cf901b..d1a239cbb4242bc9f97ac59b7c79529c6a7ebab9 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -59,7 +59,7 @@ use waiting_room::WaitingRoom; type ProjectItemBuilders = HashMap< TypeId, - fn(usize, ModelHandle, AnyModelHandle, &mut MutableAppContext) -> Box, + fn(ModelHandle, AnyModelHandle, &mut ViewContext) -> Box, >; type FollowableItemBuilder = fn( @@ -219,9 +219,9 @@ pub fn init(app_state: Arc, cx: &mut MutableAppContext) { pub fn register_project_item(cx: &mut MutableAppContext) { cx.update_default_global(|builders: &mut ProjectItemBuilders, _| { - builders.insert(TypeId::of::(), |window_id, project, model, cx| { + builders.insert(TypeId::of::(), |project, model, cx| { let item = model.downcast::().unwrap(); - Box::new(cx.add_view(window_id, |cx| I::for_project_item(project, item, cx))) + Box::new(cx.add_view(|cx| I::for_project_item(project, item, cx))) }); }); } @@ -1475,12 +1475,11 @@ impl Workspace { ) -> Task< Result<( ProjectEntryId, - impl 'static + FnOnce(&mut MutableAppContext) -> Box, + impl 'static + FnOnce(&mut ViewContext) -> Box, )>, > { let project = self.project().clone(); let project_item = project.update(cx, |project, cx| project.open_path(path, cx)); - let window_id = cx.window_id(); cx.as_mut().spawn(|mut cx| async move { let (project_entry_id, project_item) = project_item.await?; let build_item = cx.update(|cx| { @@ -1490,7 +1489,7 @@ impl Workspace { .cloned() })?; let build_item = - move |cx: &mut MutableAppContext| build_item(window_id, project, project_item, cx); + move |cx: &mut ViewContext| build_item(project, project_item, cx); Ok((project_entry_id, build_item)) }) } @@ -2732,7 +2731,7 @@ fn open_new(app_state: &Arc, cx: &mut MutableAppContext) { (app_state.initialize_workspace)(&mut workspace, app_state, cx); workspace }); - cx.dispatch_action(window_id, vec![workspace.id()], &NewFile); + cx.dispatch_action_at(window_id, workspace.id(), NewFile); } #[cfg(test)] @@ -2751,10 +2750,10 @@ mod tests { let fs = FakeFs::new(cx.background()); let project = Project::test(fs, [], cx).await; - let (window_id, workspace) = cx.add_window(|cx| Workspace::new(project.clone(), cx)); + let (_, workspace) = cx.add_window(|cx| Workspace::new(project.clone(), cx)); // Adding an item with no ambiguity renders the tab without detail. - let item1 = cx.add_view(window_id, |_| { + let item1 = cx.add_view(&workspace, |_| { let mut item = TestItem::new(); item.tab_descriptions = Some(vec!["c", "b1/c", "a/b1/c"]); item @@ -2766,7 +2765,7 @@ mod tests { // Adding an item that creates ambiguity increases the level of detail on // both tabs. - let item2 = cx.add_view(window_id, |_| { + let item2 = cx.add_view(&workspace, |_| { let mut item = TestItem::new(); item.tab_descriptions = Some(vec!["c", "b2/c", "a/b2/c"]); item @@ -2780,7 +2779,7 @@ mod tests { // Adding an item that creates ambiguity increases the level of detail only // on the ambiguous tabs. In this case, the ambiguity can't be resolved so // we stop at the highest detail available. - let item3 = cx.add_view(window_id, |_| { + let item3 = cx.add_view(&workspace, |_| { let mut item = TestItem::new(); item.tab_descriptions = Some(vec!["c", "b2/c", "a/b2/c"]); item @@ -2820,12 +2819,12 @@ mod tests { project.worktrees(cx).next().unwrap().read(cx).id() }); - let item1 = cx.add_view(window_id, |_| { + let item1 = cx.add_view(&workspace, |_| { let mut item = TestItem::new(); item.project_path = Some((worktree_id, "one.txt").into()); item }); - let item2 = cx.add_view(window_id, |_| { + let item2 = cx.add_view(&workspace, |_| { let mut item = TestItem::new(); item.project_path = Some((worktree_id, "two.txt").into()); item @@ -2914,19 +2913,19 @@ mod tests { let (window_id, workspace) = cx.add_window(|cx| Workspace::new(project.clone(), cx)); // When there are no dirty items, there's nothing to do. - let item1 = cx.add_view(window_id, |_| TestItem::new()); + let item1 = cx.add_view(&workspace, |_| TestItem::new()); workspace.update(cx, |w, cx| w.add_item(Box::new(item1.clone()), cx)); let task = workspace.update(cx, |w, cx| w.prepare_to_close(cx)); assert_eq!(task.await.unwrap(), true); // When there are dirty untitled items, prompt to save each one. If the user // cancels any prompt, then abort. - let item2 = cx.add_view(window_id, |_| { + let item2 = cx.add_view(&workspace, |_| { let mut item = TestItem::new(); item.is_dirty = true; item }); - let item3 = cx.add_view(window_id, |_| { + let item3 = cx.add_view(&workspace, |_| { let mut item = TestItem::new(); item.is_dirty = true; item.project_entry_ids = vec![ProjectEntryId::from_proto(1)]; @@ -2953,27 +2952,27 @@ mod tests { let project = Project::test(fs, None, cx).await; let (window_id, workspace) = cx.add_window(|cx| Workspace::new(project, cx)); - let item1 = cx.add_view(window_id, |_| { + let item1 = cx.add_view(&workspace, |_| { let mut item = TestItem::new(); item.is_dirty = true; item.project_entry_ids = vec![ProjectEntryId::from_proto(1)]; item }); - let item2 = cx.add_view(window_id, |_| { + let item2 = cx.add_view(&workspace, |_| { let mut item = TestItem::new(); item.is_dirty = true; item.has_conflict = true; item.project_entry_ids = vec![ProjectEntryId::from_proto(2)]; item }); - let item3 = cx.add_view(window_id, |_| { + let item3 = cx.add_view(&workspace, |_| { let mut item = TestItem::new(); item.is_dirty = true; item.has_conflict = true; item.project_entry_ids = vec![ProjectEntryId::from_proto(3)]; item }); - let item4 = cx.add_view(window_id, |_| { + let item4 = cx.add_view(&workspace, |_| { let mut item = TestItem::new(); item.is_dirty = true; item @@ -3144,7 +3143,7 @@ mod tests { let project = Project::test(fs, [], cx).await; let (window_id, workspace) = cx.add_window(|cx| Workspace::new(project, cx)); - let item = cx.add_view(window_id, |_| { + let item = cx.add_view(&workspace, |_| { let mut item = TestItem::new(); item.project_entry_ids = vec![ProjectEntryId::from_proto(1)]; item @@ -3259,9 +3258,9 @@ mod tests { let fs = FakeFs::new(cx.background()); let project = Project::test(fs, [], cx).await; - let (window_id, workspace) = cx.add_window(|cx| Workspace::new(project, cx)); + let (_, workspace) = cx.add_window(|cx| Workspace::new(project, cx)); - let item = cx.add_view(window_id, |_| { + let item = cx.add_view(&workspace, |_| { let mut item = TestItem::new(); item.project_entry_ids = vec![ProjectEntryId::from_proto(1)]; item From 6442ec59e71f44fb44920e6d1dec326338e9279b Mon Sep 17 00:00:00 2001 From: K Simmons Date: Fri, 5 Aug 2022 12:38:05 -0700 Subject: [PATCH 11/27] Switch action dispatch to use MutableAppContext parent utilities and delete parent map from presenter --- crates/gpui/src/app.rs | 101 +++++++++++++++-------------- crates/gpui/src/presenter.rs | 41 +++++++++++- crates/workspace/src/pane.rs | 1 + crates/workspace/src/sidebar.rs | 1 + crates/workspace/src/status_bar.rs | 2 + crates/workspace/src/workspace.rs | 6 ++ 6 files changed, 100 insertions(+), 52 deletions(-) diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index a1b782039a618d2bf756d8dd66c42eaea5fefc2a..ac9ef6f82914d0d1c8916f7f97afa4df39e7ed9b 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -230,7 +230,7 @@ impl App { let mut cx = cx.borrow_mut(); if let Some(key_window_id) = cx.cx.platform.key_window_id() { if let Some(view_id) = cx.focused_view_id(key_window_id) { - cx.handle_dispatch_action_any_effect(key_window_id, Some(view_id), action); + cx.handle_dispatch_action_from_effect(key_window_id, Some(view_id), action); return; } } @@ -457,7 +457,7 @@ impl TestAppContext { pub fn dispatch_action(&self, window_id: usize, action: A) { let mut cx = self.cx.borrow_mut(); if let Some(view_id) = cx.focused_view_id(window_id) { - cx.handle_dispatch_action_any_effect(window_id, Some(view_id), &action); + cx.handle_dispatch_action_from_effect(window_id, Some(view_id), &action); } } @@ -477,6 +477,7 @@ impl TestAppContext { if cx.dispatch_keystroke(window_id, &keystroke) { return true; } + if presenter.borrow_mut().dispatch_event( Event::KeyDown(KeyDownEvent { keystroke: keystroke.clone(), @@ -1606,6 +1607,12 @@ impl MutableAppContext { } } + pub(crate) fn name_for_view(&self, window_id: usize, view_id: usize) -> Option<&str> { + self.views + .get(&(window_id, view_id)) + .map(|view| view.ui_name()) + } + pub fn all_action_names<'a>(&'a self) -> impl Iterator + 'a { self.action_deserializers.keys().copied() } @@ -1685,29 +1692,6 @@ impl MutableAppContext { None } - // pub fn dispatch_action_at(&mut self, window_id: usize, view_id: usize, action: &dyn Action) { - // let presenter = self - // .presenters_and_platform_windows - // .get(&window_id) - // .unwrap() - // .0 - // .clone(); - // let mut dispatch_path = Vec::new(); - // presenter - // .borrow() - // .compute_dispatch_path_from(view_id, &mut dispatch_path); - // self.dispatch_action_any(window_id, &dispatch_path, action); - // } - - // pub fn dispatch_action( - // &mut self, - // window_id: usize, - // dispatch_path: Vec, - // action: &A, - // ) { - // self.dispatch_action_any(window_id, &dispatch_path, action); - // } - // Traverses the parent tree. Walks down the tree toward the passed // view calling visit with true. Then walks back up the tree calling visit with false. // If `visit` returns false this function will immediately return. @@ -1719,12 +1703,7 @@ impl MutableAppContext { mut visit: impl FnMut(usize, bool, &mut MutableAppContext) -> bool, ) -> bool { // List of view ids from the leaf to the root of the window - let mut path = vec![view_id]; - let mut current_view = view_id; - while let Some(ParentId::View(parent_id)) = self.parents.get(&(window_id, current_view)) { - current_view = *parent_id; - path.push(current_view); - } + let path = self.parents(window_id, view_id).collect::>(); // Walk down from the root to the leaf calling visit with capture_phase = true for view_id in path.iter().rev() { @@ -1746,15 +1725,18 @@ impl MutableAppContext { // Returns an iterator over all of the view ids from the passed view up to the root of the window // Includes the passed view itself fn parents(&self, window_id: usize, mut view_id: usize) -> impl Iterator + '_ { - std::iter::from_fn(move || { - if let Some(ParentId::View(parent_id)) = self.parents.get(&(window_id, view_id)) { - view_id = *parent_id; - Some(view_id) - } else { - None - } - }) + std::iter::once(view_id) + .into_iter() + .chain(std::iter::from_fn(move || { + if let Some(ParentId::View(parent_id)) = self.parents.get(&(window_id, view_id)) { + view_id = *parent_id; + Some(view_id) + } else { + None + } + })) } + fn actions_mut( &mut self, capture_phase: bool, @@ -1793,8 +1775,8 @@ impl MutableAppContext { pub fn dispatch_keystroke(&mut self, window_id: usize, keystroke: &Keystroke) -> bool { let mut pending = false; - if let Some(view_id) = self.focused_view_id(window_id) { - for view_id in self.parents(window_id, view_id).collect::>() { + if let Some(focused_view_id) = self.focused_view_id(window_id) { + for view_id in self.parents(window_id, focused_view_id).collect::>() { let keymap_context = self .cx .views @@ -1810,7 +1792,7 @@ impl MutableAppContext { MatchResult::None => {} MatchResult::Pending => pending = true, MatchResult::Action(action) => { - if self.handle_dispatch_action_any_effect( + if self.handle_dispatch_action_from_effect( window_id, Some(view_id), action.as_ref(), @@ -2303,7 +2285,7 @@ impl MutableAppContext { view_id, action, } => { - self.handle_dispatch_action_any_effect( + self.handle_dispatch_action_from_effect( window_id, Some(view_id), action.as_ref(), @@ -2579,7 +2561,7 @@ impl MutableAppContext { }) } - fn handle_dispatch_action_any_effect( + fn handle_dispatch_action_from_effect( &mut self, window_id: usize, view_id: Option, @@ -2587,6 +2569,7 @@ impl MutableAppContext { ) -> bool { self.update(|this| { if let Some(view_id) = view_id { + this.halt_action_dispatch = false; this.visit_dispatch_path(window_id, view_id, |view_id, capture_phase, this| { if let Some(mut view) = this.cx.views.remove(&(window_id, view_id)) { let type_id = view.as_any().type_id(); @@ -2809,6 +2792,7 @@ impl Deref for MutableAppContext { } } +#[derive(Debug)] pub enum ParentId { View(usize), Root, @@ -2817,7 +2801,7 @@ pub enum ParentId { pub struct AppContext { models: HashMap>, views: HashMap<(usize, usize), Box>, - parents: HashMap<(usize, usize), ParentId>, + pub(crate) parents: HashMap<(usize, usize), ParentId>, windows: HashMap, globals: HashMap>, element_states: HashMap>, @@ -3733,6 +3717,21 @@ impl<'a, T: View> ViewContext<'a, T> { .build_and_insert_view(self.window_id, ParentId::View(self.view_id), build_view) } + pub fn reparent(&mut self, view_handle: impl Into) { + let view_handle = view_handle.into(); + if self.window_id != view_handle.window_id { + panic!("Can't reparent view to a view from a different window"); + } + self.cx + .parents + .remove(&(view_handle.window_id, view_handle.view_id)); + let new_parent_id = self.view_id; + self.cx.parents.insert( + (view_handle.window_id, view_handle.view_id), + ParentId::View(new_parent_id), + ); + } + pub fn replace_root_view(&mut self, build_root_view: F) -> ViewHandle where V: View, @@ -6914,7 +6913,7 @@ mod tests { let view_3 = cx.add_view(&view_2, |_| ViewA { id: 3 }); let view_4 = cx.add_view(&view_3, |_| ViewB { id: 4 }); - cx.handle_dispatch_action_any_effect( + cx.handle_dispatch_action_from_effect( window_id, Some(view_4.id()), &Action("bar".to_string()), @@ -6938,12 +6937,12 @@ mod tests { // Remove view_1, which doesn't propagate the action - let (window_id, view_2) = cx.add_window(Default::default(), |_| ViewA { id: 1 }); + let (window_id, view_2) = cx.add_window(Default::default(), |_| ViewB { id: 2 }); let view_3 = cx.add_view(&view_2, |_| ViewA { id: 3 }); let view_4 = cx.add_view(&view_3, |_| ViewB { id: 4 }); actions.borrow_mut().clear(); - cx.handle_dispatch_action_any_effect( + cx.handle_dispatch_action_from_effect( window_id, Some(view_4.id()), &Action("bar".to_string()), @@ -7019,8 +7018,10 @@ mod tests { let (window_id, view_1) = cx.add_window(Default::default(), |_| view_1); let view_2 = cx.add_view(&view_1, |_| view_2); - let view_3 = cx.add_view(&view_2, |_| view_3); - cx.focus(window_id, Some(view_3.id())); + let view_3 = cx.add_view(&view_2, |cx| { + cx.focus_self(); + view_3 + }); // This keymap's only binding dispatches an action on view 2 because that view will have // "a" and "b" in its context, but not "c". diff --git a/crates/gpui/src/presenter.rs b/crates/gpui/src/presenter.rs index 57d3a1a3fda11addf7d4f9aff392a29cbc53af70..9cba57810b49992da9ea1610a0949fce2c65ad48 100644 --- a/crates/gpui/src/presenter.rs +++ b/crates/gpui/src/presenter.rs @@ -10,8 +10,8 @@ use crate::{ text_layout::TextLayoutCache, Action, AnyModelHandle, AnyViewHandle, AnyWeakModelHandle, AssetCache, ElementBox, Entity, FontSystem, ModelHandle, MouseButtonEvent, MouseMovedEvent, MouseRegion, MouseRegionId, - ReadModel, ReadView, RenderContext, RenderParams, Scene, UpgradeModelHandle, UpgradeViewHandle, - View, ViewHandle, WeakModelHandle, WeakViewHandle, + ParentId, ReadModel, ReadView, RenderContext, RenderParams, Scene, UpgradeModelHandle, + UpgradeViewHandle, View, ViewHandle, WeakModelHandle, WeakViewHandle, }; use collections::{HashMap, HashSet}; use pathfinder_geometry::vector::{vec2f, Vector2F}; @@ -482,6 +482,43 @@ impl<'a> LayoutContext<'a> { } fn layout(&mut self, view_id: usize, constraint: SizeConstraint) -> Vector2F { + let print_error = |view_id| { + format!( + "{} with id {}", + self.app.name_for_view(self.window_id, view_id).unwrap(), + view_id, + ) + }; + match ( + self.view_stack.last(), + self.app.parents.get(&(self.window_id, view_id)), + ) { + (Some(layout_parent), Some(ParentId::View(app_parent))) => { + if layout_parent != app_parent { + panic!( + "View {} was laid out with parent {} when it was constructed with parent {}", + print_error(view_id), + print_error(*layout_parent), + print_error(*app_parent)) + } + } + (None, Some(ParentId::View(app_parent))) => panic!( + "View {} was laid out without a parent when it was constructed with parent {}", + print_error(view_id), + print_error(*app_parent) + ), + (Some(layout_parent), Some(ParentId::Root)) => panic!( + "View {} was laid out with parent {} when it was constructed as a window root", + print_error(view_id), + print_error(*layout_parent), + ), + (_, None) => panic!( + "View {} did not have a registered parent in the app context", + print_error(view_id), + ), + _ => {} + } + self.view_stack.push(view_id); let mut rendered_view = self.rendered_views.remove(&view_id).unwrap(); let size = rendered_view.layout(constraint, self); diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index 354331974ff370784cceee5d888b23f113755800..572e1032b3ae1a084412c0c619c2baa0bd393c66 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -441,6 +441,7 @@ impl Pane { pane.active_item_index = usize::MAX; }; + cx.reparent(&item); pane.items.insert(item_ix, item); pane.activate_item(item_ix, activate_pane, focus_item, false, cx); cx.notify(); diff --git a/crates/workspace/src/sidebar.rs b/crates/workspace/src/sidebar.rs index 542cd51cb6f9eefa84eabf403ca7e8d6dc46940b..b7ed8140c9fbabef93338e683ac939e103626a3c 100644 --- a/crates/workspace/src/sidebar.rs +++ b/crates/workspace/src/sidebar.rs @@ -140,6 +140,7 @@ impl Sidebar { } }), ]; + cx.reparent(&view); self.items.push(Item { icon_path, tooltip, diff --git a/crates/workspace/src/status_bar.rs b/crates/workspace/src/status_bar.rs index f84940e8fb65ee51e5400906e720cfdd67b2bd5e..ca44cf7c27cacddacd36ef0d359cc122649956ac 100644 --- a/crates/workspace/src/status_bar.rs +++ b/crates/workspace/src/status_bar.rs @@ -81,6 +81,7 @@ impl StatusBar { where T: 'static + StatusItemView, { + cx.reparent(&item); self.left_items.push(Box::new(item)); cx.notify(); } @@ -89,6 +90,7 @@ impl StatusBar { where T: 'static + StatusItemView, { + cx.reparent(&item); self.right_items.push(Box::new(item)); cx.notify(); } diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index d1a239cbb4242bc9f97ac59b7c79529c6a7ebab9..02ad18eb3d954d3cd0bf858892f7b78a34c30a54 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -708,6 +708,12 @@ impl Into for Box { } } +impl Into for &Box { + fn into(self) -> AnyViewHandle { + self.to_any() + } +} + impl Clone for Box { fn clone(&self) -> Box { self.boxed_clone() From 690ea57211bc29584eafd86a3262c493e244a55f Mon Sep 17 00:00:00 2001 From: K Simmons Date: Sun, 7 Aug 2022 19:23:22 -0700 Subject: [PATCH 12/27] WIP compiling but failing with circular reference --- crates/chat_panel/src/chat_panel.rs | 6 +- crates/command_palette/src/command_palette.rs | 5 +- crates/contacts_panel/src/contact_finder.rs | 6 +- crates/contacts_panel/src/contacts_panel.rs | 8 +- crates/context_menu/src/context_menu.rs | 4 +- crates/diagnostics/src/diagnostics.rs | 2 +- crates/editor/src/editor.rs | 8 +- crates/file_finder/src/file_finder.rs | 6 +- crates/go_to_line/src/go_to_line.rs | 6 +- .../grammars/context-predicate/src/parser.c | 909 ++++++++++-------- crates/gpui/src/app.rs | 149 ++- crates/outline/src/outline.rs | 6 +- crates/picker/src/picker.rs | 6 +- crates/project_symbols/src/project_symbols.rs | 6 +- crates/search/src/buffer_search.rs | 6 +- crates/search/src/project_search.rs | 8 +- crates/terminal/src/connected_view.rs | 5 +- crates/terminal/src/terminal.rs | 7 + crates/theme_selector/src/theme_selector.rs | 6 +- crates/workspace/src/pane.rs | 15 +- crates/workspace/src/workspace.rs | 2 +- styles/package-lock.json | 1 + 22 files changed, 663 insertions(+), 514 deletions(-) diff --git a/crates/chat_panel/src/chat_panel.rs b/crates/chat_panel/src/chat_panel.rs index fa913971df2921227f3d77d6b294791782d48e72..7f947fef160de57ac47889e3618b825cc739cdb4 100644 --- a/crates/chat_panel/src/chat_panel.rs +++ b/crates/chat_panel/src/chat_panel.rs @@ -8,8 +8,8 @@ use gpui::{ elements::*, platform::CursorStyle, views::{ItemType, Select, SelectStyle}, - AppContext, Entity, ModelHandle, MouseButton, MutableAppContext, RenderContext, Subscription, - Task, View, ViewContext, ViewHandle, + AnyViewHandle, AppContext, Entity, ModelHandle, MouseButton, MutableAppContext, RenderContext, + Subscription, Task, View, ViewContext, ViewHandle, }; use menu::Confirm; use postage::prelude::Stream; @@ -397,7 +397,7 @@ impl View for ChatPanel { .boxed() } - fn on_focus(&mut self, cx: &mut ViewContext) { + fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext) { if matches!( *self.rpc.status().borrow(), client::Status::Connected { .. } diff --git a/crates/command_palette/src/command_palette.rs b/crates/command_palette/src/command_palette.rs index 5f213284e8f10779eb903df2d850c5a49af39b10..5d6f6e14a8a0b85754234a4a8479ca66ff48bd2e 100644 --- a/crates/command_palette/src/command_palette.rs +++ b/crates/command_palette/src/command_palette.rs @@ -4,7 +4,8 @@ use gpui::{ actions, elements::{ChildView, Flex, Label, ParentElement}, keymap::Keystroke, - Action, Element, Entity, MouseState, MutableAppContext, View, ViewContext, ViewHandle, + Action, AnyViewHandle, Element, Entity, MouseState, MutableAppContext, View, ViewContext, + ViewHandle, }; use picker::{Picker, PickerDelegate}; use settings::Settings; @@ -132,7 +133,7 @@ impl View for CommandPalette { ChildView::new(self.picker.clone()).boxed() } - fn on_focus(&mut self, cx: &mut ViewContext) { + fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext) { cx.focus(&self.picker); } } diff --git a/crates/contacts_panel/src/contact_finder.rs b/crates/contacts_panel/src/contact_finder.rs index 40271609509d44dad75e232b6124dd849c651add..978466dfcb2d01cf4cd4029e2014a89aaa8006d1 100644 --- a/crates/contacts_panel/src/contact_finder.rs +++ b/crates/contacts_panel/src/contact_finder.rs @@ -1,7 +1,7 @@ use client::{ContactRequestStatus, User, UserStore}; use gpui::{ - actions, elements::*, Entity, ModelHandle, MouseState, MutableAppContext, RenderContext, Task, - View, ViewContext, ViewHandle, + actions, elements::*, AnyViewHandle, Entity, ModelHandle, MouseState, MutableAppContext, + RenderContext, Task, View, ViewContext, ViewHandle, }; use picker::{Picker, PickerDelegate}; use settings::Settings; @@ -42,7 +42,7 @@ impl View for ContactFinder { ChildView::new(self.picker.clone()).boxed() } - fn on_focus(&mut self, cx: &mut ViewContext) { + fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext) { cx.focus(&self.picker); } } diff --git a/crates/contacts_panel/src/contacts_panel.rs b/crates/contacts_panel/src/contacts_panel.rs index 4aff5b1a74fe61d2522b456e0d80fc13b726cd87..9bc7972b2983568ff672e8bce6ecbe0c76584fbd 100644 --- a/crates/contacts_panel/src/contacts_panel.rs +++ b/crates/contacts_panel/src/contacts_panel.rs @@ -13,9 +13,9 @@ use gpui::{ geometry::{rect::RectF, vector::vec2f}, impl_actions, impl_internal_actions, platform::CursorStyle, - AppContext, ClipboardItem, Element, ElementBox, Entity, ModelHandle, MouseButton, - MutableAppContext, RenderContext, Subscription, View, ViewContext, ViewHandle, WeakModelHandle, - WeakViewHandle, + AnyViewHandle, AppContext, ClipboardItem, Element, ElementBox, Entity, ModelHandle, + MouseButton, MutableAppContext, RenderContext, Subscription, View, ViewContext, ViewHandle, + WeakModelHandle, WeakViewHandle, }; use join_project_notification::JoinProjectNotification; use menu::{Confirm, SelectNext, SelectPrev}; @@ -1152,7 +1152,7 @@ impl View for ContactsPanel { .boxed() } - fn on_focus(&mut self, cx: &mut ViewContext) { + fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext) { cx.focus(&self.filter_editor); } diff --git a/crates/context_menu/src/context_menu.rs b/crates/context_menu/src/context_menu.rs index b17718577ffc39908f0b29cd0041eb866d73f53a..e301e62467ebfb8d900e284ce564680b5b050c87 100644 --- a/crates/context_menu/src/context_menu.rs +++ b/crates/context_menu/src/context_menu.rs @@ -1,6 +1,6 @@ use gpui::{ elements::*, geometry::vector::Vector2F, impl_internal_actions, keymap, platform::CursorStyle, - Action, AppContext, Axis, Entity, MouseButton, MutableAppContext, RenderContext, + Action, AnyViewHandle, AppContext, Axis, Entity, MouseButton, MutableAppContext, RenderContext, SizeConstraint, Subscription, View, ViewContext, }; use menu::*; @@ -106,7 +106,7 @@ impl View for ContextMenu { .boxed() } - fn on_blur(&mut self, cx: &mut ViewContext) { + fn on_focus_out(&mut self, _: AnyViewHandle, cx: &mut ViewContext) { self.reset(cx); } } diff --git a/crates/diagnostics/src/diagnostics.rs b/crates/diagnostics/src/diagnostics.rs index e9692c5493641944274aaa3bca46feab551e67b7..42a3bb9f133ca38cb691ddc6dca41822d048425d 100644 --- a/crates/diagnostics/src/diagnostics.rs +++ b/crates/diagnostics/src/diagnostics.rs @@ -99,7 +99,7 @@ impl View for ProjectDiagnosticsEditor { } } - fn on_focus(&mut self, cx: &mut ViewContext) { + fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext) { if !self.path_states.is_empty() { cx.focus(&self.editor); } diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index e4ff272440ab114a61333cd2a658f48c9d571517..6e84b275aaa050fdfe36c42c621ad67a7e93aa4a 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -29,8 +29,8 @@ use gpui::{ geometry::vector::{vec2f, Vector2F}, impl_actions, impl_internal_actions, platform::CursorStyle, - text_layout, AppContext, AsyncAppContext, ClipboardItem, Element, ElementBox, Entity, - ModelHandle, MouseButton, MutableAppContext, RenderContext, Subscription, Task, View, + text_layout, AnyViewHandle, AppContext, AsyncAppContext, ClipboardItem, Element, ElementBox, + Entity, ModelHandle, MouseButton, MutableAppContext, RenderContext, Subscription, Task, View, ViewContext, ViewHandle, WeakViewHandle, }; use highlight_matching_bracket::refresh_matching_bracket_highlights; @@ -6025,7 +6025,7 @@ impl View for Editor { "Editor" } - fn on_focus(&mut self, cx: &mut ViewContext) { + fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext) { let focused_event = EditorFocused(cx.handle()); cx.emit_global(focused_event); if let Some(rename) = self.pending_rename.as_ref() { @@ -6046,7 +6046,7 @@ impl View for Editor { } } - fn on_blur(&mut self, cx: &mut ViewContext) { + fn on_focus_out(&mut self, _: AnyViewHandle, cx: &mut ViewContext) { let blurred_event = EditorBlurred(cx.handle()); cx.emit_global(blurred_event); self.focused = false; diff --git a/crates/file_finder/src/file_finder.rs b/crates/file_finder/src/file_finder.rs index d69c95605dcf885006c3d3825cc1b475c4c1c539..aeec79901563c2449ddb90c15b944ab0bfae36b6 100644 --- a/crates/file_finder/src/file_finder.rs +++ b/crates/file_finder/src/file_finder.rs @@ -1,7 +1,7 @@ use fuzzy::PathMatch; use gpui::{ - actions, elements::*, AppContext, Entity, ModelHandle, MouseState, MutableAppContext, - RenderContext, Task, View, ViewContext, ViewHandle, + actions, elements::*, AnyViewHandle, AppContext, Entity, ModelHandle, MouseState, + MutableAppContext, RenderContext, Task, View, ViewContext, ViewHandle, }; use picker::{Picker, PickerDelegate}; use project::{PathMatchCandidateSet, Project, ProjectPath, WorktreeId}; @@ -53,7 +53,7 @@ impl View for FileFinder { ChildView::new(self.picker.clone()).boxed() } - fn on_focus(&mut self, cx: &mut ViewContext) { + fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext) { cx.focus(&self.picker); } } diff --git a/crates/go_to_line/src/go_to_line.rs b/crates/go_to_line/src/go_to_line.rs index f2df235a7bd0b2ded5e6ad928c9f910ae582223d..3ca50cee42584aaa0d73dc853c51d0cfaec6badd 100644 --- a/crates/go_to_line/src/go_to_line.rs +++ b/crates/go_to_line/src/go_to_line.rs @@ -1,7 +1,7 @@ use editor::{display_map::ToDisplayPoint, Autoscroll, DisplayPoint, Editor}; use gpui::{ - actions, elements::*, geometry::vector::Vector2F, Axis, Entity, MutableAppContext, - RenderContext, View, ViewContext, ViewHandle, + actions, elements::*, geometry::vector::Vector2F, AnyViewHandle, Axis, Entity, + MutableAppContext, RenderContext, View, ViewContext, ViewHandle, }; use menu::{Cancel, Confirm}; use settings::Settings; @@ -183,7 +183,7 @@ impl View for GoToLine { .named("go to line") } - fn on_focus(&mut self, cx: &mut ViewContext) { + fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext) { cx.focus(&self.line_editor); } } diff --git a/crates/gpui/grammars/context-predicate/src/parser.c b/crates/gpui/grammars/context-predicate/src/parser.c index e2af5e03caa032537a74a10e68de4536efdd8e59..57a7364a43df051cc26975720751d54d37c1ffcb 100644 --- a/crates/gpui/grammars/context-predicate/src/parser.c +++ b/crates/gpui/grammars/context-predicate/src/parser.c @@ -35,115 +35,132 @@ enum { sym_parenthesized = 16, }; -static const char * const ts_symbol_names[] = { - [ts_builtin_sym_end] = "end", - [sym_identifier] = "identifier", - [anon_sym_BANG] = "!", - [anon_sym_AMP_AMP] = "&&", - [anon_sym_PIPE_PIPE] = "||", - [anon_sym_EQ_EQ] = "==", - [anon_sym_BANG_EQ] = "!=", - [anon_sym_LPAREN] = "(", - [anon_sym_RPAREN] = ")", - [sym_source] = "source", - [sym__expression] = "_expression", - [sym_not] = "not", - [sym_and] = "and", - [sym_or] = "or", - [sym_equal] = "equal", - [sym_not_equal] = "not_equal", - [sym_parenthesized] = "parenthesized", +static const char *const ts_symbol_names[] = { + [ts_builtin_sym_end] = "end", + [sym_identifier] = "identifier", + [anon_sym_BANG] = "!", + [anon_sym_AMP_AMP] = "&&", + [anon_sym_PIPE_PIPE] = "||", + [anon_sym_EQ_EQ] = "==", + [anon_sym_BANG_EQ] = "!=", + [anon_sym_LPAREN] = "(", + [anon_sym_RPAREN] = ")", + [sym_source] = "source", + [sym__expression] = "_expression", + [sym_not] = "not", + [sym_and] = "and", + [sym_or] = "or", + [sym_equal] = "equal", + [sym_not_equal] = "not_equal", + [sym_parenthesized] = "parenthesized", }; static const TSSymbol ts_symbol_map[] = { - [ts_builtin_sym_end] = ts_builtin_sym_end, - [sym_identifier] = sym_identifier, - [anon_sym_BANG] = anon_sym_BANG, - [anon_sym_AMP_AMP] = anon_sym_AMP_AMP, - [anon_sym_PIPE_PIPE] = anon_sym_PIPE_PIPE, - [anon_sym_EQ_EQ] = anon_sym_EQ_EQ, - [anon_sym_BANG_EQ] = anon_sym_BANG_EQ, - [anon_sym_LPAREN] = anon_sym_LPAREN, - [anon_sym_RPAREN] = anon_sym_RPAREN, - [sym_source] = sym_source, - [sym__expression] = sym__expression, - [sym_not] = sym_not, - [sym_and] = sym_and, - [sym_or] = sym_or, - [sym_equal] = sym_equal, - [sym_not_equal] = sym_not_equal, - [sym_parenthesized] = sym_parenthesized, + [ts_builtin_sym_end] = ts_builtin_sym_end, + [sym_identifier] = sym_identifier, + [anon_sym_BANG] = anon_sym_BANG, + [anon_sym_AMP_AMP] = anon_sym_AMP_AMP, + [anon_sym_PIPE_PIPE] = anon_sym_PIPE_PIPE, + [anon_sym_EQ_EQ] = anon_sym_EQ_EQ, + [anon_sym_BANG_EQ] = anon_sym_BANG_EQ, + [anon_sym_LPAREN] = anon_sym_LPAREN, + [anon_sym_RPAREN] = anon_sym_RPAREN, + [sym_source] = sym_source, + [sym__expression] = sym__expression, + [sym_not] = sym_not, + [sym_and] = sym_and, + [sym_or] = sym_or, + [sym_equal] = sym_equal, + [sym_not_equal] = sym_not_equal, + [sym_parenthesized] = sym_parenthesized, }; static const TSSymbolMetadata ts_symbol_metadata[] = { - [ts_builtin_sym_end] = { - .visible = false, - .named = true, - }, - [sym_identifier] = { - .visible = true, - .named = true, - }, - [anon_sym_BANG] = { - .visible = true, - .named = false, - }, - [anon_sym_AMP_AMP] = { - .visible = true, - .named = false, - }, - [anon_sym_PIPE_PIPE] = { - .visible = true, - .named = false, - }, - [anon_sym_EQ_EQ] = { - .visible = true, - .named = false, - }, - [anon_sym_BANG_EQ] = { - .visible = true, - .named = false, - }, - [anon_sym_LPAREN] = { - .visible = true, - .named = false, - }, - [anon_sym_RPAREN] = { - .visible = true, - .named = false, - }, - [sym_source] = { - .visible = true, - .named = true, - }, - [sym__expression] = { - .visible = false, - .named = true, - }, - [sym_not] = { - .visible = true, - .named = true, - }, - [sym_and] = { - .visible = true, - .named = true, - }, - [sym_or] = { - .visible = true, - .named = true, - }, - [sym_equal] = { - .visible = true, - .named = true, - }, - [sym_not_equal] = { - .visible = true, - .named = true, - }, - [sym_parenthesized] = { - .visible = true, - .named = true, - }, + [ts_builtin_sym_end] = + { + .visible = false, + .named = true, + }, + [sym_identifier] = + { + .visible = true, + .named = true, + }, + [anon_sym_BANG] = + { + .visible = true, + .named = false, + }, + [anon_sym_AMP_AMP] = + { + .visible = true, + .named = false, + }, + [anon_sym_PIPE_PIPE] = + { + .visible = true, + .named = false, + }, + [anon_sym_EQ_EQ] = + { + .visible = true, + .named = false, + }, + [anon_sym_BANG_EQ] = + { + .visible = true, + .named = false, + }, + [anon_sym_LPAREN] = + { + .visible = true, + .named = false, + }, + [anon_sym_RPAREN] = + { + .visible = true, + .named = false, + }, + [sym_source] = + { + .visible = true, + .named = true, + }, + [sym__expression] = + { + .visible = false, + .named = true, + }, + [sym_not] = + { + .visible = true, + .named = true, + }, + [sym_and] = + { + .visible = true, + .named = true, + }, + [sym_or] = + { + .visible = true, + .named = true, + }, + [sym_equal] = + { + .visible = true, + .named = true, + }, + [sym_not_equal] = + { + .visible = true, + .named = true, + }, + [sym_parenthesized] = + { + .visible = true, + .named = true, + }, }; enum { @@ -152,340 +169,378 @@ enum { field_right = 3, }; -static const char * const ts_field_names[] = { - [0] = NULL, - [field_expression] = "expression", - [field_left] = "left", - [field_right] = "right", +static const char *const ts_field_names[] = { + [0] = NULL, + [field_expression] = "expression", + [field_left] = "left", + [field_right] = "right", }; static const TSFieldMapSlice ts_field_map_slices[PRODUCTION_ID_COUNT] = { - [1] = {.index = 0, .length = 1}, - [2] = {.index = 1, .length = 2}, + [1] = {.index = 0, .length = 1}, + [2] = {.index = 1, .length = 2}, }; static const TSFieldMapEntry ts_field_map_entries[] = { - [0] = - {field_expression, 1}, - [1] = - {field_left, 0}, + [0] = {field_expression, 1}, + [1] = {field_left, 0}, {field_right, 2}, }; -static const TSSymbol ts_alias_sequences[PRODUCTION_ID_COUNT][MAX_ALIAS_SEQUENCE_LENGTH] = { - [0] = {0}, +static const TSSymbol ts_alias_sequences[PRODUCTION_ID_COUNT] + [MAX_ALIAS_SEQUENCE_LENGTH] = { + [0] = {0}, }; static const uint16_t ts_non_terminal_alias_map[] = { - 0, + 0, }; static bool ts_lex(TSLexer *lexer, TSStateId state) { START_LEXER(); eof = lexer->eof(lexer); switch (state) { - case 0: - if (eof) ADVANCE(7); - if (lookahead == '!') ADVANCE(10); - if (lookahead == '&') ADVANCE(2); - if (lookahead == '(') ADVANCE(15); - if (lookahead == ')') ADVANCE(16); - if (lookahead == '=') ADVANCE(4); - if (lookahead == '|') ADVANCE(5); - if (lookahead == '\t' || - lookahead == '\n' || - lookahead == '\r' || - lookahead == ' ') SKIP(0) - if (lookahead == '-' || - ('0' <= lookahead && lookahead <= '9') || - ('A' <= lookahead && lookahead <= 'Z') || - lookahead == '_' || - ('a' <= lookahead && lookahead <= 'z')) ADVANCE(8); - END_STATE(); - case 1: - if (lookahead == '!') ADVANCE(9); - if (lookahead == '(') ADVANCE(15); - if (lookahead == '\t' || - lookahead == '\n' || - lookahead == '\r' || - lookahead == ' ') SKIP(1) - if (lookahead == '-' || - ('0' <= lookahead && lookahead <= '9') || - ('A' <= lookahead && lookahead <= 'Z') || - lookahead == '_' || - ('a' <= lookahead && lookahead <= 'z')) ADVANCE(8); - END_STATE(); - case 2: - if (lookahead == '&') ADVANCE(11); - END_STATE(); - case 3: - if (lookahead == '=') ADVANCE(14); - END_STATE(); - case 4: - if (lookahead == '=') ADVANCE(13); - END_STATE(); - case 5: - if (lookahead == '|') ADVANCE(12); - END_STATE(); - case 6: - if (eof) ADVANCE(7); - if (lookahead == '!') ADVANCE(3); - if (lookahead == '&') ADVANCE(2); - if (lookahead == ')') ADVANCE(16); - if (lookahead == '=') ADVANCE(4); - if (lookahead == '|') ADVANCE(5); - if (lookahead == '\t' || - lookahead == '\n' || - lookahead == '\r' || - lookahead == ' ') SKIP(6) - END_STATE(); - case 7: - ACCEPT_TOKEN(ts_builtin_sym_end); - END_STATE(); - case 8: - ACCEPT_TOKEN(sym_identifier); - if (lookahead == '-' || - ('0' <= lookahead && lookahead <= '9') || - ('A' <= lookahead && lookahead <= 'Z') || - lookahead == '_' || - ('a' <= lookahead && lookahead <= 'z')) ADVANCE(8); - END_STATE(); - case 9: - ACCEPT_TOKEN(anon_sym_BANG); - END_STATE(); - case 10: - ACCEPT_TOKEN(anon_sym_BANG); - if (lookahead == '=') ADVANCE(14); - END_STATE(); - case 11: - ACCEPT_TOKEN(anon_sym_AMP_AMP); - END_STATE(); - case 12: - ACCEPT_TOKEN(anon_sym_PIPE_PIPE); - END_STATE(); - case 13: - ACCEPT_TOKEN(anon_sym_EQ_EQ); - END_STATE(); - case 14: - ACCEPT_TOKEN(anon_sym_BANG_EQ); - END_STATE(); - case 15: - ACCEPT_TOKEN(anon_sym_LPAREN); - END_STATE(); - case 16: - ACCEPT_TOKEN(anon_sym_RPAREN); - END_STATE(); - default: - return false; + case 0: + if (eof) + ADVANCE(7); + if (lookahead == '!') + ADVANCE(10); + if (lookahead == '&') + ADVANCE(2); + if (lookahead == '(') + ADVANCE(15); + if (lookahead == ')') + ADVANCE(16); + if (lookahead == '=') + ADVANCE(4); + if (lookahead == '|') + ADVANCE(5); + if (lookahead == '\t' || lookahead == '\n' || lookahead == '\r' || + lookahead == ' ') + SKIP(0) + if (lookahead == '-' || ('0' <= lookahead && lookahead <= '9') || + ('A' <= lookahead && lookahead <= 'Z') || lookahead == '_' || + ('a' <= lookahead && lookahead <= 'z')) + ADVANCE(8); + END_STATE(); + case 1: + if (lookahead == '!') + ADVANCE(9); + if (lookahead == '(') + ADVANCE(15); + if (lookahead == '\t' || lookahead == '\n' || lookahead == '\r' || + lookahead == ' ') + SKIP(1) + if (lookahead == '-' || ('0' <= lookahead && lookahead <= '9') || + ('A' <= lookahead && lookahead <= 'Z') || lookahead == '_' || + ('a' <= lookahead && lookahead <= 'z')) + ADVANCE(8); + END_STATE(); + case 2: + if (lookahead == '&') + ADVANCE(11); + END_STATE(); + case 3: + if (lookahead == '=') + ADVANCE(14); + END_STATE(); + case 4: + if (lookahead == '=') + ADVANCE(13); + END_STATE(); + case 5: + if (lookahead == '|') + ADVANCE(12); + END_STATE(); + case 6: + if (eof) + ADVANCE(7); + if (lookahead == '!') + ADVANCE(3); + if (lookahead == '&') + ADVANCE(2); + if (lookahead == ')') + ADVANCE(16); + if (lookahead == '=') + ADVANCE(4); + if (lookahead == '|') + ADVANCE(5); + if (lookahead == '\t' || lookahead == '\n' || lookahead == '\r' || + lookahead == ' ') + SKIP(6) + END_STATE(); + case 7: + ACCEPT_TOKEN(ts_builtin_sym_end); + END_STATE(); + case 8: + ACCEPT_TOKEN(sym_identifier); + if (lookahead == '-' || ('0' <= lookahead && lookahead <= '9') || + ('A' <= lookahead && lookahead <= 'Z') || lookahead == '_' || + ('a' <= lookahead && lookahead <= 'z')) + ADVANCE(8); + END_STATE(); + case 9: + ACCEPT_TOKEN(anon_sym_BANG); + END_STATE(); + case 10: + ACCEPT_TOKEN(anon_sym_BANG); + if (lookahead == '=') + ADVANCE(14); + END_STATE(); + case 11: + ACCEPT_TOKEN(anon_sym_AMP_AMP); + END_STATE(); + case 12: + ACCEPT_TOKEN(anon_sym_PIPE_PIPE); + END_STATE(); + case 13: + ACCEPT_TOKEN(anon_sym_EQ_EQ); + END_STATE(); + case 14: + ACCEPT_TOKEN(anon_sym_BANG_EQ); + END_STATE(); + case 15: + ACCEPT_TOKEN(anon_sym_LPAREN); + END_STATE(); + case 16: + ACCEPT_TOKEN(anon_sym_RPAREN); + END_STATE(); + default: + return false; } } static const TSLexMode ts_lex_modes[STATE_COUNT] = { - [0] = {.lex_state = 0}, - [1] = {.lex_state = 1}, - [2] = {.lex_state = 1}, - [3] = {.lex_state = 1}, - [4] = {.lex_state = 1}, - [5] = {.lex_state = 1}, - [6] = {.lex_state = 6}, - [7] = {.lex_state = 0}, - [8] = {.lex_state = 0}, - [9] = {.lex_state = 0}, - [10] = {.lex_state = 0}, - [11] = {.lex_state = 0}, - [12] = {.lex_state = 0}, - [13] = {.lex_state = 0}, - [14] = {.lex_state = 0}, - [15] = {.lex_state = 0}, - [16] = {.lex_state = 0}, - [17] = {.lex_state = 0}, + [0] = {.lex_state = 0}, [1] = {.lex_state = 1}, [2] = {.lex_state = 1}, + [3] = {.lex_state = 1}, [4] = {.lex_state = 1}, [5] = {.lex_state = 1}, + [6] = {.lex_state = 6}, [7] = {.lex_state = 0}, [8] = {.lex_state = 0}, + [9] = {.lex_state = 0}, [10] = {.lex_state = 0}, [11] = {.lex_state = 0}, + [12] = {.lex_state = 0}, [13] = {.lex_state = 0}, [14] = {.lex_state = 0}, + [15] = {.lex_state = 0}, [16] = {.lex_state = 0}, [17] = {.lex_state = 0}, }; static const uint16_t ts_parse_table[LARGE_STATE_COUNT][SYMBOL_COUNT] = { - [0] = { - [ts_builtin_sym_end] = ACTIONS(1), - [sym_identifier] = ACTIONS(1), - [anon_sym_BANG] = ACTIONS(1), - [anon_sym_AMP_AMP] = ACTIONS(1), - [anon_sym_PIPE_PIPE] = ACTIONS(1), - [anon_sym_EQ_EQ] = ACTIONS(1), - [anon_sym_BANG_EQ] = ACTIONS(1), - [anon_sym_LPAREN] = ACTIONS(1), - [anon_sym_RPAREN] = ACTIONS(1), - }, - [1] = { - [sym_source] = STATE(15), - [sym__expression] = STATE(13), - [sym_not] = STATE(13), - [sym_and] = STATE(13), - [sym_or] = STATE(13), - [sym_equal] = STATE(13), - [sym_not_equal] = STATE(13), - [sym_parenthesized] = STATE(13), - [sym_identifier] = ACTIONS(3), - [anon_sym_BANG] = ACTIONS(5), - [anon_sym_LPAREN] = ACTIONS(7), - }, - [2] = { - [sym__expression] = STATE(7), - [sym_not] = STATE(7), - [sym_and] = STATE(7), - [sym_or] = STATE(7), - [sym_equal] = STATE(7), - [sym_not_equal] = STATE(7), - [sym_parenthesized] = STATE(7), - [sym_identifier] = ACTIONS(3), - [anon_sym_BANG] = ACTIONS(5), - [anon_sym_LPAREN] = ACTIONS(7), - }, - [3] = { - [sym__expression] = STATE(14), - [sym_not] = STATE(14), - [sym_and] = STATE(14), - [sym_or] = STATE(14), - [sym_equal] = STATE(14), - [sym_not_equal] = STATE(14), - [sym_parenthesized] = STATE(14), - [sym_identifier] = ACTIONS(3), - [anon_sym_BANG] = ACTIONS(5), - [anon_sym_LPAREN] = ACTIONS(7), - }, - [4] = { - [sym__expression] = STATE(11), - [sym_not] = STATE(11), - [sym_and] = STATE(11), - [sym_or] = STATE(11), - [sym_equal] = STATE(11), - [sym_not_equal] = STATE(11), - [sym_parenthesized] = STATE(11), - [sym_identifier] = ACTIONS(3), - [anon_sym_BANG] = ACTIONS(5), - [anon_sym_LPAREN] = ACTIONS(7), - }, - [5] = { - [sym__expression] = STATE(12), - [sym_not] = STATE(12), - [sym_and] = STATE(12), - [sym_or] = STATE(12), - [sym_equal] = STATE(12), - [sym_not_equal] = STATE(12), - [sym_parenthesized] = STATE(12), - [sym_identifier] = ACTIONS(3), - [anon_sym_BANG] = ACTIONS(5), - [anon_sym_LPAREN] = ACTIONS(7), - }, + [0] = + { + [ts_builtin_sym_end] = ACTIONS(1), + [sym_identifier] = ACTIONS(1), + [anon_sym_BANG] = ACTIONS(1), + [anon_sym_AMP_AMP] = ACTIONS(1), + [anon_sym_PIPE_PIPE] = ACTIONS(1), + [anon_sym_EQ_EQ] = ACTIONS(1), + [anon_sym_BANG_EQ] = ACTIONS(1), + [anon_sym_LPAREN] = ACTIONS(1), + [anon_sym_RPAREN] = ACTIONS(1), + }, + [1] = + { + [sym_source] = STATE(15), + [sym__expression] = STATE(13), + [sym_not] = STATE(13), + [sym_and] = STATE(13), + [sym_or] = STATE(13), + [sym_equal] = STATE(13), + [sym_not_equal] = STATE(13), + [sym_parenthesized] = STATE(13), + [sym_identifier] = ACTIONS(3), + [anon_sym_BANG] = ACTIONS(5), + [anon_sym_LPAREN] = ACTIONS(7), + }, + [2] = + { + [sym__expression] = STATE(7), + [sym_not] = STATE(7), + [sym_and] = STATE(7), + [sym_or] = STATE(7), + [sym_equal] = STATE(7), + [sym_not_equal] = STATE(7), + [sym_parenthesized] = STATE(7), + [sym_identifier] = ACTIONS(3), + [anon_sym_BANG] = ACTIONS(5), + [anon_sym_LPAREN] = ACTIONS(7), + }, + [3] = + { + [sym__expression] = STATE(14), + [sym_not] = STATE(14), + [sym_and] = STATE(14), + [sym_or] = STATE(14), + [sym_equal] = STATE(14), + [sym_not_equal] = STATE(14), + [sym_parenthesized] = STATE(14), + [sym_identifier] = ACTIONS(3), + [anon_sym_BANG] = ACTIONS(5), + [anon_sym_LPAREN] = ACTIONS(7), + }, + [4] = + { + [sym__expression] = STATE(11), + [sym_not] = STATE(11), + [sym_and] = STATE(11), + [sym_or] = STATE(11), + [sym_equal] = STATE(11), + [sym_not_equal] = STATE(11), + [sym_parenthesized] = STATE(11), + [sym_identifier] = ACTIONS(3), + [anon_sym_BANG] = ACTIONS(5), + [anon_sym_LPAREN] = ACTIONS(7), + }, + [5] = + { + [sym__expression] = STATE(12), + [sym_not] = STATE(12), + [sym_and] = STATE(12), + [sym_or] = STATE(12), + [sym_equal] = STATE(12), + [sym_not_equal] = STATE(12), + [sym_parenthesized] = STATE(12), + [sym_identifier] = ACTIONS(3), + [anon_sym_BANG] = ACTIONS(5), + [anon_sym_LPAREN] = ACTIONS(7), + }, }; static const uint16_t ts_small_parse_table[] = { - [0] = 3, - ACTIONS(11), 1, - anon_sym_EQ_EQ, - ACTIONS(13), 1, - anon_sym_BANG_EQ, - ACTIONS(9), 4, - ts_builtin_sym_end, - anon_sym_AMP_AMP, - anon_sym_PIPE_PIPE, - anon_sym_RPAREN, - [13] = 1, - ACTIONS(15), 4, - ts_builtin_sym_end, - anon_sym_AMP_AMP, - anon_sym_PIPE_PIPE, - anon_sym_RPAREN, - [20] = 1, - ACTIONS(17), 4, - ts_builtin_sym_end, - anon_sym_AMP_AMP, - anon_sym_PIPE_PIPE, - anon_sym_RPAREN, - [27] = 1, - ACTIONS(19), 4, - ts_builtin_sym_end, - anon_sym_AMP_AMP, - anon_sym_PIPE_PIPE, - anon_sym_RPAREN, - [34] = 1, - ACTIONS(21), 4, - ts_builtin_sym_end, - anon_sym_AMP_AMP, - anon_sym_PIPE_PIPE, - anon_sym_RPAREN, - [41] = 1, - ACTIONS(23), 4, - ts_builtin_sym_end, - anon_sym_AMP_AMP, - anon_sym_PIPE_PIPE, - anon_sym_RPAREN, - [48] = 2, - ACTIONS(27), 1, - anon_sym_AMP_AMP, - ACTIONS(25), 3, - ts_builtin_sym_end, - anon_sym_PIPE_PIPE, - anon_sym_RPAREN, - [57] = 3, - ACTIONS(27), 1, - anon_sym_AMP_AMP, - ACTIONS(29), 1, - ts_builtin_sym_end, - ACTIONS(31), 1, - anon_sym_PIPE_PIPE, - [67] = 3, - ACTIONS(27), 1, - anon_sym_AMP_AMP, - ACTIONS(31), 1, - anon_sym_PIPE_PIPE, - ACTIONS(33), 1, - anon_sym_RPAREN, - [77] = 1, - ACTIONS(35), 1, - ts_builtin_sym_end, - [81] = 1, - ACTIONS(37), 1, - sym_identifier, - [85] = 1, - ACTIONS(39), 1, - sym_identifier, + [0] = 3, + ACTIONS(11), + 1, + anon_sym_EQ_EQ, + ACTIONS(13), + 1, + anon_sym_BANG_EQ, + ACTIONS(9), + 4, + ts_builtin_sym_end, + anon_sym_AMP_AMP, + anon_sym_PIPE_PIPE, + anon_sym_RPAREN, + [13] = 1, + ACTIONS(15), + 4, + ts_builtin_sym_end, + anon_sym_AMP_AMP, + anon_sym_PIPE_PIPE, + anon_sym_RPAREN, + [20] = 1, + ACTIONS(17), + 4, + ts_builtin_sym_end, + anon_sym_AMP_AMP, + anon_sym_PIPE_PIPE, + anon_sym_RPAREN, + [27] = 1, + ACTIONS(19), + 4, + ts_builtin_sym_end, + anon_sym_AMP_AMP, + anon_sym_PIPE_PIPE, + anon_sym_RPAREN, + [34] = 1, + ACTIONS(21), + 4, + ts_builtin_sym_end, + anon_sym_AMP_AMP, + anon_sym_PIPE_PIPE, + anon_sym_RPAREN, + [41] = 1, + ACTIONS(23), + 4, + ts_builtin_sym_end, + anon_sym_AMP_AMP, + anon_sym_PIPE_PIPE, + anon_sym_RPAREN, + [48] = 2, + ACTIONS(27), + 1, + anon_sym_AMP_AMP, + ACTIONS(25), + 3, + ts_builtin_sym_end, + anon_sym_PIPE_PIPE, + anon_sym_RPAREN, + [57] = 3, + ACTIONS(27), + 1, + anon_sym_AMP_AMP, + ACTIONS(29), + 1, + ts_builtin_sym_end, + ACTIONS(31), + 1, + anon_sym_PIPE_PIPE, + [67] = 3, + ACTIONS(27), + 1, + anon_sym_AMP_AMP, + ACTIONS(31), + 1, + anon_sym_PIPE_PIPE, + ACTIONS(33), + 1, + anon_sym_RPAREN, + [77] = 1, + ACTIONS(35), + 1, + ts_builtin_sym_end, + [81] = 1, + ACTIONS(37), + 1, + sym_identifier, + [85] = 1, + ACTIONS(39), + 1, + sym_identifier, }; static const uint32_t ts_small_parse_table_map[] = { - [SMALL_STATE(6)] = 0, - [SMALL_STATE(7)] = 13, - [SMALL_STATE(8)] = 20, - [SMALL_STATE(9)] = 27, - [SMALL_STATE(10)] = 34, - [SMALL_STATE(11)] = 41, - [SMALL_STATE(12)] = 48, - [SMALL_STATE(13)] = 57, - [SMALL_STATE(14)] = 67, - [SMALL_STATE(15)] = 77, - [SMALL_STATE(16)] = 81, - [SMALL_STATE(17)] = 85, + [SMALL_STATE(6)] = 0, [SMALL_STATE(7)] = 13, [SMALL_STATE(8)] = 20, + [SMALL_STATE(9)] = 27, [SMALL_STATE(10)] = 34, [SMALL_STATE(11)] = 41, + [SMALL_STATE(12)] = 48, [SMALL_STATE(13)] = 57, [SMALL_STATE(14)] = 67, + [SMALL_STATE(15)] = 77, [SMALL_STATE(16)] = 81, [SMALL_STATE(17)] = 85, }; static const TSParseActionEntry ts_parse_actions[] = { - [0] = {.entry = {.count = 0, .reusable = false}}, - [1] = {.entry = {.count = 1, .reusable = false}}, RECOVER(), - [3] = {.entry = {.count = 1, .reusable = true}}, SHIFT(6), - [5] = {.entry = {.count = 1, .reusable = true}}, SHIFT(2), - [7] = {.entry = {.count = 1, .reusable = true}}, SHIFT(3), - [9] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym__expression, 1), - [11] = {.entry = {.count = 1, .reusable = true}}, SHIFT(16), - [13] = {.entry = {.count = 1, .reusable = true}}, SHIFT(17), - [15] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_not, 2, .production_id = 1), - [17] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_equal, 3, .production_id = 2), - [19] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_not_equal, 3, .production_id = 2), - [21] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_parenthesized, 3, .production_id = 1), - [23] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_and, 3, .production_id = 2), - [25] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_or, 3, .production_id = 2), - [27] = {.entry = {.count = 1, .reusable = true}}, SHIFT(4), - [29] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_source, 1), - [31] = {.entry = {.count = 1, .reusable = true}}, SHIFT(5), - [33] = {.entry = {.count = 1, .reusable = true}}, SHIFT(10), - [35] = {.entry = {.count = 1, .reusable = true}}, ACCEPT_INPUT(), - [37] = {.entry = {.count = 1, .reusable = true}}, SHIFT(8), - [39] = {.entry = {.count = 1, .reusable = true}}, SHIFT(9), + [0] = {.entry = {.count = 0, .reusable = false}}, + [1] = {.entry = {.count = 1, .reusable = false}}, + RECOVER(), + [3] = {.entry = {.count = 1, .reusable = true}}, + SHIFT(6), + [5] = {.entry = {.count = 1, .reusable = true}}, + SHIFT(2), + [7] = {.entry = {.count = 1, .reusable = true}}, + SHIFT(3), + [9] = {.entry = {.count = 1, .reusable = true}}, + REDUCE(sym__expression, 1), + [11] = {.entry = {.count = 1, .reusable = true}}, + SHIFT(16), + [13] = {.entry = {.count = 1, .reusable = true}}, + SHIFT(17), + [15] = {.entry = {.count = 1, .reusable = true}}, + REDUCE(sym_not, 2, .production_id = 1), + [17] = {.entry = {.count = 1, .reusable = true}}, + REDUCE(sym_equal, 3, .production_id = 2), + [19] = {.entry = {.count = 1, .reusable = true}}, + REDUCE(sym_not_equal, 3, .production_id = 2), + [21] = {.entry = {.count = 1, .reusable = true}}, + REDUCE(sym_parenthesized, 3, .production_id = 1), + [23] = {.entry = {.count = 1, .reusable = true}}, + REDUCE(sym_and, 3, .production_id = 2), + [25] = {.entry = {.count = 1, .reusable = true}}, + REDUCE(sym_or, 3, .production_id = 2), + [27] = {.entry = {.count = 1, .reusable = true}}, + SHIFT(4), + [29] = {.entry = {.count = 1, .reusable = true}}, + REDUCE(sym_source, 1), + [31] = {.entry = {.count = 1, .reusable = true}}, + SHIFT(5), + [33] = {.entry = {.count = 1, .reusable = true}}, + SHIFT(10), + [35] = {.entry = {.count = 1, .reusable = true}}, + ACCEPT_INPUT(), + [37] = {.entry = {.count = 1, .reusable = true}}, + SHIFT(8), + [39] = {.entry = {.count = 1, .reusable = true}}, + SHIFT(9), }; #ifdef __cplusplus @@ -497,30 +552,30 @@ extern "C" { extern const TSLanguage *tree_sitter_context_predicate(void) { static const TSLanguage language = { - .version = LANGUAGE_VERSION, - .symbol_count = SYMBOL_COUNT, - .alias_count = ALIAS_COUNT, - .token_count = TOKEN_COUNT, - .external_token_count = EXTERNAL_TOKEN_COUNT, - .state_count = STATE_COUNT, - .large_state_count = LARGE_STATE_COUNT, - .production_id_count = PRODUCTION_ID_COUNT, - .field_count = FIELD_COUNT, - .max_alias_sequence_length = MAX_ALIAS_SEQUENCE_LENGTH, - .parse_table = &ts_parse_table[0][0], - .small_parse_table = ts_small_parse_table, - .small_parse_table_map = ts_small_parse_table_map, - .parse_actions = ts_parse_actions, - .symbol_names = ts_symbol_names, - .field_names = ts_field_names, - .field_map_slices = ts_field_map_slices, - .field_map_entries = ts_field_map_entries, - .symbol_metadata = ts_symbol_metadata, - .public_symbol_map = ts_symbol_map, - .alias_map = ts_non_terminal_alias_map, - .alias_sequences = &ts_alias_sequences[0][0], - .lex_modes = ts_lex_modes, - .lex_fn = ts_lex, + .version = LANGUAGE_VERSION, + .symbol_count = SYMBOL_COUNT, + .alias_count = ALIAS_COUNT, + .token_count = TOKEN_COUNT, + .external_token_count = EXTERNAL_TOKEN_COUNT, + .state_count = STATE_COUNT, + .large_state_count = LARGE_STATE_COUNT, + .production_id_count = PRODUCTION_ID_COUNT, + .field_count = FIELD_COUNT, + .max_alias_sequence_length = MAX_ALIAS_SEQUENCE_LENGTH, + .parse_table = &ts_parse_table[0][0], + .small_parse_table = ts_small_parse_table, + .small_parse_table_map = ts_small_parse_table_map, + .parse_actions = ts_parse_actions, + .symbol_names = ts_symbol_names, + .field_names = ts_field_names, + .field_map_slices = ts_field_map_slices, + .field_map_entries = ts_field_map_entries, + .symbol_metadata = ts_symbol_metadata, + .public_symbol_map = ts_symbol_map, + .alias_map = ts_non_terminal_alias_map, + .alias_sequences = &ts_alias_sequences[0][0], + .lex_modes = ts_lex_modes, + .lex_fn = ts_lex, }; return &language; } diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index ac9ef6f82914d0d1c8916f7f97afa4df39e7ed9b..8246ea31ed5c34d76e95bf5f91aaccd035fea6c7 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -55,8 +55,8 @@ pub trait Entity: 'static { pub trait View: Entity + Sized { fn ui_name() -> &'static str; fn render(&mut self, cx: &mut RenderContext<'_, Self>) -> ElementBox; - fn on_focus(&mut self, _: &mut ViewContext) {} - fn on_blur(&mut self, _: &mut ViewContext) {} + fn on_focus_in(&mut self, _: AnyViewHandle, _: &mut ViewContext) {} + fn on_focus_out(&mut self, _: AnyViewHandle, _: &mut ViewContext) {} fn keymap_context(&self, _: &AppContext) -> keymap::Context { Self::default_keymap_context() } @@ -1903,7 +1903,7 @@ impl MutableAppContext { is_fullscreen: false, }, ); - root_view.update(this, |view, cx| view.on_focus(cx)); + root_view.update(this, |view, cx| view.on_focus_in(cx.handle().into(), cx)); this.open_platform_window(window_id, window_options); (window_id, root_view) @@ -2500,14 +2500,16 @@ impl MutableAppContext { window.is_active = active; //Handle focus - let view_id = window.focused_view_id?; - if let Some(mut view) = this.cx.views.remove(&(window_id, view_id)) { - if active { - view.on_focus(this, window_id, view_id); - } else { - view.on_blur(this, window_id, view_id); + let focused_id = window.focused_view_id?; + for view_id in this.parents(window_id, focused_id).collect::>() { + if let Some(mut view) = this.cx.views.remove(&(window_id, view_id)) { + if active { + view.on_focus_in(this, window_id, view_id, focused_id); + } else { + view.on_focus_out(this, window_id, view_id, focused_id); + } + this.cx.views.insert((window_id, view_id), view); } - this.cx.views.insert((window_id, view_id), view); } let mut observations = this.window_activation_observations.clone(); @@ -2537,26 +2539,45 @@ impl MutableAppContext { blurred_id }); + let blurred_parents = blurred_id + .map(|blurred_id| this.parents(window_id, blurred_id).collect::>()) + .unwrap_or_default(); + let focused_parents = focused_id + .map(|focused_id| this.parents(window_id, focused_id).collect::>()) + .unwrap_or_default(); + if let Some(blurred_id) = blurred_id { - if let Some(mut blurred_view) = this.cx.views.remove(&(window_id, blurred_id)) { - blurred_view.on_blur(this, window_id, blurred_id); - this.cx.views.insert((window_id, blurred_id), blurred_view); + for view_id in blurred_parents.iter().copied() { + // We've reached a common anscestor. Break. + if focused_parents.contains(&view_id) { + break; + } - let mut subscriptions = this.focus_observations.clone(); - subscriptions - .emit_and_cleanup(blurred_id, this, |callback, this| callback(false, this)); + if let Some(mut view) = this.cx.views.remove(&(window_id, view_id)) { + view.on_focus_out(this, window_id, view_id, blurred_id); + this.cx.views.insert((window_id, view_id), view); + } } + + let mut subscriptions = this.focus_observations.clone(); + subscriptions + .emit_and_cleanup(blurred_id, this, |callback, this| callback(false, this)); } if let Some(focused_id) = focused_id { - if let Some(mut focused_view) = this.cx.views.remove(&(window_id, focused_id)) { - focused_view.on_focus(this, window_id, focused_id); - this.cx.views.insert((window_id, focused_id), focused_view); - - let mut subscriptions = this.focus_observations.clone(); - subscriptions - .emit_and_cleanup(focused_id, this, |callback, this| callback(true, this)); + for view_id in focused_parents { + if blurred_parents.contains(&view_id) { + break; + } + if let Some(mut view) = this.cx.views.remove(&(window_id, view_id)) { + view.on_focus_in(this, window_id, view_id, focused_id); + this.cx.views.insert((window_id, focused_id), view); + } } + + let mut subscriptions = this.focus_observations.clone(); + subscriptions + .emit_and_cleanup(focused_id, this, |callback, this| callback(true, this)); } }) } @@ -2742,7 +2763,7 @@ impl ReadView for MutableAppContext { if let Some(view) = self.cx.views.get(&(handle.window_id, handle.view_id)) { view.as_any().downcast_ref().expect("downcast is type safe") } else { - panic!("circular view reference"); + panic!("circular view reference for type {}", type_name::()); } } } @@ -3216,8 +3237,20 @@ pub trait AnyView { ) -> Option>>>; fn ui_name(&self) -> &'static str; fn render<'a>(&mut self, params: RenderParams, cx: &mut MutableAppContext) -> ElementBox; - fn on_focus(&mut self, cx: &mut MutableAppContext, window_id: usize, view_id: usize); - fn on_blur(&mut self, cx: &mut MutableAppContext, window_id: usize, view_id: usize); + fn on_focus_in( + &mut self, + cx: &mut MutableAppContext, + window_id: usize, + view_id: usize, + focused_id: usize, + ); + fn on_focus_out( + &mut self, + cx: &mut MutableAppContext, + window_id: usize, + view_id: usize, + focused_id: usize, + ); fn keymap_context(&self, cx: &AppContext) -> keymap::Context; fn debug_json(&self, cx: &AppContext) -> serde_json::Value; @@ -3242,6 +3275,14 @@ pub trait AnyView { window_id: usize, view_id: usize, ); + fn any_handle(&self, window_id: usize, view_id: usize, cx: &AppContext) -> AnyViewHandle { + AnyViewHandle::new( + window_id, + view_id, + self.as_any().type_id(), + cx.ref_counts.clone(), + ) + } } impl AnyView for T @@ -3275,14 +3316,48 @@ where View::render(self, &mut RenderContext::new(params, cx)) } - fn on_focus(&mut self, cx: &mut MutableAppContext, window_id: usize, view_id: usize) { + fn on_focus_in( + &mut self, + cx: &mut MutableAppContext, + window_id: usize, + view_id: usize, + focused_id: usize, + ) { let mut cx = ViewContext::new(cx, window_id, view_id); - View::on_focus(self, &mut cx); + let focused_view_handle: AnyViewHandle = if view_id == focused_id { + cx.handle().into() + } else { + let focused_type = cx + .views + .get(&(window_id, focused_id)) + .unwrap() + .as_any() + .type_id(); + AnyViewHandle::new(window_id, focused_id, focused_type, cx.ref_counts.clone()) + }; + View::on_focus_in(self, focused_view_handle, &mut cx); } - fn on_blur(&mut self, cx: &mut MutableAppContext, window_id: usize, view_id: usize) { + fn on_focus_out( + &mut self, + cx: &mut MutableAppContext, + window_id: usize, + view_id: usize, + blurred_id: usize, + ) { let mut cx = ViewContext::new(cx, window_id, view_id); - View::on_blur(self, &mut cx); + let blurred_view_handle: AnyViewHandle = if view_id == blurred_id { + cx.handle().into() + } else { + let blurred_type = cx + .views + .get(&(window_id, blurred_id)) + .unwrap() + .as_any() + .type_id(); + AnyViewHandle::new(window_id, blurred_id, blurred_type, cx.ref_counts.clone()) + }; + View::on_focus_out(self, blurred_view_handle, &mut cx); } fn keymap_context(&self, cx: &AppContext) -> keymap::Context { @@ -6665,12 +6740,16 @@ mod tests { "View" } - fn on_focus(&mut self, _: &mut ViewContext) { - self.events.lock().push(format!("{} focused", &self.name)); + fn on_focus_in(&mut self, focused: AnyViewHandle, cx: &mut ViewContext) { + if cx.handle().id() == focused.id() { + self.events.lock().push(format!("{} focused", &self.name)); + } } - fn on_blur(&mut self, _: &mut ViewContext) { - self.events.lock().push(format!("{} blurred", &self.name)); + fn on_focus_out(&mut self, blurred: AnyViewHandle, cx: &mut ViewContext) { + if cx.handle().id() == blurred.id() { + self.events.lock().push(format!("{} blurred", &self.name)); + } } } @@ -7018,7 +7097,7 @@ mod tests { let (window_id, view_1) = cx.add_window(Default::default(), |_| view_1); let view_2 = cx.add_view(&view_1, |_| view_2); - let view_3 = cx.add_view(&view_2, |cx| { + cx.add_view(&view_2, |cx| { cx.focus_self(); view_3 }); diff --git a/crates/outline/src/outline.rs b/crates/outline/src/outline.rs index 19b309116a45f7486d07c235c23212d66b77762a..8a8c559cf3d75fb426deca62aefff5e697939ea9 100644 --- a/crates/outline/src/outline.rs +++ b/crates/outline/src/outline.rs @@ -4,8 +4,8 @@ use editor::{ }; use fuzzy::StringMatch; use gpui::{ - actions, elements::*, geometry::vector::Vector2F, AppContext, Entity, MouseState, - MutableAppContext, RenderContext, Task, View, ViewContext, ViewHandle, + actions, elements::*, geometry::vector::Vector2F, AnyViewHandle, AppContext, Entity, + MouseState, MutableAppContext, RenderContext, Task, View, ViewContext, ViewHandle, }; use language::Outline; use ordered_float::OrderedFloat; @@ -52,7 +52,7 @@ impl View for OutlineView { ChildView::new(self.picker.clone()).boxed() } - fn on_focus(&mut self, cx: &mut ViewContext) { + fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext) { cx.focus(&self.picker); } } diff --git a/crates/picker/src/picker.rs b/crates/picker/src/picker.rs index 6f247ebb6eae39c48b1683e0395909f826e1c522..d3f729ba8371690af40b2c8e05d1d98166fa80f9 100644 --- a/crates/picker/src/picker.rs +++ b/crates/picker/src/picker.rs @@ -7,8 +7,8 @@ use gpui::{ geometry::vector::{vec2f, Vector2F}, keymap, platform::CursorStyle, - AppContext, Axis, Element, ElementBox, Entity, MouseButton, MouseState, MutableAppContext, - RenderContext, Task, View, ViewContext, ViewHandle, WeakViewHandle, + AnyViewHandle, AppContext, Axis, Element, ElementBox, Entity, MouseButton, MouseState, + MutableAppContext, RenderContext, Task, View, ViewContext, ViewHandle, WeakViewHandle, }; use menu::{Cancel, Confirm, SelectFirst, SelectIndex, SelectLast, SelectNext, SelectPrev}; use settings::Settings; @@ -118,7 +118,7 @@ impl View for Picker { cx } - fn on_focus(&mut self, cx: &mut ViewContext) { + fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext) { cx.focus(&self.query_editor); } } diff --git a/crates/project_symbols/src/project_symbols.rs b/crates/project_symbols/src/project_symbols.rs index 8f2305eaff7ec17d78cc58852a4f299dc7720e76..755bca20d67cc1c94303a12c3ff4b67fff87d580 100644 --- a/crates/project_symbols/src/project_symbols.rs +++ b/crates/project_symbols/src/project_symbols.rs @@ -3,8 +3,8 @@ use editor::{ }; use fuzzy::{StringMatch, StringMatchCandidate}; use gpui::{ - actions, elements::*, AppContext, Entity, ModelHandle, MouseState, MutableAppContext, - RenderContext, Task, View, ViewContext, ViewHandle, + actions, elements::*, AnyViewHandle, AppContext, Entity, ModelHandle, MouseState, + MutableAppContext, RenderContext, Task, View, ViewContext, ViewHandle, }; use ordered_float::OrderedFloat; use picker::{Picker, PickerDelegate}; @@ -51,7 +51,7 @@ impl View for ProjectSymbolsView { ChildView::new(self.picker.clone()).boxed() } - fn on_focus(&mut self, cx: &mut ViewContext) { + fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext) { cx.focus(&self.picker); } } diff --git a/crates/search/src/buffer_search.rs b/crates/search/src/buffer_search.rs index ada785f85415898799dcb810752d74d478b6918b..d9a048b604c412ff41761b3276b558e4dcad0f5d 100644 --- a/crates/search/src/buffer_search.rs +++ b/crates/search/src/buffer_search.rs @@ -6,8 +6,8 @@ use crate::{ use collections::HashMap; use editor::{Anchor, Autoscroll, Editor}; use gpui::{ - actions, elements::*, impl_actions, platform::CursorStyle, Action, AppContext, Entity, - MouseButton, MutableAppContext, RenderContext, Subscription, Task, View, ViewContext, + actions, elements::*, impl_actions, platform::CursorStyle, Action, AnyViewHandle, AppContext, + Entity, MouseButton, MutableAppContext, RenderContext, Subscription, Task, View, ViewContext, ViewHandle, WeakViewHandle, }; use language::OffsetRangeExt; @@ -80,7 +80,7 @@ impl View for BufferSearchBar { "BufferSearchBar" } - fn on_focus(&mut self, cx: &mut ViewContext) { + fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext) { cx.focus(&self.query_editor); } diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 6cbd4c7e2dcf1aa8ef57cf60091b9a8dd61c9894..bcbeb0ac5fab80aa1b7a573adfb6013fc24b1485 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -6,9 +6,9 @@ use crate::{ use collections::HashMap; use editor::{Anchor, Autoscroll, Editor, MultiBuffer, SelectAll, MAX_TAB_TITLE_LEN}; use gpui::{ - actions, elements::*, platform::CursorStyle, Action, AppContext, ElementBox, Entity, - ModelContext, ModelHandle, MouseButton, MutableAppContext, RenderContext, Subscription, Task, - View, ViewContext, ViewHandle, WeakModelHandle, WeakViewHandle, + actions, elements::*, platform::CursorStyle, Action, AnyViewHandle, AppContext, ElementBox, + Entity, ModelContext, ModelHandle, MouseButton, MutableAppContext, RenderContext, Subscription, + Task, View, ViewContext, ViewHandle, WeakModelHandle, WeakViewHandle, }; use menu::Confirm; use project::{search::SearchQuery, Project}; @@ -190,7 +190,7 @@ impl View for ProjectSearchView { } } - fn on_focus(&mut self, cx: &mut ViewContext) { + fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext) { let handle = cx.weak_handle(); cx.update_global(|state: &mut ActiveSearches, cx| { state diff --git a/crates/terminal/src/connected_view.rs b/crates/terminal/src/connected_view.rs index 8b3099990a463c6d623b910e03f0326c8505a8b7..ed9b994e755185e61fd3c3b33752d829aaecb32b 100644 --- a/crates/terminal/src/connected_view.rs +++ b/crates/terminal/src/connected_view.rs @@ -6,7 +6,8 @@ use gpui::{ geometry::vector::Vector2F, impl_internal_actions, keymap::Keystroke, - AppContext, Element, ElementBox, ModelHandle, MutableAppContext, View, ViewContext, ViewHandle, + AnyViewHandle, AppContext, Element, ElementBox, ModelHandle, MutableAppContext, View, + ViewContext, ViewHandle, }; use workspace::pane; @@ -190,7 +191,7 @@ impl View for ConnectedView { .boxed() } - fn on_focus(&mut self, _cx: &mut ViewContext) { + fn on_focus_in(&mut self, _: AnyViewHandle, _cx: &mut ViewContext) { self.has_new_content = false; } diff --git a/crates/terminal/src/terminal.rs b/crates/terminal/src/terminal.rs index 4e5ca37a9debf9dae031ae5d23b8eddb5b5dfc50..b71f6bdcb217ce8b28cd1d6e839c519a852b268a 100644 --- a/crates/terminal/src/terminal.rs +++ b/crates/terminal/src/terminal.rs @@ -161,6 +161,13 @@ impl Dimensions for TerminalSize { fn columns(&self) -> usize { self.num_columns() } + + fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext) { + cx.emit(Event::Activate); + cx.defer(|view, cx| { + cx.focus(view.content.handle()); + }); + } } #[derive(Error, Debug)] diff --git a/crates/theme_selector/src/theme_selector.rs b/crates/theme_selector/src/theme_selector.rs index 106e6ad42921fabc425e65dea1a68f634e730ab6..d1e81b11a729ccd4baa6369f7831368c24b68dbc 100644 --- a/crates/theme_selector/src/theme_selector.rs +++ b/crates/theme_selector/src/theme_selector.rs @@ -1,7 +1,7 @@ use fuzzy::{match_strings, StringMatch, StringMatchCandidate}; use gpui::{ - actions, elements::*, AppContext, Element, ElementBox, Entity, MouseState, MutableAppContext, - RenderContext, View, ViewContext, ViewHandle, + actions, elements::*, AnyViewHandle, AppContext, Element, ElementBox, Entity, MouseState, + MutableAppContext, RenderContext, View, ViewContext, ViewHandle, }; use picker::{Picker, PickerDelegate}; use settings::Settings; @@ -249,7 +249,7 @@ impl View for ThemeSelector { ChildView::new(self.picker.clone()).boxed() } - fn on_focus(&mut self, cx: &mut ViewContext) { + fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext) { cx.focus(&self.picker); } } diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index 572e1032b3ae1a084412c0c619c2baa0bd393c66..f2cfee3ec117f3823d73dd65c54f85904e4857cc 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -13,9 +13,9 @@ use gpui::{ }, impl_actions, impl_internal_actions, platform::{CursorStyle, NavigationDirection}, - AppContext, AsyncAppContext, Entity, EventContext, ModelHandle, MouseButton, MouseButtonEvent, - MutableAppContext, PromptLevel, Quad, RenderContext, Task, View, ViewContext, ViewHandle, - WeakViewHandle, + AnyViewHandle, AppContext, AsyncAppContext, Entity, EventContext, ModelHandle, MouseButton, + MouseButtonEvent, MutableAppContext, PromptLevel, Quad, RenderContext, Task, View, ViewContext, + ViewHandle, WeakViewHandle, }; use project::{Project, ProjectEntryId, ProjectPath}; use serde::Deserialize; @@ -830,6 +830,7 @@ impl Pane { pub fn focus_active_item(&mut self, cx: &mut ViewContext) { if let Some(active_item) = self.active_item() { cx.focus(active_item); + self.activate(cx); } } @@ -1210,8 +1211,12 @@ impl View for Pane { .named("pane") } - fn on_focus(&mut self, cx: &mut ViewContext) { - self.focus_active_item(cx); + fn on_focus_in(&mut self, focused: AnyViewHandle, cx: &mut ViewContext) { + if cx.handle().id() == focused.id() { + self.focus_active_item(cx); + } else { + self.activate(cx); + } } } diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 02ad18eb3d954d3cd0bf858892f7b78a34c30a54..c8e804f59be365be30c0778107ef7e9f6fcdb684 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -2489,7 +2489,7 @@ impl View for Workspace { .named("workspace") } - fn on_focus(&mut self, cx: &mut ViewContext) { + fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext) { cx.focus(&self.active_pane); } } diff --git a/styles/package-lock.json b/styles/package-lock.json index 5499f1852cb4330467268dee6436b53589a90e9b..582f1c84968a5c1a25ddac5fd3c21ba907353c6d 100644 --- a/styles/package-lock.json +++ b/styles/package-lock.json @@ -5,6 +5,7 @@ "requires": true, "packages": { "": { + "name": "styles", "version": "1.0.0", "license": "ISC", "dependencies": { From 049149320c5c0e6ace074450a860037544e1c2cd Mon Sep 17 00:00:00 2001 From: K Simmons Date: Mon, 8 Aug 2022 12:21:29 -0700 Subject: [PATCH 13/27] build fix --- crates/terminal/src/terminal.rs | 7 ------- crates/terminal/src/terminal_view.rs | 2 +- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/crates/terminal/src/terminal.rs b/crates/terminal/src/terminal.rs index b71f6bdcb217ce8b28cd1d6e839c519a852b268a..4e5ca37a9debf9dae031ae5d23b8eddb5b5dfc50 100644 --- a/crates/terminal/src/terminal.rs +++ b/crates/terminal/src/terminal.rs @@ -161,13 +161,6 @@ impl Dimensions for TerminalSize { fn columns(&self) -> usize { self.num_columns() } - - fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext) { - cx.emit(Event::Activate); - cx.defer(|view, cx| { - cx.focus(view.content.handle()); - }); - } } #[derive(Error, Debug)] diff --git a/crates/terminal/src/terminal_view.rs b/crates/terminal/src/terminal_view.rs index ba6f49af02c0de6cec38df971defb9b2512a81ea..75c9658bd6769d3bbc4bb9d646c66f0fbd445f94 100644 --- a/crates/terminal/src/terminal_view.rs +++ b/crates/terminal/src/terminal_view.rs @@ -152,7 +152,7 @@ impl View for TerminalView { } } - fn on_focus(&mut self, cx: &mut ViewContext) { + fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext) { cx.emit(Event::Activate); cx.defer(|view, cx| { cx.focus(view.content.handle()); From 6f180ed822ea5a2bb92e1ffc88ab035a7f6912c0 Mon Sep 17 00:00:00 2001 From: K Simmons Date: Tue, 9 Aug 2022 15:09:38 -0700 Subject: [PATCH 14/27] Pane focus working. Modals seem broken now --- crates/diagnostics/src/diagnostics.rs | 4 --- crates/editor/src/editor.rs | 3 -- crates/editor/src/items.rs | 4 --- crates/editor/src/link_go_to_definition.rs | 5 ++- crates/editor/src/mouse_context_menu.rs | 3 +- crates/gpui/src/app.rs | 14 ++------ crates/search/src/project_search.rs | 31 ++---------------- crates/terminal/src/terminal.rs | 1 - crates/terminal/src/terminal_view.rs | 9 +---- crates/workspace/src/pane.rs | 34 +++++++++++-------- crates/workspace/src/workspace.rs | 38 ++++++++-------------- 11 files changed, 43 insertions(+), 103 deletions(-) diff --git a/crates/diagnostics/src/diagnostics.rs b/crates/diagnostics/src/diagnostics.rs index 42a3bb9f133ca38cb691ddc6dca41822d048425d..facccadb7677a4e14d87394719c58016dac2dca4 100644 --- a/crates/diagnostics/src/diagnostics.rs +++ b/crates/diagnostics/src/diagnostics.rs @@ -568,10 +568,6 @@ impl workspace::Item for ProjectDiagnosticsEditor { unreachable!() } - fn should_activate_item_on_event(event: &Self::Event) -> bool { - Editor::should_activate_item_on_event(event) - } - fn should_update_tab_on_event(event: &Event) -> bool { Editor::should_update_tab_on_event(event) } diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 6e84b275aaa050fdfe36c42c621ad67a7e93aa4a..128dae965c8f7e59efd6b7b7501f5d514690d3c8 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -1561,7 +1561,6 @@ impl Editor { ) { if !self.focused { cx.focus_self(); - cx.emit(Event::Activate); } let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); @@ -1623,7 +1622,6 @@ impl Editor { ) { if !self.focused { cx.focus_self(); - cx.emit(Event::Activate); } let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx)); @@ -5969,7 +5967,6 @@ fn compute_scroll_position( #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum Event { - Activate, BufferEdited, Edited, Reparsed, diff --git a/crates/editor/src/items.rs b/crates/editor/src/items.rs index 9837c5070f53f2b9aa0e9093c5fddeec84843391..59f9a98448f1368a0b3b4d2252cda0923f2b2c61 100644 --- a/crates/editor/src/items.rs +++ b/crates/editor/src/items.rs @@ -469,10 +469,6 @@ impl Item for Editor { }) } - fn should_activate_item_on_event(event: &Event) -> bool { - matches!(event, Event::Activate) - } - fn should_close_item_on_event(event: &Event) -> bool { matches!(event, Event::Closed) } diff --git a/crates/editor/src/link_go_to_definition.rs b/crates/editor/src/link_go_to_definition.rs index cc4592b6d4702818e7948faa4dfeb9f1816f4fb2..cbdeb3019117bbf7b59c6f363761fc62d5ff3f91 100644 --- a/crates/editor/src/link_go_to_definition.rs +++ b/crates/editor/src/link_go_to_definition.rs @@ -8,8 +8,8 @@ use util::TryFutureExt; use workspace::Workspace; use crate::{ - Anchor, DisplayPoint, Editor, EditorSnapshot, Event, GoToDefinition, GoToTypeDefinition, - Select, SelectPhase, + Anchor, DisplayPoint, Editor, EditorSnapshot, GoToDefinition, GoToTypeDefinition, Select, + SelectPhase, }; #[derive(Clone, PartialEq)] @@ -355,7 +355,6 @@ fn go_to_fetched_definition_of_kind( editor_handle.update(cx, |editor, cx| { if !editor.focused { cx.focus_self(); - cx.emit(Event::Activate); } }); diff --git a/crates/editor/src/mouse_context_menu.rs b/crates/editor/src/mouse_context_menu.rs index 3098e96e0714d6561882cb50608607414a15ea7b..202b009e3c9583f0a9f708c7480a2407ff09d001 100644 --- a/crates/editor/src/mouse_context_menu.rs +++ b/crates/editor/src/mouse_context_menu.rs @@ -2,7 +2,7 @@ use context_menu::ContextMenuItem; use gpui::{geometry::vector::Vector2F, impl_internal_actions, MutableAppContext, ViewContext}; use crate::{ - DisplayPoint, Editor, EditorMode, Event, FindAllReferences, GoToDefinition, GoToTypeDefinition, + DisplayPoint, Editor, EditorMode, FindAllReferences, GoToDefinition, GoToTypeDefinition, Rename, SelectMode, ToggleCodeActions, }; @@ -25,7 +25,6 @@ pub fn deploy_context_menu( ) { if !editor.focused { cx.focus_self(); - cx.emit(Event::Activate); } // Don't show context menu for inline editors diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 8246ea31ed5c34d76e95bf5f91aaccd035fea6c7..722e8be9976f52166ebcf9a35d9959afd83ad12e 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -1239,7 +1239,7 @@ impl MutableAppContext { let mut view = self .cx .views - .remove(&(params.window_id, params.view_id)) + .remove(&(window_id, view_id)) .ok_or(anyhow!("view not found"))?; let element = view.render(params, self); self.cx.views.insert((window_id, view_id), view); @@ -1781,7 +1781,7 @@ impl MutableAppContext { .cx .views .get(&(window_id, view_id)) - .expect("View passed to visit does not exist") + .unwrap() .keymap_context(self.as_ref()); match self.keystroke_matcher.push_keystroke( @@ -2548,11 +2548,6 @@ impl MutableAppContext { if let Some(blurred_id) = blurred_id { for view_id in blurred_parents.iter().copied() { - // We've reached a common anscestor. Break. - if focused_parents.contains(&view_id) { - break; - } - if let Some(mut view) = this.cx.views.remove(&(window_id, view_id)) { view.on_focus_out(this, window_id, view_id, blurred_id); this.cx.views.insert((window_id, view_id), view); @@ -2566,12 +2561,9 @@ impl MutableAppContext { if let Some(focused_id) = focused_id { for view_id in focused_parents { - if blurred_parents.contains(&view_id) { - break; - } if let Some(mut view) = this.cx.views.remove(&(window_id, view_id)) { view.on_focus_in(this, window_id, view_id, focused_id); - this.cx.views.insert((window_id, focused_id), view); + this.cx.views.insert((window_id, view_id), view); } } diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index bcbeb0ac5fab80aa1b7a573adfb6013fc24b1485..475923d6ef16de523d2a3fd6d6f07d3d69cc0813 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -73,7 +73,6 @@ pub struct ProjectSearchView { regex: bool, query_contains_error: bool, active_match_index: Option, - results_editor_was_focused: bool, } pub struct ProjectSearchBar { @@ -197,12 +196,6 @@ impl View for ProjectSearchView { .0 .insert(self.model.read(cx).project.downgrade(), handle) }); - - if self.results_editor_was_focused && !self.model.read(cx).match_ranges.is_empty() { - self.focus_results_editor(cx); - } else { - cx.focus(&self.query_editor); - } } } @@ -330,14 +323,6 @@ impl Item for ProjectSearchView { .update(cx, |editor, cx| editor.navigate(data, cx)) } - fn should_activate_item_on_event(event: &Self::Event) -> bool { - if let ViewEvent::EditorEvent(editor_event) = event { - Editor::should_activate_item_on_event(editor_event) - } else { - false - } - } - fn should_update_tab_on_event(event: &ViewEvent) -> bool { matches!(event, ViewEvent::UpdateTab) } @@ -385,12 +370,6 @@ impl ProjectSearchView { cx.emit(ViewEvent::EditorEvent(event.clone())) }) .detach(); - cx.observe_focus(&query_editor, |this, _, focused, _| { - if focused { - this.results_editor_was_focused = false; - } - }) - .detach(); let results_editor = cx.add_view(|cx| { let mut editor = Editor::for_multibuffer(excerpts, Some(project), cx); @@ -399,12 +378,7 @@ impl ProjectSearchView { }); cx.observe(&results_editor, |_, _, cx| cx.emit(ViewEvent::UpdateTab)) .detach(); - cx.observe_focus(&results_editor, |this, _, focused, _| { - if focused { - this.results_editor_was_focused = true; - } - }) - .detach(); + cx.subscribe(&results_editor, |this, _, event, cx| { if matches!(event, editor::Event::SelectionsChanged { .. }) { this.update_match_index(cx); @@ -423,7 +397,6 @@ impl ProjectSearchView { regex, query_contains_error: false, active_match_index: None, - results_editor_was_focused: false, }; this.model_changed(false, cx); this @@ -905,6 +878,8 @@ impl ToolbarItemView for ProjectSearchBar { self.subscription = None; self.active_project_search = None; if let Some(search) = active_pane_item.and_then(|i| i.downcast::()) { + let query_editor = search.read(cx).query_editor.clone(); + cx.reparent(query_editor); self.subscription = Some(cx.observe(&search, |_, _, cx| cx.notify())); self.active_project_search = Some(search); ToolbarItemLocation::PrimaryLeft { diff --git a/crates/terminal/src/terminal.rs b/crates/terminal/src/terminal.rs index 4e5ca37a9debf9dae031ae5d23b8eddb5b5dfc50..b54685c45819253f469b42abcf4e73e330e8cb99 100644 --- a/crates/terminal/src/terminal.rs +++ b/crates/terminal/src/terminal.rs @@ -60,7 +60,6 @@ const DEBUG_LINE_HEIGHT: f32 = 5.; pub enum Event { TitleChanged, CloseTerminal, - Activate, Bell, Wakeup, } diff --git a/crates/terminal/src/terminal_view.rs b/crates/terminal/src/terminal_view.rs index 75c9658bd6769d3bbc4bb9d646c66f0fbd445f94..a3492c2a94a8f306b06596268094b13d52a14d7f 100644 --- a/crates/terminal/src/terminal_view.rs +++ b/crates/terminal/src/terminal_view.rs @@ -153,10 +153,7 @@ impl View for TerminalView { } fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext) { - cx.emit(Event::Activate); - cx.defer(|view, cx| { - cx.focus(view.content.handle()); - }); + cx.focus(self.content.handle()); } fn keymap_context(&self, _: &gpui::AppContext) -> gpui::keymap::Context { @@ -314,10 +311,6 @@ impl Item for TerminalView { fn should_close_item_on_event(event: &Self::Event) -> bool { matches!(event, &Event::CloseTerminal) } - - fn should_activate_item_on_event(event: &Self::Event) -> bool { - matches!(event, &Event::Activate) - } } ///Get's the working directory for the given workspace, respecting the user's settings. diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index f2cfee3ec117f3823d73dd65c54f85904e4857cc..4a96699dee2fecb75bac0eded9caeaf7794ced76 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -13,9 +13,9 @@ use gpui::{ }, impl_actions, impl_internal_actions, platform::{CursorStyle, NavigationDirection}, - AnyViewHandle, AppContext, AsyncAppContext, Entity, EventContext, ModelHandle, MouseButton, - MouseButtonEvent, MutableAppContext, PromptLevel, Quad, RenderContext, Task, View, ViewContext, - ViewHandle, WeakViewHandle, + AnyViewHandle, AnyWeakViewHandle, AppContext, AsyncAppContext, Entity, EventContext, + ModelHandle, MouseButton, MouseButtonEvent, MutableAppContext, PromptLevel, Quad, + RenderContext, Task, View, ViewContext, ViewHandle, WeakViewHandle, }; use project::{Project, ProjectEntryId, ProjectPath}; use serde::Deserialize; @@ -132,7 +132,7 @@ pub fn init(cx: &mut MutableAppContext) { } pub enum Event { - Activate, + Focused, ActivateItem { local: bool }, Remove, RemoveItem, @@ -144,6 +144,7 @@ pub struct Pane { items: Vec>, is_active: bool, active_item_index: usize, + last_focused_view: Option, autoscroll: bool, nav_history: Rc>, toolbar: ViewHandle, @@ -193,6 +194,7 @@ impl Pane { items: Vec::new(), is_active: true, active_item_index: 0, + last_focused_view: None, autoscroll: false, nav_history: Rc::new(RefCell::new(NavHistory { mode: NavigationMode::Normal, @@ -219,10 +221,6 @@ impl Pane { } } - pub fn activate(&self, cx: &mut ViewContext) { - cx.emit(Event::Activate); - } - pub fn go_back( workspace: &mut Workspace, pane: Option>, @@ -287,7 +285,7 @@ impl Pane { mode: NavigationMode, cx: &mut ViewContext, ) -> Task<()> { - workspace.activate_pane(pane.clone(), cx); + cx.focus(pane.clone()); let to_load = pane.update(cx, |pane, cx| { loop { @@ -523,7 +521,7 @@ impl Pane { self.focus_active_item(cx); } if activate_pane { - self.activate(cx); + cx.emit(Event::Focused); } self.autoscroll = true; cx.notify(); @@ -830,7 +828,6 @@ impl Pane { pub fn focus_active_item(&mut self, cx: &mut ViewContext) { if let Some(active_item) = self.active_item() { cx.focus(active_item); - self.activate(cx); } } @@ -1212,11 +1209,20 @@ impl View for Pane { } fn on_focus_in(&mut self, focused: AnyViewHandle, cx: &mut ViewContext) { - if cx.handle().id() == focused.id() { - self.focus_active_item(cx); + if cx.is_self_focused() { + if let Some(last_focused_view) = self + .last_focused_view + .as_ref() + .and_then(|handle| handle.upgrade(cx)) + { + cx.focus(last_focused_view); + } else { + self.focus_active_item(cx); + } } else { - self.activate(cx); + self.last_focused_view = Some(focused.downgrade()); } + cx.emit(Event::Focused); } } diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index c8e804f59be365be30c0778107ef7e9f6fcdb684..c4b625c725b73ddc66d0b8922ccdf18f95a57dee 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -297,9 +297,6 @@ pub trait Item: View { project: ModelHandle, cx: &mut ViewContext, ) -> Task>; - fn should_activate_item_on_event(_: &Self::Event) -> bool { - false - } fn should_close_item_on_event(_: &Self::Event) -> bool { false } @@ -577,15 +574,6 @@ impl ItemHandle for ViewHandle { return; } - if T::should_activate_item_on_event(event) { - pane.update(cx, |pane, cx| { - if let Some(ix) = pane.index_for_item(&item) { - pane.activate_item(ix, true, true, false, cx); - pane.activate(cx); - } - }); - } - if T::should_update_tab_on_event(event) { pane.update(cx, |_, cx| { cx.emit(pane::Event::ChangeItemTitle); @@ -1438,7 +1426,7 @@ impl Workspace { }) .detach(); self.panes.push(pane.clone()); - self.activate_pane(pane.clone(), cx); + cx.focus(pane.clone()); cx.emit(Event::PaneAdded(pane.clone())); pane } @@ -1533,7 +1521,6 @@ impl Workspace { } }); if let Some((pane, ix)) = result { - self.activate_pane(pane.clone(), cx); pane.update(cx, |pane, cx| pane.activate_item(ix, true, true, false, cx)); true } else { @@ -1544,7 +1531,7 @@ impl Workspace { fn activate_pane_at_index(&mut self, action: &ActivatePane, cx: &mut ViewContext) { let panes = self.center.panes(); if let Some(pane) = panes.get(action.0).map(|p| (*p).clone()) { - self.activate_pane(pane, cx); + cx.focus(pane); } else { self.split_pane(self.active_pane.clone(), SplitDirection::Right, cx); } @@ -1560,7 +1547,7 @@ impl Workspace { let next_ix = (ix + 1) % panes.len(); panes[next_ix].clone() }; - self.activate_pane(next_pane, cx); + cx.focus(next_pane); } pub fn activate_previous_pane(&mut self, cx: &mut ViewContext) { @@ -1573,10 +1560,10 @@ impl Workspace { let prev_ix = if ix == 0 { panes.len() - 1 } else { ix - 1 }; panes[prev_ix].clone() }; - self.activate_pane(prev_pane, cx); + cx.focus(prev_pane); } - fn activate_pane(&mut self, pane: ViewHandle, cx: &mut ViewContext) { + fn handle_pane_focused(&mut self, pane: ViewHandle, cx: &mut ViewContext) { if self.active_pane != pane { self.active_pane .update(cx, |pane, cx| pane.set_active(false, cx)); @@ -1587,7 +1574,6 @@ impl Workspace { status_bar.set_active_pane(&self.active_pane, cx); }); self.active_item_path_changed(cx); - cx.focus(&self.active_pane); cx.notify(); } @@ -1614,8 +1600,8 @@ impl Workspace { pane::Event::Remove => { self.remove_pane(pane, cx); } - pane::Event::Activate => { - self.activate_pane(pane, cx); + pane::Event::Focused => { + self.handle_pane_focused(pane, cx); } pane::Event::ActivateItem { local } => { if *local { @@ -1648,7 +1634,6 @@ impl Workspace { ) -> Option> { pane.read(cx).active_item().map(|item| { let new_pane = self.add_pane(cx); - self.activate_pane(new_pane.clone(), cx); if let Some(clone) = item.clone_on_split(cx.as_mut()) { Pane::add_item(self, new_pane.clone(), clone, true, true, cx); } @@ -1661,7 +1646,7 @@ impl Workspace { fn remove_pane(&mut self, pane: ViewHandle, cx: &mut ViewContext) { if self.center.remove(&pane).unwrap() { self.panes.retain(|p| p != &pane); - self.activate_pane(self.panes.last().unwrap().clone(), cx); + cx.focus(self.panes.last().unwrap().clone()); self.unfollow(&pane, cx); self.last_leaders_by_pane.remove(&pane.downgrade()); cx.notify(); @@ -2490,7 +2475,10 @@ impl View for Workspace { } fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext) { - cx.focus(&self.active_pane); + if cx.is_self_focused() { + println!("Active Pane Focused"); + cx.focus(&self.active_pane); + } } } @@ -3110,7 +3098,7 @@ mod tests { // once for project entry 0, and once for project entry 2. After those two // prompts, the task should complete. let close = workspace.update(cx, |workspace, cx| { - workspace.activate_pane(left_pane.clone(), cx); + cx.focus(left_pane.clone()); Pane::close_items(workspace, left_pane.clone(), cx, |_| true) }); From f5a6a112c8318f8c766d2a211d5954ae86787411 Mon Sep 17 00:00:00 2001 From: K Simmons Date: Tue, 9 Aug 2022 15:51:17 -0700 Subject: [PATCH 15/27] Address picker issues --- crates/command_palette/src/command_palette.rs | 4 +++- crates/file_finder/src/file_finder.rs | 4 +++- crates/outline/src/outline.rs | 4 +++- crates/picker/src/picker.rs | 4 +++- crates/project_symbols/src/project_symbols.rs | 4 +++- crates/search/src/buffer_search.rs | 4 +++- crates/terminal/src/terminal_view.rs | 4 +++- crates/theme_selector/src/theme_selector.rs | 4 +++- crates/workspace/src/workspace.rs | 1 - 9 files changed, 24 insertions(+), 9 deletions(-) diff --git a/crates/command_palette/src/command_palette.rs b/crates/command_palette/src/command_palette.rs index 5d6f6e14a8a0b85754234a4a8479ca66ff48bd2e..6bef826e5b0458d44f15d1110d841af1538d8a6d 100644 --- a/crates/command_palette/src/command_palette.rs +++ b/crates/command_palette/src/command_palette.rs @@ -134,7 +134,9 @@ impl View for CommandPalette { } fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext) { - cx.focus(&self.picker); + if cx.is_self_focused() { + cx.focus(&self.picker); + } } } diff --git a/crates/file_finder/src/file_finder.rs b/crates/file_finder/src/file_finder.rs index aeec79901563c2449ddb90c15b944ab0bfae36b6..dbdc3ec3299497d61bf7f4f35a2261017b72cf88 100644 --- a/crates/file_finder/src/file_finder.rs +++ b/crates/file_finder/src/file_finder.rs @@ -54,7 +54,9 @@ impl View for FileFinder { } fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext) { - cx.focus(&self.picker); + if cx.is_self_focused() { + cx.focus(&self.picker); + } } } diff --git a/crates/outline/src/outline.rs b/crates/outline/src/outline.rs index 8a8c559cf3d75fb426deca62aefff5e697939ea9..414a48ed109cfdb4aa3522d7467c257396b4a2ac 100644 --- a/crates/outline/src/outline.rs +++ b/crates/outline/src/outline.rs @@ -53,7 +53,9 @@ impl View for OutlineView { } fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext) { - cx.focus(&self.picker); + if cx.is_self_focused() { + cx.focus(&self.picker); + } } } diff --git a/crates/picker/src/picker.rs b/crates/picker/src/picker.rs index d3f729ba8371690af40b2c8e05d1d98166fa80f9..19a01fcbadebdde13b576a013c1e59e58db42fc8 100644 --- a/crates/picker/src/picker.rs +++ b/crates/picker/src/picker.rs @@ -119,7 +119,9 @@ impl View for Picker { } fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext) { - cx.focus(&self.query_editor); + if cx.is_self_focused() { + cx.focus(&self.query_editor); + } } } diff --git a/crates/project_symbols/src/project_symbols.rs b/crates/project_symbols/src/project_symbols.rs index 755bca20d67cc1c94303a12c3ff4b67fff87d580..c310cfb0437b6e433cc6c8fac7b9660de4dc0ecf 100644 --- a/crates/project_symbols/src/project_symbols.rs +++ b/crates/project_symbols/src/project_symbols.rs @@ -52,7 +52,9 @@ impl View for ProjectSymbolsView { } fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext) { - cx.focus(&self.picker); + if cx.is_self_focused() { + cx.focus(&self.picker); + } } } diff --git a/crates/search/src/buffer_search.rs b/crates/search/src/buffer_search.rs index d9a048b604c412ff41761b3276b558e4dcad0f5d..bc6f37202dc10f9054c1e463d67d9541d73d5fee 100644 --- a/crates/search/src/buffer_search.rs +++ b/crates/search/src/buffer_search.rs @@ -81,7 +81,9 @@ impl View for BufferSearchBar { } fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext) { - cx.focus(&self.query_editor); + if cx.is_self_focused() { + cx.focus(&self.query_editor); + } } fn render(&mut self, cx: &mut RenderContext) -> ElementBox { diff --git a/crates/terminal/src/terminal_view.rs b/crates/terminal/src/terminal_view.rs index a3492c2a94a8f306b06596268094b13d52a14d7f..1b4544a3dc01290842794ac764fdfc5944af0c50 100644 --- a/crates/terminal/src/terminal_view.rs +++ b/crates/terminal/src/terminal_view.rs @@ -153,7 +153,9 @@ impl View for TerminalView { } fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext) { - cx.focus(self.content.handle()); + if cx.is_self_focused() { + cx.focus(self.content.handle()); + } } fn keymap_context(&self, _: &gpui::AppContext) -> gpui::keymap::Context { diff --git a/crates/theme_selector/src/theme_selector.rs b/crates/theme_selector/src/theme_selector.rs index d1e81b11a729ccd4baa6369f7831368c24b68dbc..dcda882168bc96aec91ee81013a8ec050b886b7e 100644 --- a/crates/theme_selector/src/theme_selector.rs +++ b/crates/theme_selector/src/theme_selector.rs @@ -250,6 +250,8 @@ impl View for ThemeSelector { } fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext) { - cx.focus(&self.picker); + if cx.is_self_focused() { + cx.focus(&self.picker); + } } } diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index c4b625c725b73ddc66d0b8922ccdf18f95a57dee..7043c3a683d5705ee7ec537e771b861b90545bdc 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -2476,7 +2476,6 @@ impl View for Workspace { fn on_focus_in(&mut self, _: AnyViewHandle, cx: &mut ViewContext) { if cx.is_self_focused() { - println!("Active Pane Focused"); cx.focus(&self.active_pane); } } From 3bdf05c0cdc389796fa4d22c1b05fc6c0f51f2dc Mon Sep 17 00:00:00 2001 From: K Simmons Date: Tue, 9 Aug 2022 16:11:01 -0700 Subject: [PATCH 16/27] fix up command palette --- crates/command_palette/src/command_palette.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/command_palette/src/command_palette.rs b/crates/command_palette/src/command_palette.rs index 6bef826e5b0458d44f15d1110d841af1538d8a6d..46327cf1bce797d507cb80e3e91d2099702756d6 100644 --- a/crates/command_palette/src/command_palette.rs +++ b/crates/command_palette/src/command_palette.rs @@ -86,8 +86,8 @@ impl CommandPalette { let focused_view_id = cx.focused_view_id(window_id).unwrap_or(workspace.id()); cx.as_mut().defer(move |cx| { + let this = cx.add_view(workspace.clone(), |cx| Self::new(focused_view_id, cx)); workspace.update(cx, |workspace, cx| { - let this = cx.add_view(|cx| Self::new(focused_view_id, cx)); workspace.toggle_modal(cx, |_, cx| { cx.subscribe(&this, Self::on_event).detach(); this From 3460a24da703749f5eb5a5a6087e81cb0b1b61e6 Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Wed, 10 Aug 2022 09:11:06 -0700 Subject: [PATCH 17/27] Changed CI and default.json to run clippy --- .github/workflows/ci.yml | 6 +++++- assets/settings/default.json | 19 ++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e596fad9bd1a051653fa5398bae2acc80b9441c5..ac20fdc3ab9ddcdc6fb7a8a8562c15075421042c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,6 +28,7 @@ jobs: run: | rustup set profile minimal rustup update stable + rustup component add clippy rustup target add wasm32-wasi - name: Install Node @@ -39,7 +40,10 @@ jobs: uses: actions/checkout@v2 with: clean: false - + + - name: Run clippy + run: cargo clippy + - name: Run tests run: cargo test --workspace --no-fail-fast diff --git a/assets/settings/default.json b/assets/settings/default.json index 33eb64e2019992ffca8cc94242ff12b5dcec19b6..9cf915d1a6f1c69a55b93686407f10e8319b9d08 100644 --- a/assets/settings/default.json +++ b/assets/settings/default.json @@ -145,5 +145,22 @@ "tab_size": 2 } }, - "lsp": {} + //LSP Specific settings. + "lsp": { + //Specify the LSP name as a key here. + //As of 8/10/22, supported LSPs are: + //pyright + //gopls + //rust-analyzer + //typescript-language-server + //vscode-json-languageserver + "rust_analyzer": { + //These initialization options are merged into Zed's defaults + "initialization_options": { + "checkOnSave": { + "command": "clippy" + } + } + } + } } From ee0e6a010939eb0f60d57cff22346093fc3d6535 Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Wed, 10 Aug 2022 15:07:02 -0700 Subject: [PATCH 18/27] Added env toml so readme db instructions are correct --- .gitignore | 1 - crates/collab/{.env.template.toml => .env.toml} | 0 2 files changed, 1 deletion(-) rename crates/collab/{.env.template.toml => .env.toml} (100%) diff --git a/.gitignore b/.gitignore index d3d0634a401a3fe5f8131ca5e1797289f1c01939..fcebdc84a2126b9d974ed64942896caf576434f0 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,6 @@ /plugins/bin /script/node_modules /styles/node_modules -/crates/collab/.env.toml /crates/collab/static/styles.css /vendor/bin /assets/themes/*.json diff --git a/crates/collab/.env.template.toml b/crates/collab/.env.toml similarity index 100% rename from crates/collab/.env.template.toml rename to crates/collab/.env.toml From d68f227ec4f2fd8ee87428cc6b085babbf16b7a5 Mon Sep 17 00:00:00 2001 From: K Simmons Date: Wed, 10 Aug 2022 16:26:53 -0700 Subject: [PATCH 19/27] Fix failing tests --- crates/collab/src/integration_tests.rs | 32 ++++++++++++++++++++++---- crates/gpui/src/app.rs | 3 ++- crates/workspace/src/workspace.rs | 13 +++++++++-- 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/crates/collab/src/integration_tests.rs b/crates/collab/src/integration_tests.rs index 4118e5963cdd7d706095ff4968b5f12b10d163ee..02b8d2f81ed4bc7449b5eebad2159dd60cb648fb 100644 --- a/crates/collab/src/integration_tests.rs +++ b/crates/collab/src/integration_tests.rs @@ -4246,7 +4246,10 @@ async fn test_peers_following_each_other(cx_a: &mut TestAppContext, cx_b: &mut T // Clients A and B follow each other in split panes workspace_a.update(cx_a, |workspace, cx| { workspace.split_pane(workspace.active_pane().clone(), SplitDirection::Right, cx); - assert_ne!(*workspace.active_pane(), pane_a1); + let pane_a1 = pane_a1.clone(); + cx.defer(move |workspace, _| { + assert_ne!(*workspace.active_pane(), pane_a1); + }); }); workspace_a .update(cx_a, |workspace, cx| { @@ -4259,7 +4262,10 @@ async fn test_peers_following_each_other(cx_a: &mut TestAppContext, cx_b: &mut T .unwrap(); workspace_b.update(cx_b, |workspace, cx| { workspace.split_pane(workspace.active_pane().clone(), SplitDirection::Right, cx); - assert_ne!(*workspace.active_pane(), pane_b1); + let pane_b1 = pane_b1.clone(); + cx.defer(move |workspace, _| { + assert_ne!(*workspace.active_pane(), pane_b1); + }); }); workspace_b .update(cx_b, |workspace, cx| { @@ -4271,17 +4277,26 @@ async fn test_peers_following_each_other(cx_a: &mut TestAppContext, cx_b: &mut T .await .unwrap(); + workspace_a.update(cx_a, |workspace, cx| { + workspace.activate_next_pane(cx); + }); + // Wait for focus effects to be fully flushed + workspace_a.update(cx_a, |workspace, _| { + assert_eq!(*workspace.active_pane(), pane_a1); + }); + workspace_a .update(cx_a, |workspace, cx| { - workspace.activate_next_pane(cx); - assert_eq!(*workspace.active_pane(), pane_a1); workspace.open_path((worktree_id, "3.txt"), true, cx) }) .await .unwrap(); + workspace_b.update(cx_b, |workspace, cx| { + workspace.activate_next_pane(cx); + }); + workspace_b .update(cx_b, |workspace, cx| { - workspace.activate_next_pane(cx); assert_eq!(*workspace.active_pane(), pane_b1); workspace.open_path((worktree_id, "4.txt"), true, cx) }) @@ -4311,17 +4326,24 @@ async fn test_peers_following_each_other(cx_a: &mut TestAppContext, cx_b: &mut T Some((worktree_id, "3.txt").into()) ); workspace.activate_next_pane(cx); + }); + + workspace_a.update(cx_a, |workspace, cx| { assert_eq!( workspace.active_item(cx).unwrap().project_path(cx), Some((worktree_id, "4.txt").into()) ); }); + workspace_b.update(cx_b, |workspace, cx| { assert_eq!( workspace.active_item(cx).unwrap().project_path(cx), Some((worktree_id, "4.txt").into()) ); workspace.activate_next_pane(cx); + }); + + workspace_b.update(cx_b, |workspace, cx| { assert_eq!( workspace.active_item(cx).unwrap().project_path(cx), Some((worktree_id, "3.txt").into()) diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 722e8be9976f52166ebcf9a35d9959afd83ad12e..c028c5de738e3d1b5ff51ed55e655c40ffaf4007 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -7089,7 +7089,7 @@ mod tests { let (window_id, view_1) = cx.add_window(Default::default(), |_| view_1); let view_2 = cx.add_view(&view_1, |_| view_2); - cx.add_view(&view_2, |cx| { + let _view_3 = cx.add_view(&view_2, |cx| { cx.focus_self(); view_3 }); @@ -7135,6 +7135,7 @@ mod tests { assert_eq!(&*actions.borrow(), &["2 a"]); actions.borrow_mut().clear(); + cx.dispatch_keystroke(window_id, &Keystroke::parse("b").unwrap()); assert_eq!(&*actions.borrow(), &["3 b", "2 b", "1 b", "global b"]); diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 7043c3a683d5705ee7ec537e771b861b90545bdc..5f188ef910178d164a94328c273c5085ea3e87d6 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -1,3 +1,7 @@ +/// NOTE: Focus only 'takes' after an update has flushed_effects. Pane sends an event in on_focus_in +/// which the workspace uses to change the activated pane. +/// This may cause issues when you're trying to write tests that use workspace focus to add items at +/// specific locations. pub mod pane; pub mod pane_group; pub mod sidebar; @@ -3088,16 +3092,21 @@ mod tests { workspace .split_pane(left_pane.clone(), SplitDirection::Right, cx) .unwrap(); - workspace.add_item(Box::new(cx.add_view(|_| item_3_4.clone())), cx); left_pane }); + //Need to cause an effect flush in order to respect new focus + workspace.update(cx, |workspace, cx| { + workspace.add_item(Box::new(cx.add_view(|_| item_3_4.clone())), cx); + cx.focus(left_pane.clone()); + }); + // When closing all of the items in the left pane, we should be prompted twice: // once for project entry 0, and once for project entry 2. After those two // prompts, the task should complete. + let close = workspace.update(cx, |workspace, cx| { - cx.focus(left_pane.clone()); Pane::close_items(workspace, left_pane.clone(), cx, |_| true) }); From 4d38dcfc54ecc634ecec2ee5623b0dd66f871f3e Mon Sep 17 00:00:00 2001 From: K Simmons Date: Wed, 10 Aug 2022 16:27:45 -0700 Subject: [PATCH 20/27] Fix workspace --- crates/workspace/src/workspace.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 5f188ef910178d164a94328c273c5085ea3e87d6..0d4ced4293cb40cef2843cf3685a5ae8749faa1b 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -1,5 +1,6 @@ /// NOTE: Focus only 'takes' after an update has flushed_effects. Pane sends an event in on_focus_in /// which the workspace uses to change the activated pane. +/// /// This may cause issues when you're trying to write tests that use workspace focus to add items at /// specific locations. pub mod pane; From e7540d2833cd436691aed7dad8c71090e02a3a7f Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Wed, 10 Aug 2022 09:11:06 -0700 Subject: [PATCH 21/27] Changed CI and default.json to run clippy --- .github/workflows/ci.yml | 6 +++++- assets/settings/default.json | 19 ++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e596fad9bd1a051653fa5398bae2acc80b9441c5..e54324c8c989afe195b5f8423cde9d93fb196f22 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,6 +28,7 @@ jobs: run: | rustup set profile minimal rustup update stable + rustup component add clippy rustup target add wasm32-wasi - name: Install Node @@ -39,7 +40,10 @@ jobs: uses: actions/checkout@v2 with: clean: false - + + - name: Run clippy + run: cargo clippy --workspace -- -D warnings + - name: Run tests run: cargo test --workspace --no-fail-fast diff --git a/assets/settings/default.json b/assets/settings/default.json index 33eb64e2019992ffca8cc94242ff12b5dcec19b6..9cf915d1a6f1c69a55b93686407f10e8319b9d08 100644 --- a/assets/settings/default.json +++ b/assets/settings/default.json @@ -145,5 +145,22 @@ "tab_size": 2 } }, - "lsp": {} + //LSP Specific settings. + "lsp": { + //Specify the LSP name as a key here. + //As of 8/10/22, supported LSPs are: + //pyright + //gopls + //rust-analyzer + //typescript-language-server + //vscode-json-languageserver + "rust_analyzer": { + //These initialization options are merged into Zed's defaults + "initialization_options": { + "checkOnSave": { + "command": "clippy" + } + } + } + } } From 8ba2f771485dec94fac03484b1b4a374ae88bc40 Mon Sep 17 00:00:00 2001 From: ForLoveOfCats Date: Wed, 10 Aug 2022 17:39:24 -0400 Subject: [PATCH 22/27] One big cleanup pass of clippy lints Co-authored-by: Mikayla --- .cargo/config.toml | 6 + .../src/activity_indicator.rs | 8 +- crates/auto_update/src/auto_update.rs | 5 +- crates/chat_panel/src/chat_panel.rs | 4 +- crates/client/src/channel.rs | 14 +- crates/client/src/client.rs | 30 ++- crates/client/src/http.rs | 4 +- crates/client/src/test.rs | 9 +- crates/client/src/user.rs | 2 +- crates/clock/src/clock.rs | 6 +- crates/collab/src/api.rs | 2 +- crates/collab/src/auth.rs | 4 +- crates/collab/src/db.rs | 33 ++- crates/collab/src/integration_tests.rs | 194 +++++++------- crates/collab/src/rpc.rs | 6 +- crates/collab/src/rpc/store.rs | 22 +- crates/command_palette/src/command_palette.rs | 4 +- crates/contacts_panel/src/contact_finder.rs | 4 +- crates/contacts_panel/src/contacts_panel.rs | 39 ++- crates/diagnostics/src/diagnostics.rs | 22 +- crates/editor/src/display_map.rs | 37 ++- crates/editor/src/display_map/block_map.rs | 45 ++-- crates/editor/src/display_map/fold_map.rs | 49 ++-- crates/editor/src/display_map/tab_map.rs | 10 +- crates/editor/src/display_map/wrap_map.rs | 14 +- crates/editor/src/editor.rs | 253 +++++++++--------- crates/editor/src/element.rs | 33 ++- crates/editor/src/hover_popover.rs | 4 +- crates/editor/src/items.rs | 37 +-- crates/editor/src/link_go_to_definition.rs | 12 +- crates/editor/src/multi_buffer.rs | 126 ++++----- crates/editor/src/multi_buffer/anchor.rs | 8 +- crates/editor/src/selections_collection.rs | 17 +- crates/file_finder/src/file_finder.rs | 4 +- crates/fsevent/examples/events.rs | 2 +- crates/fsevent/src/fsevent.rs | 8 +- crates/fuzzy/src/char_bag.rs | 12 +- crates/fuzzy/src/fuzzy.rs | 34 +-- crates/gpui/build.rs | 2 +- crates/gpui/examples/text.rs | 10 +- crates/gpui/src/app.rs | 64 ++--- crates/gpui/src/elements.rs | 6 +- crates/gpui/src/elements/empty.rs | 3 +- crates/gpui/src/elements/expanded.rs | 4 +- crates/gpui/src/elements/image.rs | 4 +- crates/gpui/src/elements/list.rs | 23 +- .../gpui/src/elements/mouse_event_handler.rs | 2 +- crates/gpui/src/elements/overlay.rs | 2 +- crates/gpui/src/elements/stack.rs | 5 +- crates/gpui/src/elements/text.rs | 2 +- crates/gpui/src/elements/uniform_list.rs | 23 +- crates/gpui/src/executor.rs | 8 +- crates/gpui/src/font_cache.rs | 6 +- crates/gpui/src/fonts.rs | 3 +- crates/gpui/src/geometry.rs | 11 +- crates/gpui/src/keymap.rs | 27 +- crates/gpui/src/platform.rs | 2 +- crates/gpui/src/platform/mac/event.rs | 2 +- crates/gpui/src/platform/mac/fonts.rs | 14 +- crates/gpui/src/platform/mac/platform.rs | 8 +- crates/gpui/src/platform/mac/renderer.rs | 45 ++-- crates/gpui/src/platform/mac/window.rs | 41 +-- crates/gpui/src/platform/test.rs | 2 +- crates/gpui/src/presenter.rs | 32 +-- crates/gpui/src/scene/mouse_region.rs | 2 + crates/gpui/src/text_layout.rs | 28 +- crates/gpui_macros/src/gpui_macros.rs | 2 +- crates/language/src/buffer.rs | 102 ++++--- crates/language/src/diagnostic_set.rs | 27 +- crates/language/src/highlight_map.rs | 5 +- crates/language/src/language.rs | 7 +- crates/language/src/proto.rs | 12 +- crates/language/src/tests.rs | 76 +++--- crates/lsp/src/lsp.rs | 16 +- crates/outline/src/outline.rs | 8 +- crates/plugin/src/lib.rs | 2 +- crates/plugin_runtime/build.rs | 7 +- crates/plugin_runtime/src/lib.rs | 4 +- crates/plugin_runtime/src/plugin.rs | 16 +- crates/project/src/fs.rs | 2 +- crates/project/src/lsp_command.rs | 10 +- crates/project/src/project.rs | 92 +++---- crates/project/src/project_tests.rs | 32 +-- crates/project/src/search.rs | 2 +- crates/project/src/worktree.rs | 62 ++--- crates/project_panel/src/project_panel.rs | 59 ++-- crates/rpc/src/conn.rs | 7 +- crates/rpc/src/peer.rs | 3 +- crates/rpc/src/proto.rs | 15 +- crates/search/src/buffer_search.rs | 27 +- crates/search/src/project_search.rs | 14 +- crates/search/src/search.rs | 8 +- crates/settings/src/keymap_file.rs | 52 ++-- crates/settings/src/settings.rs | 13 +- crates/snippet/src/snippet.rs | 8 +- crates/sum_tree/src/cursor.rs | 8 +- crates/sum_tree/src/sum_tree.rs | 10 +- crates/sum_tree/src/tree_map.rs | 4 +- crates/terminal/src/connected_el.rs | 38 +-- crates/terminal/src/connected_view.rs | 6 +- crates/terminal/src/mappings/colors.rs | 2 +- crates/terminal/src/mappings/keys.rs | 4 +- crates/terminal/src/modal.rs | 4 +- crates/terminal/src/terminal.rs | 47 ++-- crates/terminal/src/terminal_view.rs | 6 +- crates/text/src/anchor.rs | 20 +- crates/text/src/locator.rs | 4 + crates/text/src/operation_queue.rs | 10 + crates/text/src/patch.rs | 4 +- crates/text/src/point.rs | 2 +- crates/text/src/rope.rs | 10 +- crates/text/src/tests.rs | 12 +- crates/text/src/text.rs | 51 ++-- crates/theme_selector/src/theme_selector.rs | 2 +- crates/util/src/lib.rs | 4 +- crates/util/src/test/marked_text.rs | 10 +- crates/vim/src/motion.rs | 11 +- crates/vim/src/normal.rs | 2 +- crates/vim/src/normal/change.rs | 4 +- crates/vim/src/normal/delete.rs | 2 +- crates/vim/src/state.rs | 7 +- crates/vim/src/vim_test_context.rs | 2 +- crates/vim/src/visual.rs | 8 +- crates/workspace/src/pane.rs | 32 ++- crates/workspace/src/pane_group.rs | 2 +- crates/workspace/src/sidebar.rs | 11 +- crates/workspace/src/status_bar.rs | 6 +- crates/workspace/src/toolbar.rs | 13 +- crates/workspace/src/waiting_room.rs | 2 +- crates/workspace/src/workspace.rs | 65 +++-- crates/zed/src/feedback.rs | 3 +- crates/zed/src/languages/c.rs | 2 +- crates/zed/src/languages/go.rs | 6 +- crates/zed/src/languages/python.rs | 2 +- crates/zed/src/languages/typescript.rs | 2 +- crates/zed/src/main.rs | 18 +- crates/zed/src/settings_file.rs | 8 +- crates/zed/src/zed.rs | 34 +-- 138 files changed, 1328 insertions(+), 1366 deletions(-) create mode 100644 .cargo/config.toml diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000000000000000000000000000000000000..4dddb54d240aaa79b5ac139f9f5c19aea382c146 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,6 @@ +[target.'cfg(all())'] +rustflags = [ + "-Aclippy::reversed_empty_ranges", + "-Aclippy::missing_safety_doc", + "-Aclippy::let_unit_value", +] diff --git a/crates/activity_indicator/src/activity_indicator.rs b/crates/activity_indicator/src/activity_indicator.rs index 02ad100df81e8ba13e5d52ad805017cab6a498b3..7d4d01e8a18893616eac2189e5ccbf559e3d7c10 100644 --- a/crates/activity_indicator/src/activity_indicator.rs +++ b/crates/activity_indicator/src/activity_indicator.rs @@ -15,9 +15,9 @@ use workspace::{ItemHandle, StatusItemView, Workspace}; actions!(lsp_status, [ShowErrorMessage]); -const DOWNLOAD_ICON: &'static str = "icons/download_12.svg"; -const WARNING_ICON: &'static str = "icons/triangle_exclamation_12.svg"; -const DONE_ICON: &'static str = "icons/circle_check_12.svg"; +const DOWNLOAD_ICON: &str = "icons/download_12.svg"; +const WARNING_ICON: &str = "icons/triangle_exclamation_12.svg"; +const DONE_ICON: &str = "icons/circle_check_12.svg"; pub enum Event { ShowError { lsp_name: Arc, error: String }, @@ -76,7 +76,7 @@ impl ActivityIndicator { cx.subscribe(&this, move |workspace, _, event, cx| match event { Event::ShowError { lsp_name, error } => { if let Some(buffer) = project - .update(cx, |project, cx| project.create_buffer(&error, None, cx)) + .update(cx, |project, cx| project.create_buffer(error, None, cx)) .log_err() { buffer.update(cx, |buffer, cx| { diff --git a/crates/auto_update/src/auto_update.rs b/crates/auto_update/src/auto_update.rs index 6e4f171f6086ccdda1d82461421e52efe5f6e549..d32835547c6c1ba5903eb9251fa776d5a7bc5544 100644 --- a/crates/auto_update/src/auto_update.rs +++ b/crates/auto_update/src/auto_update.rs @@ -13,8 +13,7 @@ use std::{env, ffi::OsString, path::PathBuf, sync::Arc, time::Duration}; use update_notification::UpdateNotification; use workspace::Workspace; -const SHOULD_SHOW_UPDATE_NOTIFICATION_KEY: &'static str = - "auto-updater-should-show-updated-notification"; +const SHOULD_SHOW_UPDATE_NOTIFICATION_KEY: &str = "auto-updater-should-show-updated-notification"; const POLL_INTERVAL: Duration = Duration::from_secs(60 * 60); lazy_static! { @@ -61,7 +60,7 @@ pub fn init( server_url: String, cx: &mut MutableAppContext, ) { - if let Some(version) = ZED_APP_VERSION.clone().or(cx.platform().app_version().ok()) { + if let Some(version) = (*ZED_APP_VERSION).or_else(|| cx.platform().app_version().ok()) { let auto_updater = cx.add_model(|cx| { let updater = AutoUpdater::new(version, db.clone(), http_client, server_url.clone()); updater.start_polling(cx).detach(); diff --git a/crates/chat_panel/src/chat_panel.rs b/crates/chat_panel/src/chat_panel.rs index 7f947fef160de57ac47889e3618b825cc739cdb4..3ff7062f40f49630ae31ca1ab1211ca981a55262 100644 --- a/crates/chat_panel/src/chat_panel.rs +++ b/crates/chat_panel/src/chat_panel.rs @@ -70,7 +70,7 @@ impl ChatPanel { let theme = &cx.global::().theme.chat_panel.channel_select; SelectStyle { header: theme.header.container, - menu: theme.menu.clone(), + menu: theme.menu, } }) }); @@ -91,7 +91,7 @@ impl ChatPanel { let _observe_status = cx.spawn_weak(|this, mut cx| { let mut status = rpc.status(); async move { - while let Some(_) = status.recv().await { + while (status.recv().await).is_some() { if let Some(this) = this.upgrade(&cx) { this.update(&mut cx, |_, cx| cx.notify()); } else { diff --git a/crates/client/src/channel.rs b/crates/client/src/channel.rs index 0d44c6719139d3b4ed1344295841480f6df2f1f9..a88f872d11761f9e1ba461720ecc34c590b1f150 100644 --- a/crates/client/src/channel.rs +++ b/crates/client/src/channel.rs @@ -145,7 +145,7 @@ impl ChannelList { } pub fn available_channels(&self) -> Option<&[ChannelDetails]> { - self.available_channels.as_ref().map(Vec::as_slice) + self.available_channels.as_deref() } pub fn get_channel( @@ -601,8 +601,8 @@ mod tests { let user_id = 5; let http_client = FakeHttpClient::with_404_response(); - let mut client = Client::new(http_client.clone()); - let server = FakeServer::for_client(user_id, &mut client, &cx).await; + let client = Client::new(http_client.clone()); + let server = FakeServer::for_client(user_id, &client, cx).await; Channel::init(&client); let user_store = cx.add_model(|cx| UserStore::new(client.clone(), http_client, cx)); @@ -623,7 +623,7 @@ mod tests { }, ) .await; - channel_list.next_notification(&cx).await; + channel_list.next_notification(cx).await; channel_list.read_with(cx, |list, _| { assert_eq!( list.available_channels().unwrap(), @@ -701,7 +701,7 @@ mod tests { .await; assert_eq!( - channel.next_event(&cx).await, + channel.next_event(cx).await, ChannelEvent::MessagesUpdated { old_range: 0..0, new_count: 2, @@ -749,7 +749,7 @@ mod tests { .await; assert_eq!( - channel.next_event(&cx).await, + channel.next_event(cx).await, ChannelEvent::MessagesUpdated { old_range: 2..2, new_count: 1, @@ -798,7 +798,7 @@ mod tests { .await; assert_eq!( - channel.next_event(&cx).await, + channel.next_event(cx).await, ChannelEvent::MessagesUpdated { old_range: 0..0, new_count: 2, diff --git a/crates/client/src/client.rs b/crates/client/src/client.rs index af084dc88d45eff6acbcf57c3de73499e34fbee6..e328108a520b10b353aaf9e4c7e3dc73499802d9 100644 --- a/crates/client/src/client.rs +++ b/crates/client/src/client.rs @@ -41,13 +41,13 @@ pub use user::*; lazy_static! { pub static ref ZED_SERVER_URL: String = - std::env::var("ZED_SERVER_URL").unwrap_or("https://zed.dev".to_string()); + std::env::var("ZED_SERVER_URL").unwrap_or_else(|_| "https://zed.dev".to_string()); pub static ref IMPERSONATE_LOGIN: Option = std::env::var("ZED_IMPERSONATE") .ok() .and_then(|s| if s.is_empty() { None } else { Some(s) }); } -pub const ZED_SECRET_CLIENT_TOKEN: &'static str = "618033988749894"; +pub const ZED_SECRET_CLIENT_TOKEN: &str = "618033988749894"; actions!(client, [Authenticate]); @@ -65,10 +65,13 @@ pub struct Client { http: Arc, state: RwLock, + #[allow(clippy::type_complexity)] #[cfg(any(test, feature = "test-support"))] authenticate: RwLock< Option Task>>>, >, + + #[allow(clippy::type_complexity)] #[cfg(any(test, feature = "test-support"))] establish_connection: RwLock< Option< @@ -149,6 +152,7 @@ struct ClientState { entities_by_type_and_remote_id: HashMap<(TypeId, u64), AnyWeakEntityHandle>, models_by_message_type: HashMap, entity_types_by_message_type: HashMap, + #[allow(clippy::type_complexity)] message_handlers: HashMap< TypeId, Arc< @@ -596,7 +600,7 @@ impl Client { let mut status_rx = self.status(); let _ = status_rx.next().await; futures::select_biased! { - authenticate = self.authenticate(&cx).fuse() => { + authenticate = self.authenticate(cx).fuse() => { match authenticate { Ok(creds) => credentials = Some(creds), Err(err) => { @@ -819,7 +823,7 @@ impl Client { .get("Location") .ok_or_else(|| anyhow!("missing location header in /rpc response"))? .to_str() - .map_err(|error| EstablishConnectionError::other(error))? + .map_err(EstablishConnectionError::other)? .to_string(); } // Until we switch the zed.dev domain to point to the new Next.js app, there @@ -1051,7 +1055,7 @@ fn write_credentials_to_keychain(credentials: &Credentials, cx: &AsyncAppContext ) } -const WORKTREE_URL_PREFIX: &'static str = "zed://worktrees/"; +const WORKTREE_URL_PREFIX: &str = "zed://worktrees/"; pub fn encode_worktree_url(id: u64, access_token: &str) -> String { format!("{}{}/{}", WORKTREE_URL_PREFIX, id, access_token) @@ -1081,8 +1085,8 @@ mod tests { cx.foreground().forbid_parking(); let user_id = 5; - let mut client = Client::new(FakeHttpClient::with_404_response()); - let server = FakeServer::for_client(user_id, &mut client, &cx).await; + let client = Client::new(FakeHttpClient::with_404_response()); + let server = FakeServer::for_client(user_id, &client, cx).await; let mut status = client.status(); assert!(matches!( status.next().await, @@ -1169,8 +1173,8 @@ mod tests { cx.foreground().forbid_parking(); let user_id = 5; - let mut client = Client::new(FakeHttpClient::with_404_response()); - let server = FakeServer::for_client(user_id, &mut client, &cx).await; + let client = Client::new(FakeHttpClient::with_404_response()); + let server = FakeServer::for_client(user_id, &client, cx).await; let (done_tx1, mut done_rx1) = smol::channel::unbounded(); let (done_tx2, mut done_rx2) = smol::channel::unbounded(); @@ -1215,8 +1219,8 @@ mod tests { cx.foreground().forbid_parking(); let user_id = 5; - let mut client = Client::new(FakeHttpClient::with_404_response()); - let server = FakeServer::for_client(user_id, &mut client, &cx).await; + let client = Client::new(FakeHttpClient::with_404_response()); + let server = FakeServer::for_client(user_id, &client, cx).await; let model = cx.add_model(|_| Model::default()); let (done_tx1, _done_rx1) = smol::channel::unbounded(); @@ -1243,8 +1247,8 @@ mod tests { cx.foreground().forbid_parking(); let user_id = 5; - let mut client = Client::new(FakeHttpClient::with_404_response()); - let server = FakeServer::for_client(user_id, &mut client, &cx).await; + let client = Client::new(FakeHttpClient::with_404_response()); + let server = FakeServer::for_client(user_id, &client, cx).await; let model = cx.add_model(|_| Model::default()); let (done_tx, mut done_rx) = smol::channel::unbounded(); diff --git a/crates/client/src/http.rs b/crates/client/src/http.rs index 7f4cafa17d68f78b2abb61243bee87a0e7f66a31..5139bb8d03cef71698ffb2286f134900c2bc269f 100644 --- a/crates/client/src/http.rs +++ b/crates/client/src/http.rs @@ -16,7 +16,7 @@ pub type Request = isahc::Request; pub type Response = isahc::Response; pub trait HttpClient: Send + Sync { - fn send<'a>(&'a self, req: Request) -> BoxFuture<'a, Result>; + fn send(&self, req: Request) -> BoxFuture>; fn get<'a>( &'a self, @@ -45,7 +45,7 @@ pub fn client() -> Arc { } impl HttpClient for isahc::HttpClient { - fn send<'a>(&'a self, req: Request) -> BoxFuture<'a, Result> { + fn send(&self, req: Request) -> BoxFuture> { Box::pin(async move { self.send_async(req).await }) } } diff --git a/crates/client/src/test.rs b/crates/client/src/test.rs index 92183e25663ab896ea21c39c5701ad79a586a4b0..c634978a57edb3dade3bfc39e3c7ec97cf943c8a 100644 --- a/crates/client/src/test.rs +++ b/crates/client/src/test.rs @@ -56,7 +56,7 @@ impl FakeServer { } }) .override_establish_connection({ - let peer = Arc::downgrade(&server.peer).clone(); + let peer = Arc::downgrade(&server.peer); let state = Arc::downgrade(&server.state); move |credentials, cx| { let peer = peer.clone(); @@ -123,6 +123,7 @@ impl FakeServer { self.peer.send(self.connection_id(), message).unwrap(); } + #[allow(clippy::await_holding_lock)] pub async fn receive(&self) -> Result> { self.executor.start_waiting(); let message = self @@ -194,7 +195,7 @@ pub struct FakeHttpClient { } impl FakeHttpClient { - pub fn new(handler: F) -> Arc + pub fn create(handler: F) -> Arc where Fut: 'static + Send + Future>, F: 'static + Send + Sync + Fn(Request) -> Fut, @@ -205,7 +206,7 @@ impl FakeHttpClient { } pub fn with_404_response() -> Arc { - Self::new(|_| async move { + Self::create(|_| async move { Ok(isahc::Response::builder() .status(404) .body(Default::default()) @@ -221,7 +222,7 @@ impl fmt::Debug for FakeHttpClient { } impl HttpClient for FakeHttpClient { - fn send<'a>(&'a self, req: Request) -> BoxFuture<'a, Result> { + fn send(&self, req: Request) -> BoxFuture> { let future = (self.handler)(req); Box::pin(async move { future.await.map(Into::into) }) } diff --git a/crates/client/src/user.rs b/crates/client/src/user.rs index 5e56b53b877cd4f58a89241455289498b13c5ff3..149d22e77aec8fdb0803764eb7f9c863ed018797 100644 --- a/crates/client/src/user.rs +++ b/crates/client/src/user.rs @@ -17,7 +17,7 @@ pub struct User { impl PartialOrd for User { fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(&other)) + Some(self.cmp(other)) } } diff --git a/crates/clock/src/clock.rs b/crates/clock/src/clock.rs index e122a8b96a8eb8c25638c3c73897c812d9bb6508..89f8fda3ee2cbe96d47614b24f1e4ba079ac7970 100644 --- a/crates/clock/src/clock.rs +++ b/crates/clock/src/clock.rs @@ -54,14 +54,14 @@ impl<'a> Add<&'a Self> for Local { type Output = Local; fn add(self, other: &'a Self) -> Self::Output { - cmp::max(&self, other).clone() + *cmp::max(&self, other) } } impl<'a> AddAssign<&'a Local> for Local { fn add_assign(&mut self, other: &Self) { if *self < *other { - *self = other.clone(); + *self = *other; } } } @@ -177,7 +177,7 @@ impl Global { false } - pub fn iter<'a>(&'a self) -> impl 'a + Iterator { + pub fn iter(&self) -> impl Iterator + '_ { self.0.iter().enumerate().map(|(replica_id, seq)| Local { replica_id: replica_id as ReplicaId, value: *seq, diff --git a/crates/collab/src/api.rs b/crates/collab/src/api.rs index f3209cab7312cf8c8c516e6bf6c926efd6306f5b..eafeae086433509920bef60ff80ef440ff423273 100644 --- a/crates/collab/src/api.rs +++ b/crates/collab/src/api.rs @@ -394,7 +394,7 @@ async fn create_access_token( } else { return Err(Error::Http( StatusCode::UNAUTHORIZED, - format!("you do not have permission to impersonate other users"), + "you do not have permission to impersonate other users".to_string(), )); } } diff --git a/crates/collab/src/auth.rs b/crates/collab/src/auth.rs index b61043109b410d8df02f2bd857bd7935bd2017e7..a1fac6a2b6abc5f49403aaa0fbbfb7b44fc22c8f 100644 --- a/crates/collab/src/auth.rs +++ b/crates/collab/src/auth.rs @@ -44,7 +44,7 @@ pub async fn validate_header(mut req: Request, next: Next) -> impl Into let state = req.extensions().get::>().unwrap(); let mut credentials_valid = false; for password_hash in state.db.get_access_token_hashes(user_id).await? { - if verify_access_token(&access_token, &password_hash)? { + if verify_access_token(access_token, &password_hash)? { credentials_valid = true; break; } @@ -100,7 +100,7 @@ pub fn encrypt_access_token(access_token: &str, public_key: String) -> Result(&'a self) -> Option<&'a tests::FakeDb>; + fn as_fake(&self) -> Option<&tests::FakeDb>; } pub struct PostgresDb { @@ -165,7 +165,7 @@ impl PostgresDb { pub async fn new(url: &str, max_connections: u32) -> Result { let pool = DbOptions::new() .max_connections(max_connections) - .connect(&url) + .connect(url) .await .context("failed to connect to postgres database")?; Ok(Self { pool }) @@ -568,7 +568,7 @@ impl Db for PostgresDb { for count in counts { extension_counts .entry(count.worktree_id as u64) - .or_insert(HashMap::default()) + .or_insert_with(HashMap::default) .insert(count.extension, count.count as usize); } Ok(extension_counts) @@ -863,20 +863,18 @@ impl Db for PostgresDb { should_notify, }); } + } else if accepted { + contacts.push(Contact::Accepted { + user_id: user_id_a, + should_notify: should_notify && !a_to_b, + }); + } else if a_to_b { + contacts.push(Contact::Incoming { + user_id: user_id_a, + should_notify, + }); } else { - if accepted { - contacts.push(Contact::Accepted { - user_id: user_id_a, - should_notify: should_notify && !a_to_b, - }); - } else if a_to_b { - contacts.push(Contact::Incoming { - user_id: user_id_a, - should_notify, - }); - } else { - contacts.push(Contact::Outgoing { user_id: user_id_a }); - } + contacts.push(Contact::Outgoing { user_id: user_id_a }); } } @@ -1331,7 +1329,7 @@ macro_rules! id_type { } #[allow(unused)] - pub fn to_proto(&self) -> u64 { + pub fn to_proto(self) -> u64 { self.0 as u64 } } @@ -2408,6 +2406,7 @@ pub mod tests { } impl TestDb { + #[allow(clippy::await_holding_lock)] pub async fn postgres() -> Self { lazy_static! { static ref LOCK: Mutex<()> = Mutex::new(()); diff --git a/crates/collab/src/integration_tests.rs b/crates/collab/src/integration_tests.rs index 02b8d2f81ed4bc7449b5eebad2159dd60cb648fb..2327aa6aadc06a33f8aee58b09a05cd35ef207bb 100644 --- a/crates/collab/src/integration_tests.rs +++ b/crates/collab/src/integration_tests.rs @@ -157,7 +157,7 @@ async fn test_share_project( // Edit the buffer as client B and see that edit as client A. editor_b.update(cx_b, |editor, cx| editor.handle_input("ok, ", cx)); buffer_a - .condition(&cx_a, |buffer, _| buffer.text() == "ok, b-contents") + .condition(cx_a, |buffer, _| buffer.text() == "ok, b-contents") .await; // TODO @@ -482,7 +482,7 @@ async fn test_cancel_join_request( client_b.client.clone(), client_b.user_store.clone(), client_b.project_store.clone(), - client_b.language_registry.clone().clone(), + client_b.language_registry.clone(), FakeFs::new(cx.background()), cx, ) @@ -504,7 +504,7 @@ async fn test_cancel_join_request( deterministic.run_until_parked(); assert_eq!( &*project_a_events.borrow(), - &[project::Event::ContactCancelledJoinRequest(user_b.clone())] + &[project::Event::ContactCancelledJoinRequest(user_b)] ); } @@ -554,17 +554,17 @@ async fn test_offline_projects( user_store: ModelHandle, cx: &mut gpui::MutableAppContext, ) { - let open_project_ids = project_store - .read(cx) - .projects(cx) - .filter_map(|project| project.read(cx).remote_id()) - .collect::>(); - let user_store = user_store.read(cx); for contact in user_store.contacts() { if contact.user.id == user_store.current_user().unwrap().id { for project in &contact.projects { - if !open_project_ids.contains(&project.id) { + let store_contains_project = project_store + .read(cx) + .projects(cx) + .filter_map(|project| project.read(cx).remote_id()) + .any(|x| x == project.id); + + if !store_contains_project { panic!( concat!( "current user's contact data has a project", @@ -903,7 +903,7 @@ async fn test_propagate_saves_and_fs_changes( client_a.fs.insert_file("/a/file4", "4".into()).await; worktree_a - .condition(&cx_a, |tree, _| { + .condition(cx_a, |tree, _| { tree.paths() .map(|p| p.to_string_lossy()) .collect::>() @@ -911,7 +911,7 @@ async fn test_propagate_saves_and_fs_changes( }) .await; worktree_b - .condition(&cx_b, |tree, _| { + .condition(cx_b, |tree, _| { tree.paths() .map(|p| p.to_string_lossy()) .collect::>() @@ -919,7 +919,7 @@ async fn test_propagate_saves_and_fs_changes( }) .await; worktree_c - .condition(&cx_c, |tree, _| { + .condition(cx_c, |tree, _| { tree.paths() .map(|p| p.to_string_lossy()) .collect::>() @@ -929,17 +929,17 @@ async fn test_propagate_saves_and_fs_changes( // Ensure buffer files are updated as well. buffer_a - .condition(&cx_a, |buf, _| { + .condition(cx_a, |buf, _| { buf.file().unwrap().path().to_str() == Some("file1-renamed") }) .await; buffer_b - .condition(&cx_b, |buf, _| { + .condition(cx_b, |buf, _| { buf.file().unwrap().path().to_str() == Some("file1-renamed") }) .await; buffer_c - .condition(&cx_c, |buf, _| { + .condition(cx_c, |buf, _| { buf.file().unwrap().path().to_str() == Some("file1-renamed") }) .await; @@ -1246,7 +1246,7 @@ async fn test_buffer_conflict_after_save(cx_a: &mut TestAppContext, cx_b: &mut T buffer_b.update(cx_b, |buf, cx| buf.save(cx)).await.unwrap(); buffer_b - .condition(&cx_b, |buffer_b, _| !buffer_b.is_dirty()) + .condition(cx_b, |buffer_b, _| !buffer_b.is_dirty()) .await; buffer_b.read_with(cx_b, |buf, _| { assert!(!buf.has_conflict()); @@ -1299,7 +1299,7 @@ async fn test_buffer_reloading(cx_a: &mut TestAppContext, cx_b: &mut TestAppCont .await .unwrap(); buffer_b - .condition(&cx_b, |buf, _| { + .condition(cx_b, |buf, _| { buf.text() == new_contents.to_string() && !buf.is_dirty() }) .await; @@ -1349,7 +1349,7 @@ async fn test_editing_while_guest_opens_buffer( let text = buffer_a.read_with(cx_a, |buf, _| buf.text()); let buffer_b = buffer_b.await.unwrap(); - buffer_b.condition(&cx_b, |buf, _| buf.text() == text).await; + buffer_b.condition(cx_b, |buf, _| buf.text() == text).await; } #[gpui::test(iterations = 10)] @@ -1374,7 +1374,7 @@ async fn test_leaving_worktree_while_opening_buffer( // See that a guest has joined as client A. project_a - .condition(&cx_a, |p, _| p.collaborators().len() == 1) + .condition(cx_a, |p, _| p.collaborators().len() == 1) .await; // Begin opening a buffer as client B, but leave the project before the open completes. @@ -1386,7 +1386,7 @@ async fn test_leaving_worktree_while_opening_buffer( // See that the guest has left. project_a - .condition(&cx_a, |p, _| p.collaborators().len() == 0) + .condition(cx_a, |p, _| p.collaborators().is_empty()) .await; } @@ -1421,7 +1421,7 @@ async fn test_leaving_project(cx_a: &mut TestAppContext, cx_b: &mut TestAppConte // Drop client B's connection and ensure client A observes client B leaving the project. client_b.disconnect(&cx_b.to_async()).unwrap(); project_a - .condition(cx_a, |p, _| p.collaborators().len() == 0) + .condition(cx_a, |p, _| p.collaborators().is_empty()) .await; // Rejoin the project as client B @@ -1437,7 +1437,7 @@ async fn test_leaving_project(cx_a: &mut TestAppContext, cx_b: &mut TestAppConte server.disconnect_client(client_b.current_user_id(cx_b)); cx_a.foreground().advance_clock(rpc::RECEIVE_TIMEOUT); project_a - .condition(cx_a, |p, _| p.collaborators().len() == 0) + .condition(cx_a, |p, _| p.collaborators().is_empty()) .await; } @@ -1639,7 +1639,6 @@ async fn test_collaborating_with_diagnostics( buffer .snapshot() .diagnostics_in_range::<_, Point>(0..buffer.len(), false) - .map(|entry| entry) .collect::>(), &[ DiagnosticEntry { @@ -1744,7 +1743,7 @@ async fn test_collaborating_with_completion(cx_a: &mut TestAppContext, cx_b: &mu let fake_language_server = fake_language_servers.next().await.unwrap(); buffer_b - .condition(&cx_b, |buffer, _| !buffer.completion_triggers().is_empty()) + .condition(cx_b, |buffer, _| !buffer.completion_triggers().is_empty()) .await; // Type a completion trigger character as the guest. @@ -1808,12 +1807,12 @@ async fn test_collaborating_with_completion(cx_a: &mut TestAppContext, cx_b: &mu .await .unwrap(); buffer_a - .condition(&cx_a, |buffer, _| buffer.text() == "fn main() { a. }") + .condition(cx_a, |buffer, _| buffer.text() == "fn main() { a. }") .await; // Confirm a completion on the guest. editor_b - .condition(&cx_b, |editor, _| editor.context_menu_visible()) + .condition(cx_b, |editor, _| editor.context_menu_visible()) .await; editor_b.update(cx_b, |editor, cx| { editor.confirm_completion(&ConfirmCompletion { item_ix: Some(0) }, cx); @@ -1844,12 +1843,12 @@ async fn test_collaborating_with_completion(cx_a: &mut TestAppContext, cx_b: &mu // The additional edit is applied. buffer_a - .condition(&cx_a, |buffer, _| { + .condition(cx_a, |buffer, _| { buffer.text() == "use d::SomeTrait;\nfn main() { a.first_method() }" }) .await; buffer_b - .condition(&cx_b, |buffer, _| { + .condition(cx_b, |buffer, _| { buffer.text() == "use d::SomeTrait;\nfn main() { a.first_method() }" }) .await; @@ -2256,9 +2255,9 @@ async fn test_references(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) { Path::new("three.rs") ); - assert_eq!(references[0].range.to_offset(&two_buffer), 24..27); - assert_eq!(references[1].range.to_offset(&two_buffer), 35..38); - assert_eq!(references[2].range.to_offset(&three_buffer), 37..40); + assert_eq!(references[0].range.to_offset(two_buffer), 24..27); + assert_eq!(references[1].range.to_offset(two_buffer), 35..38); + assert_eq!(references[2].range.to_offset(three_buffer), 37..40); }); } @@ -2707,7 +2706,7 @@ async fn test_collaborating_with_code_actions( cx_b: &mut TestAppContext, ) { cx_a.foreground().forbid_parking(); - cx_b.update(|cx| editor::init(cx)); + cx_b.update(editor::init); let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await; let client_a = server.create_client(cx_a, "user_a").await; let client_b = server.create_client(cx_b, "user_b").await; @@ -2839,7 +2838,7 @@ async fn test_collaborating_with_code_actions( ); }); editor_b - .condition(&cx_b, |editor, _| editor.context_menu_visible()) + .condition(cx_b, |editor, _| editor.context_menu_visible()) .await; fake_language_server.remove_request_handler::(); @@ -2912,7 +2911,7 @@ async fn test_collaborating_with_code_actions( #[gpui::test(iterations = 10)] async fn test_collaborating_with_renames(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) { cx_a.foreground().forbid_parking(); - cx_b.update(|cx| editor::init(cx)); + cx_b.update(editor::init); let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await; let client_a = server.create_client(cx_a, "user_a").await; let client_b = server.create_client(cx_b, "user_b").await; @@ -3098,7 +3097,7 @@ async fn test_language_server_statuses( ) { deterministic.forbid_parking(); - cx_b.update(|cx| editor::init(cx)); + cx_b.update(editor::init); let mut server = TestServer::start(cx_a.foreground(), cx_a.background()).await; let client_a = server.create_client(cx_a, "user_a").await; let client_b = server.create_client(cx_b, "user_b").await; @@ -3207,24 +3206,24 @@ async fn test_basic_chat(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) { // Create an org that includes these 2 users. let db = &server.app_state.db; let org_id = db.create_org("Test Org", "test-org").await.unwrap(); - db.add_org_member(org_id, client_a.current_user_id(&cx_a), false) + db.add_org_member(org_id, client_a.current_user_id(cx_a), false) .await .unwrap(); - db.add_org_member(org_id, client_b.current_user_id(&cx_b), false) + db.add_org_member(org_id, client_b.current_user_id(cx_b), false) .await .unwrap(); // Create a channel that includes all the users. let channel_id = db.create_org_channel(org_id, "test-channel").await.unwrap(); - db.add_channel_member(channel_id, client_a.current_user_id(&cx_a), false) + db.add_channel_member(channel_id, client_a.current_user_id(cx_a), false) .await .unwrap(); - db.add_channel_member(channel_id, client_b.current_user_id(&cx_b), false) + db.add_channel_member(channel_id, client_b.current_user_id(cx_b), false) .await .unwrap(); db.create_channel_message( channel_id, - client_b.current_user_id(&cx_b), + client_b.current_user_id(cx_b), "hello A, it's B.", OffsetDateTime::now_utc(), 1, @@ -3251,7 +3250,7 @@ async fn test_basic_chat(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) { }); channel_a.read_with(cx_a, |channel, _| assert!(channel.messages().is_empty())); channel_a - .condition(&cx_a, |channel, _| { + .condition(cx_a, |channel, _| { channel_messages(channel) == [("user_b".to_string(), "hello A, it's B.".to_string(), false)] }) @@ -3277,7 +3276,7 @@ async fn test_basic_chat(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) { }); channel_b.read_with(cx_b, |channel, _| assert!(channel.messages().is_empty())); channel_b - .condition(&cx_b, |channel, _| { + .condition(cx_b, |channel, _| { channel_messages(channel) == [("user_b".to_string(), "hello A, it's B.".to_string(), false)] }) @@ -3304,7 +3303,7 @@ async fn test_basic_chat(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) { .unwrap(); channel_b - .condition(&cx_b, |channel, _| { + .condition(cx_b, |channel, _| { channel_messages(channel) == [ ("user_b".to_string(), "hello A, it's B.".to_string(), false), @@ -3344,10 +3343,10 @@ async fn test_chat_message_validation(cx_a: &mut TestAppContext) { let db = &server.app_state.db; let org_id = db.create_org("Test Org", "test-org").await.unwrap(); let channel_id = db.create_org_channel(org_id, "test-channel").await.unwrap(); - db.add_org_member(org_id, client_a.current_user_id(&cx_a), false) + db.add_org_member(org_id, client_a.current_user_id(cx_a), false) .await .unwrap(); - db.add_channel_member(channel_id, client_a.current_user_id(&cx_a), false) + db.add_channel_member(channel_id, client_a.current_user_id(cx_a), false) .await .unwrap(); @@ -3406,24 +3405,24 @@ async fn test_chat_reconnection(cx_a: &mut TestAppContext, cx_b: &mut TestAppCon // Create an org that includes these 2 users. let db = &server.app_state.db; let org_id = db.create_org("Test Org", "test-org").await.unwrap(); - db.add_org_member(org_id, client_a.current_user_id(&cx_a), false) + db.add_org_member(org_id, client_a.current_user_id(cx_a), false) .await .unwrap(); - db.add_org_member(org_id, client_b.current_user_id(&cx_b), false) + db.add_org_member(org_id, client_b.current_user_id(cx_b), false) .await .unwrap(); // Create a channel that includes all the users. let channel_id = db.create_org_channel(org_id, "test-channel").await.unwrap(); - db.add_channel_member(channel_id, client_a.current_user_id(&cx_a), false) + db.add_channel_member(channel_id, client_a.current_user_id(cx_a), false) .await .unwrap(); - db.add_channel_member(channel_id, client_b.current_user_id(&cx_b), false) + db.add_channel_member(channel_id, client_b.current_user_id(cx_b), false) .await .unwrap(); db.create_channel_message( channel_id, - client_b.current_user_id(&cx_b), + client_b.current_user_id(cx_b), "hello A, it's B.", OffsetDateTime::now_utc(), 2, @@ -3451,7 +3450,7 @@ async fn test_chat_reconnection(cx_a: &mut TestAppContext, cx_b: &mut TestAppCon }); channel_a.read_with(cx_a, |channel, _| assert!(channel.messages().is_empty())); channel_a - .condition(&cx_a, |channel, _| { + .condition(cx_a, |channel, _| { channel_messages(channel) == [("user_b".to_string(), "hello A, it's B.".to_string(), false)] }) @@ -3477,7 +3476,7 @@ async fn test_chat_reconnection(cx_a: &mut TestAppContext, cx_b: &mut TestAppCon }); channel_b.read_with(cx_b, |channel, _| assert!(channel.messages().is_empty())); channel_b - .condition(&cx_b, |channel, _| { + .condition(cx_b, |channel, _| { channel_messages(channel) == [("user_b".to_string(), "hello A, it's B.".to_string(), false)] }) @@ -3485,7 +3484,7 @@ async fn test_chat_reconnection(cx_a: &mut TestAppContext, cx_b: &mut TestAppCon // Disconnect client B, ensuring we can still access its cached channel data. server.forbid_connections(); - server.disconnect_client(client_b.current_user_id(&cx_b)); + server.disconnect_client(client_b.current_user_id(cx_b)); cx_b.foreground().advance_clock(rpc::RECEIVE_TIMEOUT); while !matches!( status_b.next().await, @@ -3554,7 +3553,7 @@ async fn test_chat_reconnection(cx_a: &mut TestAppContext, cx_b: &mut TestAppCon // Verify that B sees the new messages upon reconnection, as well as the message client B // sent while offline. channel_b - .condition(&cx_b, |channel, _| { + .condition(cx_b, |channel, _| { channel_messages(channel) == [ ("user_b".to_string(), "hello A, it's B.".to_string(), false), @@ -3573,7 +3572,7 @@ async fn test_chat_reconnection(cx_a: &mut TestAppContext, cx_b: &mut TestAppCon .await .unwrap(); channel_b - .condition(&cx_b, |channel, _| { + .condition(cx_b, |channel, _| { channel_messages(channel) == [ ("user_b".to_string(), "hello A, it's B.".to_string(), false), @@ -3592,7 +3591,7 @@ async fn test_chat_reconnection(cx_a: &mut TestAppContext, cx_b: &mut TestAppCon .await .unwrap(); channel_a - .condition(&cx_a, |channel, _| { + .condition(cx_a, |channel, _| { channel_messages(channel) == [ ("user_b".to_string(), "hello A, it's B.".to_string(), false), @@ -3701,7 +3700,7 @@ async fn test_contacts( } project_a - .condition(&cx_a, |project, _| { + .condition(cx_a, |project, _| { project.collaborators().contains_key(&client_b.peer_id) }) .await; @@ -3766,6 +3765,7 @@ async fn test_contacts( }); } + #[allow(clippy::type_complexity)] fn contacts(user_store: &UserStore) -> Vec<(&str, bool, Vec<(&str, Vec<&str>)>)> { user_store .contacts() @@ -3831,27 +3831,27 @@ async fn test_contact_requests( // All users see the pending request appear in all their clients. assert_eq!( - client_a.summarize_contacts(&cx_a).outgoing_requests, + client_a.summarize_contacts(cx_a).outgoing_requests, &["user_b"] ); assert_eq!( - client_a2.summarize_contacts(&cx_a2).outgoing_requests, + client_a2.summarize_contacts(cx_a2).outgoing_requests, &["user_b"] ); assert_eq!( - client_b.summarize_contacts(&cx_b).incoming_requests, + client_b.summarize_contacts(cx_b).incoming_requests, &["user_a", "user_c"] ); assert_eq!( - client_b2.summarize_contacts(&cx_b2).incoming_requests, + client_b2.summarize_contacts(cx_b2).incoming_requests, &["user_a", "user_c"] ); assert_eq!( - client_c.summarize_contacts(&cx_c).outgoing_requests, + client_c.summarize_contacts(cx_c).outgoing_requests, &["user_b"] ); assert_eq!( - client_c2.summarize_contacts(&cx_c2).outgoing_requests, + client_c2.summarize_contacts(cx_c2).outgoing_requests, &["user_b"] ); @@ -3861,15 +3861,15 @@ async fn test_contact_requests( disconnect_and_reconnect(&client_c, cx_c).await; executor.run_until_parked(); assert_eq!( - client_a.summarize_contacts(&cx_a).outgoing_requests, + client_a.summarize_contacts(cx_a).outgoing_requests, &["user_b"] ); assert_eq!( - client_b.summarize_contacts(&cx_b).incoming_requests, + client_b.summarize_contacts(cx_b).incoming_requests, &["user_a", "user_c"] ); assert_eq!( - client_c.summarize_contacts(&cx_c).outgoing_requests, + client_c.summarize_contacts(cx_c).outgoing_requests, &["user_b"] ); @@ -3885,18 +3885,18 @@ async fn test_contact_requests( executor.run_until_parked(); // User B sees user A as their contact now in all client, and the incoming request from them is removed. - let contacts_b = client_b.summarize_contacts(&cx_b); + let contacts_b = client_b.summarize_contacts(cx_b); assert_eq!(contacts_b.current, &["user_a", "user_b"]); assert_eq!(contacts_b.incoming_requests, &["user_c"]); - let contacts_b2 = client_b2.summarize_contacts(&cx_b2); + let contacts_b2 = client_b2.summarize_contacts(cx_b2); assert_eq!(contacts_b2.current, &["user_a", "user_b"]); assert_eq!(contacts_b2.incoming_requests, &["user_c"]); // User A sees user B as their contact now in all clients, and the outgoing request to them is removed. - let contacts_a = client_a.summarize_contacts(&cx_a); + let contacts_a = client_a.summarize_contacts(cx_a); assert_eq!(contacts_a.current, &["user_a", "user_b"]); assert!(contacts_a.outgoing_requests.is_empty()); - let contacts_a2 = client_a2.summarize_contacts(&cx_a2); + let contacts_a2 = client_a2.summarize_contacts(cx_a2); assert_eq!(contacts_a2.current, &["user_a", "user_b"]); assert!(contacts_a2.outgoing_requests.is_empty()); @@ -3906,20 +3906,20 @@ async fn test_contact_requests( disconnect_and_reconnect(&client_c, cx_c).await; executor.run_until_parked(); assert_eq!( - client_a.summarize_contacts(&cx_a).current, + client_a.summarize_contacts(cx_a).current, &["user_a", "user_b"] ); assert_eq!( - client_b.summarize_contacts(&cx_b).current, + client_b.summarize_contacts(cx_b).current, &["user_a", "user_b"] ); assert_eq!( - client_b.summarize_contacts(&cx_b).incoming_requests, + client_b.summarize_contacts(cx_b).incoming_requests, &["user_c"] ); - assert_eq!(client_c.summarize_contacts(&cx_c).current, &["user_c"]); + assert_eq!(client_c.summarize_contacts(cx_c).current, &["user_c"]); assert_eq!( - client_c.summarize_contacts(&cx_c).outgoing_requests, + client_c.summarize_contacts(cx_c).outgoing_requests, &["user_b"] ); @@ -3935,18 +3935,18 @@ async fn test_contact_requests( executor.run_until_parked(); // User B doesn't see user C as their contact, and the incoming request from them is removed. - let contacts_b = client_b.summarize_contacts(&cx_b); + let contacts_b = client_b.summarize_contacts(cx_b); assert_eq!(contacts_b.current, &["user_a", "user_b"]); assert!(contacts_b.incoming_requests.is_empty()); - let contacts_b2 = client_b2.summarize_contacts(&cx_b2); + let contacts_b2 = client_b2.summarize_contacts(cx_b2); assert_eq!(contacts_b2.current, &["user_a", "user_b"]); assert!(contacts_b2.incoming_requests.is_empty()); // User C doesn't see user B as their contact, and the outgoing request to them is removed. - let contacts_c = client_c.summarize_contacts(&cx_c); + let contacts_c = client_c.summarize_contacts(cx_c); assert_eq!(contacts_c.current, &["user_c"]); assert!(contacts_c.outgoing_requests.is_empty()); - let contacts_c2 = client_c2.summarize_contacts(&cx_c2); + let contacts_c2 = client_c2.summarize_contacts(cx_c2); assert_eq!(contacts_c2.current, &["user_c"]); assert!(contacts_c2.outgoing_requests.is_empty()); @@ -3956,20 +3956,20 @@ async fn test_contact_requests( disconnect_and_reconnect(&client_c, cx_c).await; executor.run_until_parked(); assert_eq!( - client_a.summarize_contacts(&cx_a).current, + client_a.summarize_contacts(cx_a).current, &["user_a", "user_b"] ); assert_eq!( - client_b.summarize_contacts(&cx_b).current, + client_b.summarize_contacts(cx_b).current, &["user_a", "user_b"] ); assert!(client_b - .summarize_contacts(&cx_b) + .summarize_contacts(cx_b) .incoming_requests .is_empty()); - assert_eq!(client_c.summarize_contacts(&cx_c).current, &["user_c"]); + assert_eq!(client_c.summarize_contacts(cx_c).current, &["user_c"]); assert!(client_c - .summarize_contacts(&cx_c) + .summarize_contacts(cx_c) .outgoing_requests .is_empty()); @@ -4553,13 +4553,13 @@ async fn test_peers_simultaneously_following_each_other( futures::try_join!(a_follow_b, b_follow_a).unwrap(); workspace_a.read_with(cx_a, |workspace, _| { assert_eq!( - workspace.leader_for_pane(&workspace.active_pane()), + workspace.leader_for_pane(workspace.active_pane()), Some(client_b_id) ); }); workspace_b.read_with(cx_b, |workspace, _| { assert_eq!( - workspace.leader_for_pane(&workspace.active_pane()), + workspace.leader_for_pane(workspace.active_pane()), Some(client_a_id) ); }); @@ -4740,7 +4740,7 @@ async fn test_random_collaboration( fake_server.handle_request::({ let rng = rng.clone(); - let project = project.clone(); + let project = project; move |params, mut cx| { let highlights = if let Some(project) = project.upgrade(&cx) { project.update(&mut cx, |project, cx| { @@ -5027,10 +5027,12 @@ async fn test_random_collaboration( for guest_buffer in &guest_client.buffers { let buffer_id = guest_buffer.read_with(&guest_cx, |buffer, _| buffer.remote_id()); let host_buffer = host_project.read_with(&host_cx, |project, cx| { - project.buffer_for_id(buffer_id, cx).expect(&format!( - "host does not have buffer for guest:{}, peer:{}, id:{}", - guest_client.username, guest_client.peer_id, buffer_id - )) + project.buffer_for_id(buffer_id, cx).unwrap_or_else(|| { + panic!( + "host does not have buffer for guest:{}, peer:{}, id:{}", + guest_client.username, guest_client.peer_id, buffer_id + ) + }) }); let path = host_buffer.read_with(&host_cx, |buffer, cx| buffer.file().unwrap().full_path(cx)); @@ -5174,7 +5176,7 @@ impl TestServer { languages: Arc::new(LanguageRegistry::new(Task::ready(()))), themes: ThemeRegistry::new((), cx.font_cache()), fs: fs.clone(), - build_window_options: || Default::default(), + build_window_options: Default::default, initialize_workspace: |_, _, _| unimplemented!(), }); @@ -5540,7 +5542,7 @@ impl TestClient { log::info!("Host: creating file {:?}", path,); - if fs.create_dir(&parent_path).await.is_ok() + if fs.create_dir(parent_path).await.is_ok() && fs.create_file(&path, Default::default()).await.is_ok() { break; @@ -5587,7 +5589,7 @@ impl TestClient { let buffer = if client.buffers.is_empty() || rng.lock().gen() { let worktree = if let Some(worktree) = project.read_with(cx, |project, cx| { project - .worktrees(&cx) + .worktrees(cx) .filter(|worktree| { let worktree = worktree.read(cx); worktree.is_visible() @@ -5820,7 +5822,7 @@ impl TestClient { let worktree = project .read_with(cx, |project, cx| { project - .worktrees(&cx) + .worktrees(cx) .filter(|worktree| { let worktree = worktree.read(cx); worktree.is_visible() diff --git a/crates/collab/src/rpc.rs b/crates/collab/src/rpc.rs index a4a48af5be6b0b5bab7cf9f93b3f826517634588..6346e15830e915fa66a9d74635a6e3a43ca7d64c 100644 --- a/crates/collab/src/rpc.rs +++ b/crates/collab/src/rpc.rs @@ -832,7 +832,7 @@ impl Server { // First, we send the metadata associated with each worktree. for (receipt, replica_id) in &receipts_with_replica_ids { self.peer.respond( - receipt.clone(), + *receipt, proto::JoinProjectResponse { variant: Some(proto::join_project_response::Variant::Accept( proto::join_project_response::Accept { @@ -1711,7 +1711,7 @@ impl Server { Ok(()) } - pub(crate) async fn store<'a>(&'a self) -> StoreGuard<'a> { + pub(crate) async fn store(&self) -> StoreGuard { #[cfg(test)] tokio::task::yield_now().await; let guard = self.store.lock().await; @@ -1796,7 +1796,7 @@ impl Header for ProtocolVersion { { let version = values .next() - .ok_or_else(|| axum::headers::Error::invalid())? + .ok_or_else(axum::headers::Error::invalid)? .to_str() .map_err(|_| axum::headers::Error::invalid())? .parse() diff --git a/crates/collab/src/rpc/store.rs b/crates/collab/src/rpc/store.rs index f5cc87cca893ffdce650c7bef2f756acef2d5b5d..fe18e0404b214e47e7f2e9d42019e8ae9b86bf0a 100644 --- a/crates/collab/src/rpc/store.rs +++ b/crates/collab/src/rpc/store.rs @@ -159,8 +159,10 @@ impl Store { let connection_projects = mem::take(&mut connection.projects); let connection_channels = mem::take(&mut connection.channels); - let mut result = RemovedConnectionState::default(); - result.user_id = user_id; + let mut result = RemovedConnectionState { + user_id, + ..Default::default() + }; // Leave all channels. for channel_id in connection_channels { @@ -223,10 +225,10 @@ impl Store { .user_id) } - pub fn connection_ids_for_user<'a>( - &'a self, + pub fn connection_ids_for_user( + &self, user_id: UserId, - ) -> impl 'a + Iterator { + ) -> impl Iterator + '_ { self.connections_by_user_id .get(&user_id) .into_iter() @@ -425,14 +427,14 @@ impl Store { } for guest_connection in project.guests.keys() { - if let Some(connection) = self.connections.get_mut(&guest_connection) { + if let Some(connection) = self.connections.get_mut(guest_connection) { connection.projects.remove(&project_id); } } for requester_user_id in project.join_requests.keys() { if let Some(requester_connection_ids) = - self.connections_by_user_id.get_mut(&requester_user_id) + self.connections_by_user_id.get_mut(requester_user_id) { for requester_connection_id in requester_connection_ids.iter() { if let Some(requester_connection) = @@ -544,6 +546,7 @@ impl Store { Some(receipts) } + #[allow(clippy::type_complexity)] pub fn accept_join_project_request( &mut self, responder_connection_id: ConnectionId, @@ -638,6 +641,7 @@ impl Store { }) } + #[allow(clippy::too_many_arguments)] pub fn update_worktree( &mut self, connection_id: ConnectionId, @@ -660,7 +664,7 @@ impl Store { worktree.root_name = worktree_root_name.to_string(); for entry_id in removed_entries { - worktree.entries.remove(&entry_id); + worktree.entries.remove(entry_id); } for entry in updated_entries { @@ -760,7 +764,7 @@ impl Store { pub fn check_invariants(&self) { for (connection_id, connection) in &self.connections { for project_id in &connection.projects { - let project = &self.projects.get(&project_id).unwrap(); + let project = &self.projects.get(project_id).unwrap(); if project.host_connection_id != *connection_id { assert!(project.guests.contains_key(connection_id)); } diff --git a/crates/command_palette/src/command_palette.rs b/crates/command_palette/src/command_palette.rs index 46327cf1bce797d507cb80e3e91d2099702756d6..9b51415069e5df8fbaa82d44b4e68de8376835a1 100644 --- a/crates/command_palette/src/command_palette.rs +++ b/crates/command_palette/src/command_palette.rs @@ -83,7 +83,9 @@ impl CommandPalette { fn toggle(_: &mut Workspace, _: &Toggle, cx: &mut ViewContext) { let workspace = cx.handle(); let window_id = cx.window_id(); - let focused_view_id = cx.focused_view_id(window_id).unwrap_or(workspace.id()); + let focused_view_id = cx + .focused_view_id(window_id) + .unwrap_or_else(|| workspace.id()); cx.as_mut().defer(move |cx| { let this = cx.add_view(workspace.clone(), |cx| Self::new(focused_view_id, cx)); diff --git a/crates/contacts_panel/src/contact_finder.rs b/crates/contacts_panel/src/contact_finder.rs index 978466dfcb2d01cf4cd4029e2014a89aaa8006d1..d7c096aaa9076f152e947464a4687ddef0c67651 100644 --- a/crates/contacts_panel/src/contact_finder.rs +++ b/crates/contacts_panel/src/contact_finder.rs @@ -111,7 +111,7 @@ impl PickerDelegate for ContactFinder { ) -> ElementBox { let theme = &cx.global::().theme; let user = &self.potential_contacts[ix]; - let request_status = self.user_store.read(cx).contact_request_status(&user); + let request_status = self.user_store.read(cx).contact_request_status(user); let icon_path = match request_status { ContactRequestStatus::None | ContactRequestStatus::RequestReceived => { @@ -121,7 +121,7 @@ impl PickerDelegate for ContactFinder { "icons/x_mark_8.svg" } }; - let button_style = if self.user_store.read(cx).is_contact_request_pending(&user) { + let button_style = if self.user_store.read(cx).is_contact_request_pending(user) { &theme.contact_finder.disabled_contact_button } else { &theme.contact_finder.contact_button diff --git a/crates/contacts_panel/src/contacts_panel.rs b/crates/contacts_panel/src/contacts_panel.rs index 9bc7972b2983568ff672e8bce6ecbe0c76584fbd..9198efceba2adcad2fce421fc70713a722f32881 100644 --- a/crates/contacts_panel/src/contacts_panel.rs +++ b/crates/contacts_panel/src/contacts_panel.rs @@ -131,9 +131,9 @@ impl ContactsPanel { move |_, cx| { if let Some(workspace_handle) = workspace.upgrade(cx) { cx.subscribe(&workspace_handle.read(cx).project().clone(), { - let workspace = workspace.clone(); - move |_, project, event, cx| match event { - project::Event::ContactRequestedJoin(user) => { + let workspace = workspace; + move |_, project, event, cx| { + if let project::Event::ContactRequestedJoin(user) = event { if let Some(workspace) = workspace.upgrade(cx) { workspace.update(cx, |workspace, cx| { workspace.show_notification(user.id as usize, cx, |cx| { @@ -148,7 +148,6 @@ impl ContactsPanel { }); } } - _ => {} } }) .detach(); @@ -161,17 +160,16 @@ impl ContactsPanel { cx.subscribe(&user_store, move |_, user_store, event, cx| { if let Some(workspace) = workspace.upgrade(cx) { - workspace.update(cx, |workspace, cx| match event { - client::Event::Contact { user, kind } => match kind { - ContactEventKind::Requested | ContactEventKind::Accepted => workspace - .show_notification(user.id as usize, cx, |cx| { + workspace.update(cx, |workspace, cx| { + if let client::Event::Contact { user, kind } = event { + if let ContactEventKind::Requested | ContactEventKind::Accepted = kind { + workspace.show_notification(user.id as usize, cx, |cx| { cx.add_view(|cx| { ContactNotification::new(user.clone(), *kind, user_store, cx) }) - }), - _ => {} - }, - _ => {} + }) + } + } }); } @@ -188,7 +186,7 @@ impl ContactsPanel { match &this.entries[ix] { ContactEntry::Header(section) => { - let is_collapsed = this.collapsed_sections.contains(§ion); + let is_collapsed = this.collapsed_sections.contains(section); Self::render_header( *section, &theme.contacts_panel, @@ -229,7 +227,7 @@ impl ContactsPanel { contact.clone(), current_user_id, *project_ix, - open_project.clone(), + *open_project, &theme.contacts_panel, &theme.tooltip, is_last_project_for_contact, @@ -238,7 +236,7 @@ impl ContactsPanel { ) } ContactEntry::OfflineProject(project) => Self::render_offline_project( - project.clone(), + *project, &theme.contacts_panel, &theme.tooltip, is_selected, @@ -345,6 +343,7 @@ impl ContactsPanel { .boxed() } + #[allow(clippy::too_many_arguments)] fn render_project( contact: Arc, current_user_id: Option, @@ -370,7 +369,7 @@ impl ContactsPanel { .or(theme.contact_avatar.height) .unwrap_or(0.); let row = &theme.project_row.default; - let tree_branch = theme.tree_branch.clone(); + let tree_branch = theme.tree_branch; let line_height = row.name.text.line_height(font_cache); let cap_height = row.name.text.cap_height(font_cache); let baseline_offset = @@ -641,7 +640,7 @@ impl ContactsPanel { let button_style = if is_contact_request_pending { &theme.disabled_button } else { - &theme.contact_button.style_for(mouse_state, false) + theme.contact_button.style_for(mouse_state, false) }; render_icon_button(button_style, "icons/x_mark_8.svg") .aligned() @@ -663,7 +662,7 @@ impl ContactsPanel { let button_style = if is_contact_request_pending { &theme.disabled_button } else { - &theme.contact_button.style_for(mouse_state, false) + theme.contact_button.style_for(mouse_state, false) }; render_icon_button(button_style, "icons/check_8.svg") .aligned() @@ -685,7 +684,7 @@ impl ContactsPanel { let button_style = if is_contact_request_pending { &theme.disabled_button } else { - &theme.contact_button.style_for(mouse_state, false) + theme.contact_button.style_for(mouse_state, false) }; render_icon_button(button_style, "icons/x_mark_8.svg") .aligned() @@ -1224,7 +1223,7 @@ mod tests { let client = Client::new(http_client.clone()); let user_store = cx.add_model(|cx| UserStore::new(client.clone(), http_client, cx)); let project_store = cx.add_model(|_| ProjectStore::new(project::Db::open_fake())); - let server = FakeServer::for_client(current_user_id, &client, &cx).await; + let server = FakeServer::for_client(current_user_id, &client, cx).await; let fs = FakeFs::new(cx.background()); fs.insert_tree("/private_dir", json!({ "one.rs": "" })) .await; diff --git a/crates/diagnostics/src/diagnostics.rs b/crates/diagnostics/src/diagnostics.rs index facccadb7677a4e14d87394719c58016dac2dca4..e14a44b05825f39656ca3ccd4f8b121ba8eb8753 100644 --- a/crates/diagnostics/src/diagnostics.rs +++ b/crates/diagnostics/src/diagnostics.rs @@ -365,7 +365,7 @@ impl ProjectDiagnosticsEditor { if !diagnostic.message.is_empty() { group_state.block_count += 1; blocks_to_add.push(BlockProperties { - position: (excerpt_id.clone(), entry.range.start.clone()), + position: (excerpt_id.clone(), entry.range.start), height: diagnostic.message.matches('\n').count() as u8 + 1, style: BlockStyle::Fixed, render: diagnostic_block_renderer(diagnostic, true), @@ -460,7 +460,7 @@ impl ProjectDiagnosticsEditor { for selection in &mut selections { if let Some(new_excerpt_id) = new_excerpt_ids_by_selection_id.get(&selection.id) { let group_ix = match groups.binary_search_by(|probe| { - probe.excerpts.last().unwrap().cmp(&new_excerpt_id) + probe.excerpts.last().unwrap().cmp(new_excerpt_id) }) { Ok(ix) | Err(ix) => ix, }; @@ -468,7 +468,7 @@ impl ProjectDiagnosticsEditor { let offset = excerpts_snapshot .anchor_in_excerpt( group.excerpts[group.primary_excerpt_ix].clone(), - group.primary_diagnostic.range.start.clone(), + group.primary_diagnostic.range.start, ) .to_offset(&excerpts_snapshot); selection.start = offset; @@ -486,10 +486,8 @@ impl ProjectDiagnosticsEditor { if self.editor.is_focused(cx) { cx.focus_self(); } - } else { - if cx.handle().is_focused(cx) { - cx.focus(&self.editor); - } + } else if cx.handle().is_focused(cx) { + cx.focus(&self.editor); } cx.notify(); } @@ -725,12 +723,12 @@ fn compare_diagnostics( ) -> Ordering { lhs.range .start - .to_offset(&snapshot) + .to_offset(snapshot) .cmp(&rhs.range.start.to_offset(snapshot)) .then_with(|| { lhs.range .end - .to_offset(&snapshot) + .to_offset(snapshot) .cmp(&rhs.range.end.to_offset(snapshot)) }) .then_with(|| lhs.diagnostic.message.cmp(&rhs.diagnostic.message)) @@ -873,7 +871,7 @@ mod tests { ProjectDiagnosticsEditor::new(project.clone(), workspace.downgrade(), cx) }); - view.next_notification(&cx).await; + view.next_notification(cx).await; view.update(cx, |view, cx| { assert_eq!( editor_blocks(&view.editor, cx), @@ -960,7 +958,7 @@ mod tests { project.disk_based_diagnostics_finished(0, cx); }); - view.next_notification(&cx).await; + view.next_notification(cx).await; view.update(cx, |view, cx| { assert_eq!( editor_blocks(&view.editor, cx), @@ -1074,7 +1072,7 @@ mod tests { project.disk_based_diagnostics_finished(0, cx); }); - view.next_notification(&cx).await; + view.next_notification(cx).await; view.update(cx, |view, cx| { assert_eq!( editor_blocks(&view.editor, cx), diff --git a/crates/editor/src/display_map.rs b/crates/editor/src/display_map.rs index ab5b7155a5e25b31fceda39521bbd47ffa160f3e..58fc2e4fe719754f23483565730ea6260c8bf098 100644 --- a/crates/editor/src/display_map.rs +++ b/crates/editor/src/display_map.rs @@ -253,7 +253,7 @@ impl DisplaySnapshot { self.buffer_snapshot.len() == 0 } - pub fn buffer_rows<'a>(&'a self, start_row: u32) -> DisplayBufferRows<'a> { + pub fn buffer_rows(&self, start_row: u32) -> DisplayBufferRows { self.blocks_snapshot.buffer_rows(start_row) } @@ -313,7 +313,7 @@ impl DisplaySnapshot { fn point_to_display_point(&self, point: Point, bias: Bias) -> DisplayPoint { let fold_point = self.folds_snapshot.to_fold_point(point, bias); let tab_point = self.tabs_snapshot.to_tab_point(fold_point); - let wrap_point = self.wraps_snapshot.from_tab_point(tab_point); + let wrap_point = self.wraps_snapshot.tab_point_to_wrap_point(tab_point); let block_point = self.blocks_snapshot.to_block_point(wrap_point); DisplayPoint(block_point) } @@ -336,16 +336,12 @@ impl DisplaySnapshot { .map(|h| h.text) } - pub fn chunks<'a>( - &'a self, - display_rows: Range, - language_aware: bool, - ) -> DisplayChunks<'a> { + pub fn chunks(&self, display_rows: Range, language_aware: bool) -> DisplayChunks<'_> { self.blocks_snapshot .chunks(display_rows, language_aware, Some(&self.text_highlights)) } - pub fn chars_at<'a>(&'a self, point: DisplayPoint) -> impl Iterator + 'a { + pub fn chars_at(&self, point: DisplayPoint) -> impl Iterator + '_ { let mut column = 0; let mut chars = self.text_chunks(point.row()).flat_map(str::chars); while column < point.column() { @@ -372,15 +368,15 @@ impl DisplaySnapshot { } pub fn column_from_chars(&self, display_row: u32, char_count: u32) -> u32 { - let mut count = 0; let mut column = 0; - for c in self.chars_at(DisplayPoint::new(display_row, 0)) { - if c == '\n' || count >= char_count { + + for (count, c) in self.chars_at(DisplayPoint::new(display_row, 0)).enumerate() { + if c == '\n' || count >= char_count as usize { break; } - count += 1; column += c.len_utf8() as u32; } + column } @@ -401,20 +397,17 @@ impl DisplaySnapshot { DisplayPoint(point) } - pub fn folds_in_range<'a, T>( - &'a self, - range: Range, - ) -> impl Iterator> + pub fn folds_in_range(&self, range: Range) -> impl Iterator> where T: ToOffset, { self.folds_snapshot.folds_in_range(range) } - pub fn blocks_in_range<'a>( - &'a self, + pub fn blocks_in_range( + &self, rows: Range, - ) -> impl Iterator { + ) -> impl Iterator { self.blocks_snapshot.blocks_in_range(rows) } @@ -1015,7 +1008,7 @@ pub mod tests { }); let buffer = cx.add_model(|cx| Buffer::new(0, text, cx).with_language(language, cx)); - buffer.condition(&cx, |buf, _| !buf.is_parsing()).await; + buffer.condition(cx, |buf, _| !buf.is_parsing()).await; let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx)); let font_cache = cx.font_cache(); @@ -1102,7 +1095,7 @@ pub mod tests { cx.update(|cx| cx.set_global(Settings::test(cx))); let buffer = cx.add_model(|cx| Buffer::new(0, text, cx).with_language(language, cx)); - buffer.condition(&cx, |buf, _| !buf.is_parsing()).await; + buffer.condition(cx, |buf, _| !buf.is_parsing()).await; let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx)); let font_cache = cx.font_cache(); @@ -1173,7 +1166,7 @@ pub mod tests { let (text, highlighted_ranges) = marked_text_ranges(r#"constˇ «a»: B = "c «d»""#, false); let buffer = cx.add_model(|cx| Buffer::new(0, text, cx).with_language(language, cx)); - buffer.condition(&cx, |buf, _| !buf.is_parsing()).await; + buffer.condition(cx, |buf, _| !buf.is_parsing()).await; let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx)); let buffer_snapshot = buffer.read_with(cx, |buffer, cx| buffer.snapshot(cx)); diff --git a/crates/editor/src/display_map/block_map.rs b/crates/editor/src/display_map/block_map.rs index 52379011709c2b3fc81183065fcbf22e643e5114..210daccac26b54e057947457b52c4c749e2adb61 100644 --- a/crates/editor/src/display_map/block_map.rs +++ b/crates/editor/src/display_map/block_map.rs @@ -20,7 +20,7 @@ use std::{ use sum_tree::{Bias, SumTree}; use text::{Edit, Point}; -const NEWLINES: &'static [u8] = &[b'\n'; u8::MAX as usize]; +const NEWLINES: &[u8] = &[b'\n'; u8::MAX as usize]; pub struct BlockMap { next_block_id: AtomicUsize, @@ -102,6 +102,7 @@ struct Transform { block: Option, } +#[allow(clippy::large_enum_variant)] #[derive(Clone)] pub enum TransformBlock { Custom(Arc), @@ -317,7 +318,7 @@ impl BlockMap { let start_block_ix = match self.blocks[last_block_ix..].binary_search_by(|probe| { probe .position - .to_point(&buffer) + .to_point(buffer) .cmp(&new_buffer_start) .then(Ordering::Greater) }) { @@ -335,7 +336,7 @@ impl BlockMap { match self.blocks[start_block_ix..].binary_search_by(|probe| { probe .position - .to_point(&buffer) + .to_point(buffer) .cmp(&new_buffer_end) .then(Ordering::Greater) }) { @@ -349,14 +350,14 @@ impl BlockMap { self.blocks[start_block_ix..end_block_ix] .iter() .map(|block| { - let mut position = block.position.to_point(&buffer); + let mut position = block.position.to_point(buffer); match block.disposition { BlockDisposition::Above => position.column = 0, BlockDisposition::Below => { position.column = buffer.line_len(position.row) } } - let position = wrap_snapshot.from_point(position, Bias::Left); + let position = wrap_snapshot.make_wrap_point(position, Bias::Left); (position.row(), TransformBlock::Custom(block.clone())) }), ); @@ -366,7 +367,7 @@ impl BlockMap { .map(|excerpt_boundary| { ( wrap_snapshot - .from_point(Point::new(excerpt_boundary.row, 0), Bias::Left) + .make_wrap_point(Point::new(excerpt_boundary.row, 0), Bias::Left) .row(), TransformBlock::ExcerptHeader { key: excerpt_boundary.key, @@ -385,7 +386,7 @@ impl BlockMap { // Place excerpt headers above custom blocks on the same row. blocks_in_edit.sort_unstable_by(|(row_a, block_a), (row_b, block_b)| { - row_a.cmp(&row_b).then_with(|| match (block_a, block_b) { + row_a.cmp(row_b).then_with(|| match (block_a, block_b) { ( TransformBlock::ExcerptHeader { .. }, TransformBlock::ExcerptHeader { .. }, @@ -498,9 +499,9 @@ impl<'a> BlockMapWriter<'a> { ids.push(id); let position = block.position; - let point = position.to_point(&buffer); + let point = position.to_point(buffer); let wrap_row = wrap_snapshot - .from_point(Point::new(point.row, 0), Bias::Left) + .make_wrap_point(Point::new(point.row, 0), Bias::Left) .row(); let start_row = wrap_snapshot.prev_row_boundary(WrapPoint::new(wrap_row, 0)); let end_row = wrap_snapshot @@ -510,7 +511,7 @@ impl<'a> BlockMapWriter<'a> { let block_ix = match self .0 .blocks - .binary_search_by(|probe| probe.position.cmp(&position, &buffer)) + .binary_search_by(|probe| probe.position.cmp(&position, buffer)) { Ok(ix) | Err(ix) => ix, }; @@ -543,11 +544,11 @@ impl<'a> BlockMapWriter<'a> { let mut last_block_buffer_row = None; self.0.blocks.retain(|block| { if block_ids.contains(&block.id) { - let buffer_row = block.position.to_point(&buffer).row; + let buffer_row = block.position.to_point(buffer).row; if last_block_buffer_row != Some(buffer_row) { last_block_buffer_row = Some(buffer_row); let wrap_row = wrap_snapshot - .from_point(Point::new(buffer_row, 0), Bias::Left) + .make_wrap_point(Point::new(buffer_row, 0), Bias::Left) .row(); let start_row = wrap_snapshot.prev_row_boundary(WrapPoint::new(wrap_row, 0)); let end_row = wrap_snapshot @@ -620,7 +621,7 @@ impl BlockSnapshot { } } - pub fn buffer_rows<'a>(&'a self, start_row: u32) -> BlockBufferRows<'a> { + pub fn buffer_rows(&self, start_row: u32) -> BlockBufferRows { let mut cursor = self.transforms.cursor::<(BlockRow, WrapRow)>(); cursor.seek(&BlockRow(start_row), Bias::Right, &()); let (output_start, input_start) = cursor.start(); @@ -638,10 +639,10 @@ impl BlockSnapshot { } } - pub fn blocks_in_range<'a>( - &'a self, + pub fn blocks_in_range( + &self, rows: Range, - ) -> impl Iterator { + ) -> impl Iterator { let mut cursor = self.transforms.cursor::(); cursor.seek(&BlockRow(rows.start), Bias::Right, &()); std::iter::from_fn(move || { @@ -1025,7 +1026,7 @@ mod tests { let buffer_snapshot = buffer.read(cx).snapshot(cx); let subscription = buffer.update(cx, |buffer, _| buffer.subscribe()); let (fold_map, folds_snapshot) = FoldMap::new(buffer_snapshot.clone()); - let (tab_map, tabs_snapshot) = TabMap::new(folds_snapshot.clone(), 1.try_into().unwrap()); + let (tab_map, tabs_snapshot) = TabMap::new(folds_snapshot, 1.try_into().unwrap()); let (wrap_map, wraps_snapshot) = WrapMap::new(tabs_snapshot, font_id, 14.0, None, cx); let mut block_map = BlockMap::new(wraps_snapshot.clone(), 1, 1); @@ -1194,7 +1195,7 @@ mod tests { let buffer = MultiBuffer::build_simple(text, cx); let buffer_snapshot = buffer.read(cx).snapshot(cx); let (_, folds_snapshot) = FoldMap::new(buffer_snapshot.clone()); - let (_, tabs_snapshot) = TabMap::new(folds_snapshot.clone(), 1.try_into().unwrap()); + let (_, tabs_snapshot) = TabMap::new(folds_snapshot, 1.try_into().unwrap()); let (_, wraps_snapshot) = WrapMap::new(tabs_snapshot, font_id, 14.0, Some(60.), cx); let mut block_map = BlockMap::new(wraps_snapshot.clone(), 1, 1); @@ -1262,11 +1263,11 @@ mod tests { let mut buffer_snapshot = buffer.read(cx).snapshot(cx); let (fold_map, folds_snapshot) = FoldMap::new(buffer_snapshot.clone()); - let (tab_map, tabs_snapshot) = TabMap::new(folds_snapshot.clone(), tab_size); + let (tab_map, tabs_snapshot) = TabMap::new(folds_snapshot, tab_size); let (wrap_map, wraps_snapshot) = WrapMap::new(tabs_snapshot, font_id, font_size, wrap_width, cx); let mut block_map = BlockMap::new( - wraps_snapshot.clone(), + wraps_snapshot, buffer_start_header_height, excerpt_header_height, ); @@ -1383,7 +1384,7 @@ mod tests { position.column = buffer_snapshot.line_len(position.row); } }; - let row = wraps_snapshot.from_point(position, Bias::Left).row(); + let row = wraps_snapshot.make_wrap_point(position, Bias::Left).row(); ( row, ExpectedBlock::Custom { @@ -1396,7 +1397,7 @@ mod tests { expected_blocks.extend(buffer_snapshot.excerpt_boundaries_in_range(0..).map( |boundary| { let position = - wraps_snapshot.from_point(Point::new(boundary.row, 0), Bias::Left); + wraps_snapshot.make_wrap_point(Point::new(boundary.row, 0), Bias::Left); ( position.row(), ExpectedBlock::ExcerptHeader { diff --git a/crates/editor/src/display_map/fold_map.rs b/crates/editor/src/display_map/fold_map.rs index a6e5536d15ac6b1ddc4dac29029f11d402351a7c..970910f969ee42fc30048b80fd5735ffa971ca30 100644 --- a/crates/editor/src/display_map/fold_map.rs +++ b/crates/editor/src/display_map/fold_map.rs @@ -41,27 +41,27 @@ impl FoldPoint { &mut self.0.column } - pub fn to_buffer_point(&self, snapshot: &FoldSnapshot) -> Point { + pub fn to_buffer_point(self, snapshot: &FoldSnapshot) -> Point { let mut cursor = snapshot.transforms.cursor::<(FoldPoint, Point)>(); - cursor.seek(self, Bias::Right, &()); + cursor.seek(&self, Bias::Right, &()); let overshoot = self.0 - cursor.start().0 .0; cursor.start().1 + overshoot } - pub fn to_buffer_offset(&self, snapshot: &FoldSnapshot) -> usize { + pub fn to_buffer_offset(self, snapshot: &FoldSnapshot) -> usize { let mut cursor = snapshot.transforms.cursor::<(FoldPoint, Point)>(); - cursor.seek(self, Bias::Right, &()); + cursor.seek(&self, Bias::Right, &()); let overshoot = self.0 - cursor.start().0 .0; snapshot .buffer_snapshot .point_to_offset(cursor.start().1 + overshoot) } - pub fn to_offset(&self, snapshot: &FoldSnapshot) -> FoldOffset { + pub fn to_offset(self, snapshot: &FoldSnapshot) -> FoldOffset { let mut cursor = snapshot .transforms .cursor::<(FoldPoint, TransformSummary)>(); - cursor.seek(self, Bias::Right, &()); + cursor.seek(&self, Bias::Right, &()); let overshoot = self.0 - cursor.start().1.output.lines; let mut offset = cursor.start().1.output.len; if !overshoot.is_zero() { @@ -600,10 +600,7 @@ impl FoldSnapshot { self.transforms.summary().output.longest_row } - pub fn folds_in_range<'a, T>( - &'a self, - range: Range, - ) -> impl Iterator> + pub fn folds_in_range(&self, range: Range) -> impl Iterator> where T: ToOffset, { @@ -689,7 +686,7 @@ impl FoldSnapshot { let ranges = &highlights.1; let start_ix = match ranges.binary_search_by(|probe| { - let cmp = probe.end.cmp(&transform_start, &self.buffer_snapshot()); + let cmp = probe.end.cmp(&transform_start, self.buffer_snapshot()); if cmp.is_gt() { Ordering::Greater } else { @@ -1040,11 +1037,7 @@ impl<'a> Iterator for FoldChunks<'a> { return None; } - let transform = if let Some(item) = self.transform_cursor.item() { - item - } else { - return None; - }; + let transform = self.transform_cursor.item()?; // If we're in a fold, then return the fold's display text and // advance the transform and buffer cursors to the end of the fold. @@ -1150,11 +1143,11 @@ impl Ord for HighlightEndpoint { pub struct FoldOffset(pub usize); impl FoldOffset { - pub fn to_point(&self, snapshot: &FoldSnapshot) -> FoldPoint { + pub fn to_point(self, snapshot: &FoldSnapshot) -> FoldPoint { let mut cursor = snapshot .transforms .cursor::<(FoldOffset, TransformSummary)>(); - cursor.seek(self, Bias::Right, &()); + cursor.seek(&self, Bias::Right, &()); let overshoot = if cursor.item().map_or(true, |t| t.is_fold()) { Point::new(0, (self.0 - cursor.start().0 .0) as u32) } else { @@ -1214,7 +1207,7 @@ mod tests { let buffer_snapshot = buffer.read(cx).snapshot(cx); let mut map = FoldMap::new(buffer_snapshot.clone()).0; - let (mut writer, _, _) = map.write(buffer_snapshot.clone(), vec![]); + let (mut writer, _, _) = map.write(buffer_snapshot, vec![]); let (snapshot2, edits) = writer.fold(vec![ Point::new(0, 2)..Point::new(2, 2), Point::new(2, 4)..Point::new(4, 1), @@ -1245,8 +1238,7 @@ mod tests { ); buffer.snapshot(cx) }); - let (snapshot3, edits) = - map.read(buffer_snapshot.clone(), subscription.consume().into_inner()); + let (snapshot3, edits) = map.read(buffer_snapshot, subscription.consume().into_inner()); assert_eq!(snapshot3.text(), "123a…c123c…eeeee"); assert_eq!( edits, @@ -1276,7 +1268,7 @@ mod tests { let (mut writer, _, _) = map.write(buffer_snapshot.clone(), vec![]); writer.unfold(Some(Point::new(0, 4)..Point::new(0, 4)), true); - let (snapshot6, _) = map.read(buffer_snapshot.clone(), vec![]); + let (snapshot6, _) = map.read(buffer_snapshot, vec![]); assert_eq!(snapshot6.text(), "123aaaaa\nbbbbbb\nccc123456eee"); } @@ -1314,7 +1306,7 @@ mod tests { // Create two adjacent folds. let (mut writer, _, _) = map.write(buffer_snapshot.clone(), vec![]); writer.fold(vec![0..2, 2..5]); - let (snapshot, _) = map.read(buffer_snapshot.clone(), vec![]); + let (snapshot, _) = map.read(buffer_snapshot, vec![]); assert_eq!(snapshot.text(), "…fghijkl"); // Edit within one of the folds. @@ -1322,8 +1314,7 @@ mod tests { buffer.edit([(0..1, "12345")], None, cx); buffer.snapshot(cx) }); - let (snapshot, _) = - map.read(buffer_snapshot.clone(), subscription.consume().into_inner()); + let (snapshot, _) = map.read(buffer_snapshot, subscription.consume().into_inner()); assert_eq!(snapshot.text(), "12345…fghijkl"); } } @@ -1340,7 +1331,7 @@ mod tests { Point::new(1, 2)..Point::new(3, 2), Point::new(3, 1)..Point::new(4, 1), ]); - let (snapshot, _) = map.read(buffer_snapshot.clone(), vec![]); + let (snapshot, _) = map.read(buffer_snapshot, vec![]); assert_eq!(snapshot.text(), "aa…eeeee"); } @@ -1357,14 +1348,14 @@ mod tests { Point::new(0, 2)..Point::new(2, 2), Point::new(3, 1)..Point::new(4, 1), ]); - let (snapshot, _) = map.read(buffer_snapshot.clone(), vec![]); + let (snapshot, _) = map.read(buffer_snapshot, vec![]); assert_eq!(snapshot.text(), "aa…cccc\nd…eeeee"); let buffer_snapshot = buffer.update(cx, |buffer, cx| { buffer.edit([(Point::new(2, 2)..Point::new(3, 1), "")], None, cx); buffer.snapshot(cx) }); - let (snapshot, _) = map.read(buffer_snapshot.clone(), subscription.consume().into_inner()); + let (snapshot, _) = map.read(buffer_snapshot, subscription.consume().into_inner()); assert_eq!(snapshot.text(), "aa…eeeee"); } @@ -1661,7 +1652,7 @@ mod tests { Point::new(3, 1)..Point::new(4, 1), ]); - let (snapshot, _) = map.read(buffer_snapshot.clone(), vec![]); + let (snapshot, _) = map.read(buffer_snapshot, vec![]); assert_eq!(snapshot.text(), "aa…cccc\nd…eeeee\nffffff\n"); assert_eq!( snapshot.buffer_rows(0).collect::>(), diff --git a/crates/editor/src/display_map/tab_map.rs b/crates/editor/src/display_map/tab_map.rs index 4f718a91398816fd62de8e49be06a48c1c5724c5..4d89767a1977a1fdd3d66a2ed3fd5cba1b065e39 100644 --- a/crates/editor/src/display_map/tab_map.rs +++ b/crates/editor/src/display_map/tab_map.rs @@ -253,7 +253,7 @@ impl TabSnapshot { ) } - pub fn from_point(&self, point: Point, bias: Bias) -> TabPoint { + pub fn make_tab_point(&self, point: Point, bias: Bias) -> TabPoint { self.to_tab_point(self.fold_snapshot.to_fold_point(point, bias)) } @@ -290,7 +290,7 @@ impl TabSnapshot { } fn collapse_tabs( - mut chars: impl Iterator, + chars: impl Iterator, column: usize, bias: Bias, tab_size: NonZeroU32, @@ -298,7 +298,7 @@ impl TabSnapshot { let mut expanded_bytes = 0; let mut expanded_chars = 0; let mut collapsed_bytes = 0; - while let Some(c) = chars.next() { + for c in chars { if expanded_bytes >= column { break; } @@ -410,7 +410,7 @@ impl<'a> std::ops::AddAssign<&'a Self> for TextSummary { } // Handles a tab width <= 16 -const SPACES: &'static str = " "; +const SPACES: &str = " "; pub struct TabChunks<'a> { fold_chunks: fold_map::FoldChunks<'a>, @@ -518,7 +518,7 @@ mod tests { let (mut fold_map, _) = FoldMap::new(buffer_snapshot.clone()); fold_map.randomly_mutate(&mut rng); - let (folds_snapshot, _) = fold_map.read(buffer_snapshot.clone(), vec![]); + let (folds_snapshot, _) = fold_map.read(buffer_snapshot, vec![]); log::info!("FoldMap text: {:?}", folds_snapshot.text()); let (_, tabs_snapshot) = TabMap::new(folds_snapshot.clone(), tab_size); diff --git a/crates/editor/src/display_map/wrap_map.rs b/crates/editor/src/display_map/wrap_map.rs index aa90f942dbfd8a71aec6591c76e9d59506d820ec..ee6ce2860ded8f830481258e5a8e4c59d7bbeba9 100644 --- a/crates/editor/src/display_map/wrap_map.rs +++ b/crates/editor/src/display_map/wrap_map.rs @@ -285,7 +285,7 @@ impl WrapMap { if tab_snapshot.version <= self.snapshot.tab_snapshot.version { to_remove_len += 1; } else { - let interpolated_edits = self.snapshot.interpolate(tab_snapshot.clone(), &edits); + let interpolated_edits = self.snapshot.interpolate(tab_snapshot.clone(), edits); self.edits_since_sync = self.edits_since_sync.compose(&interpolated_edits); self.interpolated_edits = self.interpolated_edits.compose(&interpolated_edits); } @@ -394,7 +394,7 @@ impl WrapSnapshot { new_rows: Range, } - let mut tab_edits_iter = tab_edits.into_iter().peekable(); + let mut tab_edits_iter = tab_edits.iter().peekable(); let mut row_edits = Vec::new(); while let Some(edit) = tab_edits_iter.next() { let mut row_edit = RowEdit { @@ -671,11 +671,11 @@ impl WrapSnapshot { self.tab_snapshot.to_point(self.to_tab_point(point), bias) } - pub fn from_point(&self, point: Point, bias: Bias) -> WrapPoint { - self.from_tab_point(self.tab_snapshot.from_point(point, bias)) + pub fn make_wrap_point(&self, point: Point, bias: Bias) -> WrapPoint { + self.tab_point_to_wrap_point(self.tab_snapshot.make_tab_point(point, bias)) } - pub fn from_tab_point(&self, point: TabPoint) -> WrapPoint { + pub fn tab_point_to_wrap_point(&self, point: TabPoint) -> WrapPoint { let mut cursor = self.transforms.cursor::<(TabPoint, WrapPoint)>(); cursor.seek(&point, Bias::Right, &()); WrapPoint(cursor.start().1 .0 + (point.0 - cursor.start().0 .0)) @@ -691,7 +691,7 @@ impl WrapSnapshot { } } - self.from_tab_point(self.tab_snapshot.clip_point(self.to_tab_point(point), bias)) + self.tab_point_to_wrap_point(self.tab_snapshot.clip_point(self.to_tab_point(point), bias)) } pub fn prev_row_boundary(&self, mut point: WrapPoint) -> u32 { @@ -1301,7 +1301,7 @@ mod tests { end_row += 1; let mut expected_text = self.text_chunks(start_row).collect::(); - if expected_text.ends_with("\n") { + if expected_text.ends_with('\n') { expected_text.push('\n'); } let mut expected_text = expected_text diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index a07a59e87709c0030a4480066b83e7632bc0443f..e8d3ad4650304acaf85ae8ed1799cd3391b5f89d 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -425,6 +425,7 @@ pub struct Editor { vertical_scroll_margin: f32, placeholder_text: Option>, highlighted_rows: Option>, + #[allow(clippy::type_complexity)] background_highlights: BTreeMap Color, Vec>)>, nav_history: Option, context_menu: Option, @@ -475,6 +476,7 @@ impl Default for SelectionHistoryMode { #[derive(Default)] struct SelectionHistory { + #[allow(clippy::type_complexity)] selections_by_transaction: HashMap]>, Option]>>)>, mode: SelectionHistoryMode, @@ -492,6 +494,7 @@ impl SelectionHistory { .insert(transaction_id, (selections, None)); } + #[allow(clippy::type_complexity)] fn transaction( &self, transaction_id: TransactionId, @@ -499,6 +502,7 @@ impl SelectionHistory { self.selections_by_transaction.get(&transaction_id) } + #[allow(clippy::type_complexity)] fn transaction_mut( &mut self, transaction_id: TransactionId, @@ -1023,7 +1027,7 @@ impl Editor { background_highlights: Default::default(), nav_history: None, context_menu: None, - mouse_context_menu: cx.add_view(|cx| context_menu::ContextMenu::new(cx)), + mouse_context_menu: cx.add_view(context_menu::ContextMenu::new), completion_tasks: Default::default(), next_completion_id: 0, available_code_actions: Default::default(), @@ -1649,7 +1653,7 @@ impl Editor { if let Some(tail) = self.columnar_selection_tail.as_ref() { let tail = tail.to_display_point(&display_map); self.select_columns(tail, position, goal_column, &display_map, cx); - } else if let Some(mut pending) = self.selections.pending_anchor().clone() { + } else if let Some(mut pending) = self.selections.pending_anchor() { let buffer = self.buffer.read(cx).snapshot(cx); let head; let tail; @@ -1764,10 +1768,10 @@ impl Editor { if start_column <= display_map.line_len(row) && !display_map.is_block_line(row) { let start = display_map .clip_point(DisplayPoint::new(row, start_column), Bias::Left) - .to_point(&display_map); + .to_point(display_map); let end = display_map .clip_point(DisplayPoint::new(row, end_column), Bias::Right) - .to_point(&display_map); + .to_point(display_map); if reversed { Some(end..start) } else { @@ -1915,7 +1919,7 @@ impl Editor { cursor.row -= 1; cursor.column = buffer.line_len(cursor.row); } - new_selection.map(|_| cursor.clone()) + new_selection.map(|_| cursor) }) .collect(); @@ -2279,7 +2283,7 @@ impl Editor { let query = Self::completion_query(&self.buffer.read(cx).read(cx), position.clone()); let completions = project.update(cx, |project, cx| { - project.completions(&buffer, buffer_position.clone(), cx) + project.completions(&buffer, buffer_position, cx) }); let id = post_inc(&mut self.next_completion_id); @@ -2369,7 +2373,7 @@ impl Editor { }; let selections = self.selections.all::(cx); let buffer = buffer_handle.read(cx); - let old_range = completion.old_range.to_offset(&buffer); + let old_range = completion.old_range.to_offset(buffer); let old_text = buffer.text_for_range(old_range.clone()).collect::(); let newest_selection = self.selections.newest_anchor(); @@ -2807,7 +2811,7 @@ impl Editor { let mut tabstop_ranges = tabstop .iter() .flat_map(|tabstop_range| { - let mut delta = 0 as isize; + let mut delta = 0_isize; insertion_ranges.iter().map(move |insertion_range| { let insertion_start = insertion_range.start as isize + delta; delta += @@ -2871,7 +2875,7 @@ impl Editor { } if let Some(current_ranges) = snippet.ranges.get(snippet.active_index) { self.change_selections(Some(Autoscroll::Fit), cx, |s| { - s.select_anchor_ranges(current_ranges.into_iter().cloned()) + s.select_anchor_ranges(current_ranges.iter().cloned()) }); // If snippet state is not at the last tabstop, push it back on the stack if snippet.active_index + 1 < snippet.ranges.len() { @@ -2953,7 +2957,7 @@ impl Editor { } }) }); - this.insert(&"", cx); + this.insert("", cx); }); } @@ -3220,13 +3224,13 @@ impl Editor { } let buffer = &display_map.buffer_snapshot; - let mut edit_start = Point::new(rows.start, 0).to_offset(&buffer); + let mut edit_start = Point::new(rows.start, 0).to_offset(buffer); let edit_end; let cursor_buffer_row; if buffer.max_point().row >= rows.end { // If there's a line after the range, delete the \n from the end of the row range // and position the cursor on the next line. - edit_end = Point::new(rows.end, 0).to_offset(&buffer); + edit_end = Point::new(rows.end, 0).to_offset(buffer); cursor_buffer_row = rows.end; } else { // If there isn't a line after the range, delete the \n from the line before the @@ -3292,7 +3296,7 @@ impl Editor { while let Some(next_selection) = selections_iter.peek() { let next_rows = next_selection.spanned_rows(false, &display_map); - if next_rows.start <= rows.end - 1 { + if next_rows.start < rows.end { rows.end = next_rows.end; selections_iter.next().unwrap(); } else { @@ -3414,7 +3418,7 @@ impl Editor { } // If we didn't move line(s), preserve the existing selections - new_selections.extend(contiguous_row_selections.drain(..)); + new_selections.append(&mut contiguous_row_selections); } self.transact(cx, |this, cx| { @@ -3519,7 +3523,7 @@ impl Editor { } // If we didn't move line(s), preserve the existing selections - new_selections.extend(contiguous_row_selections.drain(..)); + new_selections.append(&mut contiguous_row_selections); } self.transact(cx, |this, cx| { @@ -3831,7 +3835,7 @@ impl Editor { if !selection.is_empty() && !line_mode { selection.goal = SelectionGoal::None; } - let (cursor, goal) = movement::up(&map, selection.start, selection.goal, false); + let (cursor, goal) = movement::up(map, selection.start, selection.goal, false); selection.collapse_to(cursor, goal); }); }) @@ -3863,7 +3867,7 @@ impl Editor { if !selection.is_empty() && !line_mode { selection.goal = SelectionGoal::None; } - let (cursor, goal) = movement::down(&map, selection.end, selection.goal, false); + let (cursor, goal) = movement::down(map, selection.end, selection.goal, false); selection.collapse_to(cursor, goal); }); }); @@ -4779,12 +4783,10 @@ impl Editor { } else { search_start = buffer.len(); } + } else if search_start == 0 { + break; } else { - if search_start == 0 { - break; - } else { - search_start = 0; - } + search_start = 0; } } } @@ -5107,13 +5109,7 @@ impl Editor { })?; let rename = workspace.project().clone().update(cx, |project, cx| { - project.perform_rename( - buffer.clone(), - range.start.clone(), - new_name.clone(), - true, - cx, - ) + project.perform_rename(buffer.clone(), range.start, new_name.clone(), true, cx) }); Some(cx.spawn(|workspace, mut cx| async move { @@ -5292,7 +5288,7 @@ impl Editor { fn push_to_selection_history(&mut self) { self.selection_history.push(SelectionHistoryEntry { - selections: self.selections.disjoint_anchors().clone(), + selections: self.selections.disjoint_anchors(), select_next_state: self.select_next_state.clone(), add_selections_state: self.add_selections_state.clone(), }); @@ -5325,7 +5321,7 @@ impl Editor { .update(cx, |buffer, cx| buffer.start_transaction_at(now, cx)) { self.selection_history - .insert_transaction(tx_id, self.selections.disjoint_anchors().clone()); + .insert_transaction(tx_id, self.selections.disjoint_anchors()); } } @@ -5339,7 +5335,7 @@ impl Editor { .update(cx, |buffer, cx| buffer.end_transaction_at(now, cx)) { if let Some((_, end_selections)) = self.selection_history.transaction_mut(tx_id) { - *end_selections = Some(self.selections.disjoint_anchors().clone()); + *end_selections = Some(self.selections.disjoint_anchors()); } else { log::error!("unexpectedly ended a transaction that wasn't started by this editor"); } @@ -5441,7 +5437,7 @@ impl Editor { } let end = end.unwrap_or(max_point); - return start.to_point(display_map)..end.to_point(display_map); + start.to_point(display_map)..end.to_point(display_map) } pub fn fold_selected_ranges(&mut self, _: &FoldSelectedRanges, cx: &mut ViewContext) { @@ -5588,6 +5584,7 @@ impl Editor { cx.notify(); } + #[allow(clippy::type_complexity)] pub fn clear_background_highlights( &mut self, cx: &mut ViewContext, @@ -5629,7 +5626,7 @@ impl Editor { .chain(write_highlights) .flat_map(move |ranges| { let start_ix = match ranges.binary_search_by(|probe| { - let cmp = probe.end.cmp(&left_position, &buffer); + let cmp = probe.end.cmp(&left_position, buffer); if cmp.is_ge() { Ordering::Greater } else { @@ -5642,7 +5639,7 @@ impl Editor { let right_position = right_position.clone(); ranges[start_ix..] .iter() - .take_while(move |range| range.start.cmp(&right_position, &buffer).is_le()) + .take_while(move |range| range.start.cmp(&right_position, buffer).is_le()) }) } @@ -5657,7 +5654,7 @@ impl Editor { for (color_fetcher, ranges) in self.background_highlights.values() { let color = color_fetcher(theme); let start_ix = match ranges.binary_search_by(|probe| { - let cmp = probe.end.cmp(&search_range.start, &buffer); + let cmp = probe.end.cmp(&search_range.start, buffer); if cmp.is_gt() { Ordering::Greater } else { @@ -5667,7 +5664,7 @@ impl Editor { Ok(i) | Err(i) => i, }; for range in &ranges[start_ix..] { - if range.start.cmp(&search_range.end, &buffer).is_ge() { + if range.start.cmp(&search_range.end, buffer).is_ge() { break; } let start = range @@ -5899,7 +5896,7 @@ impl Editor { let (_, ranges) = self.text_highlights::(cx)?; Some( ranges - .into_iter() + .iter() .map(move |range| { range.start.to_offset_utf16(&snapshot)..range.end.to_offset_utf16(&snapshot) }) @@ -6138,10 +6135,8 @@ impl View for Editor { let new_selected_ranges = if let Some(range_utf16) = range_utf16 { let range_utf16 = OffsetUtf16(range_utf16.start)..OffsetUtf16(range_utf16.end); Some(this.selection_replacement_ranges(range_utf16, cx)) - } else if let Some(marked_ranges) = this.marked_text_ranges(cx) { - Some(marked_ranges) } else { - None + this.marked_text_ranges(cx) }; if let Some(new_selected_ranges) = new_selected_ranges { @@ -6202,7 +6197,7 @@ impl View for Editor { let snapshot = this.buffer.read(cx).read(cx); this.selections .disjoint_anchors() - .into_iter() + .iter() .map(|selection| { selection.start.bias_left(&*snapshot)..selection.end.bias_right(&*snapshot) }) @@ -6385,9 +6380,9 @@ impl InvalidationStack { if selections.len() == region.ranges().len() { selections .iter() - .zip(region.ranges().iter().map(|r| r.to_offset(&buffer))) + .zip(region.ranges().iter().map(|r| r.to_offset(buffer))) .all(|(selection, invalidation_range)| { - let head = selection.head().to_offset(&buffer); + let head = selection.head().to_offset(buffer); invalidation_range.start <= head && invalidation_range.end >= head }) } else { @@ -6602,7 +6597,7 @@ pub fn styled_runs_for_code_label<'a>( } else { return Default::default(); }; - let mut muted_style = style.clone(); + let mut muted_style = style; muted_style.highlight(fade_out); let mut runs = SmallVec::<[(Range, HighlightStyle); 3]>::new(); @@ -7104,7 +7099,7 @@ mod tests { fn test_navigation_history(cx: &mut gpui::MutableAppContext) { cx.set_global(Settings::test(cx)); use workspace::Item; - let (_, pane) = cx.add_window(Default::default(), |cx| Pane::new(cx)); + let (_, pane) = cx.add_window(Default::default(), Pane::new); let buffer = MultiBuffer::build_simple(&sample_text(300, 5, 'a'), cx); cx.add_view(&pane, |cx| { @@ -7194,7 +7189,7 @@ mod tests { Box::new(NavigationData { cursor_anchor: invalid_anchor.clone(), cursor_position: invalid_point, - scroll_top_anchor: invalid_anchor.clone(), + scroll_top_anchor: invalid_anchor, scroll_top_row: invalid_point.row, scroll_position: Default::default(), }), @@ -8704,98 +8699,102 @@ mod tests { fn test_transpose(cx: &mut gpui::MutableAppContext) { cx.set_global(Settings::test(cx)); - cx.add_window(Default::default(), |cx| { - let mut editor = build_editor(MultiBuffer::build_simple("abc", cx), cx); + _ = cx + .add_window(Default::default(), |cx| { + let mut editor = build_editor(MultiBuffer::build_simple("abc", cx), cx); - editor.change_selections(None, cx, |s| s.select_ranges([1..1])); - editor.transpose(&Default::default(), cx); - assert_eq!(editor.text(cx), "bac"); - assert_eq!(editor.selections.ranges(cx), [2..2]); + editor.change_selections(None, cx, |s| s.select_ranges([1..1])); + editor.transpose(&Default::default(), cx); + assert_eq!(editor.text(cx), "bac"); + assert_eq!(editor.selections.ranges(cx), [2..2]); - editor.transpose(&Default::default(), cx); - assert_eq!(editor.text(cx), "bca"); - assert_eq!(editor.selections.ranges(cx), [3..3]); + editor.transpose(&Default::default(), cx); + assert_eq!(editor.text(cx), "bca"); + assert_eq!(editor.selections.ranges(cx), [3..3]); - editor.transpose(&Default::default(), cx); - assert_eq!(editor.text(cx), "bac"); - assert_eq!(editor.selections.ranges(cx), [3..3]); + editor.transpose(&Default::default(), cx); + assert_eq!(editor.text(cx), "bac"); + assert_eq!(editor.selections.ranges(cx), [3..3]); - editor - }) - .1; + editor + }) + .1; - cx.add_window(Default::default(), |cx| { - let mut editor = build_editor(MultiBuffer::build_simple("abc\nde", cx), cx); + _ = cx + .add_window(Default::default(), |cx| { + let mut editor = build_editor(MultiBuffer::build_simple("abc\nde", cx), cx); - editor.change_selections(None, cx, |s| s.select_ranges([3..3])); - editor.transpose(&Default::default(), cx); - assert_eq!(editor.text(cx), "acb\nde"); - assert_eq!(editor.selections.ranges(cx), [3..3]); + editor.change_selections(None, cx, |s| s.select_ranges([3..3])); + editor.transpose(&Default::default(), cx); + assert_eq!(editor.text(cx), "acb\nde"); + assert_eq!(editor.selections.ranges(cx), [3..3]); - editor.change_selections(None, cx, |s| s.select_ranges([4..4])); - editor.transpose(&Default::default(), cx); - assert_eq!(editor.text(cx), "acbd\ne"); - assert_eq!(editor.selections.ranges(cx), [5..5]); + editor.change_selections(None, cx, |s| s.select_ranges([4..4])); + editor.transpose(&Default::default(), cx); + assert_eq!(editor.text(cx), "acbd\ne"); + assert_eq!(editor.selections.ranges(cx), [5..5]); - editor.transpose(&Default::default(), cx); - assert_eq!(editor.text(cx), "acbde\n"); - assert_eq!(editor.selections.ranges(cx), [6..6]); + editor.transpose(&Default::default(), cx); + assert_eq!(editor.text(cx), "acbde\n"); + assert_eq!(editor.selections.ranges(cx), [6..6]); - editor.transpose(&Default::default(), cx); - assert_eq!(editor.text(cx), "acbd\ne"); - assert_eq!(editor.selections.ranges(cx), [6..6]); + editor.transpose(&Default::default(), cx); + assert_eq!(editor.text(cx), "acbd\ne"); + assert_eq!(editor.selections.ranges(cx), [6..6]); - editor - }) - .1; + editor + }) + .1; - cx.add_window(Default::default(), |cx| { - let mut editor = build_editor(MultiBuffer::build_simple("abc\nde", cx), cx); + _ = cx + .add_window(Default::default(), |cx| { + let mut editor = build_editor(MultiBuffer::build_simple("abc\nde", cx), cx); - editor.change_selections(None, cx, |s| s.select_ranges([1..1, 2..2, 4..4])); - editor.transpose(&Default::default(), cx); - assert_eq!(editor.text(cx), "bacd\ne"); - assert_eq!(editor.selections.ranges(cx), [2..2, 3..3, 5..5]); + editor.change_selections(None, cx, |s| s.select_ranges([1..1, 2..2, 4..4])); + editor.transpose(&Default::default(), cx); + assert_eq!(editor.text(cx), "bacd\ne"); + assert_eq!(editor.selections.ranges(cx), [2..2, 3..3, 5..5]); - editor.transpose(&Default::default(), cx); - assert_eq!(editor.text(cx), "bcade\n"); - assert_eq!(editor.selections.ranges(cx), [3..3, 4..4, 6..6]); + editor.transpose(&Default::default(), cx); + assert_eq!(editor.text(cx), "bcade\n"); + assert_eq!(editor.selections.ranges(cx), [3..3, 4..4, 6..6]); - editor.transpose(&Default::default(), cx); - assert_eq!(editor.text(cx), "bcda\ne"); - assert_eq!(editor.selections.ranges(cx), [4..4, 6..6]); + editor.transpose(&Default::default(), cx); + assert_eq!(editor.text(cx), "bcda\ne"); + assert_eq!(editor.selections.ranges(cx), [4..4, 6..6]); - editor.transpose(&Default::default(), cx); - assert_eq!(editor.text(cx), "bcade\n"); - assert_eq!(editor.selections.ranges(cx), [4..4, 6..6]); + editor.transpose(&Default::default(), cx); + assert_eq!(editor.text(cx), "bcade\n"); + assert_eq!(editor.selections.ranges(cx), [4..4, 6..6]); - editor.transpose(&Default::default(), cx); - assert_eq!(editor.text(cx), "bcaed\n"); - assert_eq!(editor.selections.ranges(cx), [5..5, 6..6]); + editor.transpose(&Default::default(), cx); + assert_eq!(editor.text(cx), "bcaed\n"); + assert_eq!(editor.selections.ranges(cx), [5..5, 6..6]); - editor - }) - .1; + editor + }) + .1; - cx.add_window(Default::default(), |cx| { - let mut editor = build_editor(MultiBuffer::build_simple("🍐🏀✋", cx), cx); + _ = cx + .add_window(Default::default(), |cx| { + let mut editor = build_editor(MultiBuffer::build_simple("🍐🏀✋", cx), cx); - editor.change_selections(None, cx, |s| s.select_ranges([4..4])); - editor.transpose(&Default::default(), cx); - assert_eq!(editor.text(cx), "🏀🍐✋"); - assert_eq!(editor.selections.ranges(cx), [8..8]); + editor.change_selections(None, cx, |s| s.select_ranges([4..4])); + editor.transpose(&Default::default(), cx); + assert_eq!(editor.text(cx), "🏀🍐✋"); + assert_eq!(editor.selections.ranges(cx), [8..8]); - editor.transpose(&Default::default(), cx); - assert_eq!(editor.text(cx), "🏀✋🍐"); - assert_eq!(editor.selections.ranges(cx), [11..11]); + editor.transpose(&Default::default(), cx); + assert_eq!(editor.text(cx), "🏀✋🍐"); + assert_eq!(editor.selections.ranges(cx), [11..11]); - editor.transpose(&Default::default(), cx); - assert_eq!(editor.text(cx), "🏀🍐✋"); - assert_eq!(editor.selections.ranges(cx), [11..11]); + editor.transpose(&Default::default(), cx); + assert_eq!(editor.text(cx), "🏀🍐✋"); + assert_eq!(editor.selections.ranges(cx), [11..11]); - editor - }) - .1; + editor + }) + .1; } #[gpui::test] @@ -9347,7 +9346,7 @@ mod tests { let buffer = cx.add_model(|cx| Buffer::new(0, text, cx).with_language(language, cx)); let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx)); let (_, view) = cx.add_window(|cx| build_editor(buffer, cx)); - view.condition(&cx, |view, cx| !view.buffer.read(cx).is_parsing(cx)) + view.condition(cx, |view, cx| !view.buffer.read(cx).is_parsing(cx)) .await; view.update(cx, |view, cx| { @@ -9506,7 +9505,7 @@ mod tests { let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx)); let (_, editor) = cx.add_window(|cx| build_editor(buffer, cx)); editor - .condition(&cx, |editor, cx| !editor.buffer.read(cx).is_parsing(cx)) + .condition(cx, |editor, cx| !editor.buffer.read(cx).is_parsing(cx)) .await; editor.update(cx, |editor, cx| { @@ -9566,7 +9565,7 @@ mod tests { let buffer = cx.add_model(|cx| Buffer::new(0, text, cx).with_language(language, cx)); let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx)); let (_, view) = cx.add_window(|cx| build_editor(buffer, cx)); - view.condition(&cx, |view, cx| !view.buffer.read(cx).is_parsing(cx)) + view.condition(cx, |view, cx| !view.buffer.read(cx).is_parsing(cx)) .await; view.update(cx, |view, cx| { @@ -9742,7 +9741,7 @@ mod tests { let buffer = cx.add_model(|cx| Buffer::new(0, text, cx).with_language(language, cx)); let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx)); let (_, view) = cx.add_window(|cx| build_editor(buffer, cx)); - view.condition(&cx, |view, cx| !view.buffer.read(cx).is_parsing(cx)) + view.condition(cx, |view, cx| !view.buffer.read(cx).is_parsing(cx)) .await; view.update(cx, |view, cx| { @@ -9824,7 +9823,7 @@ mod tests { let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx)); let (_, editor) = cx.add_window(|cx| build_editor(buffer, cx)); editor - .condition(&cx, |view, cx| !view.buffer.read(cx).is_parsing(cx)) + .condition(cx, |view, cx| !view.buffer.read(cx).is_parsing(cx)) .await; editor.update(cx, |editor, cx| { @@ -10028,7 +10027,7 @@ mod tests { })) .await; - let fs = FakeFs::new(cx.background().clone()); + let fs = FakeFs::new(cx.background()); fs.insert_file("/file.rs", Default::default()).await; let project = Project::test(fs, ["/file.rs".as_ref()], cx).await; @@ -10142,7 +10141,7 @@ mod tests { })) .await; - let fs = FakeFs::new(cx.background().clone()); + let fs = FakeFs::new(cx.background()); fs.insert_file("/file.rs", Default::default()).await; let project = Project::test(fs, ["/file.rs".as_ref()], cx).await; @@ -10425,7 +10424,7 @@ mod tests { .map(|completion_text| lsp::CompletionItem { label: completion_text.to_string(), text_edit: Some(lsp::CompletionTextEdit::Edit(lsp::TextEdit { - range: replace_range.clone(), + range: replace_range, new_text: completion_text.to_string(), })), ..Default::default() @@ -10856,7 +10855,7 @@ mod tests { let buffer = cx.add_model(|cx| Buffer::new(0, text, cx).with_language(language, cx)); let buffer = cx.add_model(|cx| MultiBuffer::singleton(buffer, cx)); let (_, view) = cx.add_window(|cx| build_editor(buffer, cx)); - view.condition(&cx, |view, cx| !view.buffer.read(cx).is_parsing(cx)) + view.condition(cx, |view, cx| !view.buffer.read(cx).is_parsing(cx)) .await; view.update(cx, |view, cx| { @@ -11084,7 +11083,7 @@ mod tests { let match_indices = [4, 6, 7, 8]; assert_eq!( combine_syntax_and_fuzzy_match_highlights( - &string, + string, Default::default(), syntax_ranges.into_iter(), &match_indices, diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 25a71b93dc0d6099135f18c6c2c39c6eb60b333f..da1e78179a5e0096cece863d4a43e6b74934231a 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -110,6 +110,7 @@ impl EditorElement { self.update_view(cx, |view, cx| view.snapshot(cx)) } + #[allow(clippy::too_many_arguments)] fn mouse_down( &self, position: Vector2F, @@ -696,6 +697,7 @@ impl EditorElement { cx.scene.pop_layer(); } + #[allow(clippy::too_many_arguments)] fn paint_highlighted_range( &self, range: Range, @@ -857,7 +859,7 @@ impl EditorElement { .style .placeholder_text .as_ref() - .unwrap_or_else(|| &self.style.text); + .unwrap_or(&self.style.text); let placeholder_text = snapshot.placeholder_text(); let placeholder_lines = placeholder_text .as_ref() @@ -866,7 +868,7 @@ impl EditorElement { .skip(rows.start as usize) .chain(iter::repeat("")) .take(rows.len()); - return placeholder_lines + placeholder_lines .map(|line| { cx.text_layout_cache.layout_str( line, @@ -881,7 +883,7 @@ impl EditorElement { )], ) }) - .collect(); + .collect() } else { let style = &self.style; let chunks = snapshot.chunks(rows.clone(), true).map(|chunk| { @@ -926,14 +928,15 @@ impl EditorElement { layout_highlighted_chunks( chunks, &style.text, - &cx.text_layout_cache, - &cx.font_cache, + cx.text_layout_cache, + cx.font_cache, MAX_LINE_LEN, rows.len() as usize, ) } } + #[allow(clippy::too_many_arguments)] fn layout_blocks( &mut self, rows: Range, @@ -1299,7 +1302,9 @@ impl Element for EditorElement { } // Render the local selections in the leader's color when following. - let local_replica_id = view.leader_replica_id.unwrap_or(view.replica_id(cx)); + let local_replica_id = view + .leader_replica_id + .unwrap_or_else(|| view.replica_id(cx)); selections.push(( local_replica_id, @@ -1357,19 +1362,19 @@ impl Element for EditorElement { self.update_view(cx.app, |view, cx| { let clamped = view.clamp_scroll_left(scroll_max.x()); - let autoscrolled; - if autoscroll_horizontally { - autoscrolled = view.autoscroll_horizontally( + + let autoscrolled = if autoscroll_horizontally { + view.autoscroll_horizontally( start_row, text_size.x(), scroll_width, em_width, &line_layouts, cx, - ); + ) } else { - autoscrolled = false; - } + false + }; if clamped || autoscrolled { snapshot = view.snapshot(cx); @@ -1991,8 +1996,8 @@ mod tests { let layouts = editor.update(cx, |editor, cx| { let snapshot = editor.snapshot(cx); let mut presenter = cx.build_presenter(window_id, 30.); - let mut layout_cx = presenter.build_layout_context(Vector2F::zero(), false, cx); - element.layout_line_numbers(0..6, &Default::default(), &snapshot, &mut layout_cx) + let layout_cx = presenter.build_layout_context(Vector2F::zero(), false, cx); + element.layout_line_numbers(0..6, &Default::default(), &snapshot, &layout_cx) }); assert_eq!(layouts.len(), 6); } diff --git a/crates/editor/src/hover_popover.rs b/crates/editor/src/hover_popover.rs index 37a2a66e0562192eea28f0477ad3bcbe660dc180..d8240920c06c841b46f8c5904824973ba18a8c75 100644 --- a/crates/editor/src/hover_popover.rs +++ b/crates/editor/src/hover_popover.rs @@ -158,7 +158,7 @@ fn show_hover( // query the LSP for hover info let hover_request = cx.update(|cx| { project.update(cx, |project, cx| { - project.hover(&buffer, buffer_position.clone(), cx) + project.hover(&buffer, buffer_position, cx) }) }); @@ -222,7 +222,7 @@ fn show_hover( Some(InfoPopover { project: project.clone(), - symbol_range: range.clone(), + symbol_range: range, contents: hover_result.contents, }) }); diff --git a/crates/editor/src/items.rs b/crates/editor/src/items.rs index 59f9a98448f1368a0b3b4d2252cda0923f2b2c61..cb7632d5e2352bb7b784c0a37fd43ff2e92b19e5 100644 --- a/crates/editor/src/items.rs +++ b/crates/editor/src/items.rs @@ -76,14 +76,14 @@ impl FollowableItem for Editor { }) .collect::>>()?; if !selections.is_empty() { - editor.set_selections_from_remote(selections.into(), cx); + editor.set_selections_from_remote(selections, cx); } if let Some(anchor) = state.scroll_top_anchor { editor.set_scroll_top_anchor( Anchor { buffer_id: Some(state.buffer_id as usize), - excerpt_id: excerpt_id.clone(), + excerpt_id, text_anchor: language::proto::deserialize_anchor(anchor) .ok_or_else(|| anyhow!("invalid scroll top"))?, }, @@ -198,19 +198,17 @@ impl FollowableItem for Editor { if !selections.is_empty() { self.set_selections_from_remote(selections, cx); self.request_autoscroll_remotely(Autoscroll::Newest, cx); - } else { - if let Some(anchor) = message.scroll_top_anchor { - self.set_scroll_top_anchor( - Anchor { - buffer_id: Some(buffer_id), - excerpt_id: excerpt_id.clone(), - text_anchor: language::proto::deserialize_anchor(anchor) - .ok_or_else(|| anyhow!("invalid scroll top"))?, - }, - vec2f(message.scroll_x, message.scroll_y), - cx, - ); - } + } else if let Some(anchor) = message.scroll_top_anchor { + self.set_scroll_top_anchor( + Anchor { + buffer_id: Some(buffer_id), + excerpt_id, + text_anchor: language::proto::deserialize_anchor(anchor) + .ok_or_else(|| anyhow!("invalid scroll top"))?, + }, + vec2f(message.scroll_x, message.scroll_y), + cx, + ); } } } @@ -436,8 +434,7 @@ impl Item for Editor { .buffer() .read(cx) .as_singleton() - .expect("cannot call save_as on an excerpt list") - .clone(); + .expect("cannot call save_as on an excerpt list"); project.update(cx, |project, cx| { project.save_buffer_as(buffer, abs_path, cx) @@ -503,6 +500,12 @@ pub struct CursorPosition { _observe_active_editor: Option, } +impl Default for CursorPosition { + fn default() -> Self { + Self::new() + } +} + impl CursorPosition { pub fn new() -> Self { Self { diff --git a/crates/editor/src/link_go_to_definition.rs b/crates/editor/src/link_go_to_definition.rs index cbdeb3019117bbf7b59c6f363761fc62d5ff3f91..c1544306d649022ab3ba6df3c570eb9cb6c482c0 100644 --- a/crates/editor/src/link_go_to_definition.rs +++ b/crates/editor/src/link_go_to_definition.rs @@ -83,7 +83,7 @@ pub fn update_go_to_definition_link( &point, &editor.link_go_to_definition_state.last_mouse_location, ) { - if a.cmp(&b, &snapshot.buffer_snapshot).is_eq() { + if a.cmp(b, &snapshot.buffer_snapshot).is_eq() { return; } } @@ -126,7 +126,7 @@ pub fn cmd_shift_changed( LinkDefinitionKind::Symbol }; - show_link_definition(kind, editor, point.clone(), snapshot, cx); + show_link_definition(kind, editor, point, snapshot, cx); } else { hide_link_definition(editor, cx) } @@ -204,12 +204,10 @@ pub fn show_link_definition( // query the LSP for definition info let definition_request = cx.update(|cx| { project.update(cx, |project, cx| match definition_kind { - LinkDefinitionKind::Symbol => { - project.definition(&buffer, buffer_position.clone(), cx) - } + LinkDefinitionKind::Symbol => project.definition(&buffer, buffer_position, cx), LinkDefinitionKind::Type => { - project.type_definition(&buffer, buffer_position.clone(), cx) + project.type_definition(&buffer, buffer_position, cx) } }) }); @@ -363,7 +361,7 @@ fn go_to_fetched_definition_of_kind( editor_handle.update(cx, |editor, cx| { editor.select( &Select(SelectPhase::Begin { - position: point.clone(), + position: point, add: false, click_count: 1, }), diff --git a/crates/editor/src/multi_buffer.rs b/crates/editor/src/multi_buffer.rs index b9e8b7e6829b05c6d82a87d2677ac8cc8098d8e7..53021870c6e3d9363d19fe641bdd27b82550980a 100644 --- a/crates/editor/src/multi_buffer.rs +++ b/crates/editor/src/multi_buffer.rs @@ -33,7 +33,7 @@ use text::{ use theme::SyntaxTheme; use util::post_inc; -const NEWLINES: &'static [u8] = &[b'\n'; u8::MAX as usize]; +const NEWLINES: &[u8] = &[b'\n'; u8::MAX as usize]; pub type ExcerptId = Locator; @@ -289,10 +289,16 @@ impl MultiBuffer { self.read(cx).has_conflict() } + // The `is_empty` signature doesn't match what clippy expects + #[allow(clippy::len_without_is_empty)] pub fn len(&self, cx: &AppContext) -> usize { self.read(cx).len() } + pub fn is_empty(&self, cx: &AppContext) -> bool { + self.len(cx) != 0 + } + pub fn symbols_containing( &self, offset: T, @@ -338,6 +344,7 @@ impl MultiBuffer { _ => Default::default(), }; + #[allow(clippy::type_complexity)] let mut buffer_edits: HashMap, Arc, bool, u32)>> = Default::default(); let mut cursor = snapshot.excerpts.cursor::(); @@ -594,13 +601,13 @@ impl MultiBuffer { break; } - let mut start = excerpt.range.context.start.clone(); - let mut end = excerpt.range.context.end.clone(); + let mut start = excerpt.range.context.start; + let mut end = excerpt.range.context.end; if excerpt.id == selection.start.excerpt_id { - start = selection.start.text_anchor.clone(); + start = selection.start.text_anchor; } if excerpt.id == selection.end.excerpt_id { - end = selection.end.text_anchor.clone(); + end = selection.end.text_anchor; } selections_by_buffer .entry(excerpt.buffer_id) @@ -666,7 +673,7 @@ impl MultiBuffer { while let Some(transaction) = self.history.pop_undo() { let mut undone = false; for (buffer_id, buffer_transaction_id) in &mut transaction.buffer_transactions { - if let Some(BufferState { buffer, .. }) = self.buffers.borrow().get(&buffer_id) { + if let Some(BufferState { buffer, .. }) = self.buffers.borrow().get(buffer_id) { undone |= buffer.update(cx, |buffer, cx| { let undo_to = *buffer_transaction_id; if let Some(entry) = buffer.peek_undo_stack() { @@ -693,7 +700,7 @@ impl MultiBuffer { while let Some(transaction) = self.history.pop_redo() { let mut redone = false; for (buffer_id, buffer_transaction_id) in &mut transaction.buffer_transactions { - if let Some(BufferState { buffer, .. }) = self.buffers.borrow().get(&buffer_id) { + if let Some(BufferState { buffer, .. }) = self.buffers.borrow().get(buffer_id) { redone |= buffer.update(cx, |buffer, cx| { let redo_to = *buffer_transaction_id; if let Some(entry) = buffer.peek_redo_stack() { @@ -982,8 +989,8 @@ impl MultiBuffer { } // If point is at the end of the buffer, the last excerpt is returned - pub fn point_to_buffer_offset<'a, T: ToOffset>( - &'a self, + pub fn point_to_buffer_offset( + &self, point: T, cx: &AppContext, ) -> Option<(ModelHandle, usize)> { @@ -1004,8 +1011,8 @@ impl MultiBuffer { }) } - pub fn range_to_buffer_ranges<'a, T: ToOffset>( - &'a self, + pub fn range_to_buffer_ranges( + &self, range: Range, cx: &AppContext, ) -> Vec<(ModelHandle, Range)> { @@ -1112,8 +1119,8 @@ impl MultiBuffer { cx.notify(); } - pub fn text_anchor_for_position<'a, T: ToOffset>( - &'a self, + pub fn text_anchor_for_position( + &self, position: T, cx: &AppContext, ) -> Option<(ModelHandle, language::Anchor)> { @@ -1439,7 +1446,7 @@ impl MultiBuffer { .flat_map(|b| &b.excerpts) .cloned() .collect::>(); - if excerpt_ids.len() == 0 || (rng.gen() && excerpt_ids.len() < max_excerpts) { + if excerpt_ids.is_empty() || (rng.gen() && excerpt_ids.len() < max_excerpts) { let buffer_handle = if rng.gen() || self.buffers.borrow().is_empty() { let text = RandomCharIter::new(&mut *rng).take(10).collect::(); buffers.push(cx.add_model(|cx| Buffer::new(0, text, cx))); @@ -1514,8 +1521,8 @@ impl MultiBuffer { .choose(rng) .map(|state| state.buffer.clone()); - if rng.gen() && buffer.is_some() { - buffer.unwrap().update(cx, |buffer, cx| { + if let Some(buffer) = buffer { + buffer.update(cx, |buffer, cx| { if rng.gen() { buffer.randomly_edit(rng, mutation_count, cx); } else { @@ -1542,10 +1549,7 @@ impl MultiBufferSnapshot { .collect() } - pub fn reversed_chars_at<'a, T: ToOffset>( - &'a self, - position: T, - ) -> impl Iterator + 'a { + pub fn reversed_chars_at(&self, position: T) -> impl Iterator + '_ { let mut offset = position.to_offset(self); let mut cursor = self.excerpts.cursor::(); cursor.seek(&offset, Bias::Left, &()); @@ -1579,16 +1583,13 @@ impl MultiBufferSnapshot { .flat_map(|c| c.chars().rev()) } - pub fn chars_at<'a, T: ToOffset>(&'a self, position: T) -> impl Iterator + 'a { + pub fn chars_at(&self, position: T) -> impl Iterator + '_ { let offset = position.to_offset(self); self.text_for_range(offset..self.len()) .flat_map(|chunk| chunk.chars()) } - pub fn text_for_range<'a, T: ToOffset>( - &'a self, - range: Range, - ) -> impl Iterator { + pub fn text_for_range(&self, range: Range) -> impl Iterator + '_ { self.chunks(range, false).map(|chunk| chunk.text) } @@ -1655,6 +1656,10 @@ impl MultiBufferSnapshot { self.excerpts.summary().text.len } + pub fn is_empty(&self) -> bool { + self.excerpts.summary().text.len == 0 + } + pub fn max_buffer_row(&self) -> u32 { self.excerpts.summary().max_buffer_row } @@ -1737,7 +1742,7 @@ impl MultiBufferSnapshot { *cursor.start() + overshoot } - pub fn bytes_in_range<'a, T: ToOffset>(&'a self, range: Range) -> MultiBufferBytes<'a> { + pub fn bytes_in_range(&self, range: Range) -> MultiBufferBytes { let range = range.start.to_offset(self)..range.end.to_offset(self); let mut excerpts = self.excerpts.cursor::(); excerpts.seek(&range.start, Bias::Right, &()); @@ -1760,7 +1765,7 @@ impl MultiBufferSnapshot { } } - pub fn buffer_rows<'a>(&'a self, start_row: u32) -> MultiBufferRows<'a> { + pub fn buffer_rows(&self, start_row: u32) -> MultiBufferRows { let mut result = MultiBufferRows { buffer_row_range: 0..0, excerpts: self.excerpts.cursor(), @@ -1769,11 +1774,7 @@ impl MultiBufferSnapshot { result } - pub fn chunks<'a, T: ToOffset>( - &'a self, - range: Range, - language_aware: bool, - ) -> MultiBufferChunks<'a> { + pub fn chunks(&self, range: Range, language_aware: bool) -> MultiBufferChunks { let range = range.start.to_offset(self)..range.end.to_offset(self); let mut chunks = MultiBufferChunks { range: range.clone(), @@ -2033,7 +2034,7 @@ impl MultiBufferSnapshot { self.excerpts.summary().text.clone() } - pub fn text_summary_for_range<'a, D, O>(&'a self, range: Range) -> D + pub fn text_summary_for_range(&self, range: Range) -> D where D: TextDimension, O: ToOffset, @@ -2204,15 +2205,15 @@ impl MultiBufferSnapshot { let (anchor_ix, anchor) = anchors.next().unwrap(); let mut anchor = anchor.clone(); - // Leave min and max anchors unchanged. - if *old_excerpt_id == ExcerptId::max() || *old_excerpt_id == ExcerptId::min() { - kept_position = true; - } - // If the old excerpt still exists at this location, then leave - // the anchor unchanged. - else if next_excerpt.map_or(false, |excerpt| { + let id_invalid = + *old_excerpt_id == ExcerptId::max() || *old_excerpt_id == ExcerptId::min(); + let still_exists = next_excerpt.map_or(false, |excerpt| { excerpt.id == *old_excerpt_id && excerpt.contains(&anchor) - }) { + }); + + // Leave min and max anchors unchanged if invalid or + // if the old excerpt still exists at this location + if id_invalid || still_exists { kept_position = true; } // If the old excerpt no longer exists at this location, then attempt to @@ -2239,7 +2240,7 @@ impl MultiBufferSnapshot { .cmp(&excerpt.range.context.end, &excerpt.buffer) .is_gt() { - text_anchor = excerpt.range.context.end.clone(); + text_anchor = excerpt.range.context.end; } Anchor { buffer_id: Some(excerpt.buffer_id), @@ -2256,7 +2257,7 @@ impl MultiBufferSnapshot { .cmp(&excerpt.range.context.start, &excerpt.buffer) .is_lt() { - text_anchor = excerpt.range.context.start.clone(); + text_anchor = excerpt.range.context.start; } Anchor { buffer_id: Some(excerpt.buffer_id), @@ -2349,10 +2350,10 @@ impl MultiBufferSnapshot { } } - pub fn excerpt_boundaries_in_range<'a, R, T>( - &'a self, + pub fn excerpt_boundaries_in_range( + &self, range: R, - ) -> impl Iterator + 'a + ) -> impl Iterator + '_ where R: RangeBounds, T: ToOffset, @@ -2635,13 +2636,12 @@ impl MultiBufferSnapshot { cursor .take_while(move |excerpt| excerpt.id <= range.end.excerpt_id) .flat_map(move |excerpt| { - let mut query_range = - excerpt.range.context.start.clone()..excerpt.range.context.end.clone(); + let mut query_range = excerpt.range.context.start..excerpt.range.context.end; if excerpt.id == range.start.excerpt_id { - query_range.start = range.start.text_anchor.clone(); + query_range.start = range.start.text_anchor; } if excerpt.id == range.end.excerpt_id { - query_range.end = range.end.text_anchor.clone(); + query_range.end = range.end.text_anchor; } excerpt @@ -2652,12 +2652,12 @@ impl MultiBufferSnapshot { let mut start = Anchor { buffer_id: Some(excerpt.buffer_id), excerpt_id: excerpt.id.clone(), - text_anchor: selection.start.clone(), + text_anchor: selection.start, }; let mut end = Anchor { buffer_id: Some(excerpt.buffer_id), excerpt_id: excerpt.id.clone(), - text_anchor: selection.end.clone(), + text_anchor: selection.end, }; if range.start.cmp(&start, self).is_gt() { start = range.start.clone(); @@ -2862,11 +2862,7 @@ impl Excerpt { } } - fn chunks_in_range<'a>( - &'a self, - range: Range, - language_aware: bool, - ) -> ExcerptChunks<'a> { + fn chunks_in_range(&self, range: Range, language_aware: bool) -> ExcerptChunks { let content_start = self.range.context.start.to_offset(&self.buffer); let chunks_start = content_start + range.start; let chunks_end = content_start + cmp::min(range.end, self.text_summary.len); @@ -2913,12 +2909,12 @@ impl Excerpt { .cmp(&self.range.context.start, &self.buffer) .is_lt() { - self.range.context.start.clone() + self.range.context.start } else if text_anchor .cmp(&self.range.context.end, &self.buffer) .is_gt() { - self.range.context.end.clone() + self.range.context.end } else { text_anchor } @@ -3835,7 +3831,7 @@ mod tests { "Removing excerpt {}: {:?}", ix, buffer - .text_for_range(range.to_offset(&buffer)) + .text_for_range(range.to_offset(buffer)) .collect::(), ); } @@ -3851,7 +3847,7 @@ mod tests { let bias = if rng.gen() { Bias::Left } else { Bias::Right }; log::info!("Creating anchor at {} with bias {:?}", offset, bias); anchors.push(multibuffer.anchor_at(offset, bias)); - anchors.sort_by(|a, b| a.cmp(&b, &multibuffer)); + anchors.sort_by(|a, b| a.cmp(b, &multibuffer)); } 40..=44 if !anchors.is_empty() => { let multibuffer = multibuffer.read(cx).read(cx); @@ -3896,7 +3892,7 @@ mod tests { let prev_excerpt_id = excerpt_ids .get(prev_excerpt_ix) .cloned() - .unwrap_or(ExcerptId::max()); + .unwrap_or_else(ExcerptId::max); let excerpt_ix = (prev_excerpt_ix + 1).min(expected_excerpts.len()); log::info!( @@ -3984,11 +3980,7 @@ mod tests { assert_eq!( snapshot.max_buffer_row(), - expected_buffer_rows - .into_iter() - .filter_map(|r| r) - .max() - .unwrap() + expected_buffer_rows.into_iter().flatten().max().unwrap() ); let mut excerpt_starts = excerpt_starts.into_iter(); diff --git a/crates/editor/src/multi_buffer/anchor.rs b/crates/editor/src/multi_buffer/anchor.rs index 1340ea814dfe746b3251415ee463d59e6486760b..cb8a1692b986d21ff534143edf13304d260aab97 100644 --- a/crates/editor/src/multi_buffer/anchor.rs +++ b/crates/editor/src/multi_buffer/anchor.rs @@ -34,7 +34,7 @@ impl Anchor { &self.excerpt_id } - pub fn cmp<'a>(&self, other: &Anchor, snapshot: &MultiBufferSnapshot) -> Ordering { + pub fn cmp(&self, other: &Anchor, snapshot: &MultiBufferSnapshot) -> Ordering { let excerpt_id_cmp = self.excerpt_id.cmp(&other.excerpt_id); if excerpt_id_cmp.is_eq() { if self.excerpt_id == ExcerptId::min() || self.excerpt_id == ExcerptId::max() { @@ -111,15 +111,15 @@ impl AnchorRangeExt for Range { fn cmp(&self, other: &Range, buffer: &MultiBufferSnapshot) -> Ordering { match self.start.cmp(&other.start, buffer) { Ordering::Equal => other.end.cmp(&self.end, buffer), - ord @ _ => ord, + ord => ord, } } fn to_offset(&self, content: &MultiBufferSnapshot) -> Range { - self.start.to_offset(&content)..self.end.to_offset(&content) + self.start.to_offset(content)..self.end.to_offset(content) } fn to_point(&self, content: &MultiBufferSnapshot) -> Range { - self.start.to_point(&content)..self.end.to_point(&content) + self.start.to_point(content)..self.end.to_point(content) } } diff --git a/crates/editor/src/selections_collection.rs b/crates/editor/src/selections_collection.rs index a05a46fc6d363ec3b92f51120cf283e9788ddbcf..9d6450f8ec93307af913a88f4d194d94a475650f 100644 --- a/crates/editor/src/selections_collection.rs +++ b/crates/editor/src/selections_collection.rs @@ -68,7 +68,7 @@ impl SelectionsCollection { self.pending = other.pending.clone(); } - pub fn count<'a>(&self) -> usize { + pub fn count(&self) -> usize { let mut count = self.disjoint.len(); if self.pending.is_some() { count += 1; @@ -365,7 +365,7 @@ impl<'a> MutableSelectionsCollection<'a> { let mut changed = false; self.collection.disjoint = self .disjoint - .into_iter() + .iter() .filter(|selection| { let found = selection.id == selection_id; changed |= found; @@ -464,7 +464,7 @@ impl<'a> MutableSelectionsCollection<'a> { return true; } - return false; + false } pub fn insert_range(&mut self, range: Range) @@ -729,8 +729,7 @@ impl<'a> MutableSelectionsCollection<'a> { kept_end }; if !kept_head { - selections_with_lost_position - .insert(selection.id, selection.head().excerpt_id.clone()); + selections_with_lost_position.insert(selection.id, selection.head().excerpt_id); } Selection { @@ -761,10 +760,8 @@ impl<'a> MutableSelectionsCollection<'a> { kept_end }; if !kept_head { - selections_with_lost_position.insert( - pending.selection.id, - pending.selection.head().excerpt_id.clone(), - ); + selections_with_lost_position + .insert(pending.selection.id, pending.selection.head().excerpt_id); } pending.selection.start = start; @@ -814,5 +811,5 @@ fn resolve>( selection: &Selection, buffer: &MultiBufferSnapshot, ) -> Selection { - selection.map(|p| p.summary::(&buffer)) + selection.map(|p| p.summary::(buffer)) } diff --git a/crates/file_finder/src/file_finder.rs b/crates/file_finder/src/file_finder.rs index dbdc3ec3299497d61bf7f4f35a2261017b72cf88..768e58407e98deae848cdbc812e44d3b972a014f 100644 --- a/crates/file_finder/src/file_finder.rs +++ b/crates/file_finder/src/file_finder.rs @@ -262,7 +262,7 @@ impl PickerDelegate for FileFinder { self.labels_for_match(path_match); Flex::column() .with_child( - Label::new(file_name.to_string(), style.label.clone()) + Label::new(file_name, style.label.clone()) .with_highlights(file_name_positions) .boxed(), ) @@ -333,7 +333,7 @@ mod tests { cx.dispatch_action(window_id, SelectNext); cx.dispatch_action(window_id, Confirm); active_pane - .condition(&cx, |pane, _| pane.active_item().is_some()) + .condition(cx, |pane, _| pane.active_item().is_some()) .await; cx.read(|cx| { let active_item = active_pane.read(cx).active_item().unwrap(); diff --git a/crates/fsevent/examples/events.rs b/crates/fsevent/examples/events.rs index 73ec6405d4286785ec40954c9881afa57eb13c34..43678dd6d6bc10ebe6f9ea94c71dbd03e85faf34 100644 --- a/crates/fsevent/examples/events.rs +++ b/crates/fsevent/examples/events.rs @@ -4,7 +4,7 @@ use std::{env::args, path::Path, time::Duration}; fn main() { let paths = args().skip(1).collect::>(); let paths = paths.iter().map(Path::new).collect::>(); - assert!(paths.len() > 0, "Must pass 1 or more paths as arguments"); + assert!(!paths.is_empty(), "Must pass 1 or more paths as arguments"); let (stream, _handle) = EventStream::new(&paths, Duration::from_millis(100)); stream.run(|events| { eprintln!("event batch"); diff --git a/crates/fsevent/src/fsevent.rs b/crates/fsevent/src/fsevent.rs index 4b4d3766bd60f77e1c800eccdbb9fbe5aeb8de6b..59c03ccc65099bea12baa080e028e4aceaa996c3 100644 --- a/crates/fsevent/src/fsevent.rs +++ b/crates/fsevent/src/fsevent.rs @@ -233,11 +233,9 @@ impl EventStream { } } - if !events.is_empty() { - if !callback(events) { - fs::FSEventStreamStop(stream_ref); - cf::CFRunLoopStop(cf::CFRunLoopGetCurrent()); - } + if !events.is_empty() && !callback(events) { + fs::FSEventStreamStop(stream_ref); + cf::CFRunLoopStop(cf::CFRunLoopGetCurrent()); } } } diff --git a/crates/fuzzy/src/char_bag.rs b/crates/fuzzy/src/char_bag.rs index 135c5a768e0d7b0d3ddc16ebeafe614efb7c2b3b..8fc36368a159b671e8199248cbdef19929961459 100644 --- a/crates/fuzzy/src/char_bag.rs +++ b/crates/fuzzy/src/char_bag.rs @@ -10,15 +10,15 @@ impl CharBag { fn insert(&mut self, c: char) { let c = c.to_ascii_lowercase(); - if c >= 'a' && c <= 'z' { + if ('a'..='z').contains(&c) { let mut count = self.0; - let idx = c as u8 - 'a' as u8; - count = count >> (idx * 2); + let idx = c as u8 - b'a'; + count >>= idx * 2; count = ((count << 1) | 1) & 3; - count = count << idx * 2; + count <<= idx * 2; self.0 |= count; - } else if c >= '0' && c <= '9' { - let idx = c as u8 - '0' as u8; + } else if ('0'..='9').contains(&c) { + let idx = c as u8 - b'0'; self.0 |= 1 << (idx + 52); } else if c == '-' { self.0 |= 1 << 62; diff --git a/crates/fuzzy/src/fuzzy.rs b/crates/fuzzy/src/fuzzy.rs index 401ab33d7f79a37101e6da93e7baa966dd3ffc09..2f108b6274287e773fdf7cfe57a56d609f5245e8 100644 --- a/crates/fuzzy/src/fuzzy.rs +++ b/crates/fuzzy/src/fuzzy.rs @@ -35,7 +35,7 @@ trait Match: Ord { trait MatchCandidate { fn has_chars(&self, bag: CharBag) -> bool; - fn to_string<'a>(&'a self) -> Cow<'a, str>; + fn to_string(&self) -> Cow<'_, str>; } #[derive(Clone, Debug)] @@ -64,6 +64,9 @@ pub trait PathMatchCandidateSet<'a>: Send + Sync { type Candidates: Iterator>; fn id(&self) -> usize; fn len(&self) -> usize; + fn is_empty(&self) -> bool { + self.len() == 0 + } fn prefix(&self) -> Arc; fn candidates(&'a self, start: usize) -> Self::Candidates; } @@ -239,7 +242,7 @@ pub async fn match_strings( if results.is_empty() { results = segment_result; } else { - util::extend_sorted(&mut results, segment_result, max_results, |a, b| b.cmp(&a)); + util::extend_sorted(&mut results, segment_result, max_results, |a, b| b.cmp(a)); } } results @@ -299,7 +302,7 @@ pub async fn match_paths<'a, Set: PathMatchCandidateSet<'a>>( candidate_set.prefix(), candidates, results, - &cancel_flag, + cancel_flag, ); } if tree_end >= segment_end { @@ -317,7 +320,7 @@ pub async fn match_paths<'a, Set: PathMatchCandidateSet<'a>>( if results.is_empty() { results = segment_result; } else { - util::extend_sorted(&mut results, segment_result, max_results, |a, b| b.cmp(&a)); + util::extend_sorted(&mut results, segment_result, max_results, |a, b| b.cmp(a)); } } results @@ -426,7 +429,7 @@ impl<'a> Matcher<'a> { lowercase_candidate_chars.push(c.to_ascii_lowercase()); } - if !self.find_last_positions(&lowercase_prefix, &lowercase_candidate_chars) { + if !self.find_last_positions(lowercase_prefix, &lowercase_candidate_chars) { continue; } @@ -439,13 +442,13 @@ impl<'a> Matcher<'a> { let score = self.score_match( &candidate_chars, &lowercase_candidate_chars, - &prefix, - &lowercase_prefix, + prefix, + lowercase_prefix, ); if score > 0.0 { let mut mat = build_match(&candidate, score); - if let Err(i) = results.binary_search_by(|m| mat.cmp(&m)) { + if let Err(i) = results.binary_search_by(|m| mat.cmp(m)) { if results.len() < self.max_results { mat.set_positions(self.match_positions.clone()); results.insert(i, mat); @@ -523,6 +526,7 @@ impl<'a> Matcher<'a> { score } + #[allow(clippy::too_many_arguments)] fn recursive_score_match( &mut self, path: &[char], @@ -579,9 +583,9 @@ impl<'a> Matcher<'a> { if last == '/' { char_score = 0.9; - } else if last == '-' || last == '_' || last == ' ' || last.is_numeric() { - char_score = 0.8; - } else if last.is_lowercase() && curr.is_uppercase() { + } else if (last == '-' || last == '_' || last == ' ' || last.is_numeric()) + || (last.is_lowercase() && curr.is_uppercase()) + { char_score = 0.8; } else if last == '.' { char_score = 0.7; @@ -662,18 +666,18 @@ mod tests { let mut query: &[char] = &['d', 'c']; let mut matcher = Matcher::new(query, query, query.into(), false, 10); let result = matcher.find_last_positions(&['a', 'b', 'c'], &['b', 'd', 'e', 'f']); - assert_eq!(result, false); + assert!(!result); query = &['c', 'd']; let mut matcher = Matcher::new(query, query, query.into(), false, 10); let result = matcher.find_last_positions(&['a', 'b', 'c'], &['b', 'd', 'e', 'f']); - assert_eq!(result, true); + assert!(result); assert_eq!(matcher.last_positions, vec![2, 4]); query = &['z', '/', 'z', 'f']; let mut matcher = Matcher::new(query, query, query.into(), false, 10); let result = matcher.find_last_positions(&['z', 'e', 'd', '/'], &['z', 'e', 'd', '/', 'f']); - assert_eq!(result, true); + assert!(result); assert_eq!(matcher.last_positions, vec![0, 3, 4, 8]); } @@ -741,7 +745,7 @@ mod tests { fn match_query<'a>( query: &str, smart_case: bool, - paths: &Vec<&'a str>, + paths: &[&'a str], ) -> Vec<(&'a str, Vec)> { let lowercase_query = query.to_lowercase().chars().collect::>(); let query = query.chars().collect::>(); diff --git a/crates/gpui/build.rs b/crates/gpui/build.rs index a9d126763d79788bbf2bec2784da35d26666fd33..836d586c26bea742d7b31832d0b17b64d0295a05 100644 --- a/crates/gpui/build.rs +++ b/crates/gpui/build.rs @@ -41,7 +41,7 @@ fn compile_context_predicate_parser() { .compile("tree_sitter_context_predicate"); } -const SHADER_HEADER_PATH: &'static str = "./src/platform/mac/shaders/shaders.h"; +const SHADER_HEADER_PATH: &str = "./src/platform/mac/shaders/shaders.h"; fn compile_metal_shaders() { let shader_path = "./src/platform/mac/shaders/shaders.metal"; diff --git a/crates/gpui/examples/text.rs b/crates/gpui/examples/text.rs index 8e0153fe38792e034f028a8582f07ac8815362dd..d4e873f039c7d907e71887e5b10325fa9ba41e37 100644 --- a/crates/gpui/examples/text.rs +++ b/crates/gpui/examples/text.rs @@ -85,11 +85,11 @@ impl gpui::Element for TextElement { text, font_size, &[ - (1, normal.clone()), - (1, bold.clone()), - (1, normal.clone()), - (1, bold.clone()), - (text.len() - 4, normal.clone()), + (1, normal), + (1, bold), + (1, normal), + (1, bold), + (text.len() - 4, normal), ], ); diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index c028c5de738e3d1b5ff51ed55e655c40ffaf4007..9071f98dfe3f39f116103507a6e2bf5a92b20671 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -432,7 +432,7 @@ impl TestAppContext { first_entity_id: usize, ) -> Self { let mut cx = MutableAppContext::new( - foreground.clone(), + foreground, background, platform, foreground_platform.clone(), @@ -964,6 +964,7 @@ pub struct MutableAppContext { release_observations: Arc>>>, action_dispatch_observations: Arc>>, + #[allow(clippy::type_complexity)] presenters_and_platform_windows: HashMap>, Box)>, foreground: Rc, @@ -1172,7 +1173,9 @@ impl MutableAppContext { F: 'static + FnMut(&mut V, &A, &mut ViewContext) -> Option>>, { self.add_action(move |view, action, cx| { - handler(view, action, cx).map(|task| task.detach_and_log_err(cx)); + if let Some(task) = handler(view, action, cx) { + task.detach_and_log_err(cx); + } }) } @@ -1240,7 +1243,7 @@ impl MutableAppContext { .cx .views .remove(&(window_id, view_id)) - .ok_or(anyhow!("view not found"))?; + .ok_or_else(|| anyhow!("view not found"))?; let element = view.render(params, self); self.cx.views.insert((window_id, view_id), view); Ok(element) @@ -1252,6 +1255,7 @@ impl MutableAppContext { titlebar_height: f32, ) -> HashMap { self.start_frame(); + #[allow(clippy::needless_collect)] let view_ids = self .views .keys() @@ -1263,6 +1267,7 @@ impl MutableAppContext { } }) .collect::>(); + view_ids .into_iter() .map(|view_id| { @@ -2401,7 +2406,7 @@ impl MutableAppContext { let mut invalidation = self .cx .windows - .get_mut(&window_id) + .get_mut(window_id) .unwrap() .invalidation .take(); @@ -2626,7 +2631,7 @@ impl MutableAppContext { fn handle_action_dispatch_notification_effect(&mut self, action_id: TypeId) { let mut callbacks = mem::take(&mut *self.action_dispatch_observations.lock()); - for (_, callback) in &mut callbacks { + for callback in callbacks.values_mut() { callback(action_id, self); } self.action_dispatch_observations.lock().extend(callbacks); @@ -3228,7 +3233,7 @@ pub trait AnyView { cx: &mut MutableAppContext, ) -> Option>>>; fn ui_name(&self) -> &'static str; - fn render<'a>(&mut self, params: RenderParams, cx: &mut MutableAppContext) -> ElementBox; + fn render(&mut self, params: RenderParams, cx: &mut MutableAppContext) -> ElementBox; fn on_focus_in( &mut self, cx: &mut MutableAppContext, @@ -3304,7 +3309,7 @@ where T::ui_name() } - fn render<'a>(&mut self, params: RenderParams, cx: &mut MutableAppContext) -> ElementBox { + fn render(&mut self, params: RenderParams, cx: &mut MutableAppContext) -> ElementBox { View::render(self, &mut RenderContext::new(params, cx)) } @@ -3611,7 +3616,7 @@ impl Deref for ModelContext<'_, M> { type Target = MutableAppContext; fn deref(&self) -> &Self::Target { - &self.app + self.app } } @@ -4140,7 +4145,7 @@ impl Deref for ViewContext<'_, M> { type Target = MutableAppContext; fn deref(&self) -> &Self::Target { - &self.app + self.app } } @@ -4290,7 +4295,7 @@ impl ModelHandle { cx.read_model(self) } - pub fn read_with<'a, C, F, S>(&self, cx: &C, read: F) -> S + pub fn read_with(&self, cx: &C, read: F) -> S where C: ReadModelWith, F: FnOnce(&T, &AppContext) -> S, @@ -4381,7 +4386,6 @@ impl ModelHandle { } }), cx.subscribe(self, { - let tx = tx.clone(); move |_, _, _| { tx.unbounded_send(()).ok(); } @@ -5258,6 +5262,7 @@ pub enum Subscription { ReleaseObservation { id: usize, entity_id: usize, + #[allow(clippy::type_complexity)] observations: Option>>>>, }, @@ -5407,7 +5412,7 @@ impl Drop for Subscription { } Subscription::ActionObservation { id, observations } => { if let Some(observations) = observations.as_ref().and_then(Weak::upgrade) { - observations.lock().remove(&id); + observations.lock().remove(id); } } Subscription::WindowActivationObservation { @@ -5465,6 +5470,7 @@ lazy_static! { #[derive(Default)] pub struct LeakDetector { next_handle_id: usize, + #[allow(clippy::type_complexity)] handle_backtraces: HashMap< usize, ( @@ -5502,11 +5508,9 @@ impl LeakDetector { pub fn assert_dropped(&mut self, entity_id: usize) { if let Some((type_name, backtraces)) = self.handle_backtraces.get_mut(&entity_id) { - for trace in backtraces.values_mut() { - if let Some(trace) = trace { - trace.resolve(); - eprintln!("{:?}", crate::util::CwdBacktrace(trace)); - } + for trace in backtraces.values_mut().flatten() { + trace.resolve(); + eprintln!("{:?}", crate::util::CwdBacktrace(trace)); } let hint = if *LEAK_BACKTRACE { @@ -5534,11 +5538,9 @@ impl LeakDetector { type_name.unwrap_or("entity"), id ); - for trace in backtraces.values_mut() { - if let Some(trace) = trace { - trace.resolve(); - eprintln!("{:?}", crate::util::CwdBacktrace(trace)); - } + for trace in backtraces.values_mut().flatten() { + trace.resolve(); + eprintln!("{:?}", crate::util::CwdBacktrace(trace)); } found_leaks = true; } @@ -6586,7 +6588,7 @@ mod tests { let subscription = subscription.clone(); move |_, _, e, _| { subscription.borrow_mut().take(); - events.borrow_mut().push(e.clone()); + events.borrow_mut().push(*e); } })); }); @@ -7158,8 +7160,8 @@ mod tests { let model = cx.add_model(|_| Counter(0)); - let condition1 = model.condition(&cx, |model, _| model.0 == 2); - let condition2 = model.condition(&cx, |model, _| model.0 == 3); + let condition1 = model.condition(cx, |model, _| model.0 == 2); + let condition2 = model.condition(cx, |model, _| model.0 == 3); smol::pin!(condition1, condition2); model.update(cx, |model, cx| model.inc(cx)); @@ -7186,7 +7188,7 @@ mod tests { } let model = cx.add_model(|_| Model); - model.condition(&cx, |_, _| false).await; + model.condition(cx, |_, _| false).await; } #[crate::test(self)] @@ -7199,7 +7201,7 @@ mod tests { } let model = cx.add_model(|_| Model); - let condition = model.condition(&cx, |_, _| false); + let condition = model.condition(cx, |_, _| false); cx.update(|_| drop(model)); condition.await; } @@ -7231,8 +7233,8 @@ mod tests { let (_, view) = cx.add_window(|_| Counter(0)); - let condition1 = view.condition(&cx, |view, _| view.0 == 2); - let condition2 = view.condition(&cx, |view, _| view.0 == 3); + let condition1 = view.condition(cx, |view, _| view.0 == 2); + let condition2 = view.condition(cx, |view, _| view.0 == 3); smol::pin!(condition1, condition2); view.update(cx, |view, cx| view.inc(cx)); @@ -7268,7 +7270,7 @@ mod tests { } let (_, view) = cx.add_window(|_| View); - view.condition(&cx, |_, _| false).await; + view.condition(cx, |_, _| false).await; } #[crate::test(self)] @@ -7293,7 +7295,7 @@ mod tests { let (_, root_view) = cx.add_window(|_| View); let view = cx.add_view(&root_view, |_| View); - let condition = view.condition(&cx, |_, _| false); + let condition = view.condition(cx, |_, _| false); cx.update(|_| drop(view)); condition.await; } diff --git a/crates/gpui/src/elements.rs b/crates/gpui/src/elements.rs index 7a0da8dad96208b77916a2372a9baab68f4d771d..8fb7bcb2789e7f666182c3d95a25c4008722cbf6 100644 --- a/crates/gpui/src/elements.rs +++ b/crates/gpui/src/elements.rs @@ -389,9 +389,9 @@ impl ElementBox { } } -impl Into for ElementBox { - fn into(self) -> ElementRc { - self.0 +impl From for ElementRc { + fn from(val: ElementBox) -> Self { + val.0 } } diff --git a/crates/gpui/src/elements/empty.rs b/crates/gpui/src/elements/empty.rs index 9a67115c2382e0cf12796073718db725ae6aa148..a7c2fc1d60ae62b1b2a77f00b14efabfb32c31e1 100644 --- a/crates/gpui/src/elements/empty.rs +++ b/crates/gpui/src/elements/empty.rs @@ -11,13 +11,14 @@ use crate::{ }; use crate::{Element, Event, EventContext, LayoutContext, PaintContext, SizeConstraint}; +#[derive(Default)] pub struct Empty { collapsed: bool, } impl Empty { pub fn new() -> Self { - Self { collapsed: false } + Self::default() } pub fn collapsed(mut self) -> Self { diff --git a/crates/gpui/src/elements/expanded.rs b/crates/gpui/src/elements/expanded.rs index e8803affab3556cb8de38e6d9785aa3bb5fb708c..d77bbdbfb9c8e33036b6e76b444aef64833bbdbc 100644 --- a/crates/gpui/src/elements/expanded.rs +++ b/crates/gpui/src/elements/expanded.rs @@ -24,13 +24,13 @@ impl Expanded { } } - pub fn to_full_width(mut self) -> Self { + pub fn full_width(mut self) -> Self { self.full_width = true; self.full_height = false; self } - pub fn to_full_height(mut self) -> Self { + pub fn full_height(mut self) -> Self { self.full_width = false; self.full_height = true; self diff --git a/crates/gpui/src/elements/image.rs b/crates/gpui/src/elements/image.rs index dff46804e7e4765c4935c779f06ff61844490d51..e0387e39bb1cadd340635ff0c0259d6486e49bad 100644 --- a/crates/gpui/src/elements/image.rs +++ b/crates/gpui/src/elements/image.rs @@ -53,8 +53,8 @@ impl Element for Image { _: &mut LayoutContext, ) -> (Vector2F, Self::LayoutState) { let desired_size = vec2f( - self.style.width.unwrap_or(constraint.max.x()), - self.style.height.unwrap_or(constraint.max.y()), + self.style.width.unwrap_or_else(|| constraint.max.x()), + self.style.height.unwrap_or_else(|| constraint.max.y()), ); let size = constrain_size_preserving_aspect_ratio( constraint.constrain(desired_size), diff --git a/crates/gpui/src/elements/list.rs b/crates/gpui/src/elements/list.rs index 2b44918e43696ae4470beb192b4936d1c1148106..e0ca47b598e2cd20c82917bc3d56f28dcd54703d 100644 --- a/crates/gpui/src/elements/list.rs +++ b/crates/gpui/src/elements/list.rs @@ -33,6 +33,7 @@ struct StateInner { logical_scroll_top: Option, orientation: Orientation, overdraw: f32, + #[allow(clippy::type_complexity)] scroll_handler: Option, &mut EventContext)>>, } @@ -311,19 +312,17 @@ impl Element for List { drop(cursor); state.items = new_items; - match event { - Event::ScrollWheel(ScrollWheelEvent { - position, - delta, - precise, - }) => { - if bounds.contains_point(*position) { - if state.scroll(scroll_top, bounds.height(), *delta, *precise, cx) { - handled = true; - } - } + if let Event::ScrollWheel(ScrollWheelEvent { + position, + delta, + precise, + }) = event + { + if bounds.contains_point(*position) + && state.scroll(scroll_top, bounds.height(), *delta, *precise, cx) + { + handled = true; } - _ => {} } handled diff --git a/crates/gpui/src/elements/mouse_event_handler.rs b/crates/gpui/src/elements/mouse_event_handler.rs index 0cdbe12304d138e0b873ac3fac2bad368838fb87..7ad43c47defc320ba7654800a676cb765865940c 100644 --- a/crates/gpui/src/elements/mouse_event_handler.rs +++ b/crates/gpui/src/elements/mouse_event_handler.rs @@ -129,7 +129,7 @@ impl Element for MouseEventHandler { cx.scene.push_mouse_region(MouseRegion::from_handlers( cx.current_view_id(), - Some(self.discriminant.clone()), + Some(self.discriminant), hit_bounds, self.handlers.clone(), )); diff --git a/crates/gpui/src/elements/overlay.rs b/crates/gpui/src/elements/overlay.rs index bf2ef595799ecc6c0d666bd695465f77a018ee62..d81c939061380f52f673cd9974723a331dcf7617 100644 --- a/crates/gpui/src/elements/overlay.rs +++ b/crates/gpui/src/elements/overlay.rs @@ -74,7 +74,7 @@ impl Element for Overlay { size: &mut Self::LayoutState, cx: &mut PaintContext, ) { - let mut bounds = RectF::new(self.abs_position.unwrap_or(bounds.origin()), *size); + let mut bounds = RectF::new(self.abs_position.unwrap_or_else(|| bounds.origin()), *size); cx.scene.push_stacking_context(None); if self.hoverable { diff --git a/crates/gpui/src/elements/stack.rs b/crates/gpui/src/elements/stack.rs index 992a8922a741c1120c42c63e0107941e020e8e05..5de53ff9e7f40712c5f36550434c6cce2058ad1a 100644 --- a/crates/gpui/src/elements/stack.rs +++ b/crates/gpui/src/elements/stack.rs @@ -8,15 +8,14 @@ use crate::{ SizeConstraint, }; +#[derive(Default)] pub struct Stack { children: Vec, } impl Stack { pub fn new() -> Self { - Stack { - children: Vec::new(), - } + Self::default() } } diff --git a/crates/gpui/src/elements/text.rs b/crates/gpui/src/elements/text.rs index 580240e3fde31649a62bf401ad1d6d60d883ae3d..92e38894c1d6170f65362f7e5ea1c71c0898ea14 100644 --- a/crates/gpui/src/elements/text.rs +++ b/crates/gpui/src/elements/text.rs @@ -100,7 +100,7 @@ impl Element for Text { chunks, &self.style, cx.text_layout_cache, - &cx.font_cache, + cx.font_cache, usize::MAX, self.text.matches('\n').count() + 1, ); diff --git a/crates/gpui/src/elements/uniform_list.rs b/crates/gpui/src/elements/uniform_list.rs index 2ab4e91538c0c8d2b51fe889d4d086605aa3f776..bf9a0a4e3024808fcc9039c5cfe6f3f563dc8f2a 100644 --- a/crates/gpui/src/elements/uniform_list.rs +++ b/crates/gpui/src/elements/uniform_list.rs @@ -45,6 +45,7 @@ pub struct LayoutState { pub struct UniformList { state: UniformListState, item_count: usize, + #[allow(clippy::type_complexity)] append_items: Box, &mut Vec, &mut LayoutContext)>, padding_top: f32, padding_bottom: f32, @@ -310,19 +311,17 @@ impl Element for UniformList { handled = item.dispatch_event(event, cx) || handled; } - match event { - Event::ScrollWheel(ScrollWheelEvent { - position, - delta, - precise, - }) => { - if bounds.contains_point(*position) { - if self.scroll(*position, *delta, *precise, layout.scroll_max, cx) { - handled = true; - } - } + if let Event::ScrollWheel(ScrollWheelEvent { + position, + delta, + precise, + }) = event + { + if bounds.contains_point(*position) + && self.scroll(*position, *delta, *precise, layout.scroll_max, cx) + { + handled = true; } - _ => {} } handled diff --git a/crates/gpui/src/executor.rs b/crates/gpui/src/executor.rs index 7c2ba44c44a3cb52efb6c3012a10429de2f9596c..539d582e5b5f4f3aab26a6086b4d0c04d24de906 100644 --- a/crates/gpui/src/executor.rs +++ b/crates/gpui/src/executor.rs @@ -332,7 +332,7 @@ impl Deterministic { pub fn now(&self) -> std::time::Instant { let state = self.state.lock(); - state.now.clone() + state.now } pub fn advance_clock(&self, duration: Duration) { @@ -681,6 +681,12 @@ impl Background { } } +impl Default for Background { + fn default() -> Self { + Self::new() + } +} + pub struct Scope<'a> { executor: Arc, futures: Vec + Send + 'static>>>, diff --git a/crates/gpui/src/font_cache.rs b/crates/gpui/src/font_cache.rs index 52acb2bcf3a1cc8f4dbfb1d2648a4e03e5fe8c59..3631cbe7243b9b69b86a348bb71ea6dc86a52abc 100644 --- a/crates/gpui/src/font_cache.rs +++ b/crates/gpui/src/font_cache.rs @@ -117,7 +117,7 @@ impl FontCache { .font_selections .entry(family_id) .or_default() - .insert(properties.clone(), font_id); + .insert(*properties, font_id); Ok(font_id) } } @@ -257,10 +257,10 @@ mod tests { let arial = fonts.load_family(&["Arial"]).unwrap(); let arial_regular = fonts.select_font(arial, &Properties::new()).unwrap(); let arial_italic = fonts - .select_font(arial, &Properties::new().style(Style::Italic)) + .select_font(arial, Properties::new().style(Style::Italic)) .unwrap(); let arial_bold = fonts - .select_font(arial, &Properties::new().weight(Weight::BOLD)) + .select_font(arial, Properties::new().weight(Weight::BOLD)) .unwrap(); assert_ne!(arial_regular, arial_italic); assert_ne!(arial_regular, arial_bold); diff --git a/crates/gpui/src/fonts.rs b/crates/gpui/src/fonts.rs index 6308f682896cbe05db6e1920681f631c7042c7e0..5c49ddcf6119459c3c2ecad4510f6db34cf44181 100644 --- a/crates/gpui/src/fonts.rs +++ b/crates/gpui/src/fonts.rs @@ -332,8 +332,7 @@ impl<'de> Deserialize<'de> for TextStyle { where D: serde::Deserializer<'de>, { - Ok(Self::from_json(TextStyleJson::deserialize(deserializer)?) - .map_err(|e| de::Error::custom(e))?) + Self::from_json(TextStyleJson::deserialize(deserializer)?).map_err(de::Error::custom) } } diff --git a/crates/gpui/src/geometry.rs b/crates/gpui/src/geometry.rs index 705184fa6bae2f2b1ffd5f9ede4e713cbb9a828e..fb93c26b0f1a91be121ed6bfa8d7c76fb0b64882 100644 --- a/crates/gpui/src/geometry.rs +++ b/crates/gpui/src/geometry.rs @@ -19,6 +19,12 @@ enum PathVertexKind { Quadratic, } +impl Default for PathBuilder { + fn default() -> Self { + PathBuilder::new() + } +} + impl PathBuilder { pub fn new() -> Self { Self { @@ -58,10 +64,7 @@ impl PathBuilder { pub fn build(mut self, color: Color, clip_bounds: Option) -> Path { if let Some(clip_bounds) = clip_bounds { - self.bounds = self - .bounds - .intersection(clip_bounds) - .unwrap_or(RectF::default()); + self.bounds = self.bounds.intersection(clip_bounds).unwrap_or_default(); } Path { bounds: self.bounds, diff --git a/crates/gpui/src/keymap.rs b/crates/gpui/src/keymap.rs index d32344b0dbc8c2096d4527616316eef9a92e73bc..c408c9896049b6128581e8873efd4ba354297443 100644 --- a/crates/gpui/src/keymap.rs +++ b/crates/gpui/src/keymap.rs @@ -202,7 +202,7 @@ impl Keymap { for (ix, binding) in bindings.iter().enumerate() { binding_indices_by_action_type .entry(binding.action.as_any().type_id()) - .or_insert_with(|| SmallVec::new()) + .or_insert_with(SmallVec::new) .push(ix); } Self { @@ -211,10 +211,7 @@ impl Keymap { } } - fn bindings_for_action_type<'a>( - &'a self, - action_type: TypeId, - ) -> impl Iterator { + fn bindings_for_action_type(&self, action_type: TypeId) -> impl Iterator { self.binding_indices_by_action_type .get(&action_type) .map(SmallVec::as_slice) @@ -253,7 +250,7 @@ impl Binding { let keystrokes = keystrokes .split_whitespace() - .map(|key| Keystroke::parse(key)) + .map(Keystroke::parse) .collect::>()?; Ok(Self { @@ -281,7 +278,7 @@ impl Keystroke { let mut function = false; let mut key = None; - let mut components = source.split("-").peekable(); + let mut components = source.split('-').peekable(); while let Some(component) = components.next() { match component { "ctrl" => ctrl = true, @@ -379,12 +376,12 @@ impl ContextPredicate { let kind = node.kind(); match kind { - "source" => Self::from_node(node.child(0).ok_or(anyhow!(parse_error))?, source), + "source" => Self::from_node(node.child(0).ok_or_else(|| anyhow!(parse_error))?, source), "identifier" => Ok(Self::Identifier(node.utf8_text(source)?.into())), "not" => { let child = Self::from_node( node.child_by_field_name("expression") - .ok_or(anyhow!(parse_error))?, + .ok_or_else(|| anyhow!(parse_error))?, source, )?; Ok(Self::Not(Box::new(child))) @@ -392,12 +389,12 @@ impl ContextPredicate { "and" | "or" => { let left = Box::new(Self::from_node( node.child_by_field_name("left") - .ok_or(anyhow!(parse_error))?, + .ok_or_else(|| anyhow!(parse_error))?, source, )?); let right = Box::new(Self::from_node( node.child_by_field_name("right") - .ok_or(anyhow!(parse_error))?, + .ok_or_else(|| anyhow!(parse_error))?, source, )?); if kind == "and" { @@ -409,12 +406,12 @@ impl ContextPredicate { "equal" | "not_equal" => { let left = node .child_by_field_name("left") - .ok_or(anyhow!(parse_error))? + .ok_or_else(|| anyhow!(parse_error))? .utf8_text(source)? .into(); let right = node .child_by_field_name("right") - .ok_or(anyhow!(parse_error))? + .ok_or_else(|| anyhow!(parse_error))? .utf8_text(source)? .into(); if kind == "equal" { @@ -425,7 +422,7 @@ impl ContextPredicate { } "parenthesized" => Self::from_node( node.child_by_field_name("expression") - .ok_or(anyhow!(parse_error))?, + .ok_or_else(|| anyhow!(parse_error))?, source, ), _ => Err(anyhow!(parse_error)), @@ -604,7 +601,7 @@ mod tests { Ok(()) } - fn downcast<'a, A: Action>(action: &'a Option>) -> Option<&'a A> { + fn downcast(action: &Option>) -> Option<&A> { action .as_ref() .and_then(|action| action.as_any().downcast_ref()) diff --git a/crates/gpui/src/platform.rs b/crates/gpui/src/platform.rs index df7727ee89ee47a463bbdb5dbe37732707553a21..b5fcfe8f0d0d70cd29532f870e4142aa5fabc5b7 100644 --- a/crates/gpui/src/platform.rs +++ b/crates/gpui/src/platform.rs @@ -74,7 +74,7 @@ pub(crate) trait ForegroundPlatform { fn on_quit(&self, callback: Box); fn on_event(&self, callback: Box bool>); fn on_open_urls(&self, callback: Box)>); - fn run(&self, on_finish_launching: Box ()>); + fn run(&self, on_finish_launching: Box); fn on_menu_command(&self, callback: Box); fn on_validate_menu_command(&self, callback: Box bool>); diff --git a/crates/gpui/src/platform/mac/event.rs b/crates/gpui/src/platform/mac/event.rs index 5aedc63b2e03caecf92d03dfc912263f4b6ca9ca..a53e00958905f3d1caf3cc1a3c06086bf4d9022e 100644 --- a/crates/gpui/src/platform/mac/event.rs +++ b/crates/gpui/src/platform/mac/event.rs @@ -223,7 +223,7 @@ unsafe fn parse_keystroke(native_event: id) -> Keystroke { let cmd = modifiers.contains(NSEventModifierFlags::NSCommandKeyMask); let function = modifiers.contains(NSEventModifierFlags::NSFunctionKeyMask) && first_char.map_or(true, |ch| { - ch < NSUpArrowFunctionKey || ch > NSModeSwitchFunctionKey + !(NSUpArrowFunctionKey..=NSModeSwitchFunctionKey).contains(&ch) }); #[allow(non_upper_case_globals)] diff --git a/crates/gpui/src/platform/mac/fonts.rs b/crates/gpui/src/platform/mac/fonts.rs index 5a08cacf09d78aa36dc1158ff7de61686c36c5c7..f39d548049ab5669ca9f754a5c7f2c0e9ed4b0d4 100644 --- a/crates/gpui/src/platform/mac/fonts.rs +++ b/crates/gpui/src/platform/mac/fonts.rs @@ -53,6 +53,12 @@ impl FontSystem { } } +impl Default for FontSystem { + fn default() -> Self { + Self::new() + } +} + impl platform::FontSystem for FontSystem { fn add_fonts(&self, fonts: &[Arc>]) -> anyhow::Result<()> { self.0.write().add_fonts(fonts) @@ -402,7 +408,7 @@ impl FontSystemState { fn wrap_line(&self, text: &str, font_id: FontId, font_size: f32, width: f32) -> Vec { let mut string = CFMutableAttributedString::new(); string.replace_str(&CFString::new(text), CFRange::init(0, 0)); - let cf_range = CFRange::init(0 as isize, text.encode_utf16().count() as isize); + let cf_range = CFRange::init(0, text.encode_utf16().count() as isize); let font = &self.fonts[font_id.0]; unsafe { string.set_attribute( @@ -505,14 +511,14 @@ mod tests { }; let menlo_italic = RunStyle { font_id: fonts - .select_font(&menlo, &Properties::new().style(Style::Italic)) + .select_font(&menlo, Properties::new().style(Style::Italic)) .unwrap(), color: Default::default(), underline: Default::default(), }; let menlo_bold = RunStyle { font_id: fonts - .select_font(&menlo, &Properties::new().weight(Weight::BOLD)) + .select_font(&menlo, Properties::new().weight(Weight::BOLD)) .unwrap(), color: Default::default(), underline: Default::default(), @@ -599,7 +605,7 @@ mod tests { let name = format!("/Users/as-cii/Desktop/twog-{}.png", i); let path = Path::new(&name); let file = File::create(path).unwrap(); - let ref mut w = BufWriter::new(file); + let w = &mut BufWriter::new(file); let mut encoder = png::Encoder::new(w, bounds.width() as u32, bounds.height() as u32); encoder.set_color(png::ColorType::Grayscale); diff --git a/crates/gpui/src/platform/mac/platform.rs b/crates/gpui/src/platform/mac/platform.rs index 365e7478255b438b23adc3c37037d8a509f37c79..113653478a8a235e47ab597229360dc5952b60cc 100644 --- a/crates/gpui/src/platform/mac/platform.rs +++ b/crates/gpui/src/platform/mac/platform.rs @@ -50,7 +50,7 @@ use time::UtcOffset; #[allow(non_upper_case_globals)] const NSUTF8StringEncoding: NSUInteger = 4; -const MAC_PLATFORM_IVAR: &'static str = "platform"; +const MAC_PLATFORM_IVAR: &str = "platform"; static mut APP_CLASS: *const Class = ptr::null(); static mut APP_DELEGATE_CLASS: *const Class = ptr::null(); @@ -118,7 +118,7 @@ pub struct MacForegroundPlatformState { validate_menu_command: Option bool>>, will_open_menu: Option>, open_urls: Option)>>, - finish_launching: Option ()>>, + finish_launching: Option>, menu_actions: Vec>, } @@ -277,7 +277,7 @@ impl platform::ForegroundPlatform for MacForegroundPlatform { self.0.borrow_mut().open_urls = Some(callback); } - fn run(&self, on_finish_launching: Box ()>) { + fn run(&self, on_finish_launching: Box) { self.0.borrow_mut().finish_launching = Some(on_finish_launching); unsafe { @@ -533,7 +533,7 @@ impl platform::Platform for MacPlatform { fn read_from_clipboard(&self) -> Option { unsafe { if let Some(text_bytes) = self.read_from_pasteboard(NSPasteboardTypeString) { - let text = String::from_utf8_lossy(&text_bytes).to_string(); + let text = String::from_utf8_lossy(text_bytes).to_string(); let hash_bytes = self .read_from_pasteboard(self.text_hash_pasteboard_type) .and_then(|bytes| bytes.try_into().ok()) diff --git a/crates/gpui/src/platform/mac/renderer.rs b/crates/gpui/src/platform/mac/renderer.rs index 6b95fd6271647b348c8b42737a69e10e29784d76..8fdbda15e84a8a2a212f80e424d6c722545e4322 100644 --- a/crates/gpui/src/platform/mac/renderer.rs +++ b/crates/gpui/src/platform/mac/renderer.rs @@ -14,8 +14,7 @@ use metal::{MTLPixelFormat, MTLResourceOptions, NSRange}; use shaders::ToFloat2 as _; use std::{collections::HashMap, ffi::c_void, iter::Peekable, mem, sync::Arc, vec}; -const SHADERS_METALLIB: &'static [u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/shaders.metallib")); +const SHADERS_METALLIB: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/shaders.metallib")); const INSTANCE_BUFFER_SIZE: usize = 8192 * 1024; // This is an arbitrary decision. There's probably a more optimal value. pub struct Renderer { @@ -385,10 +384,10 @@ impl Renderer { drawable_size: Vector2F, command_encoder: &metal::RenderCommandEncoderRef, ) { - let clip_bounds = (layer.clip_bounds().unwrap_or(RectF::new( - vec2f(0., 0.), - drawable_size / scene.scale_factor(), - )) * scene.scale_factor()) + let clip_bounds = (layer + .clip_bounds() + .unwrap_or_else(|| RectF::new(vec2f(0., 0.), drawable_size / scene.scale_factor())) + * scene.scale_factor()) .round(); command_encoder.set_scissor_rect(metal::MTLScissorRect { x: clip_bounds.origin_x() as NSUInteger, @@ -438,8 +437,7 @@ impl Renderer { ); let buffer_contents = unsafe { - (self.instances.contents() as *mut u8).offset(*offset as isize) - as *mut shaders::GPUIShadow + (self.instances.contents() as *mut u8).add(*offset) as *mut shaders::GPUIShadow }; for (ix, shadow) in shadows.iter().enumerate() { let shape_bounds = shadow.bounds * scale_factor; @@ -451,7 +449,7 @@ impl Renderer { color: shadow.color.to_uchar4(), }; unsafe { - *(buffer_contents.offset(ix as isize)) = shader_shadow; + *(buffer_contents.add(ix)) = shader_shadow; } } @@ -503,8 +501,7 @@ impl Renderer { ); let buffer_contents = unsafe { - (self.instances.contents() as *mut u8).offset(*offset as isize) - as *mut shaders::GPUIQuad + (self.instances.contents() as *mut u8).add(*offset) as *mut shaders::GPUIQuad }; for (ix, quad) in quads.iter().enumerate() { let bounds = quad.bounds * scale_factor; @@ -514,7 +511,7 @@ impl Renderer { size: bounds.size().round().to_float2(), background_color: quad .background - .unwrap_or(Color::transparent_black()) + .unwrap_or_else(Color::transparent_black) .to_uchar4(), border_top: border_width * (quad.border.top as usize as f32), border_right: border_width * (quad.border.right as usize as f32), @@ -524,7 +521,7 @@ impl Renderer { corner_radius: quad.corner_radius * scale_factor, }; unsafe { - *(buffer_contents.offset(ix as isize)) = shader_quad; + *(buffer_contents.add(ix)) = shader_quad; } } @@ -641,9 +638,8 @@ impl Renderer { ); unsafe { - let buffer_contents = (self.instances.contents() as *mut u8) - .offset(*offset as isize) - as *mut shaders::GPUISprite; + let buffer_contents = + (self.instances.contents() as *mut u8).add(*offset) as *mut shaders::GPUISprite; std::ptr::copy_nonoverlapping(sprites.as_ptr(), buffer_contents, sprites.len()); } @@ -757,9 +753,8 @@ impl Renderer { ); unsafe { - let buffer_contents = (self.instances.contents() as *mut u8) - .offset(*offset as isize) - as *mut shaders::GPUIImage; + let buffer_contents = + (self.instances.contents() as *mut u8).add(*offset) as *mut shaders::GPUIImage; std::ptr::copy_nonoverlapping(images.as_ptr(), buffer_contents, images.len()); } @@ -821,10 +816,9 @@ impl Renderer { } unsafe { - let buffer_contents = (self.instances.contents() as *mut u8) - .offset(*offset as isize) - as *mut shaders::GPUISprite; - *buffer_contents.offset(atlas_sprite_count as isize) = sprite.shader_data; + let buffer_contents = + (self.instances.contents() as *mut u8).add(*offset) as *mut shaders::GPUISprite; + *buffer_contents.add(atlas_sprite_count) = sprite.shader_data; } atlas_sprite_count += 1; @@ -917,8 +911,7 @@ impl Renderer { ); let buffer_contents = unsafe { - (self.instances.contents() as *mut u8).offset(*offset as isize) - as *mut shaders::GPUIUnderline + (self.instances.contents() as *mut u8).add(*offset) as *mut shaders::GPUIUnderline }; for (ix, underline) in underlines.iter().enumerate() { let origin = underline.origin * scale_factor; @@ -935,7 +928,7 @@ impl Renderer { squiggly: underline.squiggly as u8, }; unsafe { - *(buffer_contents.offset(ix as isize)) = shader_underline; + *(buffer_contents.add(ix)) = shader_underline; } } diff --git a/crates/gpui/src/platform/mac/window.rs b/crates/gpui/src/platform/mac/window.rs index 568356e93825ff51877091d6d77abe81dc8eebb2..cda7ce5257419d9bcf279057e8f8c1e52db5f020 100644 --- a/crates/gpui/src/platform/mac/window.rs +++ b/crates/gpui/src/platform/mac/window.rs @@ -48,7 +48,7 @@ use std::{ time::Duration, }; -const WINDOW_STATE_IVAR: &'static str = "windowState"; +const WINDOW_STATE_IVAR: &str = "windowState"; static mut WINDOW_CLASS: *const Class = ptr::null(); static mut VIEW_CLASS: *const Class = ptr::null(); @@ -72,7 +72,7 @@ impl NSRange { self.location != NSNotFound as NSUInteger } - fn to_range(&self) -> Option> { + fn to_range(self) -> Option> { if self.is_valid() { let start = self.location as usize; let end = start + self.length as usize; @@ -513,7 +513,7 @@ impl platform::Window for Window { }; let _: () = msg_send![alert, setAlertStyle: alert_style]; let _: () = msg_send![alert, setMessageText: ns_string(msg)]; - for (ix, answer) in answers.into_iter().enumerate() { + for (ix, answer) in answers.iter().enumerate() { let button: id = msg_send![alert, addButtonWithTitle: ns_string(answer)]; let _: () = msg_send![button, setTag: ix as NSInteger]; } @@ -721,14 +721,14 @@ extern "C" fn yes(_: &Object, _: Sel) -> BOOL { extern "C" fn dealloc_window(this: &Object, _: Sel) { unsafe { drop_window_state(this); - let () = msg_send![super(this, class!(NSWindow)), dealloc]; + let _: () = msg_send![super(this, class!(NSWindow)), dealloc]; } } extern "C" fn dealloc_view(this: &Object, _: Sel) { unsafe { drop_window_state(this); - let () = msg_send![super(this, class!(NSView)), dealloc]; + let _: () = msg_send![super(this, class!(NSView)), dealloc]; } } @@ -912,7 +912,7 @@ extern "C" fn cancel_operation(this: &Object, _sel: Sel, _sender: id) { extern "C" fn send_event(this: &Object, _: Sel, native_event: id) { unsafe { - let () = msg_send![super(this, class!(NSWindow)), sendEvent: native_event]; + let _: () = msg_send![super(this, class!(NSWindow)), sendEvent: native_event]; get_window_state(this).borrow_mut().performed_key_equivalent = false; } } @@ -991,7 +991,7 @@ extern "C" fn close_window(this: &Object, _: Sel) { callback(); } - let () = msg_send![super(this, class!(NSWindow)), close]; + let _: () = msg_send![super(this, class!(NSWindow)), close]; } } @@ -1157,17 +1157,22 @@ extern "C" fn insert_text(this: &Object, _: Sel, text: id, replacement_range: NS .flatten() .is_some(); - if is_composing || text.chars().count() > 1 || pending_key_down.is_none() { - with_input_handler(this, |input_handler| { - input_handler.replace_text_in_range(replacement_range, text) - }); - } else { - let mut pending_key_down = pending_key_down.unwrap(); - pending_key_down.1 = Some(InsertText { - replacement_range, - text: text.to_string(), - }); - window_state.borrow_mut().pending_key_down = Some(pending_key_down); + match pending_key_down { + None | Some(_) if is_composing || text.chars().count() > 1 => { + with_input_handler(this, |input_handler| { + input_handler.replace_text_in_range(replacement_range, text) + }); + } + + Some(mut pending_key_down) => { + pending_key_down.1 = Some(InsertText { + replacement_range, + text: text.to_string(), + }); + window_state.borrow_mut().pending_key_down = Some(pending_key_down); + } + + _ => unreachable!(), } } } diff --git a/crates/gpui/src/platform/test.rs b/crates/gpui/src/platform/test.rs index 3eb9b1e88efa354799b30af66eda18343b27d871..f75cff78e84ff43eb9fe0b8502f736aa5e8a0ae1 100644 --- a/crates/gpui/src/platform/test.rs +++ b/crates/gpui/src/platform/test.rs @@ -74,7 +74,7 @@ impl super::ForegroundPlatform for ForegroundPlatform { fn on_open_urls(&self, _: Box)>) {} - fn run(&self, _on_finish_launching: Box ()>) { + fn run(&self, _on_finish_launching: Box) { unimplemented!() } diff --git a/crates/gpui/src/presenter.rs b/crates/gpui/src/presenter.rs index 9cba57810b49992da9ea1610a0949fce2c65ad48..1556572816936aaf5cf65b7334a2832d59fb1221 100644 --- a/crates/gpui/src/presenter.rs +++ b/crates/gpui/src/presenter.rs @@ -89,8 +89,8 @@ impl Presenter { ) { cx.start_frame(); for view_id in &invalidation.removed { - invalidation.updated.remove(&view_id); - self.rendered_views.remove(&view_id); + invalidation.updated.remove(view_id); + self.rendered_views.remove(view_id); } for view_id in &invalidation.updated { self.rendered_views.insert( @@ -285,7 +285,7 @@ impl Presenter { { dragged_region = Some(( clicked_region.clone(), - MouseRegionEvent::Drag(*prev_drag_position, e.clone()), + MouseRegionEvent::Drag(*prev_drag_position, *e), )); *prev_drag_position = *position; } @@ -366,7 +366,7 @@ impl Presenter { }, ) = event { - if let None = pressed_button { + if pressed_button.is_none() { let mut style_to_assign = CursorStyle::Arrow; for region in self.cursor_regions.iter().rev() { if region.bounds.contains_point(*position) { @@ -385,23 +385,17 @@ impl Presenter { if let Some(region_id) = region.id() { if !self.hovered_region_ids.contains(®ion_id) { invalidated_views.push(region.view_id); - hover_regions.push(( - region.clone(), - MouseRegionEvent::Hover(true, e.clone()), - )); + hover_regions + .push((region.clone(), MouseRegionEvent::Hover(true, *e))); self.hovered_region_ids.insert(region_id); } } - } else { - if let Some(region_id) = region.id() { - if self.hovered_region_ids.contains(®ion_id) { - invalidated_views.push(region.view_id); - hover_regions.push(( - region.clone(), - MouseRegionEvent::Hover(false, e.clone()), - )); - self.hovered_region_ids.remove(®ion_id); - } + } else if let Some(region_id) = region.id() { + if self.hovered_region_ids.contains(®ion_id) { + invalidated_views.push(region.view_id); + hover_regions + .push((region.clone(), MouseRegionEvent::Hover(false, *e))); + self.hovered_region_ids.remove(®ion_id); } } } @@ -625,7 +619,7 @@ impl<'a> PaintContext<'a> { #[inline] pub fn paint_layer(&mut self, clip_bounds: Option, f: F) where - F: FnOnce(&mut Self) -> (), + F: FnOnce(&mut Self), { self.scene.push_layer(clip_bounds); f(self); diff --git a/crates/gpui/src/scene/mouse_region.rs b/crates/gpui/src/scene/mouse_region.rs index d3d788c4660001b255b9c08ad2ec65e6ebff0dd2..704567450a3a767592f151e7823a21b2dbfaa851 100644 --- a/crates/gpui/src/scene/mouse_region.rs +++ b/crates/gpui/src/scene/mouse_region.rs @@ -107,6 +107,7 @@ pub struct MouseRegionId { #[derive(Clone, Default)] pub struct HandlerSet { + #[allow(clippy::type_complexity)] pub set: HashMap< (Discriminant, Option), Rc, @@ -115,6 +116,7 @@ pub struct HandlerSet { impl HandlerSet { pub fn handle_all() -> Self { + #[allow(clippy::type_complexity)] let mut set: HashMap< (Discriminant, Option), Rc, diff --git a/crates/gpui/src/text_layout.rs b/crates/gpui/src/text_layout.rs index 571f932e52652e5d07f3bef20e16feb2e399c529..8fd10a6018e3149a6cabf0f59626f22a6020314e 100644 --- a/crates/gpui/src/text_layout.rs +++ b/crates/gpui/src/text_layout.rs @@ -66,7 +66,7 @@ impl TextLayoutCache { let mut curr_frame = RwLockUpgradableReadGuard::upgrade(curr_frame); if let Some((key, layout)) = self.prev_frame.lock().remove_entry(key) { curr_frame.insert(key, layout.clone()); - Line::new(layout.clone(), runs) + Line::new(layout, runs) } else { let layout = Arc::new(self.fonts.layout_line(text, font_size, runs)); let key = CacheKeyValue { @@ -81,7 +81,7 @@ impl TextLayoutCache { } trait CacheKey { - fn key<'a>(&'a self) -> CacheKeyRef<'a>; + fn key(&self) -> CacheKeyRef; } impl<'a> PartialEq for (dyn CacheKey + 'a) { @@ -98,7 +98,7 @@ impl<'a> Hash for (dyn CacheKey + 'a) { } } -#[derive(Eq, PartialEq)] +#[derive(Eq)] struct CacheKeyValue { text: String, font_size: OrderedFloat, @@ -106,15 +106,21 @@ struct CacheKeyValue { } impl CacheKey for CacheKeyValue { - fn key<'a>(&'a self) -> CacheKeyRef<'a> { + fn key(&self) -> CacheKeyRef { CacheKeyRef { - text: &self.text.as_str(), + text: self.text.as_str(), font_size: self.font_size, runs: self.runs.as_slice(), } } } +impl PartialEq for CacheKeyValue { + fn eq(&self, other: &Self) -> bool { + self.key().eq(&other.key()) + } +} + impl Hash for CacheKeyValue { fn hash(&self, state: &mut H) { self.key().hash(state); @@ -135,7 +141,7 @@ struct CacheKeyRef<'a> { } impl<'a> CacheKey for CacheKeyRef<'a> { - fn key<'b>(&'b self) -> CacheKeyRef<'b> { + fn key(&self) -> CacheKeyRef { *self } } @@ -242,6 +248,10 @@ impl Line { self.layout.len } + pub fn is_empty(&self) -> bool { + self.layout.len == 0 + } + pub fn index_for_x(&self, x: f32) -> Option { if x >= self.layout.width { None @@ -300,7 +310,7 @@ impl Line { ), Underline { color: Some(run_underline.color.unwrap_or(*run_color)), - thickness: run_underline.thickness.into(), + thickness: run_underline.thickness, squiggly: run_underline.squiggly, }, )); @@ -484,7 +494,7 @@ impl LineWrapper { let mut prev_c = '\0'; let mut char_indices = line.char_indices(); iter::from_fn(move || { - while let Some((ix, c)) = char_indices.next() { + for (ix, c) in char_indices.by_ref() { if c == '\n' { continue; } @@ -746,7 +756,7 @@ mod tests { let mut wrapper = LineWrapper::new(font_id, 16., font_system); assert_eq!( wrapper - .wrap_shaped_line(&text, &line, 72.0) + .wrap_shaped_line(text, &line, 72.0) .collect::>(), &[ ShapedBoundary { diff --git a/crates/gpui_macros/src/gpui_macros.rs b/crates/gpui_macros/src/gpui_macros.rs index 7ec8b4fb7c6c17508fe028b213e1bd9f471ce19f..a60d385e8f5305d398503e2508958d089174fbfc 100644 --- a/crates/gpui_macros/src/gpui_macros.rs +++ b/crates/gpui_macros/src/gpui_macros.rs @@ -25,7 +25,7 @@ pub fn test(args: TokenStream, function: TokenStream) -> TokenStream { NestedMeta::Meta(Meta::NameValue(meta)) => { let key_name = meta.path.get_ident().map(|i| i.to_string()); let result = (|| { - match key_name.as_ref().map(String::as_str) { + match key_name.as_deref() { Some("retries") => max_retries = parse_int(&meta.lit)?, Some("iterations") => num_iterations = parse_int(&meta.lit)?, Some("seed") => starting_seed = parse_int(&meta.lit)?, diff --git a/crates/language/src/buffer.rs b/crates/language/src/buffer.rs index 2f458b04c9c1def234e5625cfe764d87b404ff97..52ad88f092c76f5d10e8663f794ff4b082c585b9 100644 --- a/crates/language/src/buffer.rs +++ b/crates/language/src/buffer.rs @@ -737,9 +737,7 @@ impl Buffer { this.parsing_in_background = false; this.did_finish_parsing(new_tree, parsed_version, cx); - if parse_again && this.reparse(cx) { - return; - } + if parse_again && this.reparse(cx) {} }); }) .detach(); @@ -933,10 +931,12 @@ impl Buffer { indent_sizes.entry(row).or_insert_with(|| { let mut size = snapshot.indent_size_for_line(row); if size.kind == new_indent.kind { - if delta > 0 { - size.len = size.len + delta as u32; - } else if delta < 0 { - size.len = size.len.saturating_sub(-delta as u32); + match delta.cmp(&0) { + Ordering::Greater => size.len += delta as u32, + Ordering::Less => { + size.len = size.len.saturating_sub(-delta as u32) + } + Ordering::Equal => {} } } size @@ -961,7 +961,7 @@ impl Buffer { let edits: Vec<_> = indent_sizes .into_iter() .filter_map(|(row, indent_size)| { - let current_size = indent_size_for_line(&self, row); + let current_size = indent_size_for_line(self, row); Self::edit_for_indent_size_adjustment(row, current_size, indent_size) }) .collect(); @@ -978,21 +978,23 @@ impl Buffer { return None; } - if new_size.len > current_size.len { - let point = Point::new(row, 0); - Some(( - point..point, - iter::repeat(new_size.char()) - .take((new_size.len - current_size.len) as usize) - .collect::(), - )) - } else if new_size.len < current_size.len { - Some(( + match new_size.len.cmp(¤t_size.len) { + Ordering::Greater => { + let point = Point::new(row, 0); + Some(( + point..point, + iter::repeat(new_size.char()) + .take((new_size.len - current_size.len) as usize) + .collect::(), + )) + } + + Ordering::Less => Some(( Point::new(row, 0)..Point::new(row, current_size.len - new_size.len), String::new(), - )) - } else { - None + )), + + Ordering::Equal => None, } } @@ -1599,7 +1601,7 @@ impl Deref for Buffer { impl BufferSnapshot { pub fn indent_size_for_line(&self, row: u32) -> IndentSize { - indent_size_for_line(&self, row) + indent_size_for_line(self, row) } pub fn single_indent_size(&self, cx: &AppContext) -> IndentSize { @@ -1643,10 +1645,10 @@ impl BufferSnapshot { result } - fn suggest_autoindents<'a>( - &'a self, + fn suggest_autoindents( + &self, row_range: Range, - ) -> Option> + 'a> { + ) -> Option> + '_> { let language = self.language.as_ref()?; let grammar = language.grammar.as_ref()?; let config = &language.config; @@ -1675,7 +1677,7 @@ impl BufferSnapshot { start.get_or_insert(Point::from_ts_point(capture.node.start_position())); end.get_or_insert(Point::from_ts_point(capture.node.end_position())); } else if Some(capture.index) == end_capture_ix { - end = Some(Point::from_ts_point(capture.node.start_position().into())); + end = Some(Point::from_ts_point(capture.node.start_position())); } } @@ -1733,15 +1735,17 @@ impl BufferSnapshot { let mut outdent_to_row = u32::MAX; while let Some((indent_row, delta)) = indent_changes.peek() { - if *indent_row == row { - match delta { + match indent_row.cmp(&row) { + Ordering::Equal => match delta { Ordering::Less => outdent_from_prev_row = true, Ordering::Greater => indent_from_prev_row = true, _ => {} - } - } else if *indent_row > row { - break; + }, + + Ordering::Greater => break, + Ordering::Less => {} } + indent_changes.next(); } @@ -1805,11 +1809,7 @@ impl BufferSnapshot { None } - pub fn chunks<'a, T: ToOffset>( - &'a self, - range: Range, - language_aware: bool, - ) -> BufferChunks<'a> { + pub fn chunks(&self, range: Range, language_aware: bool) -> BufferChunks { let range = range.start.to_offset(self)..range.end.to_offset(self); let mut tree = None; @@ -1843,7 +1843,7 @@ impl BufferSnapshot { ) } - pub fn for_each_line<'a>(&'a self, range: Range, mut callback: impl FnMut(u32, &str)) { + pub fn for_each_line(&self, range: Range, mut callback: impl FnMut(u32, &str)) { let mut line = String::new(); let mut row = range.start.row; for chunk in self @@ -1969,7 +1969,7 @@ impl BufferSnapshot { position: T, theme: Option<&SyntaxTheme>, ) -> Option>> { - let position = position.to_offset(&self); + let position = position.to_offset(self); let mut items = self.outline_items_containing(position.saturating_sub(1)..position + 1, theme)?; let mut prev_depth = None; @@ -2050,7 +2050,7 @@ impl BufferSnapshot { let mut offset = range.start; chunks.seek(offset); - while let Some(mut chunk) = chunks.next() { + for mut chunk in chunks.by_ref() { if chunk.text.len() > range.end - offset { chunk.text = &chunk.text[0..(range.end - offset)]; offset = range.end; @@ -2105,7 +2105,7 @@ impl BufferSnapshot { let range = range.start.to_offset(self).saturating_sub(1)..range.end.to_offset(self) + 1; let mut cursor = QueryCursorHandle::new(); let matches = cursor.set_byte_range(range).matches( - &brackets_query, + brackets_query, tree.root_node(), TextProvider(self.as_rope()), ); @@ -2120,17 +2120,17 @@ impl BufferSnapshot { .min_by_key(|(open_range, close_range)| close_range.end - open_range.start) } - pub fn remote_selections_in_range<'a>( - &'a self, + #[allow(clippy::type_complexity)] + pub fn remote_selections_in_range( + &self, range: Range, - ) -> impl 'a - + Iterator< + ) -> impl Iterator< Item = ( ReplicaId, bool, - impl 'a + Iterator>, + impl Iterator> + '_, ), - > { + > + '_ { self.remote_selections .iter() .filter(|(replica_id, set)| { @@ -2165,8 +2165,7 @@ impl BufferSnapshot { T: 'a + Clone + ToOffset, O: 'a + FromAnchor, { - self.diagnostics - .range(search_range.clone(), self, true, reversed) + self.diagnostics.range(search_range, self, true, reversed) } pub fn diagnostic_groups(&self) -> Vec> { @@ -2469,10 +2468,7 @@ impl<'a> Iterator for BufferChunks<'a> { impl QueryCursorHandle { pub(crate) fn new() -> Self { - let mut cursor = QUERY_CURSORS - .lock() - .pop() - .unwrap_or_else(|| QueryCursor::new()); + let mut cursor = QUERY_CURSORS.lock().pop().unwrap_or_else(QueryCursor::new); cursor.set_match_limit(64); QueryCursorHandle(Some(cursor)) } @@ -2614,7 +2610,7 @@ pub fn contiguous_ranges( values: impl Iterator, max_len: usize, ) -> impl Iterator> { - let mut values = values.into_iter(); + let mut values = values; let mut current_range: Option> = None; std::iter::from_fn(move || loop { if let Some(value) = values.next() { diff --git a/crates/language/src/diagnostic_set.rs b/crates/language/src/diagnostic_set.rs index 51c921e61c90081e516376ad25d729315d13c678..b52327cac0e81b4ddbf7f224ebef170ac92d3f15 100644 --- a/crates/language/src/diagnostic_set.rs +++ b/crates/language/src/diagnostic_set.rs @@ -8,7 +8,7 @@ use std::{ use sum_tree::{self, Bias, SumTree}; use text::{Anchor, FromAnchor, PointUtf16, ToOffset}; -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub struct DiagnosticSet { diagnostics: SumTree>, } @@ -167,24 +167,15 @@ impl DiagnosticSet { .map(|entry| entry.resolve(buffer)) } } - -impl Default for DiagnosticSet { - fn default() -> Self { - Self { - diagnostics: Default::default(), - } - } -} - impl sum_tree::Item for DiagnosticEntry { type Summary = Summary; fn summary(&self) -> Self::Summary { Summary { - start: self.range.start.clone(), - end: self.range.end.clone(), - min_start: self.range.start.clone(), - max_end: self.range.end.clone(), + start: self.range.start, + end: self.range.end, + min_start: self.range.start, + max_end: self.range.end, count: 1, } } @@ -217,13 +208,13 @@ impl sum_tree::Summary for Summary { fn add_summary(&mut self, other: &Self, buffer: &Self::Context) { if other.min_start.cmp(&self.min_start, buffer).is_lt() { - self.min_start = other.min_start.clone(); + self.min_start = other.min_start; } if other.max_end.cmp(&self.max_end, buffer).is_gt() { - self.max_end = other.max_end.clone(); + self.max_end = other.max_end; } - self.start = other.start.clone(); - self.end = other.end.clone(); + self.start = other.start; + self.end = other.end; self.count += other.count; } } diff --git a/crates/language/src/highlight_map.rs b/crates/language/src/highlight_map.rs index 36ed286beaac48e23e15950d575136b074171bc5..ddb4dead794f57b198415aa4377e00b9163006c2 100644 --- a/crates/language/src/highlight_map.rs +++ b/crates/language/src/highlight_map.rs @@ -56,10 +56,7 @@ impl HighlightId { } pub fn style(&self, theme: &SyntaxTheme) -> Option { - theme - .highlights - .get(self.0 as usize) - .map(|entry| entry.1.clone()) + theme.highlights.get(self.0 as usize).map(|entry| entry.1) } #[cfg(any(test, feature = "test-support"))] diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index 331c8c3987afa2486c9f0969e7408557d7985c7e..fbcc983df9074663d7226cd91a718e55a8b74b0d 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -308,6 +308,7 @@ pub struct LanguageRegistry { lsp_binary_statuses_tx: async_broadcast::Sender<(Arc, LanguageServerBinaryStatus)>, lsp_binary_statuses_rx: async_broadcast::Receiver<(Arc, LanguageServerBinaryStatus)>, login_shell_env_loaded: Shared>, + #[allow(clippy::type_complexity)] lsp_binary_paths: Mutex< HashMap< LanguageServerName, @@ -342,7 +343,7 @@ impl LanguageRegistry { if let Some(theme) = self.theme.read().clone() { language.set_theme(&theme.editor.syntax); } - self.languages.write().push(language.clone()); + self.languages.write().push(language); *self.subscription.write().0.borrow_mut() = (); } @@ -409,7 +410,7 @@ impl LanguageRegistry { ) -> Option>> { #[cfg(any(test, feature = "test-support"))] if language.fake_adapter.is_some() { - let language = language.clone(); + let language = language; return Some(cx.spawn(|cx| async move { let (servers_tx, fake_adapter) = language.fake_adapter.as_ref().unwrap(); let (server, mut fake_server) = lsp::LanguageServer::fake( @@ -474,7 +475,7 @@ impl LanguageRegistry { let server = lsp::LanguageServer::new( server_id, &server_binary_path, - &server_args, + server_args, &root_path, cx, )?; diff --git a/crates/language/src/proto.rs b/crates/language/src/proto.rs index 4dca2f855dce645788d82901417eb1ca143859a0..047cef3ab6ad1fd738bed4c61774c38d74358064 100644 --- a/crates/language/src/proto.rs +++ b/crates/language/src/proto.rs @@ -408,10 +408,12 @@ pub async fn deserialize_completion( Ok(Completion { old_range: old_start..old_end, new_text: completion.new_text, - label: label.unwrap_or(CodeLabel::plain( - lsp_completion.label.clone(), - lsp_completion.filter_text.as_deref(), - )), + label: label.unwrap_or_else(|| { + CodeLabel::plain( + lsp_completion.label.clone(), + lsp_completion.filter_text.as_deref(), + ) + }), lsp_completion, }) } @@ -465,7 +467,7 @@ pub fn deserialize_transaction(transaction: proto::Transaction) -> Result buffer1_ops.borrow_mut().push(op), - event @ _ => buffer_1_events.borrow_mut().push(event), + event => buffer_1_events.borrow_mut().push(event), }) .detach(); let buffer_2_events = buffer_2_events.clone(); @@ -190,7 +190,7 @@ async fn test_apply_diff(cx: &mut gpui::TestAppContext) { buffer.update(cx, |buffer, cx| { buffer.apply_diff(diff, cx).unwrap(); assert_eq!(buffer.text(), text); - assert_eq!(anchor.to_point(&buffer), Point::new(2, 3)); + assert_eq!(anchor.to_point(buffer), Point::new(2, 3)); }); let text = "a\n1\n\nccc\ndd2dd\nffffff\n"; @@ -198,7 +198,7 @@ async fn test_apply_diff(cx: &mut gpui::TestAppContext) { buffer.update(cx, |buffer, cx| { buffer.apply_diff(diff, cx).unwrap(); assert_eq!(buffer.text(), text); - assert_eq!(anchor.to_point(&buffer), Point::new(4, 4)); + assert_eq!(anchor.to_point(buffer), Point::new(4, 4)); }); } @@ -209,11 +209,9 @@ async fn test_reparse(cx: &mut gpui::TestAppContext) { cx.add_model(|cx| Buffer::new(0, text, cx).with_language(Arc::new(rust_lang()), cx)); // Wait for the initial text to parse - buffer - .condition(&cx, |buffer, _| !buffer.is_parsing()) - .await; + buffer.condition(cx, |buffer, _| !buffer.is_parsing()).await; assert_eq!( - get_tree_sexp(&buffer, &cx), + get_tree_sexp(&buffer, cx), concat!( "(source_file (function_item name: (identifier) ", "parameters: (parameters) ", @@ -230,11 +228,11 @@ async fn test_reparse(cx: &mut gpui::TestAppContext) { buffer.update(cx, |buf, cx| { buf.start_transaction(); - let offset = buf.text().find(")").unwrap(); + let offset = buf.text().find(')').unwrap(); buf.edit([(offset..offset, "b: C")], None, cx); assert!(!buf.is_parsing()); - let offset = buf.text().find("}").unwrap(); + let offset = buf.text().find('}').unwrap(); buf.edit([(offset..offset, " d; ")], None, cx); assert!(!buf.is_parsing()); @@ -242,11 +240,9 @@ async fn test_reparse(cx: &mut gpui::TestAppContext) { assert_eq!(buf.text(), "fn a(b: C) { d; }"); assert!(buf.is_parsing()); }); - buffer - .condition(&cx, |buffer, _| !buffer.is_parsing()) - .await; + buffer.condition(cx, |buffer, _| !buffer.is_parsing()).await; assert_eq!( - get_tree_sexp(&buffer, &cx), + get_tree_sexp(&buffer, cx), concat!( "(source_file (function_item name: (identifier) ", "parameters: (parameters (parameter pattern: (identifier) type: (type_identifier))) ", @@ -259,13 +255,13 @@ async fn test_reparse(cx: &mut gpui::TestAppContext) { // * turn field expression into a method call // * add a turbofish to the method call buffer.update(cx, |buf, cx| { - let offset = buf.text().find(";").unwrap(); + let offset = buf.text().find(';').unwrap(); buf.edit([(offset..offset, ".e")], None, cx); assert_eq!(buf.text(), "fn a(b: C) { d.e; }"); assert!(buf.is_parsing()); }); buffer.update(cx, |buf, cx| { - let offset = buf.text().find(";").unwrap(); + let offset = buf.text().find(';').unwrap(); buf.edit([(offset..offset, "(f)")], None, cx); assert_eq!(buf.text(), "fn a(b: C) { d.e(f); }"); assert!(buf.is_parsing()); @@ -276,11 +272,9 @@ async fn test_reparse(cx: &mut gpui::TestAppContext) { assert_eq!(buf.text(), "fn a(b: C) { d.e::(f); }"); assert!(buf.is_parsing()); }); - buffer - .condition(&cx, |buffer, _| !buffer.is_parsing()) - .await; + buffer.condition(cx, |buffer, _| !buffer.is_parsing()).await; assert_eq!( - get_tree_sexp(&buffer, &cx), + get_tree_sexp(&buffer, cx), concat!( "(source_file (function_item name: (identifier) ", "parameters: (parameters (parameter pattern: (identifier) type: (type_identifier))) ", @@ -297,11 +291,9 @@ async fn test_reparse(cx: &mut gpui::TestAppContext) { assert_eq!(buf.text(), "fn a() {}"); assert!(buf.is_parsing()); }); - buffer - .condition(&cx, |buffer, _| !buffer.is_parsing()) - .await; + buffer.condition(cx, |buffer, _| !buffer.is_parsing()).await; assert_eq!( - get_tree_sexp(&buffer, &cx), + get_tree_sexp(&buffer, cx), concat!( "(source_file (function_item name: (identifier) ", "parameters: (parameters) ", @@ -314,11 +306,9 @@ async fn test_reparse(cx: &mut gpui::TestAppContext) { assert_eq!(buf.text(), "fn a(b: C) { d.e::(f); }"); assert!(buf.is_parsing()); }); - buffer - .condition(&cx, |buffer, _| !buffer.is_parsing()) - .await; + buffer.condition(cx, |buffer, _| !buffer.is_parsing()).await; assert_eq!( - get_tree_sexp(&buffer, &cx), + get_tree_sexp(&buffer, cx), concat!( "(source_file (function_item name: (identifier) ", "parameters: (parameters (parameter pattern: (identifier) type: (type_identifier))) ", @@ -340,21 +330,17 @@ async fn test_resetting_language(cx: &mut gpui::TestAppContext) { }); // Wait for the initial text to parse - buffer - .condition(&cx, |buffer, _| !buffer.is_parsing()) - .await; + buffer.condition(cx, |buffer, _| !buffer.is_parsing()).await; assert_eq!( - get_tree_sexp(&buffer, &cx), + get_tree_sexp(&buffer, cx), "(source_file (expression_statement (block)))" ); buffer.update(cx, |buffer, cx| { buffer.set_language(Some(Arc::new(json_lang())), cx) }); - buffer - .condition(&cx, |buffer, _| !buffer.is_parsing()) - .await; - assert_eq!(get_tree_sexp(&buffer, &cx), "(document (object))"); + buffer.condition(cx, |buffer, _| !buffer.is_parsing()).await; + assert_eq!(get_tree_sexp(&buffer, cx), "(document (object))"); } #[gpui::test] @@ -417,7 +403,7 @@ async fn test_outline(cx: &mut gpui::TestAppContext) { // Without space, we only match on names assert_eq!( - search(&outline, "oon", &cx).await, + search(&outline, "oon", cx).await, &[ ("mod module", vec![]), // included as the parent of a match ("enum LoginState", vec![]), // included as the parent of a match @@ -427,18 +413,18 @@ async fn test_outline(cx: &mut gpui::TestAppContext) { ); assert_eq!( - search(&outline, "dp p", &cx).await, + search(&outline, "dp p", cx).await, &[ ("impl Drop for Person", vec![5, 8, 9, 14]), ("fn drop", vec![]), ] ); assert_eq!( - search(&outline, "dpn", &cx).await, + search(&outline, "dpn", cx).await, &[("impl Drop for Person", vec![5, 14, 19])] ); assert_eq!( - search(&outline, "impl ", &cx).await, + search(&outline, "impl ", cx).await, &[ ("impl Eq for Person", vec![0, 1, 2, 3, 4]), ("impl Drop for Person", vec![0, 1, 2, 3, 4]), @@ -530,9 +516,9 @@ async fn test_symbols_containing(cx: &mut gpui::TestAppContext) { ] ); - fn symbols_containing<'a>( + fn symbols_containing( position: Point, - snapshot: &'a BufferSnapshot, + snapshot: &BufferSnapshot, ) -> Vec<(String, Range)> { snapshot .symbols_containing(position, None) @@ -799,7 +785,7 @@ fn test_autoindent_does_not_adjust_lines_with_unchanged_suggestion(cx: &mut Muta Ok(()) } " - .replace("|", "") // included in the string to preserve trailing whites + .replace('|', "") // included in the string to preserve trailing whites .unindent() ); @@ -971,7 +957,7 @@ fn test_autoindent_block_mode(cx: &mut MutableAppContext) { buffer.undo(cx); buffer.edit([(Point::new(2, 0)..Point::new(2, 0), " ")], None, cx); buffer.edit( - [(Point::new(2, 8)..Point::new(2, 8), inserted_text.clone())], + [(Point::new(2, 8)..Point::new(2, 8), inserted_text)], Some(AutoindentMode::Block { original_indent_columns: vec![0], }), @@ -1098,7 +1084,7 @@ fn test_random_collaboration(cx: &mut MutableAppContext, mut rng: StdRng) { if let Event::Operation(op) = event { network .borrow_mut() - .broadcast(buffer.replica_id(), vec![proto::serialize_operation(&op)]); + .broadcast(buffer.replica_id(), vec![proto::serialize_operation(op)]); } }) .detach(); @@ -1202,7 +1188,7 @@ fn test_random_collaboration(cx: &mut MutableAppContext, mut rng: StdRng) { if let Event::Operation(op) = event { network.borrow_mut().broadcast( buffer.replica_id(), - vec![proto::serialize_operation(&op)], + vec![proto::serialize_operation(op)], ); } }) diff --git a/crates/lsp/src/lsp.rs b/crates/lsp/src/lsp.rs index 5c8916e34eede7de7f6ddd109ba38841980baa14..95ef299c72ecbadb342764423cfab611aeb8a9be 100644 --- a/crates/lsp/src/lsp.rs +++ b/crates/lsp/src/lsp.rs @@ -27,8 +27,8 @@ use std::{ use std::{path::Path, process::Stdio}; use util::{ResultExt, TryFutureExt}; -const JSON_RPC_VERSION: &'static str = "2.0"; -const CONTENT_LEN_HEADER: &'static str = "Content-Length: "; +const JSON_RPC_VERSION: &str = "2.0"; +const CONTENT_LEN_HEADER: &str = "Content-Length: "; type NotificationHandler = Box, &str, AsyncAppContext)>; type ResponseHandler = Box)>; @@ -42,6 +42,7 @@ pub struct LanguageServer { notification_handlers: Arc>>, response_handlers: Arc>>, executor: Arc, + #[allow(clippy::type_complexity)] io_tasks: Mutex>, Task>)>>, output_done_rx: Mutex>, root_path: PathBuf, @@ -112,7 +113,7 @@ impl LanguageServer { let working_dir = if root_path.is_dir() { root_path } else { - root_path.parent().unwrap_or(Path::new("/")) + root_path.parent().unwrap_or_else(|| Path::new("/")) }; let mut server = process::Command::new(binary_path) .current_dir(working_dir) @@ -251,7 +252,7 @@ impl LanguageServer { capabilities: Default::default(), next_id: Default::default(), outbound_tx, - executor: cx.background().clone(), + executor: cx.background(), io_tasks: Mutex::new(Some((input_task, output_task))), output_done_rx: Mutex::new(Some(output_done_rx)), root_path: root_path.to_path_buf(), @@ -641,7 +642,7 @@ impl LanguageServer { stdin_reader, None, Path::new("/"), - cx.clone(), + cx, move |msg| { notifications_tx .try_send((msg.method.to_string(), msg.params.get().to_string())) @@ -651,7 +652,7 @@ impl LanguageServer { notifications_rx, }; fake.handle_request::({ - let capabilities = capabilities.clone(); + let capabilities = capabilities; move |_, _| { let capabilities = capabilities.clone(); let name = name.clone(); @@ -662,7 +663,6 @@ impl LanguageServer { name, ..Default::default() }), - ..Default::default() }) } } @@ -697,7 +697,7 @@ impl FakeLanguageServer { loop { let (method, params) = self.notifications_rx.next().await?; - if &method == T::METHOD { + if method == T::METHOD { return Some(serde_json::from_str::(¶ms).unwrap()); } else { log::info!("skipping message in fake language server {:?}", params); diff --git a/crates/outline/src/outline.rs b/crates/outline/src/outline.rs index 414a48ed109cfdb4aa3522d7467c257396b4a2ac..f814276306515d7aab0eb2edbff31e49782597ee 100644 --- a/crates/outline/src/outline.rs +++ b/crates/outline/src/outline.rs @@ -115,8 +115,8 @@ impl OutlineView { self.active_editor.update(cx, |active_editor, cx| { let snapshot = active_editor.snapshot(cx).display_snapshot; let buffer_snapshot = &snapshot.buffer_snapshot; - let start = outline_item.range.start.to_point(&buffer_snapshot); - let end = outline_item.range.end.to_point(&buffer_snapshot); + let start = outline_item.range.start.to_point(buffer_snapshot); + let end = outline_item.range.end.to_point(buffer_snapshot); let display_rows = start.to_display_point(&snapshot).row() ..end.to_display_point(&snapshot).row() + 1; active_editor.highlight_rows(Some(display_rows)); @@ -183,8 +183,8 @@ impl PickerDelegate for OutlineView { .map(|(ix, item)| { let range = item.range.to_offset(&buffer); let distance_to_closest_endpoint = cmp::min( - (range.start as isize - cursor_offset as isize).abs() as usize, - (range.end as isize - cursor_offset as isize).abs() as usize, + (range.start as isize - cursor_offset as isize).abs(), + (range.end as isize - cursor_offset as isize).abs(), ); let depth = if range.contains(&cursor_offset) { Some(item.depth) diff --git a/crates/plugin/src/lib.rs b/crates/plugin/src/lib.rs index bcb5b770dc1a0eaaa5c9751a1600a020a182a645..079b96fba8388a46e0938f336ce1a6c6463e3c9f 100644 --- a/crates/plugin/src/lib.rs +++ b/crates/plugin/src/lib.rs @@ -29,7 +29,7 @@ impl __Buffer { pub extern "C" fn __alloc_buffer(len: u32) -> u32 { let vec = vec![0; len as usize]; let buffer = unsafe { __Buffer::from_vec(vec) }; - return buffer.ptr; + buffer.ptr } /// Frees a given buffer, requires the size. diff --git a/crates/plugin_runtime/build.rs b/crates/plugin_runtime/build.rs index 0614659b5ed19b629df947ff10c92494ab65fdaa..d253064103cc2a68a1993c6de3df20701c25a6d8 100644 --- a/crates/plugin_runtime/build.rs +++ b/crates/plugin_runtime/build.rs @@ -17,8 +17,7 @@ fn main() { // Clear out and recreate the plugin bin directory let _ = std::fs::remove_dir_all(base.join("bin")); - let _ = - std::fs::create_dir_all(base.join("bin")).expect("Could not make plugins bin directory"); + std::fs::create_dir_all(base.join("bin")).expect("Could not make plugins bin directory"); // Compile the plugins using the same profile as the current Zed build let (profile_flags, profile_target) = match std::env::var("PROFILE").unwrap().as_str() { @@ -43,7 +42,7 @@ fn main() { // Get the target architecture for pre-cross-compilation of plugins // and create and engine with the appropriate config - let target_triple = std::env::var("TARGET").unwrap().to_string(); + let target_triple = std::env::var("TARGET").unwrap(); println!("cargo:rerun-if-env-changed=TARGET"); let engine = create_default_engine(&target_triple); @@ -77,7 +76,7 @@ fn create_default_engine(target_triple: &str) -> Engine { let mut config = Config::default(); config .target(target_triple) - .expect(&format!("Could not set target to `{}`", target_triple)); + .unwrap_or_else(|_| panic!("Could not set target to `{}`", target_triple)); config.async_support(true); config.consume_fuel(true); Engine::new(&config).expect("Could not create precompilation engine") diff --git a/crates/plugin_runtime/src/lib.rs b/crates/plugin_runtime/src/lib.rs index 8665a108c927898be821f030a16cbe7649cc2400..177092a529966bbc0f30e6b9120e22a4c56b20dd 100644 --- a/crates/plugin_runtime/src/lib.rs +++ b/crates/plugin_runtime/src/lib.rs @@ -69,13 +69,13 @@ mod tests { let unsorted = vec![1, 3, 4, 2, 5]; let sorted = vec![1, 2, 3, 4, 5]; - assert_eq!(runtime.call(&plugin.noop, ()).await.unwrap(), ()); + runtime.call(&plugin.noop, ()).await.unwrap(); assert_eq!(runtime.call(&plugin.constant, ()).await.unwrap(), 27); assert_eq!(runtime.call(&plugin.identity, 58).await.unwrap(), 58); assert_eq!(runtime.call(&plugin.add, (3, 4)).await.unwrap(), 7); assert_eq!(runtime.call(&plugin.swap, (1, 2)).await.unwrap(), (2, 1)); assert_eq!(runtime.call(&plugin.sort, unsorted).await.unwrap(), sorted); - assert_eq!(runtime.call(&plugin.print, "Hi!".into()).await.unwrap(), ()); + runtime.call(&plugin.print, "Hi!".into()).await.unwrap(); assert_eq!(runtime.call(&plugin.and_back, 1).await.unwrap(), 8); assert_eq!(runtime.call(&plugin.imports, 1).await.unwrap(), 8); assert_eq!(runtime.call(&plugin.half_async, 4).await.unwrap(), 2); diff --git a/crates/plugin_runtime/src/plugin.rs b/crates/plugin_runtime/src/plugin.rs index 2748a3f3f7f19426496faa67d5480e0723f726c9..bfcb024faa4514da0cc19186a38e0bc971c8d221 100644 --- a/crates/plugin_runtime/src/plugin.rs +++ b/crates/plugin_runtime/src/plugin.rs @@ -135,7 +135,7 @@ impl PluginBuilder { // TODO: use try block once avaliable let result: Result<(WasiBuffer, Memory, _), Trap> = (|| { // grab a handle to the memory - let mut plugin_memory = match caller.get_export("memory") { + let plugin_memory = match caller.get_export("memory") { Some(Extern::Memory(mem)) => mem, _ => return Err(Trap::new("Could not grab slice of plugin memory"))?, }; @@ -144,9 +144,9 @@ impl PluginBuilder { // get the args passed from Guest let args = - Plugin::buffer_to_bytes(&mut plugin_memory, caller.as_context(), &buffer)?; + Plugin::buffer_to_bytes(&plugin_memory, caller.as_context(), &buffer)?; - let args: A = Plugin::deserialize_to_type(&args)?; + let args: A = Plugin::deserialize_to_type(args)?; // Call the Host-side function let result = function(args); @@ -214,7 +214,7 @@ impl PluginBuilder { // TODO: use try block once avaliable let result: Result<(WasiBuffer, Memory, Vec), Trap> = (|| { // grab a handle to the memory - let mut plugin_memory = match caller.get_export("memory") { + let plugin_memory = match caller.get_export("memory") { Some(Extern::Memory(mem)) => mem, _ => return Err(Trap::new("Could not grab slice of plugin memory"))?, }; @@ -222,7 +222,7 @@ impl PluginBuilder { let buffer = WasiBuffer::from_u64(packed_buffer); // get the args passed from Guest - let args = Plugin::buffer_to_type(&mut plugin_memory, &mut caller, &buffer)?; + let args = Plugin::buffer_to_type(&plugin_memory, &mut caller, &buffer)?; // Call the Host-side function let result: R = function(args); @@ -258,7 +258,7 @@ impl PluginBuilder { /// Initializes a [`Plugin`] from a given compiled Wasm module. /// Both binary (`.wasm`) and text (`.wat`) module formats are supported. - pub async fn init<'a>(self, binary: PluginBinary<'a>) -> Result { + pub async fn init(self, binary: PluginBinary<'_>) -> Result { Plugin::init(binary, self).await } } @@ -324,7 +324,7 @@ impl Plugin { println!(); } - async fn init<'a>(binary: PluginBinary<'a>, plugin: PluginBuilder) -> Result { + async fn init(binary: PluginBinary<'_>, plugin: PluginBuilder) -> Result { // initialize the WebAssembly System Interface context let engine = plugin.engine; let mut linker = plugin.linker; @@ -576,7 +576,7 @@ impl Plugin { .await?; Self::buffer_to_type( - &mut plugin_memory, + &plugin_memory, &mut self.store, &WasiBuffer::from_u64(result_buffer), ) diff --git a/crates/project/src/fs.rs b/crates/project/src/fs.rs index 0084402b85d92661df32cf73ab95e3c5b5c0ccad..f2d62fae87e54b84ffb916e8764a5e07871d575d 100644 --- a/crates/project/src/fs.rs +++ b/crates/project/src/fs.rs @@ -460,7 +460,7 @@ impl FakeFs { } } Null => { - self.create_dir(&path).await.unwrap(); + self.create_dir(path).await.unwrap(); } String(contents) => { self.insert_file(&path, contents).await; diff --git a/crates/project/src/lsp_command.rs b/crates/project/src/lsp_command.rs index 4d679ec9cb1ac96af7d90e083a3ebb01d01d501a..7737a4df9e2bfd7d8fcf86fda6b98fc329712df8 100644 --- a/crates/project/src/lsp_command.rs +++ b/crates/project/src/lsp_command.rs @@ -1027,7 +1027,7 @@ impl LspCommand for GetHover { lsp::HoverContents::Array(marked_strings) => { let content: Vec = marked_strings .into_iter() - .filter_map(|marked_string| HoverBlock::try_new(marked_string)) + .filter_map(HoverBlock::try_new) .collect(); if content.is_empty() { None @@ -1049,9 +1049,7 @@ impl LspCommand for GetHover { } Event::Start(Tag::CodeBlock(CodeBlockKind::Fenced(new_language))) => { if !current_text.is_empty() { - let text = std::mem::replace(&mut current_text, String::new()) - .trim() - .to_string(); + let text = std::mem::take(&mut current_text).trim().to_string(); contents.push(HoverBlock { text, language }); } @@ -1067,9 +1065,7 @@ impl LspCommand for GetHover { | Event::End(Tag::BlockQuote) | Event::HardBreak => { if !current_text.is_empty() { - let text = std::mem::replace(&mut current_text, String::new()) - .trim() - .to_string(); + let text = std::mem::take(&mut current_text).trim().to_string(); contents.push(HoverBlock { text, language }); } language = None; diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 6488afd303d4194f02e8d5e2d2d2c35bcc424645..31d18f4fa86bfd4add35518fd48903de244fdd56 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -114,10 +114,12 @@ pub struct Project { _subscriptions: Vec, opened_buffer: (Rc>>, watch::Receiver<()>), shared_buffers: HashMap>, + #[allow(clippy::type_complexity)] loading_buffers: HashMap< ProjectPath, postage::watch::Receiver, Arc>>>, >, + #[allow(clippy::type_complexity)] loading_local_worktrees: HashMap, Shared, Arc>>>>, opened_buffers: HashMap, @@ -993,7 +995,7 @@ impl Project { .iter() .filter_map(|worktree| { worktree - .upgrade(&cx) + .upgrade(cx) .map(|worktree| worktree.read(cx).as_local().unwrap().metadata_proto()) }) .collect() @@ -1080,7 +1082,7 @@ impl Project { self.worktrees .iter() .filter_map(|worktree| { - let worktree = worktree.upgrade(&cx)?.read(cx); + let worktree = worktree.upgrade(cx)?.read(cx); if worktree.is_visible() { Some(format!( "project-path-online:{}", @@ -1121,7 +1123,7 @@ impl Project { } pub fn contains_paths(&self, paths: &[PathBuf], cx: &AppContext) -> bool { - paths.iter().all(|path| self.contains_path(&path, cx)) + paths.iter().all(|path| self.contains_path(path, cx)) } pub fn contains_path(&self, path: &Path, cx: &AppContext) -> bool { @@ -1395,11 +1397,8 @@ impl Project { } for open_buffer in self.opened_buffers.values_mut() { - match open_buffer { - OpenBuffer::Strong(buffer) => { - *open_buffer = OpenBuffer::Weak(buffer.downgrade()); - } - _ => {} + if let OpenBuffer::Strong(buffer) = open_buffer { + *open_buffer = OpenBuffer::Weak(buffer.downgrade()); } } @@ -1493,7 +1492,7 @@ impl Project { let buffer = cx.add_model(|cx| { Buffer::new(self.replica_id(), text, cx) - .with_language(language.unwrap_or(language::PLAIN_TEXT.clone()), cx) + .with_language(language.unwrap_or_else(|| language::PLAIN_TEXT.clone()), cx) }); self.register_buffer(&buffer, cx)?; Ok(buffer) @@ -1791,7 +1790,7 @@ impl Project { server .notify::( lsp::DidCloseTextDocumentParams { - text_document: lsp::TextDocumentIdentifier::new(uri.clone()), + text_document: lsp::TextDocumentIdentifier::new(uri), }, ) .log_err(); @@ -1825,7 +1824,7 @@ impl Project { language_server = self .language_server_ids .get(&(worktree_id, adapter.name.clone())) - .and_then(|id| self.language_servers.get(&id)) + .and_then(|id| self.language_servers.get(id)) .and_then(|server_state| { if let LanguageServerState::Running { server, .. } = server_state { Some(server.clone()) @@ -1838,7 +1837,7 @@ impl Project { if let Some(local_worktree) = file.worktree.read(cx).as_local() { if let Some(diagnostics) = local_worktree.diagnostics_for_path(file.path()) { - self.update_buffer_diagnostics(&buffer_handle, diagnostics, None, cx) + self.update_buffer_diagnostics(buffer_handle, diagnostics, None, cx) .log_err(); } } @@ -1853,8 +1852,7 @@ impl Project { 0, initial_snapshot.text(), ), - } - .clone(), + }, ) .log_err(); buffer_handle.update(cx, |buffer, cx| { @@ -1864,7 +1862,7 @@ impl Project { .completion_provider .as_ref() .and_then(|provider| provider.trigger_characters.clone()) - .unwrap_or(Vec::new()), + .unwrap_or_default(), cx, ) }); @@ -1910,7 +1908,7 @@ impl Project { let request = self.client.request(proto::UpdateBuffer { project_id, buffer_id: buffer.read(cx).remote_id(), - operations: vec![language::proto::serialize_operation(&operation)], + operations: vec![language::proto::serialize_operation(operation)], }); cx.background().spawn(request).detach_and_log_err(cx); } else if let Some(project_id) = self.remote_id() { @@ -2014,7 +2012,7 @@ impl Project { .filter_map(move |((language_server_worktree_id, _), id)| { if *language_server_worktree_id == worktree_id { if let Some(LanguageServerState::Running { adapter, server }) = - self.language_servers.get(&id) + self.language_servers.get(id) { return Some((adapter, server)); } @@ -2151,7 +2149,7 @@ impl Project { let this = this.downgrade(); let adapter = adapter.clone(); move |mut params, cx| { - let this = this.clone(); + let this = this; let adapter = adapter.clone(); cx.spawn(|mut cx| async move { adapter.process_diagnostics(&mut params).await; @@ -2371,7 +2369,7 @@ impl Project { .and_then(|provider| { provider.trigger_characters.clone() }) - .unwrap_or(Vec::new()), + .unwrap_or_default(), cx, ) }); @@ -2502,10 +2500,8 @@ impl Project { .cloned() { for orphaned_worktree in orphaned_worktrees { - this.language_server_ids.insert( - (orphaned_worktree, server_name.clone()), - new_server_id.clone(), - ); + this.language_server_ids + .insert((orphaned_worktree, server_name.clone()), new_server_id); } } }); @@ -2528,9 +2524,7 @@ impl Project { return; } }; - let progress = match progress.value { - lsp::ProgressParamsValue::WorkDone(value) => value, - }; + let lsp::ProgressParamsValue::WorkDone(progress) = progress.value; let language_server_status = if let Some(status) = self.language_server_statuses.get_mut(&server_id) { status @@ -2543,7 +2537,7 @@ impl Project { } let is_disk_based_diagnostics_progress = - Some(token.as_ref()) == disk_based_diagnostics_progress_token.as_ref().map(|x| &**x); + Some(token.as_ref()) == disk_based_diagnostics_progress_token.as_deref(); match progress { lsp::WorkDoneProgress::Begin(report) => { @@ -2796,7 +2790,7 @@ impl Project { } else { let group_id = post_inc(&mut self.next_diagnostic_group_id); let is_disk_based = - source.map_or(false, |source| disk_based_sources.contains(&source)); + source.map_or(false, |source| disk_based_sources.contains(source)); sources_by_group_id.insert(group_id, source); primary_diagnostic_group_ids @@ -3194,7 +3188,7 @@ impl Project { if let Some(lsp_edits) = lsp_edits { let edits = this .update(cx, |this, cx| { - this.edits_from_lsp(&buffer, lsp_edits, None, cx) + this.edits_from_lsp(buffer, lsp_edits, None, cx) }) .await?; buffer.update(cx, |buffer, cx| { @@ -3366,7 +3360,7 @@ impl Project { if let Some((worktree, rel_path)) = this.find_local_worktree(&abs_path, cx) { - worktree_id = (&worktree.read(cx)).id(); + worktree_id = worktree.read(cx).id(); path = rel_path; } else { path = relativize_path(&worktree_abs_path, &abs_path); @@ -3613,7 +3607,7 @@ impl Project { .clone(); ( snapshot.anchor_before(start)..snapshot.anchor_after(end), - text.clone(), + text, ) } Some(lsp::CompletionTextEdit::InsertAndReplace(_)) => { @@ -3791,7 +3785,7 @@ impl Project { let lsp_range = range_to_lsp(range.to_point_utf16(buffer)); cx.foreground().spawn(async move { - if !lang_server.capabilities().code_action_provider.is_some() { + if lang_server.capabilities().code_action_provider.is_none() { return Ok(Default::default()); } @@ -4120,6 +4114,7 @@ impl Project { ) } + #[allow(clippy::type_complexity)] pub fn search( &self, query: SearchQuery, @@ -4341,7 +4336,7 @@ impl Project { ) { let lsp_params = request.to_lsp(&file.abs_path(cx), cx); return cx.spawn(|this, cx| async move { - if !request.check_capabilities(&language_server.capabilities()) { + if !request.check_capabilities(language_server.capabilities()) { return Ok(Default::default()); } @@ -4375,7 +4370,7 @@ impl Project { ) -> Task, PathBuf)>> { let abs_path = abs_path.as_ref(); if let Some((tree, relative_path)) = self.find_local_worktree(abs_path, cx) { - Task::ready(Ok((tree.clone(), relative_path.into()))) + Task::ready(Ok((tree, relative_path))) } else { let worktree = self.create_local_worktree(abs_path, visible, cx); cx.foreground() @@ -4455,7 +4450,7 @@ impl Project { Ok(worktree) } - .map_err(|err| Arc::new(err)) + .map_err(Arc::new) }) .shared() }) @@ -4487,9 +4482,9 @@ impl Project { } fn add_worktree(&mut self, worktree: &ModelHandle, cx: &mut ModelContext) { - cx.observe(&worktree, |_, _, cx| cx.notify()).detach(); + cx.observe(worktree, |_, _, cx| cx.notify()).detach(); if worktree.read(cx).is_local() { - cx.subscribe(&worktree, |this, worktree, _, cx| { + cx.subscribe(worktree, |this, worktree, _, cx| { this.update_local_worktree_buffers(worktree, cx); }) .detach(); @@ -4508,7 +4503,7 @@ impl Project { } self.metadata_changed(true, cx); - cx.observe_release(&worktree, |this, worktree, cx| { + cx.observe_release(worktree, |this, worktree, cx| { this.remove_worktree(worktree.id(), cx); cx.notify(); }) @@ -4610,9 +4605,9 @@ impl Project { } } - pub fn language_servers_running_disk_based_diagnostics<'a>( - &'a self, - ) -> impl 'a + Iterator { + pub fn language_servers_running_disk_based_diagnostics( + &self, + ) -> impl Iterator + '_ { self.language_server_statuses .iter() .filter_map(|(id, status)| { @@ -4762,7 +4757,7 @@ impl Project { .remove(&peer_id) .ok_or_else(|| anyhow!("unknown peer {:?}", peer_id))? .replica_id; - for (_, buffer) in &this.opened_buffers { + for buffer in this.opened_buffers.values() { if let Some(buffer) = buffer.upgrade(cx) { buffer.update(cx, |buffer, cx| buffer.remove_peer(replica_id, cx)); } @@ -5088,7 +5083,7 @@ impl Project { let ops = payload .operations .into_iter() - .map(|op| language::proto::deserialize_operation(op)) + .map(language::proto::deserialize_operation) .collect::, _>>()?; let is_remote = this.is_remote(); match this.opened_buffers.entry(buffer_id) { @@ -5125,7 +5120,7 @@ impl Project { let worktree = this .worktree_for_id(WorktreeId::from_proto(file.worktree_id), cx) .ok_or_else(|| anyhow!("no such worktree"))?; - let file = File::from_proto(file, worktree.clone(), cx)?; + let file = File::from_proto(file, worktree, cx)?; let buffer = this .opened_buffers .get_mut(&buffer_id) @@ -5791,6 +5786,7 @@ impl Project { }) } + #[allow(clippy::type_complexity)] fn edits_from_lsp( &mut self, buffer: &ModelHandle, @@ -5837,7 +5833,7 @@ impl Project { new_text.push('\n'); } range.end = next_range.end; - new_text.push_str(&next_text); + new_text.push_str(next_text); lsp_edits.next(); } @@ -5872,7 +5868,7 @@ impl Project { ChangeTag::Insert => { if moved_since_edit { let anchor = snapshot.anchor_after(offset); - edits.push((anchor.clone()..anchor, value.to_string())); + edits.push((anchor..anchor, value.to_string())); } else { edits.last_mut().unwrap().1.push_str(value); } @@ -5882,7 +5878,7 @@ impl Project { } } else if range.end == range.start { let anchor = snapshot.anchor_after(range.start); - edits.push((anchor.clone()..anchor, new_text)); + edits.push((anchor..anchor, new_text)); } else { let edit_start = snapshot.anchor_after(range.start); let edit_end = snapshot.anchor_before(range.end); @@ -5944,7 +5940,7 @@ impl Project { if let Some(server_id) = self.language_server_ids.get(&key) { if let Some(LanguageServerState::Running { adapter, server }) = - self.language_servers.get(&server_id) + self.language_servers.get(server_id) { return Some((adapter, server)); } diff --git a/crates/project/src/project_tests.rs b/crates/project/src/project_tests.rs index 3dc4e9359f7dbb87ae5455a1a4ae5f6911ddcefd..ceb5d033a7fcb28c4aca73a29bc42082ad8b1d49 100644 --- a/crates/project/src/project_tests.rs +++ b/crates/project/src/project_tests.rs @@ -499,7 +499,7 @@ async fn test_single_file_worktrees_diagnostics(cx: &mut gpui::TestAppContext) { }); buffer_a.read_with(cx, |buffer, _| { - let chunks = chunks_with_diagnostics(&buffer, 0..buffer.len()); + let chunks = chunks_with_diagnostics(buffer, 0..buffer.len()); assert_eq!( chunks .iter() @@ -513,7 +513,7 @@ async fn test_single_file_worktrees_diagnostics(cx: &mut gpui::TestAppContext) { ); }); buffer_b.read_with(cx, |buffer, _| { - let chunks = chunks_with_diagnostics(&buffer, 0..buffer.len()); + let chunks = chunks_with_diagnostics(buffer, 0..buffer.len()); assert_eq!( chunks .iter() @@ -579,7 +579,7 @@ async fn test_hidden_worktrees_diagnostics(cx: &mut gpui::TestAppContext) { .await .unwrap(); buffer.read_with(cx, |buffer, _| { - let chunks = chunks_with_diagnostics(&buffer, 0..buffer.len()); + let chunks = chunks_with_diagnostics(buffer, 0..buffer.len()); assert_eq!( chunks .iter() @@ -1262,7 +1262,7 @@ async fn test_empty_diagnostic_ranges(cx: &mut gpui::TestAppContext) { // At the end of a line, an empty range is extended backward to include // the preceding character. buffer.read_with(cx, |buffer, _| { - let chunks = chunks_with_diagnostics(&buffer, 0..buffer.len()); + let chunks = chunks_with_diagnostics(buffer, 0..buffer.len()); assert_eq!( chunks .iter() @@ -1511,7 +1511,7 @@ async fn test_edits_from_lsp_with_edits_on_adjacent_lines(cx: &mut gpui::TestApp .into_iter() .map(|(range, text)| { ( - range.start.to_point(&buffer)..range.end.to_point(&buffer), + range.start.to_point(buffer)..range.end.to_point(buffer), text, ) }) @@ -1614,7 +1614,7 @@ async fn test_invalid_edits_from_lsp(cx: &mut gpui::TestAppContext) { .into_iter() .map(|(range, text)| { ( - range.start.to_point(&buffer)..range.end.to_point(&buffer), + range.start.to_point(buffer)..range.end.to_point(buffer), text, ) }) @@ -2139,7 +2139,7 @@ async fn test_rescan_and_remote_updates( let tree = project.worktrees(cx).next().unwrap(); tree.read(cx) .entry_for_path(path) - .expect(&format!("no entry for path {}", path)) + .unwrap_or_else(|| panic!("no entry for path {}", path)) .id }) }; @@ -2149,9 +2149,9 @@ async fn test_rescan_and_remote_updates( let buffer4 = buffer_for_path("b/c/file4", cx).await; let buffer5 = buffer_for_path("b/c/file5", cx).await; - let file2_id = id_for_path("a/file2", &cx); - let file3_id = id_for_path("a/file3", &cx); - let file4_id = id_for_path("b/c/file4", &cx); + let file2_id = id_for_path("a/file2", cx); + let file3_id = id_for_path("a/file3", cx); + let file4_id = id_for_path("b/c/file4", cx); // Create a remote copy of this worktree. let tree = project.read_with(cx, |project, cx| project.worktrees(cx).next().unwrap()); @@ -2183,12 +2183,12 @@ async fn test_rescan_and_remote_updates( }); // Rename and delete files and directories. - tree.flush_fs_events(&cx).await; + tree.flush_fs_events(cx).await; std::fs::rename(dir.path().join("a/file3"), dir.path().join("b/c/file3")).unwrap(); std::fs::remove_file(dir.path().join("b/c/file5")).unwrap(); std::fs::rename(dir.path().join("b/c"), dir.path().join("d")).unwrap(); std::fs::rename(dir.path().join("a/file2"), dir.path().join("a/file2.new")).unwrap(); - tree.flush_fs_events(&cx).await; + tree.flush_fs_events(cx).await; let expected_paths = vec![ "a", @@ -2209,9 +2209,9 @@ async fn test_rescan_and_remote_updates( expected_paths ); - assert_eq!(id_for_path("a/file2.new", &cx), file2_id); - assert_eq!(id_for_path("d/file3", &cx), file3_id); - assert_eq!(id_for_path("d/file4", &cx), file4_id); + assert_eq!(id_for_path("a/file2.new", cx), file2_id); + assert_eq!(id_for_path("d/file3", cx), file3_id); + assert_eq!(id_for_path("d/file4", cx), file4_id); assert_eq!( buffer2.read(app).file().unwrap().path().as_ref(), @@ -2689,7 +2689,7 @@ async fn test_grouped_diagnostics(cx: &mut gpui::TestAppContext) { message: "error 2 hint 2".to_string(), related_information: Some(vec![lsp::DiagnosticRelatedInformation { location: lsp::Location { - uri: buffer_uri.clone(), + uri: buffer_uri, range: lsp::Range::new(lsp::Position::new(2, 8), lsp::Position::new(2, 17)), }, message: "original diagnostic".to_string(), diff --git a/crates/project/src/search.rs b/crates/project/src/search.rs index 58fa04eeb2feabba45ae36c7d23b3630f22ca621..b526ab0c18bb1ddede2dc9ed83e2a5f3c6e7cc14 100644 --- a/crates/project/src/search.rs +++ b/crates/project/src/search.rs @@ -53,7 +53,7 @@ impl SearchQuery { query = word_query } - let multiline = query.contains("\n") || query.contains("\\n"); + let multiline = query.contains('\n') || query.contains("\\n"); let regex = RegexBuilder::new(&query) .case_insensitive(!case_sensitive) .multi_line(multiline) diff --git a/crates/project/src/worktree.rs b/crates/project/src/worktree.rs index 203b512d9bc5776fda24929602fe3101dc6ab206..3888e1ea3662eeee3f260398f89c2ea2f8731b69 100644 --- a/crates/project/src/worktree.rs +++ b/crates/project/src/worktree.rs @@ -57,6 +57,7 @@ lazy_static! { #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, PartialOrd, Ord)] pub struct WorktreeId(usize); +#[allow(clippy::large_enum_variant)] pub enum Worktree { Local(LocalWorktree), Remote(RemoteWorktree), @@ -157,7 +158,7 @@ impl Worktree { cx: &mut AsyncAppContext, ) -> Result> { let (tree, scan_states_tx) = - LocalWorktree::new(client, path, visible, fs.clone(), next_entry_id, cx).await?; + LocalWorktree::create(client, path, visible, fs.clone(), next_entry_id, cx).await?; tree.update(cx, |tree, cx| { let tree = tree.as_local_mut().unwrap(); let abs_path = tree.abs_path().clone(); @@ -229,7 +230,7 @@ impl Worktree { cx.spawn(|mut cx| { let this = worktree_handle.downgrade(); async move { - while let Some(_) = snapshot_updated_rx.recv().await { + while (snapshot_updated_rx.recv().await).is_some() { if let Some(this) = this.upgrade(&cx) { this.update(&mut cx, |this, cx| { this.poll_snapshot(cx); @@ -322,15 +323,15 @@ impl Worktree { } } - pub fn diagnostic_summaries<'a>( - &'a self, - ) -> impl Iterator, DiagnosticSummary)> + 'a { + pub fn diagnostic_summaries( + &self, + ) -> impl Iterator, DiagnosticSummary)> + '_ { match self { Worktree::Local(worktree) => &worktree.diagnostic_summaries, Worktree::Remote(worktree) => &worktree.diagnostic_summaries, } .iter() - .map(|(path, summary)| (path.0.clone(), summary.clone())) + .map(|(path, summary)| (path.0.clone(), *summary)) } fn poll_snapshot(&mut self, cx: &mut ModelContext) { @@ -342,7 +343,7 @@ impl Worktree { } impl LocalWorktree { - async fn new( + async fn create( client: Arc, path: impl Into>, visible: bool, @@ -386,7 +387,7 @@ impl LocalWorktree { }; if let Some(metadata) = metadata { let entry = Entry::new( - path.into(), + path, &metadata, &snapshot.next_entry_id, snapshot.root_char_bag, @@ -651,7 +652,7 @@ impl LocalWorktree { let abs_path = self.absolutize(&entry.path); let delete = cx.background().spawn({ let fs = self.fs.clone(); - let abs_path = abs_path.clone(); + let abs_path = abs_path; async move { if entry.is_file() { fs.remove_file(&abs_path, Default::default()).await @@ -848,7 +849,7 @@ impl LocalWorktree { let rpc = self.client.clone(); let worktree_id = cx.model_id() as u64; let maintain_remote_snapshot = cx.background().spawn({ - let rpc = rpc.clone(); + let rpc = rpc; let diagnostic_summaries = self.diagnostic_summaries.clone(); async move { let mut prev_snapshot = match snapshots_rx.recv().await { @@ -1002,10 +1003,9 @@ impl RemoteWorktree { warning_count: summary.warning_count as usize, }; if summary.is_empty() { - self.diagnostic_summaries.remove(&PathKey(path.clone())); + self.diagnostic_summaries.remove(&PathKey(path)); } else { - self.diagnostic_summaries - .insert(PathKey(path.clone()), summary); + self.diagnostic_summaries.insert(PathKey(path), summary); } } @@ -1513,7 +1513,7 @@ impl LocalSnapshot { let mut ignore_stack = IgnoreStack::none(); for (parent_abs_path, ignore) in new_ignores.into_iter().rev() { - if ignore_stack.is_abs_path_ignored(&parent_abs_path, true) { + if ignore_stack.is_abs_path_ignored(parent_abs_path, true) { ignore_stack = IgnoreStack::all(); break; } else if let Some(ignore) = ignore { @@ -1530,8 +1530,8 @@ impl LocalSnapshot { } async fn build_gitignore(abs_path: &Path, fs: &dyn Fs) -> Result { - let contents = fs.load(&abs_path).await?; - let parent = abs_path.parent().unwrap_or(Path::new("/")); + let contents = fs.load(abs_path).await?; + let parent = abs_path.parent().unwrap_or_else(|| Path::new("/")); let mut builder = GitignoreBuilder::new(parent); for line in contents.lines() { builder.add_line(Some(abs_path.into()), line)?; @@ -1769,7 +1769,7 @@ impl language::LocalFile for File { .send(proto::BufferReloaded { project_id, buffer_id, - version: serialize_version(&version), + version: serialize_version(version), mtime: Some(mtime.into()), fingerprint, line_ending: serialize_line_ending(line_ending) as i32, @@ -2285,7 +2285,7 @@ impl BackgroundScanner { snapshot.scan_id += 1; for event in &events { if let Ok(path) = event.path.strip_prefix(&root_canonical_path) { - snapshot.remove_path(&path); + snapshot.remove_path(path); } } @@ -2528,13 +2528,13 @@ impl WorktreeHandle for ModelHandle { fs.create_file(&root_path.join(filename), Default::default()) .await .unwrap(); - tree.condition(&cx, |tree, _| tree.entry_for_path(filename).is_some()) + tree.condition(cx, |tree, _| tree.entry_for_path(filename).is_some()) .await; fs.remove_file(&root_path.join(filename), Default::default()) .await .unwrap(); - tree.condition(&cx, |tree, _| tree.entry_for_path(filename).is_none()) + tree.condition(cx, |tree, _| tree.entry_for_path(filename).is_none()) .await; cx.read(|cx| tree.read(cx).as_local().unwrap().scan_complete()) @@ -2726,7 +2726,7 @@ impl<'a> TryFrom<(&'a CharBag, proto::Entry)> for Entry { let kind = if entry.is_dir { EntryKind::Dir } else { - let mut char_bag = root_char_bag.clone(); + let mut char_bag = *root_char_bag; char_bag.extend( String::from_utf8_lossy(&entry.path) .chars() @@ -2738,7 +2738,7 @@ impl<'a> TryFrom<(&'a CharBag, proto::Entry)> for Entry { Ok(Entry { id: ProjectEntryId::from_proto(entry.id), kind, - path: path.clone(), + path, inode: entry.inode, mtime: mtime.into(), is_symlink: entry.is_symlink, @@ -2955,7 +2955,7 @@ mod tests { .unwrap(); cx.read(|cx| tree.read(cx).as_local().unwrap().scan_complete()) .await; - tree.flush_fs_events(&cx).await; + tree.flush_fs_events(cx).await; cx.read(|cx| { let tree = tree.read(cx); assert!( @@ -2979,7 +2979,7 @@ mod tests { std::fs::write(dir.join("tracked-dir/tracked-file2"), "").unwrap(); std::fs::write(dir.join("tracked-dir/ancestor-ignored-file2"), "").unwrap(); std::fs::write(dir.join("ignored-dir/ignored-file2"), "").unwrap(); - tree.flush_fs_events(&cx).await; + tree.flush_fs_events(cx).await; cx.read(|cx| { let tree = tree.read(cx); assert!( @@ -3026,7 +3026,7 @@ mod tests { .unwrap(); cx.read(|cx| tree.read(cx).as_local().unwrap().scan_complete()) .await; - tree.flush_fs_events(&cx).await; + tree.flush_fs_events(cx).await; tree.update(cx, |tree, cx| { tree.as_local().unwrap().write_file( @@ -3052,8 +3052,8 @@ mod tests { tree.read_with(cx, |tree, _| { let tracked = tree.entry_for_path("tracked-dir/file.txt").unwrap(); let ignored = tree.entry_for_path("ignored-dir/file.txt").unwrap(); - assert_eq!(tracked.is_ignored, false); - assert_eq!(ignored.is_ignored, true); + assert!(!tracked.is_ignored); + assert!(ignored.is_ignored); }); } @@ -3226,9 +3226,9 @@ mod tests { let mut ignore_contents = String::new(); for path_to_ignore in files_to_ignore.chain(dirs_to_ignore) { - write!( + writeln!( ignore_contents, - "{}\n", + "{}", path_to_ignore .strip_prefix(&ignore_dir_path)? .to_str() @@ -3363,7 +3363,7 @@ mod tests { .collect::>(); assert_eq!(dfs_paths_via_traversal, dfs_paths_via_iter); - for (ignore_parent_abs_path, _) in &self.ignores_by_parent_abs_path { + for ignore_parent_abs_path in self.ignores_by_parent_abs_path.keys() { let ignore_parent_path = ignore_parent_abs_path.strip_prefix(&self.abs_path).unwrap(); assert!(self.entry_for_path(&ignore_parent_path).is_some()); @@ -3389,7 +3389,7 @@ mod tests { paths.push((entry.path.as_ref(), entry.inode, entry.is_ignored)); } } - paths.sort_by(|a, b| a.0.cmp(&b.0)); + paths.sort_by(|a, b| a.0.cmp(b.0)); paths } } diff --git a/crates/project_panel/src/project_panel.rs b/crates/project_panel/src/project_panel.rs index 0a32a8427bf489111065ca80b76c9086557e2ab8..f077520d72cffba2dc49012c969d3f575ad44192 100644 --- a/crates/project_panel/src/project_panel.rs +++ b/crates/project_panel/src/project_panel.rs @@ -186,15 +186,14 @@ impl ProjectPanel { }); cx.observe_focus(&filename_editor, |this, _, is_focused, cx| { - if !is_focused { - if this + if !is_focused + && this .edit_state .as_ref() .map_or(false, |state| state.processing_filename.is_none()) - { - this.edit_state = None; - this.update_visible_entries(None, cx); - } + { + this.edit_state = None; + this.update_visible_entries(None, cx); } }) .detach(); @@ -209,7 +208,7 @@ impl ProjectPanel { edit_state: None, filename_editor, clipboard_entry: None, - context_menu: cx.add_view(|cx| ContextMenu::new(cx)), + context_menu: cx.add_view(ContextMenu::new), }; this.update_visible_entries(None, cx); this @@ -380,13 +379,11 @@ impl ProjectPanel { self.index_for_selection(selection).unwrap_or_default(); if entry_ix > 0 { entry_ix -= 1; + } else if worktree_ix > 0 { + worktree_ix -= 1; + entry_ix = self.visible_entries[worktree_ix].1.len() - 1; } else { - if worktree_ix > 0 { - worktree_ix -= 1; - entry_ix = self.visible_entries[worktree_ix].1.len() - 1; - } else { - return; - } + return; } let (worktree_id, worktree_entries) = &self.visible_entries[worktree_ix]; @@ -734,17 +731,15 @@ impl ProjectPanel { self.clipboard_entry.take(); if clipboard_entry.is_cut() { - self.project - .update(cx, |project, cx| { - project.rename_entry(clipboard_entry.entry_id(), new_path, cx) - }) - .map(|task| task.detach_and_log_err(cx)); - } else { - self.project - .update(cx, |project, cx| { - project.copy_entry(clipboard_entry.entry_id(), new_path, cx) - }) - .map(|task| task.detach_and_log_err(cx)); + if let Some(task) = self.project.update(cx, |project, cx| { + project.rename_entry(clipboard_entry.entry_id(), new_path, cx) + }) { + task.detach_and_log_err(cx) + } + } else if let Some(task) = self.project.update(cx, |project, cx| { + project.copy_entry(clipboard_entry.entry_id(), new_path, cx) + }) { + task.detach_and_log_err(cx) } } None @@ -760,10 +755,9 @@ impl ProjectPanel { } fn index_for_selection(&self, selection: Selection) -> Option<(usize, usize, usize)> { - let mut worktree_index = 0; let mut entry_index = 0; let mut visible_entries_index = 0; - for (worktree_id, worktree_entries) in &self.visible_entries { + for (worktree_index, (worktree_id, worktree_entries)) in self.visible_entries.iter().enumerate() { if *worktree_id == selection.worktree_id { for entry in worktree_entries { if entry.id == selection.entry_id { @@ -777,7 +771,6 @@ impl ProjectPanel { } else { visible_entries_index += worktree_entries.len(); } - worktree_index += 1; } None } @@ -849,10 +842,10 @@ impl ProjectPanel { is_ignored: false, }); } - if expanded_dir_ids.binary_search(&entry.id).is_err() { - if entry_iter.advance_to_sibling() { - continue; - } + if expanded_dir_ids.binary_search(&entry.id).is_err() + && entry_iter.advance_to_sibling() + { + continue; } entry_iter.advance(); } @@ -982,7 +975,7 @@ impl ProjectPanel { if let Some(processing_filename) = &edit_state.processing_filename { details.is_processing = true; details.filename.clear(); - details.filename.push_str(&processing_filename); + details.filename.push_str(processing_filename); } else { if edit_state.is_new_entry { details.filename.clear(); @@ -1116,7 +1109,7 @@ impl View for ProjectPanel { cx, move |this, range, items, cx| { let theme = cx.global::().theme.clone(); - this.for_each_visible_entry(range.clone(), cx, |id, details, cx| { + this.for_each_visible_entry(range, cx, |id, details, cx| { items.push(Self::render_entry( id, details, diff --git a/crates/rpc/src/conn.rs b/crates/rpc/src/conn.rs index dfb09a09131e1e3ba732b0f07edf96574b5861a1..450e36782eea1c65e0c58805fd2b69789931c4ad 100644 --- a/crates/rpc/src/conn.rs +++ b/crates/rpc/src/conn.rs @@ -50,6 +50,7 @@ impl Connection { killed, ); + #[allow(clippy::type_complexity)] fn channel( killed: Arc, executor: Arc, @@ -76,9 +77,7 @@ impl Connection { // Writes to a half-open TCP connection will error. if killed.load(SeqCst) { - std::io::Result::Err( - Error::new(ErrorKind::Other, "connection lost").into(), - )?; + std::io::Result::Err(Error::new(ErrorKind::Other, "connection lost"))?; } Ok(msg) @@ -87,7 +86,7 @@ impl Connection { }); let rx = rx.then({ - let killed = killed.clone(); + let killed = killed; let executor = Arc::downgrade(&executor); move |msg| { let killed = killed.clone(); diff --git a/crates/rpc/src/peer.rs b/crates/rpc/src/peer.rs index a22dcfe39eb530a44f7805a7777d7035c8af1f92..6c1c4f01da887e107468757fa12f48603cf74934 100644 --- a/crates/rpc/src/peer.rs +++ b/crates/rpc/src/peer.rs @@ -94,6 +94,7 @@ pub struct ConnectionState { #[serde(skip)] outgoing_tx: mpsc::UnboundedSender, next_message_id: Arc, + #[allow(clippy::type_complexity)] #[serde(skip)] response_channels: Arc)>>>>>, @@ -139,7 +140,7 @@ impl Peer { let connection_id = ConnectionId(self.next_connection_id.fetch_add(1, SeqCst)); let connection_state = ConnectionState { - outgoing_tx: outgoing_tx.clone(), + outgoing_tx, next_message_id: Default::default(), response_channels: Arc::new(Mutex::new(Some(Default::default()))), }; diff --git a/crates/rpc/src/proto.rs b/crates/rpc/src/proto.rs index 8cd5ca36fbf523e8a25cf6ee125ba022957273ac..8cd65d34f187f54e656f1d790c4e23d247ef89a1 100644 --- a/crates/rpc/src/proto.rs +++ b/crates/rpc/src/proto.rs @@ -265,7 +265,9 @@ entity_messages!( entity_messages!(channel_id, ChannelMessageSent); -const MAX_BUFFER_LEN: usize = 1 * 1024 * 1024; +const KIB: usize = 1024; +const MIB: usize = KIB * 1024; +const MAX_BUFFER_LEN: usize = MIB; /// A stream of protobuf messages. pub struct MessageStream { @@ -273,6 +275,7 @@ pub struct MessageStream { encoding_buffer: Vec, } +#[allow(clippy::large_enum_variant)] #[derive(Debug)] pub enum Message { Envelope(Envelope), @@ -309,7 +312,7 @@ where self.encoding_buffer.reserve(message.encoded_len()); message .encode(&mut self.encoding_buffer) - .map_err(|err| io::Error::from(err))?; + .map_err(io::Error::from)?; let buffer = zstd::stream::encode_all(self.encoding_buffer.as_slice(), COMPRESSION_LEVEL) .unwrap(); @@ -360,10 +363,10 @@ where } } -impl Into for Timestamp { - fn into(self) -> SystemTime { +impl From for SystemTime { + fn from(val: Timestamp) -> Self { UNIX_EPOCH - .checked_add(Duration::new(self.seconds, self.nanos)) + .checked_add(Duration::new(val.seconds, val.nanos)) .unwrap() } } @@ -451,7 +454,7 @@ mod tests { .unwrap(); assert!(sink.encoding_buffer.capacity() <= MAX_BUFFER_LEN); - let mut stream = MessageStream::new(rx.map(|msg| anyhow::Ok(msg))); + let mut stream = MessageStream::new(rx.map(anyhow::Ok)); stream.read().await.unwrap(); assert!(stream.encoding_buffer.capacity() <= MAX_BUFFER_LEN); stream.read().await.unwrap(); diff --git a/crates/search/src/buffer_search.rs b/crates/search/src/buffer_search.rs index bc6f37202dc10f9054c1e463d67d9541d73d5fee..742d2acb64cffdbc5458bf2451055fe9cb1a6f4e 100644 --- a/crates/search/src/buffer_search.rs +++ b/crates/search/src/buffer_search.rs @@ -216,7 +216,7 @@ impl BufferSearchBar { fn dismiss(&mut self, _: &Dismiss, cx: &mut ViewContext) { self.dismissed = true; - for (editor, _) in &self.editors_with_matches { + for editor in self.editors_with_matches.keys() { if let Some(editor) = editor.upgrade(cx) { editor.update(cx, |editor, cx| { editor.clear_background_highlights::(cx) @@ -450,14 +450,11 @@ impl BufferSearchBar { event: &editor::Event, cx: &mut ViewContext, ) { - match event { - editor::Event::BufferEdited { .. } => { - self.query_contains_error = false; - self.clear_matches(cx); - self.update_matches(true, cx); - cx.notify(); - } - _ => {} + if let editor::Event::BufferEdited { .. } = event { + self.query_contains_error = false; + self.clear_matches(cx); + self.update_matches(true, cx); + cx.notify(); } } @@ -586,7 +583,7 @@ impl BufferSearchBar { let ranges = self.editors_with_matches.get(&editor.downgrade())?; let editor = editor.read(cx); active_match_index( - &ranges, + ranges, &editor.selections.newest_anchor().head(), &editor.buffer().read(cx).snapshot(cx), ) @@ -610,7 +607,7 @@ mod tests { #[gpui::test] async fn test_search_simple(cx: &mut TestAppContext) { let fonts = cx.font_cache(); - let mut theme = gpui::fonts::with_font_cache(fonts.clone(), || theme::Theme::default()); + let mut theme = gpui::fonts::with_font_cache(fonts.clone(), theme::Theme::default); theme.search.match_background = Color::red(); cx.update(|cx| { let mut settings = Settings::test(cx); @@ -649,7 +646,7 @@ mod tests { search_bar.update(cx, |search_bar, cx| { search_bar.set_query("us", cx); }); - editor.next_notification(&cx).await; + editor.next_notification(cx).await; editor.update(cx, |editor, cx| { assert_eq!( editor.all_background_highlights(cx), @@ -670,7 +667,7 @@ mod tests { search_bar.update(cx, |search_bar, cx| { search_bar.toggle_search_option(SearchOption::CaseSensitive, cx); }); - editor.next_notification(&cx).await; + editor.next_notification(cx).await; editor.update(cx, |editor, cx| { assert_eq!( editor.all_background_highlights(cx), @@ -686,7 +683,7 @@ mod tests { search_bar.update(cx, |search_bar, cx| { search_bar.set_query("or", cx); }); - editor.next_notification(&cx).await; + editor.next_notification(cx).await; editor.update(cx, |editor, cx| { assert_eq!( editor.all_background_highlights(cx), @@ -727,7 +724,7 @@ mod tests { search_bar.update(cx, |search_bar, cx| { search_bar.toggle_search_option(SearchOption::WholeWord, cx); }); - editor.next_notification(&cx).await; + editor.next_notification(cx).await; editor.update(cx, |editor, cx| { assert_eq!( editor.all_background_highlights(cx), diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 475923d6ef16de523d2a3fd6d6f07d3d69cc0813..0b30a0bd3675eea31b2d6c1b8c72c300d0107e3a 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -367,7 +367,7 @@ impl ProjectSearchView { }); // Subcribe to query_editor in order to reraise editor events for workspace item activation purposes cx.subscribe(&query_editor, |_, _, event, cx| { - cx.emit(ViewEvent::EditorEvent(event.clone())) + cx.emit(ViewEvent::EditorEvent(*event)) }) .detach(); @@ -384,7 +384,7 @@ impl ProjectSearchView { this.update_match_index(cx); } // Reraise editor events for workspace item activation purposes - cx.emit(ViewEvent::EditorEvent(event.clone())); + cx.emit(ViewEvent::EditorEvent(*event)); }) .detach(); @@ -567,6 +567,12 @@ impl ProjectSearchView { } } +impl Default for ProjectSearchBar { + fn default() -> Self { + Self::new() + } +} + impl ProjectSearchBar { pub fn new() -> Self { Self { @@ -903,7 +909,7 @@ mod tests { #[gpui::test] async fn test_project_search(cx: &mut TestAppContext) { let fonts = cx.font_cache(); - let mut theme = gpui::fonts::with_font_cache(fonts.clone(), || theme::Theme::default()); + let mut theme = gpui::fonts::with_font_cache(fonts.clone(), theme::Theme::default); theme.search.match_background = Color::red(); cx.update(|cx| { let mut settings = Settings::test(cx); @@ -933,7 +939,7 @@ mod tests { .update(cx, |query_editor, cx| query_editor.set_text("TWO", cx)); search_view.search(cx); }); - search_view.next_notification(&cx).await; + search_view.next_notification(cx).await; search_view.update(cx, |search_view, cx| { assert_eq!( search_view diff --git a/crates/search/src/search.rs b/crates/search/src/search.rs index 5d6014eaeb0a67d8837a6774e954a183c9fecb74..a975ab066679975d2f80b870279ac3e3fd21eeba 100644 --- a/crates/search/src/search.rs +++ b/crates/search/src/search.rs @@ -66,9 +66,9 @@ pub(crate) fn active_match_index( None } else { match ranges.binary_search_by(|probe| { - if probe.end.cmp(&cursor, &*buffer).is_lt() { + if probe.end.cmp(cursor, &*buffer).is_lt() { Ordering::Less - } else if probe.start.cmp(&cursor, &*buffer).is_gt() { + } else if probe.start.cmp(cursor, &*buffer).is_gt() { Ordering::Greater } else { Ordering::Equal @@ -86,7 +86,7 @@ pub(crate) fn match_index_for_direction( direction: Direction, buffer: &MultiBufferSnapshot, ) -> usize { - if ranges[index].start.cmp(&cursor, &buffer).is_gt() { + if ranges[index].start.cmp(cursor, buffer).is_gt() { if direction == Direction::Prev { if index == 0 { index = ranges.len() - 1; @@ -94,7 +94,7 @@ pub(crate) fn match_index_for_direction( index -= 1; } } - } else if ranges[index].end.cmp(&cursor, &buffer).is_lt() { + } else if ranges[index].end.cmp(cursor, buffer).is_lt() { if direction == Direction::Next { index = 0; } diff --git a/crates/settings/src/keymap_file.rs b/crates/settings/src/keymap_file.rs index 99cf81c6ba65abc2ed0373342e35e8a41853502c..c1d5db32bb0cb603734adfb58a4a6ef8a39576df 100644 --- a/crates/settings/src/keymap_file.rs +++ b/crates/settings/src/keymap_file.rs @@ -49,37 +49,37 @@ impl KeymapFileContent { pub fn load(asset_path: &str, cx: &mut MutableAppContext) -> Result<()> { let content = Assets::get(asset_path).unwrap().data; let content_str = std::str::from_utf8(content.as_ref()).unwrap(); - Ok(parse_json_with_comments::(content_str)?.add(cx)?) + parse_json_with_comments::(content_str)?.add_to_cx(cx) } - pub fn add(self, cx: &mut MutableAppContext) -> Result<()> { + pub fn add_to_cx(self, cx: &mut MutableAppContext) -> Result<()> { for KeymapBlock { context, bindings } in self.0 { - cx.add_bindings( - bindings - .into_iter() - .map(|(keystroke, action)| { - let action = action.0.get(); + let bindings = bindings + .into_iter() + .map(|(keystroke, action)| { + let action = action.0.get(); - // This is a workaround for a limitation in serde: serde-rs/json#497 - // We want to deserialize the action data as a `RawValue` so that we can - // deserialize the action itself dynamically directly from the JSON - // string. But `RawValue` currently does not work inside of an untagged enum. - let action = if action.starts_with('[') { - let ActionWithData(name, data) = serde_json::from_str(action)?; - cx.deserialize_action(&name, Some(data.get())) - } else { - let name = serde_json::from_str(action)?; - cx.deserialize_action(name, None) - } - .with_context(|| { - format!( + // This is a workaround for a limitation in serde: serde-rs/json#497 + // We want to deserialize the action data as a `RawValue` so that we can + // deserialize the action itself dynamically directly from the JSON + // string. But `RawValue` currently does not work inside of an untagged enum. + let action = if action.starts_with('[') { + let ActionWithData(name, data) = serde_json::from_str(action)?; + cx.deserialize_action(&name, Some(data.get())) + } else { + let name = serde_json::from_str(action)?; + cx.deserialize_action(name, None) + } + .with_context(|| { + format!( "invalid binding value for keystroke {keystroke}, context {context:?}" ) - })?; - Binding::load(&keystroke, action, context.as_deref()) - }) - .collect::>>()?, - ) + })?; + Binding::load(&keystroke, action, context.as_deref()) + }) + .collect::>>()?; + + cx.add_bindings(bindings); } Ok(()) } @@ -98,7 +98,7 @@ pub fn keymap_file_json_schema(action_names: &[&'static str]) -> serde_json::Val instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::String))), enum_values: Some( action_names - .into_iter() + .iter() .map(|name| Value::String(name.to_string())) .collect(), ), diff --git a/crates/settings/src/settings.rs b/crates/settings/src/settings.rs index fc5384cb3e7ac65ed502da9a6050f08ec83dda2c..ce1fa09d99cc6c977b1fcb228022a35386dc9e67 100644 --- a/crates/settings/src/settings.rs +++ b/crates/settings/src/settings.rs @@ -200,7 +200,7 @@ impl Settings { } } if let Some(value) = &data.theme { - if let Some(theme) = theme_registry.get(&value.to_string()).log_err() { + if let Some(theme) = theme_registry.get(value).log_err() { self.theme = theme; } } @@ -301,7 +301,7 @@ impl Settings { language_overrides: Default::default(), lsp: Default::default(), projects_online_by_default: true, - theme: gpui::fonts::with_font_cache(cx.font_cache().clone(), || Default::default()), + theme: gpui::fonts::with_font_cache(cx.font_cache().clone(), Default::default), } } @@ -309,7 +309,7 @@ impl Settings { pub fn test_async(cx: &mut gpui::TestAppContext) { cx.update(|cx| { let settings = Self::test(cx); - cx.set_global(settings.clone()); + cx.set_global(settings); }); } } @@ -327,12 +327,7 @@ pub fn settings_file_json_schema( // Create a schema for a theme name. let theme_name_schema = SchemaObject { instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::String))), - enum_values: Some( - theme_names - .into_iter() - .map(|name| Value::String(name)) - .collect(), - ), + enum_values: Some(theme_names.into_iter().map(Value::String).collect()), ..Default::default() }; diff --git a/crates/snippet/src/snippet.rs b/crates/snippet/src/snippet.rs index 8f4ca82c05c35a643a1e185d1e17be6af9a48946..808701569a40376858a47012fb1b8e02b730cd74 100644 --- a/crates/snippet/src/snippet.rs +++ b/crates/snippet/src/snippet.rs @@ -78,22 +78,22 @@ fn parse_tabstop<'a>( ) -> Result<&'a str> { let tabstop_start = text.len(); let tabstop_index; - if source.chars().next() == Some('{') { + if source.starts_with('{') { let (index, rest) = parse_int(&source[1..])?; tabstop_index = index; source = rest; - if source.chars().next() == Some(':') { + if source.starts_with(':') { source = parse_snippet(&source[1..], true, text, tabstops)?; } - if source.chars().next() == Some('}') { + if source.starts_with('}') { source = &source[1..]; } else { return Err(anyhow!("expected a closing brace")); } } else { - let (index, rest) = parse_int(&source)?; + let (index, rest) = parse_int(source)?; tabstop_index = index; source = rest; } diff --git a/crates/sum_tree/src/cursor.rs b/crates/sum_tree/src/cursor.rs index 39848ea56df9598caaf5b6d8f8a99749b1b953bc..09f253d43288f12e45d4eb0163c3933b84442a24 100644 --- a/crates/sum_tree/src/cursor.rs +++ b/crates/sum_tree/src/cursor.rs @@ -160,7 +160,7 @@ where let mut descending = false; while !self.stack.is_empty() { - if let Some(StackEntry { position, .. }) = self.stack.iter().rev().skip(1).next() { + if let Some(StackEntry { position, .. }) = self.stack.iter().rev().nth(1) { self.position = position.clone(); } else { self.position = D::default(); @@ -224,7 +224,7 @@ where self.did_seek = true; } - while self.stack.len() > 0 { + while !self.stack.is_empty() { let new_subtree = { let entry = self.stack.last_mut().unwrap(); match entry.tree.0.as_ref() { @@ -409,7 +409,7 @@ where .zip(&child_summaries[entry.index..]) { let mut child_end = self.position.clone(); - child_end.add_summary(&child_summary, cx); + child_end.add_summary(child_summary, cx); let comparison = target.cmp(&child_end, cx); if comparison == Ordering::Greater @@ -503,7 +503,7 @@ impl<'a, T: Item> Iterator for Iter<'a, T> { descend = true; } - while self.stack.len() > 0 { + while !self.stack.is_empty() { let new_subtree = { let entry = self.stack.last_mut().unwrap(); match entry.tree.0.as_ref() { diff --git a/crates/sum_tree/src/sum_tree.rs b/crates/sum_tree/src/sum_tree.rs index efd5c43480174b777674eeed331013466841fa8a..fdfd5d9de2b6d75dda4f70ea8fa55e027c4422a2 100644 --- a/crates/sum_tree/src/sum_tree.rs +++ b/crates/sum_tree/src/sum_tree.rs @@ -304,7 +304,7 @@ impl SumTree { } pub fn push_tree(&mut self, other: Self, cx: &::Context) { - if !other.0.is_leaf() || other.0.items().len() > 0 { + if !other.0.is_leaf() || !other.0.items().is_empty() { if self.0.height() < other.0.height() { for tree in other.0.child_trees() { self.push_tree(tree.clone(), cx); @@ -610,10 +610,7 @@ pub enum Node { impl Node { fn is_leaf(&self) -> bool { - match self { - Node::Leaf { .. } => true, - _ => false, - } + matches!(self, Node::Leaf { .. }) } fn height(&self) -> u8 { @@ -786,8 +783,7 @@ mod tests { while item_ix < expected_filtered_items.len() { log::info!("filter_cursor, item_ix: {}", item_ix); let actual_item = filter_cursor.item().unwrap(); - let (reference_index, reference_item) = - expected_filtered_items[item_ix].clone(); + let (reference_index, reference_item) = expected_filtered_items[item_ix]; assert_eq!(actual_item, &reference_item); assert_eq!(filter_cursor.start().0, reference_index); log::info!("next"); diff --git a/crates/sum_tree/src/tree_map.rs b/crates/sum_tree/src/tree_map.rs index 5218d2b4dbad5e4c3b59573c4db9e3ca3aab2f8a..8672ca398f9d13d5c9348d94f7d781adafa61dd7 100644 --- a/crates/sum_tree/src/tree_map.rs +++ b/crates/sum_tree/src/tree_map.rs @@ -73,7 +73,7 @@ impl TreeMap { removed } - pub fn iter<'a>(&'a self) -> impl 'a + Iterator { + pub fn iter(&self) -> impl Iterator + '_ { self.0.iter().map(|entry| (&entry.key, &entry.value)) } } @@ -162,7 +162,7 @@ where self.0.get(key).is_some() } - pub fn iter<'a>(&'a self) -> impl 'a + Iterator { + pub fn iter(&self) -> impl Iterator + '_ { self.0.iter().map(|(k, _)| k) } } diff --git a/crates/terminal/src/connected_el.rs b/crates/terminal/src/connected_el.rs index a68280a7c784c17ec26a9737bf4e9e5a60c52b0e..ab08efc1b3b8e9070275e8e6e3b817e58bcca791 100644 --- a/crates/terminal/src/connected_el.rs +++ b/crates/terminal/src/connected_el.rs @@ -190,7 +190,7 @@ impl RelativeHighlightedRange { let end_x = origin.x() + self.range.end as f32 * layout.size.cell_width + layout.size.cell_width; - return HighlightedRangeLine { start_x, end_x }; + HighlightedRangeLine { start_x, end_x } } } @@ -273,7 +273,7 @@ impl TerminalEl { cur_rect = cur_rect.take().map(|rect| rect.extend()); } else { cur_alac_color = Some(bg); - if let Some(_) = cur_rect { + if cur_rect.is_some() { rects.push(cur_rect.take().unwrap()); } cur_rect = Some(LayoutRect::new( @@ -402,7 +402,7 @@ impl TerminalEl { RunStyle { color: fg, - font_id: font_id, + font_id, underline, } } @@ -416,9 +416,9 @@ impl TerminalEl { display_offset: usize, cx: &mut PaintContext, ) { - let mouse_down_connection = self.terminal.clone(); - let click_connection = self.terminal.clone(); - let drag_connection = self.terminal.clone(); + let mouse_down_connection = self.terminal; + let click_connection = self.terminal; + let drag_connection = self.terminal; cx.scene.push_mouse_region( MouseRegion::new(view_id, None, visible_bounds) .on_down( @@ -500,7 +500,7 @@ impl TerminalEl { .terminal_overrides .font_family .as_ref() - .or_else(|| settings.terminal_defaults.font_family.as_ref()) + .or(settings.terminal_defaults.font_family.as_ref()) .and_then(|family_name| font_cache.load_family(&[family_name]).log_err()) .unwrap_or(settings.buffer_font_family); @@ -581,7 +581,7 @@ impl Element for TerminalEl { //Setup layout information let terminal_theme = settings.theme.terminal.clone(); //TODO: Try to minimize this clone. - let text_style = TerminalEl::make_text_style(font_cache, &settings); + let text_style = TerminalEl::make_text_style(font_cache, settings); let selection_color = settings.theme.editor.selection.selection; let dimensions = { let line_height = font_cache.line_height(text_style.font_size); @@ -590,9 +590,9 @@ impl Element for TerminalEl { }; let background_color = if self.modal { - terminal_theme.colors.modal_background.clone() + terminal_theme.colors.modal_background } else { - terminal_theme.colors.background.clone() + terminal_theme.colors.background }; let (cells, selection, cursor, display_offset, cursor_text) = self @@ -614,17 +614,17 @@ impl Element for TerminalEl { // && !ic.flags.contains(Flags::INVERSE)) // }) .map(|ic| IndexedCell { - point: ic.point.clone(), + point: ic.point, cell: ic.cell.clone(), }), ); ( cells, - content.selection.clone(), - content.cursor.clone(), - content.display_offset.clone(), - cursor_text.clone(), + content.selection, + content.cursor, + content.display_offset, + cursor_text, ) }) }); @@ -666,7 +666,7 @@ impl Element for TerminalEl { dimensions.line_height, terminal_theme.colors.cursor, CursorShape::Block, - Some(cursor_text.clone()), + Some(cursor_text), ) }, ) @@ -721,7 +721,7 @@ impl Element for TerminalEl { }); for rect in &layout.rects { - rect.paint(origin, &layout, cx) + rect.paint(origin, layout, cx) } }); @@ -786,11 +786,11 @@ impl Element for TerminalEl { let vertical_scroll = (delta.y() / layout.size.line_height) * ALACRITTY_SCROLL_MULTIPLIER; - self.terminal.upgrade(cx.app).map(|terminal| { + if let Some(terminal) = self.terminal.upgrade(cx.app) { terminal.update(cx.app, |term, _| { term.scroll(Scroll::Delta(vertical_scroll.round() as i32)) }); - }); + } cx.notify(); }) diff --git a/crates/terminal/src/connected_view.rs b/crates/terminal/src/connected_view.rs index ed9b994e755185e61fd3c3b33752d829aaecb32b..1da8aad610ec342de3fb67dc88aba9da91024626 100644 --- a/crates/terminal/src/connected_view.rs +++ b/crates/terminal/src/connected_view.rs @@ -82,7 +82,7 @@ impl ConnectedView { has_new_content: true, has_bell: false, modal, - context_menu: cx.add_view(|cx| ContextMenu::new(cx)), + context_menu: cx.add_view(ContextMenu::new), } } @@ -127,9 +127,9 @@ impl ConnectedView { ///Attempt to paste the clipboard into the terminal fn paste(&mut self, _: &Paste, cx: &mut ViewContext) { - cx.read_from_clipboard().map(|item| { + if let Some(item) = cx.read_from_clipboard() { self.terminal.read(cx).paste(item.text()); - }); + } } ///Synthesize the keyboard event corresponding to 'up' diff --git a/crates/terminal/src/mappings/colors.rs b/crates/terminal/src/mappings/colors.rs index 1a425ebaeddd252034d1c78e703336dc01915874..9359be79ff5881a7afbdde2f5c3866fb4cb97dfc 100644 --- a/crates/terminal/src/mappings/colors.rs +++ b/crates/terminal/src/mappings/colors.rs @@ -110,7 +110,7 @@ pub fn get_color_at_index(index: &usize, colors: &TerminalColors) -> Color { /// ///This function does the reverse, calculating the r, g, and b components from a given index. fn rgb_for_index(i: &u8) -> (u8, u8, u8) { - debug_assert!(i >= &16 && i <= &231); + debug_assert!((&16..=&231).contains(&i)); let i = i - 16; let r = (i - (i % 36)) / 36; let g = ((i % 36) - (i % 6)) / 6; diff --git a/crates/terminal/src/mappings/keys.rs b/crates/terminal/src/mappings/keys.rs index 215bfe1ad983770c1c14116f9f2380bbfee4fe6f..e07a3249984d07502e59ad473ba7f6e3f6d4b522 100644 --- a/crates/terminal/src/mappings/keys.rs +++ b/crates/terminal/src/mappings/keys.rs @@ -48,7 +48,7 @@ pub fn might_convert(keystroke: &Keystroke) -> bool { } pub fn to_esc_str(keystroke: &Keystroke, mode: &TermMode) -> Option { - let modifiers = Modifiers::new(&keystroke); + let modifiers = Modifiers::new(keystroke); // Manual Bindings including modifiers let manual_esc_str = match (keystroke.key.as_ref(), &modifiers) { @@ -204,7 +204,7 @@ pub fn to_esc_str(keystroke: &Keystroke, mode: &TermMode) -> Option { // Automated bindings applying modifiers if modifiers.any() { - let modifier_code = modifier_code(&keystroke); + let modifier_code = modifier_code(keystroke); let modified_esc_str = match keystroke.key.as_ref() { "up" => Some(format!("\x1b[1;{}A", modifier_code)), "down" => Some(format!("\x1b[1;{}B", modifier_code)), diff --git a/crates/terminal/src/modal.rs b/crates/terminal/src/modal.rs index 322f26ea3ca2612edb78921008ff377f9b938d0a..936a4091b6714a027fd9b7ded4c6827ca7cbf58d 100644 --- a/crates/terminal/src/modal.rs +++ b/crates/terminal/src/modal.rs @@ -58,9 +58,7 @@ pub fn deploy_modal(workspace: &mut Workspace, _: &DeployModal, cx: &mut ViewCon let terminal_handle = connected.read(cx).handle(); // Set the global immediately if terminal construction was successful, // in case the user opens the command palette - cx.set_global::>(Some(StoredTerminal( - terminal_handle.clone(), - ))); + cx.set_global::>(Some(StoredTerminal(terminal_handle))); } } } diff --git a/crates/terminal/src/terminal.rs b/crates/terminal/src/terminal.rs index b54685c45819253f469b42abcf4e73e330e8cb99..f31c07423efac4d5c5e84f849af2a5c81b6977c3 100644 --- a/crates/terminal/src/terminal.rs +++ b/crates/terminal/src/terminal.rs @@ -137,13 +137,13 @@ impl Default for TerminalSize { } } -impl Into for TerminalSize { - fn into(self) -> WindowSize { +impl From for WindowSize { + fn from(val: TerminalSize) -> Self { WindowSize { - num_lines: self.num_lines() as u16, - num_cols: self.num_columns() as u16, - cell_width: self.cell_width() as u16, - cell_height: self.line_height() as u16, + num_lines: val.num_lines() as u16, + num_cols: val.num_columns() as u16, + cell_width: val.cell_width() as u16, + cell_height: val.line_height() as u16, } } } @@ -269,7 +269,7 @@ impl TerminalBuilder { } }; - let mut env = env.unwrap_or_else(|| HashMap::new()); + let mut env = env.unwrap_or_default(); //TODO: Properly set the current locale, env.insert("LC_ALL".to_string(), "en_US.UTF-8".to_string()); @@ -293,7 +293,7 @@ impl TerminalBuilder { let term = Arc::new(FairMutex::new(term)); //Setup the pty... - let pty = match tty::new(&pty_config, initial_size.clone().into(), None) { + let pty = match tty::new(&pty_config, initial_size.into(), None) { Ok(pty) => pty, Err(error) => { bail!(TerminalError { @@ -321,7 +321,7 @@ impl TerminalBuilder { //And connect them together let event_loop = EventLoop::new( term.clone(), - ZedListener(events_tx.clone()), + ZedListener(events_tx), pty, pty_config.hold, false, @@ -379,7 +379,7 @@ impl TerminalBuilder { } } - if events.len() == 0 { + if events.is_empty() { smol::future::yield_now().await; break 'outer; } else { @@ -459,11 +459,11 @@ impl Terminal { AlacTermEvent::ClipboardLoad(_, format) => self.notify_pty(format( &cx.read_from_clipboard() .map(|ci| ci.text().to_string()) - .unwrap_or("".to_string()), + .unwrap_or_else(|| "".to_string()), )), AlacTermEvent::PtyWrite(out) => self.notify_pty(out.clone()), AlacTermEvent::TextAreaSizeRequest(format) => { - self.notify_pty(format(self.cur_size.clone().into())) + self.notify_pty(format(self.cur_size.into())) } AlacTermEvent::CursorBlinkingChange => { //TODO whatever state we need to set to get the cursor blinking @@ -500,24 +500,19 @@ impl Terminal { ) { // TODO: Handle is_self_focused in subscription on terminal view match event { - InternalEvent::TermEvent(term_event) => match term_event { - //Needs to lock - AlacTermEvent::ColorRequest(index, format) => { + InternalEvent::TermEvent(term_event) => { + if let AlacTermEvent::ColorRequest(index, format) = term_event { let color = term.colors()[*index].unwrap_or_else(|| { let term_style = &cx.global::().theme.terminal; to_alac_rgb(get_color_at_index(index, &term_style.colors)) }); self.notify_pty(format(color)) } - _ => {} //Other events are handled in the event loop - }, + } InternalEvent::Resize(new_size) => { - self.cur_size = new_size.clone(); + self.cur_size = *new_size; - self.pty_tx - .0 - .send(Msg::Resize(new_size.clone().into())) - .ok(); + self.pty_tx.0.send(Msg::Resize((*new_size).into())).ok(); term.resize(*new_size); } @@ -553,7 +548,7 @@ impl Terminal { ///Resize the terminal and the PTY. pub fn set_size(&mut self, new_size: TerminalSize) { - self.events.push(InternalEvent::Resize(new_size.into())) + self.events.push(InternalEvent::Resize(new_size)) } pub fn clear(&mut self) { @@ -574,7 +569,7 @@ impl Terminal { pub fn paste(&self, text: &str) { if self.last_mode.contains(TermMode::BRACKETED_PASTE) { self.notify_pty("\x1b[200~".to_string()); - self.notify_pty(text.replace('\x1b', "").to_string()); + self.notify_pty(text.replace('\x1b', "")); self.notify_pty("\x1b[201~".to_string()); } else { self.notify_pty(text.replace("\r\n", "\r").replace('\n', "\r")); @@ -597,7 +592,7 @@ impl Terminal { } // self.utilization = Self::estimate_utilization(term.take_last_processed_bytes()); - self.last_mode = term.mode().clone(); + self.last_mode = *term.mode(); let content = term.renderable_content(); @@ -668,7 +663,7 @@ mod tests { mod alacritty_unix { use alacritty_terminal::config::Program; use gpui::anyhow::{bail, Result}; - use libc; + use std::ffi::CStr; use std::mem::MaybeUninit; use std::ptr; diff --git a/crates/terminal/src/terminal_view.rs b/crates/terminal/src/terminal_view.rs index 1b4544a3dc01290842794ac764fdfc5944af0c50..ed632171789cd553b115600866951229201aa8b7 100644 --- a/crates/terminal/src/terminal_view.rs +++ b/crates/terminal/src/terminal_view.rs @@ -99,7 +99,7 @@ impl TerminalView { Ok(terminal) => { let terminal = cx.add_model(|cx| terminal.subscribe(cx)); let view = cx.add_view(|cx| ConnectedView::from_terminal(terminal, modal, cx)); - cx.subscribe(&view, |_this, _content, event, cx| cx.emit(event.clone())) + cx.subscribe(&view, |_this, _content, event, cx| cx.emit(*event)) .detach(); TerminalContent::Connected(view) } @@ -206,7 +206,7 @@ impl View for ErrorView { ) .with_child(Text::new(program_text, style.clone()).contained().boxed()) .with_child(Text::new(directory_text, style.clone()).contained().boxed()) - .with_child(Text::new(error_text, style.clone()).contained().boxed()) + .with_child(Text::new(error_text, style).contained().boxed()) .aligned() .boxed() } @@ -333,7 +333,7 @@ pub fn get_working_directory( .filter(|dir| dir.is_dir()) } }; - res.or_else(|| home_dir()) + res.or_else(home_dir) } ///Get's the first project's home directory, or the home directory diff --git a/crates/text/src/anchor.rs b/crates/text/src/anchor.rs index 36781bd3311c73b37a4ab098f2bb5448467777ce..dca95ce5d5ffaa8ab50cea80ca953160265c5e95 100644 --- a/crates/text/src/anchor.rs +++ b/crates/text/src/anchor.rs @@ -33,7 +33,7 @@ impl Anchor { } else { buffer .fragment_id_for_anchor(self) - .cmp(&buffer.fragment_id_for_anchor(other)) + .cmp(buffer.fragment_id_for_anchor(other)) }; fragment_id_comparison @@ -43,17 +43,17 @@ impl Anchor { pub fn min(&self, other: &Self, buffer: &BufferSnapshot) -> Self { if self.cmp(other, buffer).is_le() { - self.clone() + *self } else { - other.clone() + *other } } pub fn max(&self, other: &Self, buffer: &BufferSnapshot) -> Self { if self.cmp(other, buffer).is_ge() { - self.clone() + *self } else { - other.clone() + *other } } @@ -67,7 +67,7 @@ impl Anchor { pub fn bias_left(&self, buffer: &BufferSnapshot) -> Anchor { if self.bias == Bias::Left { - self.clone() + *self } else { buffer.anchor_before(self) } @@ -75,13 +75,13 @@ impl Anchor { pub fn bias_right(&self, buffer: &BufferSnapshot) -> Anchor { if self.bias == Bias::Right { - self.clone() + *self } else { buffer.anchor_after(self) } } - pub fn summary<'a, D>(&self, content: &'a BufferSnapshot) -> D + pub fn summary(&self, content: &BufferSnapshot) -> D where D: TextDimension, { @@ -100,7 +100,7 @@ where T: ToOffset, { fn to_offset(&self, snapshot: &BufferSnapshot) -> Range { - self.start.to_offset(snapshot)..self.end.to_offset(&snapshot) + self.start.to_offset(snapshot)..self.end.to_offset(snapshot) } fn to_point(&self, snapshot: &BufferSnapshot) -> Range { @@ -122,7 +122,7 @@ impl AnchorRangeExt for Range { fn cmp(&self, other: &Range, buffer: &BufferSnapshot) -> Result { Ok(match self.start.cmp(&other.start, buffer) { Ordering::Equal => other.end.cmp(&self.end, buffer), - ord @ _ => ord, + ord => ord, }) } } diff --git a/crates/text/src/locator.rs b/crates/text/src/locator.rs index f98f0503398987a5dbb3803ec9edc38ab069ed06..9d38a51df071d1c679f376c3f4c00baf3ab8929a 100644 --- a/crates/text/src/locator.rs +++ b/crates/text/src/locator.rs @@ -41,6 +41,10 @@ impl Locator { pub fn len(&self) -> usize { self.0.len() } + + pub fn is_empty(&self) -> bool { + self.len() == 0 + } } impl Default for Locator { diff --git a/crates/text/src/operation_queue.rs b/crates/text/src/operation_queue.rs index a3f5b9b6bd71c61a186833f9c99d8a68bbb65b99..063f05066570f60d338366768a91ab8298d03077 100644 --- a/crates/text/src/operation_queue.rs +++ b/crates/text/src/operation_queue.rs @@ -26,6 +26,12 @@ impl OperationKey { } } +impl Default for OperationQueue { + fn default() -> Self { + OperationQueue::new() + } +} + impl OperationQueue { pub fn new() -> Self { OperationQueue(SumTree::new()) @@ -35,6 +41,10 @@ impl OperationQueue { self.0.summary().len } + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + pub fn insert(&mut self, mut ops: Vec) { ops.sort_by_key(|op| op.lamport_timestamp()); ops.dedup_by_key(|op| op.lamport_timestamp()); diff --git a/crates/text/src/patch.rs b/crates/text/src/patch.rs index 63e69f45a7d231c74dd7a13f82b57ac60f19eb8d..f10acbc2d3f3e01a856524694914fd5381b31e99 100644 --- a/crates/text/src/patch.rs +++ b/crates/text/src/patch.rs @@ -548,7 +548,7 @@ mod tests { let composed = patches[0].compose(&patches[1]); log::info!("composed patch: {:?}", &composed); - let mut actual_chars = initial_chars.clone(); + let mut actual_chars = initial_chars; for edit in composed.0 { actual_chars.splice( edit.new.start as usize..edit.new.start as usize + edit.old.len(), @@ -570,7 +570,7 @@ mod tests { apply_patch(&mut expected, &old, &inserted); apply_patch(&mut expected, &new, &inserted); - let mut actual = original.clone(); + let mut actual = original; apply_patch(&mut actual, &composed, &expected); assert_eq!( actual.into_iter().collect::(), diff --git a/crates/text/src/point.rs b/crates/text/src/point.rs index 9eded9f44354a851a88e1e0ae073bf7a0e11c8cf..4be01dfdacf29b54812f8cb5c27dc31eeba8b07b 100644 --- a/crates/text/src/point.rs +++ b/crates/text/src/point.rs @@ -23,7 +23,7 @@ impl Point { Point::new(0, 0) } - pub fn from_str(s: &str) -> Self { + pub fn parse_str(s: &str) -> Self { let mut point = Self::zero(); for (row, line) in s.split('\n').enumerate() { point.row = row as u32; diff --git a/crates/text/src/rope.rs b/crates/text/src/rope.rs index 012b7fdd66afbb9294b98afb71ec3fc4ab0e58f6..d35ac46f45ec92c8c13f8c0cd90b3c08ca7c11bf 100644 --- a/crates/text/src/rope.rs +++ b/crates/text/src/rope.rs @@ -123,6 +123,10 @@ impl Rope { self.chunks.extent(&()) } + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + pub fn max_point(&self) -> Point { self.chunks.extent(&()) } @@ -152,7 +156,7 @@ impl Rope { Bytes::new(self, range) } - pub fn chunks<'a>(&'a self) -> Chunks<'a> { + pub fn chunks(&self) -> Chunks { self.chunks_in_range(0..self.len()) } @@ -896,7 +900,7 @@ impl sum_tree::Summary for TextSummary { } } -impl<'a> std::ops::Add for TextSummary { +impl std::ops::Add for TextSummary { type Output = Self; fn add(mut self, rhs: Self) -> Self::Output { @@ -946,7 +950,7 @@ pub trait TextDimension: 'static + for<'a> Dimension<'a, ChunkSummary> { fn add_assign(&mut self, other: &Self); } -impl<'a, D1: TextDimension, D2: TextDimension> TextDimension for (D1, D2) { +impl TextDimension for (D1, D2) { fn from_text_summary(summary: &TextSummary) -> Self { ( D1::from_text_summary(summary), diff --git a/crates/text/src/tests.rs b/crates/text/src/tests.rs index 33d02acf5a87d34781f743422ad515dc0b971870..ae91478f89eb4a713cc0bf992f03c8d69d123c9b 100644 --- a/crates/text/src/tests.rs +++ b/crates/text/src/tests.rs @@ -42,7 +42,7 @@ fn test_random_edits(mut rng: StdRng) { let mut reference_string = RandomCharIter::new(&mut rng) .take(reference_string_len) .collect::(); - let mut buffer = Buffer::new(0, 0, reference_string.clone().into()); + let mut buffer = Buffer::new(0, 0, reference_string.clone()); LineEnding::normalize(&mut reference_string); buffer.history.group_interval = Duration::from_millis(rng.gen_range(0..=200)); @@ -56,7 +56,7 @@ fn test_random_edits(mut rng: StdRng) { for _i in 0..operations { let (edits, _) = buffer.randomly_edit(&mut rng, 5); for (old_range, new_text) in edits.iter().rev() { - reference_string.replace_range(old_range.clone(), &new_text); + reference_string.replace_range(old_range.clone(), new_text); } assert_eq!(buffer.text(), reference_string); @@ -677,9 +677,9 @@ fn test_concurrent_edits() { buffer1.apply_op(buf2_op.clone()).unwrap(); buffer1.apply_op(buf3_op.clone()).unwrap(); buffer2.apply_op(buf1_op.clone()).unwrap(); - buffer2.apply_op(buf3_op.clone()).unwrap(); - buffer3.apply_op(buf1_op.clone()).unwrap(); - buffer3.apply_op(buf2_op.clone()).unwrap(); + buffer2.apply_op(buf3_op).unwrap(); + buffer3.apply_op(buf1_op).unwrap(); + buffer3.apply_op(buf2_op).unwrap(); assert_eq!(buffer1.text(), "a12c34e56"); assert_eq!(buffer2.text(), "a12c34e56"); @@ -704,7 +704,7 @@ fn test_random_concurrent_edits(mut rng: StdRng) { let mut network = Network::new(rng.clone()); for i in 0..peers { - let mut buffer = Buffer::new(i as ReplicaId, 0, base_text.clone().into()); + let mut buffer = Buffer::new(i as ReplicaId, 0, base_text.clone()); buffer.history.group_interval = Duration::from_millis(rng.gen_range(0..=200)); buffers.push(buffer); replica_ids.push(i as u16); diff --git a/crates/text/src/text.rs b/crates/text/src/text.rs index 7da77b22ffff69a72b71937187cb97dee7003d71..ff78f4a14b7418db61b1aca2066a9f19d125a596 100644 --- a/crates/text/src/text.rs +++ b/crates/text/src/text.rs @@ -530,7 +530,7 @@ impl Buffer { let mut version = clock::Global::new(); let visible_text = Rope::from(history.base_text.as_ref()); - if visible_text.len() > 0 { + if !visible_text.is_empty() { let insertion_timestamp = InsertionTimestamp { replica_id: 0, local: 1, @@ -860,7 +860,7 @@ impl Buffer { return; } - let edits = ranges.into_iter().zip(new_text.into_iter()); + let edits = ranges.iter().zip(new_text.iter()); let mut edits_patch = Patch::default(); let mut insertion_slices = Vec::new(); let cx = Some(version.clone()); @@ -1242,6 +1242,7 @@ impl Buffer { } } + #[allow(clippy::needless_collect)] pub fn undo_to_transaction(&mut self, transaction_id: TransactionId) -> Vec { let transactions = self .history @@ -1249,6 +1250,7 @@ impl Buffer { .iter() .map(|entry| entry.transaction.clone()) .collect::>(); + transactions .into_iter() .map(|transaction| self.undo_or_redo(transaction).unwrap()) @@ -1270,6 +1272,7 @@ impl Buffer { } } + #[allow(clippy::needless_collect)] pub fn redo_to_transaction(&mut self, transaction_id: TransactionId) -> Vec { let transactions = self .history @@ -1277,6 +1280,7 @@ impl Buffer { .iter() .map(|entry| entry.transaction.clone()) .collect::>(); + transactions .into_iter() .map(|transaction| self.undo_or_redo(transaction).unwrap()) @@ -1293,7 +1297,7 @@ impl Buffer { id: self.local_clock.tick(), version: self.version(), counts, - transaction_version: transaction.start.clone(), + transaction_version: transaction.start, }; self.apply_undo(&undo)?; let operation = Operation::Undo { @@ -1490,6 +1494,7 @@ impl Buffer { start..end } + #[allow(clippy::type_complexity)] pub fn randomly_edit( &mut self, rng: &mut T, @@ -1574,6 +1579,10 @@ impl BufferSnapshot { self.visible_text.len() } + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + pub fn chars(&self) -> impl Iterator + '_ { self.chars_at(0) } @@ -1609,8 +1618,8 @@ impl BufferSnapshot { .filter(|&len| { let left = self .chars_for_range(offset - len..offset) - .flat_map(|c| char::to_lowercase(c)); - let right = needle[..len].chars().flat_map(|c| char::to_lowercase(c)); + .flat_map(char::to_lowercase); + let right = needle[..len].chars().flat_map(char::to_lowercase); left.eq(right) }) .last() @@ -1684,15 +1693,12 @@ impl BufferSnapshot { &self.version } - pub fn chars_at<'a, T: ToOffset>(&'a self, position: T) -> impl Iterator + 'a { + pub fn chars_at(&self, position: T) -> impl Iterator + '_ { let offset = position.to_offset(self); self.visible_text.chars_at(offset) } - pub fn reversed_chars_at<'a, T: ToOffset>( - &'a self, - position: T, - ) -> impl Iterator + 'a { + pub fn reversed_chars_at(&self, position: T) -> impl Iterator + '_ { let offset = position.to_offset(self); self.visible_text.reversed_chars_at(offset) } @@ -1702,13 +1708,13 @@ impl BufferSnapshot { self.visible_text.reversed_chunks_in_range(range) } - pub fn bytes_in_range<'a, T: ToOffset>(&'a self, range: Range) -> rope::Bytes<'a> { + pub fn bytes_in_range(&self, range: Range) -> rope::Bytes<'_> { let start = range.start.to_offset(self); let end = range.end.to_offset(self); self.visible_text.bytes_in_range(start..end) } - pub fn text_for_range<'a, T: ToOffset>(&'a self, range: Range) -> Chunks<'a> { + pub fn text_for_range(&self, range: Range) -> Chunks<'_> { let start = range.start.to_offset(self); let end = range.end.to_offset(self); self.visible_text.chunks_in_range(start..end) @@ -1729,7 +1735,7 @@ impl BufferSnapshot { .all(|chunk| chunk.matches(|c: char| !c.is_whitespace()).next().is_none()) } - pub fn text_summary_for_range<'a, D, O: ToOffset>(&'a self, range: Range) -> D + pub fn text_summary_for_range(&self, range: Range) -> D where D: TextDimension, { @@ -1788,7 +1794,7 @@ impl BufferSnapshot { }) } - fn summary_for_anchor<'a, D>(&'a self, anchor: &Anchor) -> D + fn summary_for_anchor(&self, anchor: &Anchor) -> D where D: TextDimension, { @@ -2048,7 +2054,7 @@ impl<'a, D: TextDimension + Ord, F: FnMut(&FragmentSummary) -> bool> Iterator fo break; } - if !fragment.was_visible(&self.since, &self.undos) && fragment.visible { + if !fragment.was_visible(self.since, self.undos) && fragment.visible { let mut visible_end = cursor.end(&None).visible; if fragment.id == *self.range.end.0 { visible_end = cmp::min( @@ -2070,7 +2076,7 @@ impl<'a, D: TextDimension + Ord, F: FnMut(&FragmentSummary) -> bool> Iterator fo } self.new_end = new_end; - } else if fragment.was_visible(&self.since, &self.undos) && !fragment.visible { + } else if fragment.was_visible(self.since, self.undos) && !fragment.visible { let mut deleted_end = cursor.end(&None).deleted; if fragment.id == *self.range.end.0 { deleted_end = cmp::min( @@ -2354,10 +2360,7 @@ impl Operation { } pub fn is_edit(&self) -> bool { - match self { - Operation::Edit { .. } => true, - _ => false, - } + matches!(self, Operation::Edit { .. }) } } @@ -2423,7 +2426,7 @@ impl LineEnding { } pub trait ToOffset { - fn to_offset<'a>(&self, snapshot: &BufferSnapshot) -> usize; + fn to_offset(&self, snapshot: &BufferSnapshot) -> usize; } impl ToOffset for Point { @@ -2464,7 +2467,7 @@ impl<'a, T: ToOffset> ToOffset for &'a T { } pub trait ToPoint { - fn to_point<'a>(&self, snapshot: &BufferSnapshot) -> Point; + fn to_point(&self, snapshot: &BufferSnapshot) -> Point; } impl ToPoint for Anchor { @@ -2492,7 +2495,7 @@ impl ToPoint for Point { } pub trait ToPointUtf16 { - fn to_point_utf16<'a>(&self, snapshot: &BufferSnapshot) -> PointUtf16; + fn to_point_utf16(&self, snapshot: &BufferSnapshot) -> PointUtf16; } impl ToPointUtf16 for Anchor { @@ -2520,7 +2523,7 @@ impl ToPointUtf16 for Point { } pub trait ToOffsetUtf16 { - fn to_offset_utf16<'a>(&self, snapshot: &BufferSnapshot) -> OffsetUtf16; + fn to_offset_utf16(&self, snapshot: &BufferSnapshot) -> OffsetUtf16; } impl ToOffsetUtf16 for Anchor { diff --git a/crates/theme_selector/src/theme_selector.rs b/crates/theme_selector/src/theme_selector.rs index dcda882168bc96aec91ee81013a8ec050b886b7e..d09e3b298dc0fa2b15982d056edafe7e790d4aca 100644 --- a/crates/theme_selector/src/theme_selector.rs +++ b/crates/theme_selector/src/theme_selector.rs @@ -44,7 +44,7 @@ impl ThemeSelector { theme_names.sort_unstable_by(|a, b| { a.ends_with("dark") .cmp(&b.ends_with("dark")) - .then_with(|| a.cmp(&b)) + .then_with(|| a.cmp(b)) }); let matches = theme_names .iter() diff --git a/crates/util/src/lib.rs b/crates/util/src/lib.rs index 0616b2a75ec8352de152cb8d95100c2aed484dc5..9b6507461576baf0068610b69743477b720e1fb1 100644 --- a/crates/util/src/lib.rs +++ b/crates/util/src/lib.rs @@ -128,7 +128,9 @@ struct Defer(Option); impl Drop for Defer { fn drop(&mut self) { - self.0.take().map(|f| f()); + if let Some(f) = self.0.take() { + f() + } } } diff --git a/crates/util/src/test/marked_text.rs b/crates/util/src/test/marked_text.rs index b5b68c22c9e4d4d6f8ae2e52efa600a1c373b793..c2aaca383158db66833db52be667d95997bee9b6 100644 --- a/crates/util/src/test/marked_text.rs +++ b/crates/util/src/test/marked_text.rs @@ -195,19 +195,19 @@ pub fn generate_marked_text( match range.start.cmp(&range.end) { Ordering::Less => { marked_text.insert_str(range.end, "ˇ»"); - marked_text.insert_str(range.start, "«"); + marked_text.insert(range.start, '«'); } Ordering::Equal => { - marked_text.insert_str(range.start, "ˇ"); + marked_text.insert(range.start, 'ˇ'); } Ordering::Greater => { - marked_text.insert_str(range.start, "»"); + marked_text.insert(range.start, '»'); marked_text.insert_str(range.end, "«ˇ"); } } } else { - marked_text.insert_str(range.end, "»"); - marked_text.insert_str(range.start, "«"); + marked_text.insert(range.end, '»'); + marked_text.insert(range.start, '«'); } } marked_text diff --git a/crates/vim/src/motion.rs b/crates/vim/src/motion.rs index d9e4bf084c69d994c6655b1bae01b952da160cdb..b4667278ba7ab893d55230b8799257fcc03d8dc1 100644 --- a/crates/vim/src/motion.rs +++ b/crates/vim/src/motion.rs @@ -126,10 +126,10 @@ fn motion(motion: Motion, cx: &mut MutableAppContext) { impl Motion { pub fn linewise(self) -> bool { use Motion::*; - match self { - Down | Up | StartOfDocument | EndOfDocument | CurrentLine => true, - _ => false, - } + matches!( + self, + Down | Up | StartOfDocument | EndOfDocument | CurrentLine + ) } pub fn inclusive(self) -> bool { @@ -282,8 +282,7 @@ fn next_word_end( // we have backtraced already if !map .chars_at(point) - .skip(1) - .next() + .nth(1) .map(|c| c == '\n') .unwrap_or(true) { diff --git a/crates/vim/src/normal.rs b/crates/vim/src/normal.rs index 508477ea46ad57cb29d39be08a12b5bda28fc526..db5583b4ce76cc520c599b62a59235f9fe059268 100644 --- a/crates/vim/src/normal.rs +++ b/crates/vim/src/normal.rs @@ -254,7 +254,7 @@ fn paste(_: &mut Workspace, _: &Paste, cx: &mut ViewContext) { } // Drop selection at the start of the next line let selection_point = Point::new(point.row + 1, 0); - new_selections.push(selection.map(|_| selection_point.clone())); + new_selections.push(selection.map(|_| selection_point)); point } else { let mut point = selection.end; diff --git a/crates/vim/src/normal/change.rs b/crates/vim/src/normal/change.rs index 1a7b934a31d4140927e69335041a4d1454e4bf69..8695c9668ba6c6cad7cfec6978ee60dfaefd8a18 100644 --- a/crates/vim/src/normal/change.rs +++ b/crates/vim/src/normal/change.rs @@ -28,7 +28,7 @@ pub fn change_over(vim: &mut Vim, motion: Motion, cx: &mut MutableAppContext) { }); }); copy_selections_content(editor, motion.linewise(), cx); - editor.insert(&"", cx); + editor.insert("", cx); }); }); vim.switch_mode(Mode::Insert, false, cx) @@ -67,7 +67,7 @@ fn change_word( }); }); copy_selections_content(editor, false, cx); - editor.insert(&"", cx); + editor.insert("", cx); }); }); vim.switch_mode(Mode::Insert, false, cx); diff --git a/crates/vim/src/normal/delete.rs b/crates/vim/src/normal/delete.rs index c639e604dce8a627ced6b02cb009f1e441f09720..b2e228bdb1a38d9e20ef4563bb2c2c107872ae95 100644 --- a/crates/vim/src/normal/delete.rs +++ b/crates/vim/src/normal/delete.rs @@ -16,7 +16,7 @@ pub fn delete_over(vim: &mut Vim, motion: Motion, cx: &mut MutableAppContext) { }); }); copy_selections_content(editor, motion.linewise(), cx); - editor.insert(&"", cx); + editor.insert("", cx); // Fixup cursor position after the deletion editor.set_clip_at_line_ends(true, cx); diff --git a/crates/vim/src/state.rs b/crates/vim/src/state.rs index e36cb7203daffac4bbec7dd51b4498324219d729..e556048ea87fd7d0ef4640448668a785e7a6fa64 100644 --- a/crates/vim/src/state.rs +++ b/crates/vim/src/state.rs @@ -54,10 +54,7 @@ impl VimState { } pub fn clip_at_line_end(&self) -> bool { - match self.mode { - Mode::Insert | Mode::Visual { .. } => false, - _ => true, - } + !matches!(self.mode, Mode::Insert | Mode::Visual { .. }) } pub fn empty_selections_only(&self) -> bool { @@ -99,6 +96,6 @@ impl Operator { context .map - .insert("vim_operator".to_string(), operator_context.to_string()); + .insert("vim_operator".to_string(), operator_context); } } diff --git a/crates/vim/src/vim_test_context.rs b/crates/vim/src/vim_test_context.rs index dff0aaf3751fd7958152e94881b61e9f30c85433..2be2eb8d6f2ff6f6b7b74f94b1c820d12a97a99f 100644 --- a/crates/vim/src/vim_test_context.rs +++ b/crates/vim/src/vim_test_context.rs @@ -45,7 +45,7 @@ impl<'a> VimTestContext<'a> { workspace.update(cx, |workspace, cx| { workspace.active_pane().update(cx, |pane, cx| { pane.toolbar().update(cx, |toolbar, cx| { - let buffer_search_bar = cx.add_view(|cx| BufferSearchBar::new(cx)); + let buffer_search_bar = cx.add_view(BufferSearchBar::new); toolbar.add_item(buffer_search_bar, cx); let project_search_bar = cx.add_view(|_| ProjectSearchBar::new()); toolbar.add_item(project_search_bar, cx); diff --git a/crates/vim/src/visual.rs b/crates/vim/src/visual.rs index 3f7b9c0683ee2e250faf6296acdbf08e1cea531a..d46839302760a867cba2fb5f3f0e26f1572c0624 100644 --- a/crates/vim/src/visual.rs +++ b/crates/vim/src/visual.rs @@ -103,7 +103,7 @@ pub fn delete(_: &mut Workspace, _: &VisualDelete, cx: &mut ViewContext let new_position = if linewise { edits.push((range.start..range.start, "\n")); - let mut new_position = range.start.clone(); + let mut new_position = range.start; new_position.column = 0; new_position.row += 1; new_position } else { - range.start.clone() + range.start }; - new_selections.push(selection.map(|_| new_position.clone())); + new_selections.push(selection.map(|_| new_position)); if linewise && to_insert.ends_with('\n') { edits.push(( diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index 4a96699dee2fecb75bac0eded9caeaf7794ced76..34108eef5e0abbbd5939c1347c76c9d2ebc63662 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -189,7 +189,7 @@ pub struct NavigationEntry { impl Pane { pub fn new(cx: &mut ViewContext) -> Self { let handle = cx.weak_handle(); - let context_menu = cx.add_view(|cx| ContextMenu::new(cx)); + let context_menu = cx.add_view(ContextMenu::new); Self { items: Vec::new(), is_active: true, @@ -389,7 +389,7 @@ impl Pane { let existing_item = pane.update(cx, |pane, cx| { for (ix, item) in pane.items.iter().enumerate() { if item.project_path(cx).is_some() - && item.project_entry_ids(cx).as_slice() == &[project_entry_id] + && item.project_entry_ids(cx).as_slice() == [project_entry_id] { let item = item.boxed_clone(); pane.activate_item(ix, true, focus_item, true, cx); @@ -450,7 +450,7 @@ impl Pane { self.items.iter() } - pub fn items_of_type<'a, T: View>(&'a self) -> impl 'a + Iterator> { + pub fn items_of_type(&self) -> impl '_ + Iterator> { self.items .iter() .filter_map(|item| item.to_any().downcast()) @@ -466,7 +466,7 @@ impl Pane { cx: &AppContext, ) -> Option> { self.items.iter().find_map(|item| { - if item.is_singleton(cx) && item.project_entry_ids(cx).as_slice() == &[entry_id] { + if item.is_singleton(cx) && item.project_entry_ids(cx).as_slice() == [entry_id] { Some(item.boxed_clone()) } else { None @@ -532,7 +532,7 @@ impl Pane { let mut index = self.active_item_index; if index > 0 { index -= 1; - } else if self.items.len() > 0 { + } else if !self.items.is_empty() { index = self.items.len() - 1; } self.activate_item(index, true, true, false, cx); @@ -653,7 +653,7 @@ impl Pane { { let other_project_entry_ids = item.project_entry_ids(cx); project_entry_ids - .retain(|id| !other_project_entry_ids.contains(&id)); + .retain(|id| !other_project_entry_ids.contains(id)); } } }); @@ -662,12 +662,11 @@ impl Pane { .any(|id| saved_project_entry_ids.insert(*id)) }; - if should_save { - if !Self::save_item(project.clone(), &pane, item_ix, &item, true, &mut cx) + if should_save + && !Self::save_item(project.clone(), &pane, item_ix, &*item, true, &mut cx) .await? - { - break; - } + { + break; } // Remove the item from the pane. @@ -728,14 +727,13 @@ impl Pane { project: ModelHandle, pane: &ViewHandle, item_ix: usize, - item: &Box, + item: &dyn ItemHandle, should_prompt_for_save: bool, cx: &mut AsyncAppContext, ) -> Result { - const CONFLICT_MESSAGE: &'static str = + const CONFLICT_MESSAGE: &str = "This file has changed on disk since you started editing it. Do you want to overwrite it?"; - const DIRTY_MESSAGE: &'static str = - "This file contains unsaved edits. Do you want to save it?"; + const DIRTY_MESSAGE: &str = "This file contains unsaved edits. Do you want to save it?"; let (has_conflict, is_dirty, can_save, is_singleton) = cx.read(|cx| { ( @@ -765,7 +763,7 @@ impl Pane { matches!( cx.global::().autosave, Autosave::OnFocusChange | Autosave::OnWindowChange - ) && Self::can_autosave_item(item.as_ref(), cx) + ) && Self::can_autosave_item(&*item, cx) }); let should_save = if should_prompt_for_save && !will_autosave { let mut answer = pane.update(cx, |pane, cx| { @@ -794,7 +792,7 @@ impl Pane { let worktree = project.visible_worktrees(cx).next()?; Some(worktree.read(cx).as_local()?.abs_path().to_path_buf()) }) - .unwrap_or(Path::new("").into()); + .unwrap_or_else(|| Path::new("").into()); let mut abs_path = cx.update(|cx| cx.prompt_for_new_path(&start_abs_path)); if let Some(abs_path) = abs_path.next().await.flatten() { diff --git a/crates/workspace/src/pane_group.rs b/crates/workspace/src/pane_group.rs index 025d561f61d1fa40344b0aa22a2d0991f888b7b1..0ed7ed111b44183b70fd2eea7aaff1d33584f35a 100644 --- a/crates/workspace/src/pane_group.rs +++ b/crates/workspace/src/pane_group.rs @@ -50,7 +50,7 @@ impl PaneGroup { } } - pub(crate) fn render<'a>( + pub(crate) fn render( &self, theme: &Theme, follower_states: &FollowerStatesByLeader, diff --git a/crates/workspace/src/sidebar.rs b/crates/workspace/src/sidebar.rs index b7ed8140c9fbabef93338e683ac939e103626a3c..6749de36a9710f9318aaf53edf4c4a1a7868d8bc 100644 --- a/crates/workspace/src/sidebar.rs +++ b/crates/workspace/src/sidebar.rs @@ -38,7 +38,7 @@ where } fn is_focused(&self, cx: &AppContext) -> bool { - ViewHandle::is_focused(&self, cx) || self.read(cx).contains_focused_view(cx) + ViewHandle::is_focused(self, cx) || self.read(cx).contains_focused_view(cx) } fn to_any(&self) -> AnyViewHandle { @@ -46,9 +46,9 @@ where } } -impl Into for &dyn SidebarItemHandle { - fn into(self) -> AnyViewHandle { - self.to_any() +impl From<&dyn SidebarItemHandle> for AnyViewHandle { + fn from(val: &dyn SidebarItemHandle) -> Self { + val.to_any() } } @@ -284,11 +284,14 @@ impl View for SidebarButtons { Side::Left => theme.group_left, Side::Right => theme.group_right, }; + + #[allow(clippy::needless_collect)] let items = sidebar .items .iter() .map(|item| (item.icon_path, item.tooltip.clone(), item.view.clone())) .collect::>(); + Flex::row() .with_children(items.into_iter().enumerate().map( |(ix, (icon_path, tooltip, item_view))| { diff --git a/crates/workspace/src/status_bar.rs b/crates/workspace/src/status_bar.rs index ca44cf7c27cacddacd36ef0d359cc122649956ac..f055168075ac5ae059eafb034206591d09cf189e 100644 --- a/crates/workspace/src/status_bar.rs +++ b/crates/workspace/src/status_bar.rs @@ -126,8 +126,8 @@ impl StatusItemViewHandle for ViewHandle { } } -impl Into for &dyn StatusItemViewHandle { - fn into(self) -> AnyViewHandle { - self.to_any() +impl From<&dyn StatusItemViewHandle> for AnyViewHandle { + fn from(val: &dyn StatusItemViewHandle) -> Self { + val.to_any() } } diff --git a/crates/workspace/src/toolbar.rs b/crates/workspace/src/toolbar.rs index f2a3fff6c4ed6e45c37f981386f0174bd8fa7523..24edbd673ee640d28cb5ed05a8c1689f75344b55 100644 --- a/crates/workspace/src/toolbar.rs +++ b/crates/workspace/src/toolbar.rs @@ -133,12 +133,10 @@ impl View for Toolbar { .with_child(nav_button( "icons/arrow_right_16.svg", button_style, - tooltip_style.clone(), + tooltip_style, enable_go_forward, spacing, - super::GoForward { - pane: Some(pane.clone()), - }, + super::GoForward { pane: Some(pane) }, super::GoForward { pane: None }, "Go Forward", cx, @@ -156,6 +154,7 @@ impl View for Toolbar { } } +#[allow(clippy::too_many_arguments)] fn nav_button( svg_path: &'static str, style: theme::Interactive, @@ -280,8 +279,8 @@ impl ToolbarItemViewHandle for ViewHandle { } } -impl Into for &dyn ToolbarItemViewHandle { - fn into(self) -> AnyViewHandle { - self.to_any() +impl From<&dyn ToolbarItemViewHandle> for AnyViewHandle { + fn from(val: &dyn ToolbarItemViewHandle) -> Self { + val.to_any() } } diff --git a/crates/workspace/src/waiting_room.rs b/crates/workspace/src/waiting_room.rs index e5d765d4d5856008a4a9f2388283465a6415ccc4..e05e0fb5ffdafd7616c1d5fa992ba6b1b5342700 100644 --- a/crates/workspace/src/waiting_room.rs +++ b/crates/workspace/src/waiting_room.rs @@ -116,7 +116,7 @@ impl WaitingRoom { workspace }); } - Err(error @ _) => { + Err(error) => { let login = &contact.user.github_login; let message = match error { project::JoinProjectError::HostDeclined => { diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 0d4ced4293cb40cef2843cf3685a5ae8749faa1b..1137098d16799012942e7c444a3cc1e231f8544b 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -588,7 +588,9 @@ impl ItemHandle for ViewHandle { if T::is_edit_event(event) { if let Autosave::AfterDelay { milliseconds } = cx.global::().autosave { - let prev_autosave = pending_autosave.take().unwrap_or(Task::ready(Some(()))); + let prev_autosave = pending_autosave + .take() + .unwrap_or_else(|| Task::ready(Some(()))); let (cancel_tx, mut cancel_rx) = oneshot::channel::<()>(); let prev_cancel_tx = mem::replace(&mut cancel_pending_autosave, cancel_tx); let project = workspace.project.downgrade(); @@ -695,9 +697,9 @@ impl ItemHandle for ViewHandle { } } -impl Into for Box { - fn into(self) -> AnyViewHandle { - self.to_any() +impl From> for AnyViewHandle { + fn from(val: Box) -> Self { + val.to_any() } } @@ -742,9 +744,9 @@ impl NotificationHandle for ViewHandle { } } -impl Into for &dyn NotificationHandle { - fn into(self) -> AnyViewHandle { - self.to_any() +impl From<&dyn NotificationHandle> for AnyViewHandle { + fn from(val: &dyn NotificationHandle) -> Self { + val.to_any() } } @@ -769,7 +771,7 @@ impl AppState { user_store, project_store, initialize_workspace: |_, _, _| {}, - build_window_options: || Default::default(), + build_window_options: Default::default, }) } } @@ -848,7 +850,7 @@ impl Workspace { }) .detach(); - let pane = cx.add_view(|cx| Pane::new(cx)); + let pane = cx.add_view(Pane::new); let pane_id = pane.id(); cx.subscribe(&pane, move |this, _, event, cx| { this.handle_pane_event(pane_id, event, cx) @@ -860,8 +862,8 @@ impl Workspace { let fs = project.read(cx).fs().clone(); let user_store = project.read(cx).user_store(); let client = project.read(cx).client(); - let mut current_user = user_store.read(cx).watch_current_user().clone(); - let mut connection_status = client.status().clone(); + let mut current_user = user_store.read(cx).watch_current_user(); + let mut connection_status = client.status(); let _observe_current_user = cx.spawn_weak(|this, mut cx| async move { current_user.recv().await; connection_status.recv().await; @@ -1073,7 +1075,7 @@ impl Workspace { project.clone(), &pane, ix, - &item, + &*item, should_prompt_to_save, &mut cx, ) @@ -1088,6 +1090,7 @@ impl Workspace { }) } + #[allow(clippy::type_complexity)] pub fn open_paths( &mut self, mut abs_paths: Vec, @@ -1150,10 +1153,8 @@ impl Workspace { let results = this .update(&mut cx, |this, cx| this.open_paths(paths, true, cx)) .await; - for result in results { - if let Some(result) = result { - result.log_err(); - } + for result in results.into_iter().flatten() { + result.log_err(); } } }) @@ -1316,7 +1317,7 @@ impl Workspace { if let Some(item) = self.active_item(cx) { if !force_name_change && item.can_save(cx) { if item.has_conflict(cx.as_ref()) { - const CONFLICT_MESSAGE: &'static str = "This file has changed on disk since you started editing it. Do you want to overwrite it?"; + const CONFLICT_MESSAGE: &str = "This file has changed on disk since you started editing it. Do you want to overwrite it?"; let mut answer = cx.prompt( PromptLevel::Warning, @@ -1424,7 +1425,7 @@ impl Workspace { } fn add_pane(&mut self, cx: &mut ViewContext) -> ViewHandle { - let pane = cx.add_view(|cx| Pane::new(cx)); + let pane = cx.add_view(Pane::new); let pane_id = pane.id(); cx.subscribe(&pane, move |this, _, event, cx| { this.handle_pane_event(pane_id, event, cx) @@ -1519,11 +1520,9 @@ impl Workspace { pub fn activate_item(&mut self, item: &dyn ItemHandle, cx: &mut ViewContext) -> bool { let result = self.panes.iter().find_map(|pane| { - if let Some(ix) = pane.read(cx).index_for_item(item) { - Some((pane.clone(), ix)) - } else { - None - } + pane.read(cx) + .index_for_item(item) + .map(|ix| (pane.clone(), ix)) }); if let Some((pane, ix)) = result { pane.update(cx, |pane, cx| pane.activate_item(ix, true, true, false, cx)); @@ -1749,7 +1748,7 @@ impl Workspace { let collaborators = self.project.read(cx).collaborators(); let next_leader_id = if let Some(leader_id) = self.leader_for_pane(&self.active_pane) { let mut collaborators = collaborators.keys().copied(); - while let Some(peer_id) = collaborators.next() { + for peer_id in collaborators.by_ref() { if peer_id == leader_id { break; } @@ -1779,7 +1778,7 @@ impl Workspace { ) -> Option { for (leader_id, states_by_pane) in &mut self.follower_states_by_leader { let leader_id = *leader_id; - if let Some(state) = states_by_pane.remove(&pane) { + if let Some(state) = states_by_pane.remove(pane) { for (_, item) in state.items_by_leader_view_id { if let FollowerItem::Loaded(item) = item { item.set_leader_replica_id(None, cx); @@ -2253,7 +2252,6 @@ impl Workspace { .values() .map(|b| b.0) .collect::>() - .clone() }); let mut item_tasks_by_pane = HashMap::default(); @@ -2367,13 +2365,11 @@ impl Workspace { fn leader_updated(&mut self, leader_id: PeerId, cx: &mut ViewContext) -> Option<()> { let mut items_to_add = Vec::new(); for (pane, state) in self.follower_states_by_leader.get(&leader_id)? { - if let Some(active_item) = state + if let Some(FollowerItem::Loaded(item)) = state .active_view_id .and_then(|id| state.items_by_leader_view_id.get(&id)) { - if let FollowerItem::Loaded(item) = active_item { - items_to_add.push((pane.clone(), item.boxed_clone())); - } + items_to_add.push((pane.clone(), item.boxed_clone())); } } @@ -2626,6 +2622,7 @@ pub fn activate_workspace_for_project( None } +#[allow(clippy::type_complexity)] pub fn open_paths( abs_paths: &[PathBuf], app_state: &Arc, @@ -2914,7 +2911,7 @@ mod tests { let item1 = cx.add_view(&workspace, |_| TestItem::new()); workspace.update(cx, |w, cx| w.add_item(Box::new(item1.clone()), cx)); let task = workspace.update(cx, |w, cx| w.prepare_to_close(cx)); - assert_eq!(task.await.unwrap(), true); + assert!(task.await.unwrap()); // When there are dirty untitled items, prompt to save each one. If the user // cancels any prompt, then abort. @@ -2938,7 +2935,7 @@ mod tests { cx.simulate_prompt_answer(window_id, 2 /* cancel */); cx.foreground().run_until_parked(); assert!(!cx.has_pending_prompt(window_id)); - assert_eq!(task.await.unwrap(), false); + assert!(!task.await.unwrap()); } #[gpui::test] @@ -3396,7 +3393,7 @@ mod tests { impl Item for TestItem { fn tab_description<'a>(&'a self, detail: usize, _: &'a AppContext) -> Option> { self.tab_descriptions.as_ref().and_then(|descriptions| { - let description = *descriptions.get(detail).or(descriptions.last())?; + let description = *descriptions.get(detail).or_else(|| descriptions.last())?; Some(description.into()) }) } @@ -3452,7 +3449,7 @@ mod tests { } fn can_save(&self, _: &AppContext) -> bool { - self.project_entry_ids.len() > 0 + !self.project_entry_ids.is_empty() } fn save( diff --git a/crates/zed/src/feedback.rs b/crates/zed/src/feedback.rs index f4b67a12bd0d61f233724f1666de093cb847a76c..18f8c04b4a9db8902871519b2cf647d423d44492 100644 --- a/crates/zed/src/feedback.rs +++ b/crates/zed/src/feedback.rs @@ -7,8 +7,7 @@ use gpui::{ use settings::Settings; use workspace::StatusItemView; -pub const NEW_ISSUE_URL: &'static str = - "https://github.com/zed-industries/feedback/issues/new/choose"; +pub const NEW_ISSUE_URL: &str = "https://github.com/zed-industries/feedback/issues/new/choose"; pub struct FeedbackLink; diff --git a/crates/zed/src/languages/c.rs b/crates/zed/src/languages/c.rs index a4db4b9a755d030de8d98039beea31fa5312e109..6aa750f6a09fd182920c4e3027352c9e40a4ef8f 100644 --- a/crates/zed/src/languages/c.rs +++ b/crates/zed/src/languages/c.rs @@ -116,7 +116,7 @@ impl super::LspAdapter for CLspAdapter { ) -> Option { let label = completion .label - .strip_prefix("•") + .strip_prefix('•') .unwrap_or(&completion.label) .trim(); diff --git a/crates/zed/src/languages/go.rs b/crates/zed/src/languages/go.rs index 3fa47428c9055496ae747f92bb45d3c4c7977811..729d39b513311d305e8b40db0e9baa40aee103b3 100644 --- a/crates/zed/src/languages/go.rs +++ b/crates/zed/src/languages/go.rs @@ -72,7 +72,7 @@ impl super::LspAdapter for GoLspAdapter { } } } else if let Some(path) = this.cached_server_binary(container_dir.clone()).await { - return Ok(path.to_path_buf()); + return Ok(path); } let gobin_dir = container_dir.join("gobin"); @@ -122,7 +122,7 @@ impl super::LspAdapter for GoLspAdapter { } if let Some(path) = last_binary_path { - Ok(path.to_path_buf()) + Ok(path) } else { Err(anyhow!("no cached binary")) } @@ -141,7 +141,7 @@ impl super::LspAdapter for GoLspAdapter { // Gopls returns nested fields and methods as completions. // To syntax highlight these, combine their final component // with their detail. - let name_offset = label.rfind(".").unwrap_or(0); + let name_offset = label.rfind('.').unwrap_or(0); match completion.kind.zip(completion.detail.as_ref()) { Some((lsp::CompletionItemKind::MODULE, detail)) => { diff --git a/crates/zed/src/languages/python.rs b/crates/zed/src/languages/python.rs index 801c7c96f9539af14d8013f9292291e6ee42b54f..274fc3216c99977ad7fb180e37d3a4b37b831adb 100644 --- a/crates/zed/src/languages/python.rs +++ b/crates/zed/src/languages/python.rs @@ -206,7 +206,7 @@ mod tests { ); // dedent the closing paren if it is shifted to the beginning of the line - let argument_ix = buffer.text().find("1").unwrap(); + let argument_ix = buffer.text().find('1').unwrap(); buffer.edit( [(argument_ix..argument_ix + 1, "")], Some(AutoindentMode::EachLine), diff --git a/crates/zed/src/languages/typescript.rs b/crates/zed/src/languages/typescript.rs index 199a7f22ae28d029867cd3281c9b12ef1dc746f4..85a1bd6400e64103429b431dbd4f2c6a1990f86c 100644 --- a/crates/zed/src/languages/typescript.rs +++ b/crates/zed/src/languages/typescript.rs @@ -65,7 +65,7 @@ impl LspAdapter for TypeScriptLspAdapter { ("typescript", versions.typescript_version.as_str()), ( "typescript-language-server", - &versions.server_version.as_str(), + versions.server_version.as_str(), ), ], &version_dir, diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index ed718272d8fb50be0d4e96da9434ed9e4c854836..aa2f0b7ada10be2ed1aae37cf180a5d581f1745e 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -29,7 +29,7 @@ use serde_json::json; use settings::{self, KeymapFileContent, Settings, SettingsFileContent}; use smol::process::Command; use std::{env, ffi::OsStr, fs, panic, path::PathBuf, sync::Arc, thread, time::Duration}; -use terminal; + use theme::ThemeRegistry; use util::{ResultExt, TryFutureExt}; use workspace::{self, AppState, NewFile, OpenPaths}; @@ -54,7 +54,7 @@ fn main() { let db = app.background().spawn(async move { project::Db::open(&*zed::paths::DB) .log_err() - .unwrap_or(project::Db::null()) + .unwrap_or_else(project::Db::null) }); load_embedded_fonts(&app); @@ -182,10 +182,8 @@ fn main() { if client::IMPERSONATE_LOGIN.is_some() { client.authenticate_and_connect(false, &cx).await?; } - } else { - if client.has_keychain_credentials(&cx) { - client.authenticate_and_connect(true, &cx).await?; - } + } else if client.has_keychain_credentials(&cx) { + client.authenticate_and_connect(true, &cx).await?; } Ok::<_, anyhow::Error>(()) }) @@ -222,7 +220,9 @@ fn init_logger() { let level = LevelFilter::Info; // Prevent log file from becoming too large. - const MAX_LOG_BYTES: u64 = 1 * 1024 * 1024; + const KIB: u64 = 1024; + const MIB: u64 = 1024 * KIB; + const MAX_LOG_BYTES: u64 = MIB; if fs::metadata(&*zed::paths::LOG).map_or(false, |metadata| metadata.len() > MAX_LOG_BYTES) { let _ = fs::rename(&*zed::paths::LOG, &*zed::paths::OLD_LOG); @@ -406,7 +406,7 @@ fn load_embedded_fonts(app: &App) { for font_path in &font_paths { scope.spawn(async { let font_path = &*font_path; - let font_bytes = Assets.load(&font_path).unwrap().to_vec(); + let font_bytes = Assets.load(font_path).unwrap().to_vec(); embedded_fonts.lock().push(Arc::from(font_bytes)); }); } @@ -426,7 +426,7 @@ async fn watch_themes( let mut events = fs .watch("styles/src".as_ref(), Duration::from_millis(100)) .await; - while let Some(_) = events.next().await { + while (events.next().await).is_some() { let output = Command::new("npm") .current_dir("styles") .args(["run", "build-themes"]) diff --git a/crates/zed/src/settings_file.rs b/crates/zed/src/settings_file.rs index b8cdde8b2f5cc787f81af1d8788e351d001dfad1..14c9f63e95e65e0d04d615403cf3e8796e95274f 100644 --- a/crates/zed/src/settings_file.rs +++ b/crates/zed/src/settings_file.rs @@ -42,11 +42,11 @@ where ///Loads the given watched JSON file. In the special case that the file is ///empty (ignoring whitespace) or is not a file, this will return T::default() async fn load(fs: Arc, path: &Path) -> Option { - if !fs.is_file(&path).await { + if !fs.is_file(path).await { return Some(T::default()); } - fs.load(&path).await.log_err().and_then(|data| { + fs.load(path).await.log_err().and_then(|data| { if data.trim().is_empty() { Some(T::default()) } else { @@ -74,7 +74,7 @@ pub fn watch_settings_file( pub fn keymap_updated(content: KeymapFileContent, cx: &mut MutableAppContext) { cx.clear_bindings(); settings::KeymapFileContent::load_defaults(cx); - content.add(cx).log_err(); + content.add_to_cx(cx).log_err(); } pub fn settings_updated( @@ -84,7 +84,7 @@ pub fn settings_updated( cx: &mut MutableAppContext, ) { let mut settings = defaults.clone(); - settings.set_user_settings(content, theme_registry, &cx.font_cache()); + settings.set_user_settings(content, theme_registry, cx.font_cache()); cx.set_global(settings); cx.refresh_windows(); } diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 78d642120e2db4e22e15b4e4a1479bcb1100a322..3a5dd18c1c65a145e4bdc0ec561860615e576fc4 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -143,7 +143,7 @@ pub fn init(app_state: &Arc, cx: &mut gpui::MutableAppContext) { cx.add_action({ let app_state = app_state.clone(); move |_: &mut Workspace, _: &OpenKeymap, cx: &mut ViewContext| { - open_config_file(&paths::KEYMAP, app_state.clone(), cx, || Default::default()); + open_config_file(&paths::KEYMAP, app_state.clone(), cx, Default::default); } }); cx.add_action({ @@ -222,7 +222,7 @@ pub fn initialize_workspace( pane.toolbar().update(cx, |toolbar, cx| { let breadcrumbs = cx.add_view(|_| Breadcrumbs::new(project.clone())); toolbar.add_item(breadcrumbs, cx); - let buffer_search_bar = cx.add_view(|cx| BufferSearchBar::new(cx)); + let buffer_search_bar = cx.add_view(BufferSearchBar::new); toolbar.add_item(buffer_search_bar, cx); let project_search_bar = cx.add_view(|_| ProjectSearchBar::new()); toolbar.add_item(project_search_bar, cx); @@ -273,7 +273,7 @@ pub fn initialize_workspace( sidebar.add_item( "icons/folder_tree_16.svg", "Project Panel".to_string(), - project_panel.into(), + project_panel, cx, ) }); @@ -281,7 +281,7 @@ pub fn initialize_workspace( sidebar.add_item( "icons/user_group_16.svg", "Contacts Panel".to_string(), - contact_panel.into(), + contact_panel, cx, ) }); @@ -487,7 +487,7 @@ fn open_bundled_config_file( title: &str, cx: &mut ViewContext, ) { - workspace.with_local_workspace(cx, app_state.clone(), |workspace, cx| { + workspace.with_local_workspace(cx, app_state, |workspace, cx| { let project = workspace.project().clone(); let buffer = project.update(cx, |project, cx| { let text = Assets::get(asset_path).unwrap().data; @@ -1005,7 +1005,7 @@ mod tests { .insert_file("/root/a.txt", "changed".to_string()) .await; editor - .condition(&cx, |editor, cx| editor.has_conflict(cx)) + .condition(cx, |editor, cx| editor.has_conflict(cx)) .await; cx.read(|cx| assert!(editor.is_dirty(cx))); @@ -1072,7 +1072,7 @@ mod tests { // Edit the file and save it again. This time, there is no filename prompt. editor.update(cx, |editor, cx| { editor.handle_input(" there", cx); - assert_eq!(editor.is_dirty(cx.as_ref()), true); + assert!(editor.is_dirty(cx.as_ref())); }); let save_task = workspace.update(cx, |workspace, cx| workspace.save_active_item(false, cx)); save_task.await.unwrap(); @@ -1570,30 +1570,20 @@ mod tests { // Reopen all the closed items, ensuring they are reopened in the same order // in which they were closed. - workspace - .update(cx, |workspace, cx| Pane::reopen_closed_item(workspace, cx)) - .await; + workspace.update(cx, Pane::reopen_closed_item).await; assert_eq!(active_path(&workspace, cx), Some(file3.clone())); - workspace - .update(cx, |workspace, cx| Pane::reopen_closed_item(workspace, cx)) - .await; + workspace.update(cx, Pane::reopen_closed_item).await; assert_eq!(active_path(&workspace, cx), Some(file2.clone())); - workspace - .update(cx, |workspace, cx| Pane::reopen_closed_item(workspace, cx)) - .await; + workspace.update(cx, Pane::reopen_closed_item).await; assert_eq!(active_path(&workspace, cx), Some(file4.clone())); - workspace - .update(cx, |workspace, cx| Pane::reopen_closed_item(workspace, cx)) - .await; + workspace.update(cx, Pane::reopen_closed_item).await; assert_eq!(active_path(&workspace, cx), Some(file1.clone())); // Reopening past the last closed item is a no-op. - workspace - .update(cx, |workspace, cx| Pane::reopen_closed_item(workspace, cx)) - .await; + workspace.update(cx, Pane::reopen_closed_item).await; assert_eq!(active_path(&workspace, cx), Some(file1.clone())); // Reopening closed items doesn't interfere with navigation history. From 9aa3f2d7772ddd84ca3550d5f0ccd74f45249d54 Mon Sep 17 00:00:00 2001 From: K Simmons Date: Wed, 10 Aug 2022 16:49:17 -0700 Subject: [PATCH 23/27] clippy fixes for focus change --- crates/collab/src/rpc.rs | 2 +- crates/language/src/buffer.rs | 9 ++++----- crates/workspace/src/workspace.rs | 6 +++--- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/crates/collab/src/rpc.rs b/crates/collab/src/rpc.rs index 6346e15830e915fa66a9d74635a6e3a43ca7d64c..4164424a2bee7c4d916fda685c049f95bc498c86 100644 --- a/crates/collab/src/rpc.rs +++ b/crates/collab/src/rpc.rs @@ -1711,7 +1711,7 @@ impl Server { Ok(()) } - pub(crate) async fn store(&self) -> StoreGuard { + pub(crate) async fn store(&self) -> StoreGuard<'_> { #[cfg(test)] tokio::task::yield_now().await; let guard = self.store.lock().await; diff --git a/crates/language/src/buffer.rs b/crates/language/src/buffer.rs index 52ad88f092c76f5d10e8663f794ff4b082c585b9..c8180e0a8f86827b67dc16ecf286e8131fb267cd 100644 --- a/crates/language/src/buffer.rs +++ b/crates/language/src/buffer.rs @@ -442,12 +442,11 @@ impl Buffer { } fn build(buffer: TextBuffer, file: Option>) -> Self { - let saved_mtime; - if let Some(file) = file.as_ref() { - saved_mtime = file.mtime(); + let saved_mtime = if let Some(file) = file.as_ref() { + file.mtime() } else { - saved_mtime = UNIX_EPOCH; - } + UNIX_EPOCH + }; Self { saved_mtime, diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 1137098d16799012942e7c444a3cc1e231f8544b..40934f4ed7b439f0b336a923635ddd5644959277 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -703,9 +703,9 @@ impl From> for AnyViewHandle { } } -impl Into for &Box { - fn into(self) -> AnyViewHandle { - self.to_any() +impl From<&Box> for AnyViewHandle { + fn from(val: &Box) -> Self { + val.to_any() } } From c74d10809e7055126567bcd1003813038ba6f7a1 Mon Sep 17 00:00:00 2001 From: K Simmons Date: Wed, 10 Aug 2022 17:01:13 -0700 Subject: [PATCH 24/27] Testing with allow flags --- .github/workflows/ci.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e54324c8c989afe195b5f8423cde9d93fb196f22..e8e5e6f7b45f886a69451737080f4cd0b7923ff0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,8 +42,9 @@ jobs: clean: false - name: Run clippy - run: cargo clippy --workspace -- -D warnings - + run: | + cargo clippy --workspace -- -D warnings -Aclippy::reversed_empty_ranges -Aclippy::missing_safety_doc -Aclippy::let_unit_value + - name: Run tests run: cargo test --workspace --no-fail-fast From 073bd767f247161285d38b3628dafd48e6549986 Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Wed, 10 Aug 2022 17:50:44 -0700 Subject: [PATCH 25/27] Fixed build errors in json_language --- .cargo/config.toml | 1 + .github/workflows/.ci.yml.swp | Bin 12288 -> 0 bytes plugins/json_language/src/lib.rs | 23 ++++++++++------------- 3 files changed, 11 insertions(+), 13 deletions(-) delete mode 100644 .github/workflows/.ci.yml.swp diff --git a/.cargo/config.toml b/.cargo/config.toml index 4dddb54d240aaa79b5ac139f9f5c19aea382c146..cf5c88d0916b2fe89b4367e9d7c239858b2efa46 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,5 +1,6 @@ [target.'cfg(all())'] rustflags = [ + "-Dwarnings", "-Aclippy::reversed_empty_ranges", "-Aclippy::missing_safety_doc", "-Aclippy::let_unit_value", diff --git a/.github/workflows/.ci.yml.swp b/.github/workflows/.ci.yml.swp deleted file mode 100644 index 063ded33eec61c5c7dd50a9cea1af60dc3d6edfc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI2O^6&t6vr#^GcjN2K|BcM8rT@@>HUx;j0DmEJv}{>%`WjEM62Pq zy;Jq-)vJHKdeh5xW9n$BO!wtx2(Dd(oGAX%xO~qmJGO^}bgUJ&YO|E{mKC(ahT3!em8R|Xglbs1)y~-1QBU%d zR6r_l{R(U+voq6E(YX63?xT0zxqSUD=kP1izqykcb8&Cme67tDSguHMI zg2(^=2Y>(nzLSvOz|Y`&@D;cOJ_a9xcfp(BCGa9R2W+qmG;jdq!8EuR>;ix8Amk@- z1zZFdz}w(8;DSZ47io@MRzki3AAmF9AeaLb{DJ-X8hi>a zfM~y-2lA2%NCo~23efaAT&h2^Jg?WQM~am^-F^Br72NQ7AadCrdgcrn4B<{UpMIdU z;hL*?Ix&%Ha=YB``BuR5H1I>7>1kRv7ieXEiwCODZO#N&k8?9;c3K%b(`U_KY;+H= zZVe~4nn|?q6^LW#+Y`UrmGgP?K{|<_LJe3;sNKm2vf(?dgSeJG+hrzYo<|#@W7?bs zE=}U0Rx|w-9+I#W8j2`(;Wh)jQ|1Yk8G+?GN~^6T0}phkQ9#qnV+eTTwZ;LBYq0ie zhfAdU_a}>Nb7l&)!z^bqyUsY;I7Xp{{q-u)%4(wRKzAlx);fX=UX!DK=tQbSlhB6G z9HTv4DEgp^;agsy##)ZKF8G`UJfrp6W4p|@Oc*N29syw!FBB91qpenGyt1Q-Upnxc zI;PY>0wVe*v&Aq?N2MRt(P(pH#SPaGu#og1bv$>tLP{OiOxKjBlhbpPX#nfZBzO>d zN;LTD%_=z}V75&w=*>>$hXR9=l%vcvX^)A{?2Lk&mCj1Bo#S>V_s!{Z4=FegHdjpM z_pG7*YuPjA8|@7TgkH3v6u~y^p}wg9q89Dy4WRcWFEggzHEop9hYGBsS= zW(^8^=389!Z4$#MS8zaM#{m}s97a`1c+BAV-EoyBvoHZmGJ?`UveZzsq7kt_ifb*O zhHZJ?>X=um9K^}-9m{E91scjkWR%bQJgOnw)Op7XR&^A@7S@z8=vYEvkSt)aSLrk$O!lpb$-?t)SHoSM^e* zP%D;;mAbZ&r&DQjy;v*jh3Z1JmZ!|_u~k9(!KDFB?A;qbyT#w@c*H@M7uvS&^Cv@u jJ}9pWo#-Z}(R0 Option>; -const BIN_PATH: &'static str = - "node_modules/vscode-json-languageserver/bin/vscode-json-languageserver"; +const BIN_PATH: &str = "node_modules/vscode-json-languageserver/bin/vscode-json-languageserver"; #[export] pub fn name() -> &'static str { @@ -51,13 +50,11 @@ pub fn fetch_server_binary(container_dir: PathBuf, version: String) -> Result Result Option { let mut last_version_dir = None; - let mut entries = fs::read_dir(&container_dir).ok()?; + let entries = fs::read_dir(&container_dir).ok()?; - while let Some(entry) = entries.next() { + for entry in entries { let entry = entry.ok()?; if entry.file_type().ok()?.is_dir() { last_version_dir = Some(entry.path()); From 42c01c5b1011f1fdf8621db9827978e6d6d68a1f Mon Sep 17 00:00:00 2001 From: K Simmons Date: Thu, 11 Aug 2022 11:35:11 -0700 Subject: [PATCH 26/27] minor rustfmt fix --- crates/gpui/src/presenter.rs | 8 ++++---- crates/project_panel/src/project_panel.rs | 4 +++- styles/package-lock.json | 1 + 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/crates/gpui/src/presenter.rs b/crates/gpui/src/presenter.rs index 1556572816936aaf5cf65b7334a2832d59fb1221..023e013d1393428752cd43ea45fc2f0c61fc101a 100644 --- a/crates/gpui/src/presenter.rs +++ b/crates/gpui/src/presenter.rs @@ -491,24 +491,24 @@ impl<'a> LayoutContext<'a> { if layout_parent != app_parent { panic!( "View {} was laid out with parent {} when it was constructed with parent {}", - print_error(view_id), + print_error(view_id), print_error(*layout_parent), print_error(*app_parent)) } } (None, Some(ParentId::View(app_parent))) => panic!( "View {} was laid out without a parent when it was constructed with parent {}", - print_error(view_id), + print_error(view_id), print_error(*app_parent) ), (Some(layout_parent), Some(ParentId::Root)) => panic!( "View {} was laid out with parent {} when it was constructed as a window root", - print_error(view_id), + print_error(view_id), print_error(*layout_parent), ), (_, None) => panic!( "View {} did not have a registered parent in the app context", - print_error(view_id), + print_error(view_id), ), _ => {} } diff --git a/crates/project_panel/src/project_panel.rs b/crates/project_panel/src/project_panel.rs index f077520d72cffba2dc49012c969d3f575ad44192..702c750ea204172be68fbe603ceb3c59bffa88c7 100644 --- a/crates/project_panel/src/project_panel.rs +++ b/crates/project_panel/src/project_panel.rs @@ -757,7 +757,9 @@ impl ProjectPanel { fn index_for_selection(&self, selection: Selection) -> Option<(usize, usize, usize)> { let mut entry_index = 0; let mut visible_entries_index = 0; - for (worktree_index, (worktree_id, worktree_entries)) in self.visible_entries.iter().enumerate() { + for (worktree_index, (worktree_id, worktree_entries)) in + self.visible_entries.iter().enumerate() + { if *worktree_id == selection.worktree_id { for entry in worktree_entries { if entry.id == selection.entry_id { diff --git a/styles/package-lock.json b/styles/package-lock.json index 5499f1852cb4330467268dee6436b53589a90e9b..582f1c84968a5c1a25ddac5fd3c21ba907353c6d 100644 --- a/styles/package-lock.json +++ b/styles/package-lock.json @@ -5,6 +5,7 @@ "requires": true, "packages": { "": { + "name": "styles", "version": "1.0.0", "license": "ISC", "dependencies": { From 8cf2ae3b6b8f552d7f53812eb7af86949b9eebaa Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Thu, 11 Aug 2022 11:46:54 -0700 Subject: [PATCH 27/27] Removed clippy from default settings --- assets/settings/default.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/settings/default.json b/assets/settings/default.json index 9cf915d1a6f1c69a55b93686407f10e8319b9d08..43b4be512ff94e29cc05c1bd5bec3a652430f11e 100644 --- a/assets/settings/default.json +++ b/assets/settings/default.json @@ -154,13 +154,13 @@ //rust-analyzer //typescript-language-server //vscode-json-languageserver - "rust_analyzer": { - //These initialization options are merged into Zed's defaults - "initialization_options": { - "checkOnSave": { - "command": "clippy" - } - } - } + // "rust_analyzer": { + // //These initialization options are merged into Zed's defaults + // "initialization_options": { + // "checkOnSave": { + // "command": "clippy" + // } + // } + // } } }