Get compiling

Nathan Sobo created

Change summary

crates/collab/src/tests/integration_tests.rs        |  4 
crates/collab_ui/src/project_shared_notification.rs |  2 
crates/collab_ui/src/sharing_status_indicator.rs    |  8 
crates/editor/src/editor_tests.rs                   |  6 
crates/editor/src/test/editor_lsp_test_context.rs   |  2 
crates/editor/src/test/editor_test_context.rs       | 10 +
crates/go_to_line/src/go_to_line.rs                 | 18 +-
crates/gpui/src/app.rs                              |  7 +
crates/gpui/src/app/window.rs                       |  2 
crates/vim/src/editor_events.rs                     |  2 
crates/vim/src/mode_indicator.rs                    |  2 
crates/vim/src/test/vim_test_context.rs             |  2 
crates/workspace/src/workspace.rs                   | 52 ++++----
crates/zed/src/zed.rs                               | 87 +++++---------
14 files changed, 97 insertions(+), 107 deletions(-)

Detailed changes

crates/collab/src/tests/integration_tests.rs πŸ”—

@@ -3446,7 +3446,7 @@ async fn test_newline_above_or_below_does_not_move_guest_cursor(
     let editor_a = window_a.add_view(cx_a, |cx| Editor::for_buffer(buffer_a, Some(project_a), cx));
     let mut editor_cx_a = EditorTestContext {
         cx: cx_a,
-        window_id: window_a.id(),
+        window: window_a.into(),
         editor: editor_a,
     };
 
@@ -3459,7 +3459,7 @@ async fn test_newline_above_or_below_does_not_move_guest_cursor(
     let editor_b = window_b.add_view(cx_b, |cx| Editor::for_buffer(buffer_b, Some(project_b), cx));
     let mut editor_cx_b = EditorTestContext {
         cx: cx_b,
-        window_id: window_b.id(),
+        window: window_b.into(),
         editor: editor_b,
     };
 

crates/collab_ui/src/project_shared_notification.rs πŸ”—

@@ -5,7 +5,7 @@ use gpui::{
     elements::*,
     geometry::{rect::RectF, vector::vec2f},
     platform::{CursorStyle, MouseButton, WindowBounds, WindowKind, WindowOptions},
-    AppContext, Entity, View, ViewContext,
+    AppContext, BorrowWindowContext, Entity, View, ViewContext,
 };
 use std::sync::{Arc, Weak};
 use workspace::AppState;

crates/collab_ui/src/sharing_status_indicator.rs πŸ”—

@@ -20,11 +20,11 @@ pub fn init(cx: &mut AppContext) {
                 {
                     status_indicator = Some(cx.add_status_bar_item(|_| SharingStatusIndicator));
                 }
-            } else if let Some((window_id, _)) = status_indicator.take() {
-                cx.update_window(window_id, |cx| cx.remove_window());
+            } else if let Some(window) = status_indicator.take() {
+                window.update(cx, |cx| cx.remove_window());
             }
-        } else if let Some((window_id, _)) = status_indicator.take() {
-            cx.update_window(window_id, |cx| cx.remove_window());
+        } else if let Some(window) = status_indicator.take() {
+            window.update(cx, |cx| cx.remove_window());
         }
     })
     .detach();

crates/editor/src/editor_tests.rs πŸ”—

@@ -1290,7 +1290,7 @@ async fn test_move_start_of_paragraph_end_of_paragraph(cx: &mut gpui::TestAppCon
     let mut cx = EditorTestContext::new(cx).await;
 
     let line_height = cx.editor(|editor, cx| editor.style(cx).text.line_height(cx.font_cache()));
-    cx.simulate_window_resize(cx.window_id, vec2f(100., 4. * line_height));
+    cx.simulate_window_resize(cx.window.id(), vec2f(100., 4. * line_height));
 
     cx.set_state(
         &r#"Λ‡one
@@ -1401,7 +1401,7 @@ async fn test_scroll_page_up_page_down(cx: &mut gpui::TestAppContext) {
     init_test(cx, |_| {});
     let mut cx = EditorTestContext::new(cx).await;
     let line_height = cx.editor(|editor, cx| editor.style(cx).text.line_height(cx.font_cache()));
-    cx.simulate_window_resize(cx.window_id, vec2f(1000., 4. * line_height + 0.5));
+    cx.simulate_window_resize(cx.window.id(), vec2f(1000., 4. * line_height + 0.5));
 
     cx.set_state(
         &r#"Λ‡one
@@ -1439,7 +1439,7 @@ async fn test_move_page_up_page_down(cx: &mut gpui::TestAppContext) {
     let mut cx = EditorTestContext::new(cx).await;
 
     let line_height = cx.editor(|editor, cx| editor.style(cx).text.line_height(cx.font_cache()));
-    cx.simulate_window_resize(cx.window_id, vec2f(100., 4. * line_height));
+    cx.simulate_window_resize(cx.window.id(), vec2f(100., 4. * line_height));
 
     cx.set_state(
         &r#"

crates/editor/src/test/editor_test_context.rs πŸ”—

@@ -3,7 +3,8 @@ use crate::{
 };
 use futures::Future;
 use gpui::{
-    keymap_matcher::Keystroke, AppContext, ContextHandle, ModelContext, ViewContext, ViewHandle,
+    keymap_matcher::Keystroke, AnyWindowHandle, AppContext, ContextHandle, ModelContext,
+    ViewContext, ViewHandle,
 };
 use indoc::indoc;
 use language::{Buffer, BufferSnapshot};
@@ -21,7 +22,7 @@ use super::build_editor;
 
 pub struct EditorTestContext<'a> {
     pub cx: &'a mut gpui::TestAppContext,
-    pub window_id: usize,
+    pub window: AnyWindowHandle,
     pub editor: ViewHandle<Editor>,
 }
 
@@ -39,7 +40,7 @@ impl<'a> EditorTestContext<'a> {
         let editor = window.root(cx);
         Self {
             cx,
-            window_id: window.id(),
+            window: window.into(),
             editor,
         }
     }
@@ -111,7 +112,8 @@ impl<'a> EditorTestContext<'a> {
         let keystroke_under_test_handle =
             self.add_assertion_context(format!("Simulated Keystroke: {:?}", keystroke_text));
         let keystroke = Keystroke::parse(keystroke_text).unwrap();
-        self.cx.dispatch_keystroke(self.window_id, keystroke, false);
+
+        self.cx.dispatch_keystroke(self.window, keystroke, false);
         keystroke_under_test_handle
     }
 

crates/go_to_line/src/go_to_line.rs πŸ”—

@@ -135,14 +135,16 @@ impl Entity for GoToLine {
 
     fn release(&mut self, cx: &mut AppContext) {
         let scroll_position = self.prev_scroll_position.take();
-        cx.update_window(self.active_editor.window_id(), |cx| {
-            self.active_editor.update(cx, |editor, cx| {
-                editor.highlight_rows(None);
-                if let Some(scroll_position) = scroll_position {
-                    editor.set_scroll_position(scroll_position, cx);
-                }
-            })
-        });
+        if let Some(window) = self.active_editor.window(cx) {
+            window.update(cx, |cx| {
+                self.active_editor.update(cx, |editor, cx| {
+                    editor.highlight_rows(None);
+                    if let Some(scroll_position) = scroll_position {
+                        editor.set_scroll_position(scroll_position, cx);
+                    }
+                })
+            });
+        }
     }
 }
 

crates/gpui/src/app.rs πŸ”—

@@ -23,6 +23,7 @@ use std::{
 };
 
 use anyhow::{anyhow, Context, Result};
+
 use derive_more::Deref;
 use parking_lot::Mutex;
 use postage::oneshot;
@@ -4127,6 +4128,12 @@ impl<T: View> ViewHandle<T> {
         self.window_id
     }
 
+    pub fn window<C: BorrowWindowContext>(&self, cx: &C) -> C::Result<AnyWindowHandle> {
+        cx.read_window(self.window_id, |cx| {
+            AnyWindowHandle::new(self.window_id, cx.window.root_view.type_id())
+        })
+    }
+
     pub fn id(&self) -> usize {
         self.view_id
     }

crates/gpui/src/app/window.rs πŸ”—

@@ -175,7 +175,7 @@ impl BorrowWindowContext for WindowContext<'_> {
     where
         F: FnOnce(&mut WindowContext) -> Option<T>,
     {
-        BorrowWindowContext::update_window_optional(self, window_id, f)
+        BorrowWindowContext::update_window(self, window_id, f)
     }
 }
 

crates/vim/src/editor_events.rs πŸ”—

@@ -1,6 +1,6 @@
 use crate::Vim;
 use editor::{EditorBlurred, EditorFocused, EditorReleased};
-use gpui::AppContext;
+use gpui::{AppContext, BorrowWindowContext};
 
 pub fn init(cx: &mut AppContext) {
     cx.subscribe_global(focused).detach();

crates/vim/src/mode_indicator.rs πŸ”—

@@ -1,6 +1,6 @@
 use gpui::{
     elements::{Empty, Label},
-    AnyElement, Element, Entity, Subscription, View, ViewContext,
+    AnyElement, Element, Entity, Subscription, View, ViewContext, BorrowWindowContext
 };
 use settings::SettingsStore;
 use workspace::{item::ItemHandle, StatusItemView};

crates/vim/src/test/vim_test_context.rs πŸ”—

@@ -85,7 +85,7 @@ impl<'a> VimTestContext<'a> {
     }
 
     pub fn set_state(&mut self, text: &str, mode: Mode) -> ContextHandle {
-        let window_id = self.window_id;
+        let window_id = self.window.id();
         self.update_window(window_id, |cx| {
             Vim::update(cx, |vim, cx| {
                 vim.switch_mode(mode, false, cx);

crates/workspace/src/workspace.rs πŸ”—

@@ -3827,9 +3827,9 @@ pub fn activate_workspace_for_project(
     cx: &mut AsyncAppContext,
     predicate: impl Fn(&mut Project, &mut ModelContext<Project>) -> bool,
 ) -> Option<WeakViewHandle<Workspace>> {
-    for window_id in cx.window_ids() {
-        let handle = cx
-            .update_window(window_id, |cx| {
+    for window in cx.windows() {
+        let handle = window
+            .update(cx, |cx| {
                 if let Some(workspace_handle) = cx.root_view().clone().downcast::<Workspace>() {
                     let project = workspace_handle.read(cx).project.clone();
                     if project.update(cx, &predicate) {
@@ -3945,18 +3945,23 @@ pub fn join_remote_project(
 ) -> Task<Result<()>> {
     cx.spawn(|mut cx| async move {
         let existing_workspace = cx
-            .window_ids()
+            .windows()
             .into_iter()
-            .filter_map(|window_id| cx.root_view(window_id)?.clone().downcast::<Workspace>())
-            .find(|workspace| {
-                cx.read_window(workspace.window_id(), |cx| {
-                    workspace.read(cx).project().read(cx).remote_id() == Some(project_id)
+            .find_map(|window| {
+                window.downcast::<Workspace>().and_then(|window| {
+                    window.read_root_with(&cx, |workspace, cx| {
+                        if workspace.project().read(cx).remote_id() == Some(project_id) {
+                            Some(cx.handle().downgrade())
+                        } else {
+                            None
+                        }
+                    })
                 })
-                .unwrap_or(false)
-            });
+            })
+            .flatten();
 
         let workspace = if let Some(existing_workspace) = existing_workspace {
-            existing_workspace.downgrade()
+            existing_workspace
         } else {
             let active_call = cx.read(ActiveCall::global);
             let room = active_call
@@ -4034,19 +4039,19 @@ pub fn join_remote_project(
 pub fn restart(_: &Restart, cx: &mut AppContext) {
     let should_confirm = settings::get::<WorkspaceSettings>(cx).confirm_quit;
     cx.spawn(|mut cx| async move {
-        let mut workspaces = cx
+        let mut workspace_windows = cx
             .windows()
             .into_iter()
-            .filter_map(|window| Some(window.downcast::<Workspace>()?.root(&cx)?.downgrade()))
+            .filter_map(|window| window.downcast::<Workspace>())
             .collect::<Vec<_>>();
 
         // If multiple windows have unsaved changes, and need a save prompt,
         // prompt in the active window before switching to a different window.
-        workspaces.sort_by_key(|workspace| !cx.window_is_active(workspace.window_id()));
+        workspace_windows.sort_by_key(|window| window.is_active(&cx) == Some(false));
 
-        if let (true, Some(workspace)) = (should_confirm, workspaces.first()) {
+        if let (true, Some(window)) = (should_confirm, workspace_windows.first()) {
             let answer = cx.prompt(
-                workspace.window_id(),
+                window.id(),
                 PromptLevel::Info,
                 "Are you sure you want to restart?",
                 &["Restart", "Cancel"],
@@ -4061,14 +4066,13 @@ pub fn restart(_: &Restart, cx: &mut AppContext) {
         }
 
         // If the user cancels any save prompt, then keep the app open.
-        for workspace in workspaces {
-            if !workspace
-                .update(&mut cx, |workspace, cx| {
-                    workspace.prepare_to_close(true, cx)
-                })?
-                .await?
-            {
-                return Ok(());
+        for window in workspace_windows {
+            if let Some(close) = window.update_root(&mut cx, |workspace, cx| {
+                workspace.prepare_to_close(true, cx)
+            }) {
+                if !close.await? {
+                    return Ok(());
+                }
             }
         }
         cx.platform().restart();

crates/zed/src/zed.rs πŸ”—

@@ -406,26 +406,19 @@ pub fn build_window_options(
 fn quit(_: &Quit, cx: &mut gpui::AppContext) {
     let should_confirm = settings::get::<WorkspaceSettings>(cx).confirm_quit;
     cx.spawn(|mut cx| async move {
-        let mut workspaces = cx
-            .window_ids()
+        let mut workspace_windows = cx
+            .windows()
             .into_iter()
-            .filter_map(|window_id| {
-                Some(
-                    cx.root_view(window_id)?
-                        .clone()
-                        .downcast::<Workspace>()?
-                        .downgrade(),
-                )
-            })
+            .filter_map(|window| window.downcast::<Workspace>())
             .collect::<Vec<_>>();
 
         // If multiple windows have unsaved changes, and need a save prompt,
         // prompt in the active window before switching to a different window.
-        workspaces.sort_by_key(|workspace| !cx.window_is_active(workspace.window_id()));
+        workspace_windows.sort_by_key(|window| window.is_active(&cx) == Some(false));
 
-        if let (true, Some(workspace)) = (should_confirm, workspaces.first()) {
+        if let (true, Some(window)) = (should_confirm, workspace_windows.first()) {
             let answer = cx.prompt(
-                workspace.window_id(),
+                window.id(),
                 PromptLevel::Info,
                 "Are you sure you want to quit?",
                 &["Quit", "Cancel"],
@@ -440,14 +433,13 @@ fn quit(_: &Quit, cx: &mut gpui::AppContext) {
         }
 
         // If the user cancels any save prompt, then keep the app open.
-        for workspace in workspaces {
-            if !workspace
-                .update(&mut cx, |workspace, cx| {
-                    workspace.prepare_to_close(true, cx)
-                })?
-                .await?
-            {
-                return Ok(());
+        for window in workspace_windows {
+            if let Some(close) = window.update_root(&mut cx, |workspace, cx| {
+                workspace.prepare_to_close(false, cx)
+            }) {
+                if close.await? {
+                    return Ok(());
+                }
             }
         }
         cx.platform().quit();
@@ -782,17 +774,13 @@ mod tests {
         })
         .await
         .unwrap();
-        assert_eq!(cx.window_ids().len(), 1);
+        assert_eq!(cx.windows().len(), 1);
 
         cx.update(|cx| open_paths(&[PathBuf::from("/root/a")], &app_state, None, cx))
             .await
             .unwrap();
-        assert_eq!(cx.window_ids().len(), 1);
-        let workspace_1 = cx
-            .read_window(cx.window_ids()[0], |cx| cx.root_view().clone())
-            .unwrap()
-            .downcast::<Workspace>()
-            .unwrap();
+        assert_eq!(cx.windows().len(), 1);
+        let workspace_1 = cx.windows()[0].downcast::<Workspace>().unwrap().root(cx);
         workspace_1.update(cx, |workspace, cx| {
             assert_eq!(workspace.worktrees(cx).count(), 2);
             assert!(workspace.left_dock().read(cx).is_open());
@@ -809,28 +797,22 @@ mod tests {
         })
         .await
         .unwrap();
-        assert_eq!(cx.window_ids().len(), 2);
+        assert_eq!(cx.windows().len(), 2);
 
         // Replace existing windows
-        let window_id = cx.window_ids()[0];
-        let window = cx.read_window(window_id, |cx| cx.window()).flatten();
+        let window = cx.windows()[0].downcast::<Workspace>().unwrap();
         cx.update(|cx| {
             open_paths(
                 &[PathBuf::from("/root/c"), PathBuf::from("/root/d")],
                 &app_state,
-                window,
+                Some(window),
                 cx,
             )
         })
         .await
         .unwrap();
-        assert_eq!(cx.window_ids().len(), 2);
-        let workspace_1 = cx
-            .read_window(cx.window_ids()[0], |cx| cx.root_view().clone())
-            .unwrap()
-            .clone()
-            .downcast::<Workspace>()
-            .unwrap();
+        assert_eq!(cx.windows().len(), 2);
+        let workspace_1 = cx.windows()[0].downcast::<Workspace>().unwrap().root(cx);
         workspace_1.update(cx, |workspace, cx| {
             assert_eq!(
                 workspace
@@ -856,14 +838,10 @@ mod tests {
         cx.update(|cx| open_paths(&[PathBuf::from("/root/a")], &app_state, None, cx))
             .await
             .unwrap();
-        assert_eq!(cx.window_ids().len(), 1);
+        assert_eq!(cx.windows().len(), 1);
 
         // When opening the workspace, the window is not in a edited state.
-        let workspace = cx
-            .read_window(cx.window_ids()[0], |cx| cx.root_view().clone())
-            .unwrap()
-            .downcast::<Workspace>()
-            .unwrap();
+        let workspace = cx.windows()[0].downcast::<Workspace>().unwrap().root(cx);
         let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
         let editor = workspace.read_with(cx, |workspace, cx| {
             workspace
@@ -917,12 +895,12 @@ mod tests {
         // buffer having unsaved changes.
         assert!(!cx.simulate_window_close(workspace.window_id()));
         executor.run_until_parked();
-        assert_eq!(cx.window_ids().len(), 1);
+        assert_eq!(cx.windows().len(), 1);
 
         // The window is successfully closed after the user dismisses the prompt.
         cx.simulate_prompt_answer(workspace.window_id(), 1);
         executor.run_until_parked();
-        assert_eq!(cx.window_ids().len(), 0);
+        assert_eq!(cx.windows().len(), 0);
     }
 
     #[gpui::test]
@@ -935,12 +913,13 @@ mod tests {
         })
         .await;
 
-        let window_id = *cx.window_ids().first().unwrap();
-        let workspace = cx
-            .read_window(window_id, |cx| cx.root_view().clone())
+        let window = cx
+            .windows()
+            .first()
             .unwrap()
             .downcast::<Workspace>()
             .unwrap();
+        let workspace = window.root(cx);
 
         let editor = workspace.update(cx, |workspace, cx| {
             workspace
@@ -1105,12 +1084,8 @@ mod tests {
         cx.update(|cx| open_paths(&[PathBuf::from("/dir1/")], &app_state, None, cx))
             .await
             .unwrap();
-        assert_eq!(cx.window_ids().len(), 1);
-        let workspace = cx
-            .read_window(cx.window_ids()[0], |cx| cx.root_view().clone())
-            .unwrap()
-            .downcast::<Workspace>()
-            .unwrap();
+        assert_eq!(cx.windows().len(), 1);
+        let workspace = cx.windows()[0].downcast::<Workspace>().unwrap().root(cx);
 
         #[track_caller]
         fn assert_project_panel_selection(