WIP: Get everything compiling again and keep window open

Nathan Sobo created

Change summary

gpui/src/app.rs                        |  14 
gpui/src/presenter.rs                  |   2 
zed/src/assets.rs                      |   2 
zed/src/editor/buffer_view.rs          | 134 ++++++-----
zed/src/editor/display_map/fold_map.rs | 315 ++++++++++++++-------------
zed/src/editor/display_map/mod.rs      |  96 ++++----
zed/src/main.rs                        | 110 +++-----
zed/src/workspace/mod.rs               |   2 
zed/src/workspace/workspace.rs         |   2 
zed/src/workspace/workspace_view.rs    |   4 
10 files changed, 339 insertions(+), 342 deletions(-)

Detailed changes

gpui/src/app.rs 🔗

@@ -68,9 +68,9 @@ pub trait UpdateView {
 pub struct App(Rc<RefCell<MutableAppContext>>);
 
 impl App {
-    pub fn test<T, F: Future<Output = T>>(
-        asset_source: impl AssetSource,
-        f: impl FnOnce(App) -> F,
+    pub fn test<T, A: AssetSource, F: Future<Output = T>, G: FnOnce(App) -> F>(
+        asset_source: A,
+        f: G,
     ) -> T {
         let platform = platform::current::app(); // TODO: Make a test platform app
         let foreground = Rc::new(executor::Foreground::test());
@@ -248,6 +248,14 @@ impl App {
     pub fn finish_pending_tasks(&self) -> impl Future<Output = ()> {
         self.0.borrow().finish_pending_tasks()
     }
+
+    pub fn fonts(&self) -> Arc<FontCache> {
+        self.0.borrow().fonts.clone()
+    }
+
+    pub fn platform(&self) -> Arc<dyn platform::App> {
+        self.0.borrow().platform.clone()
+    }
 }
 
 impl UpdateModel for App {

gpui/src/presenter.rs 🔗

@@ -99,7 +99,7 @@ impl Presenter {
         // }
 
         // canvas.into_canvas().into_scene()
-        todo!()
+        Scene {}
     }
 
     pub fn responder_chain(&self, app: &AppContext) -> Option<Vec<usize>> {

zed/src/assets.rs 🔗

@@ -4,7 +4,7 @@ use rust_embed::RustEmbed;
 
 #[derive(RustEmbed)]
 #[folder = "assets"]
-struct Assets;
+pub struct Assets;
 
 impl AssetSource for Assets {
     fn load(&self, path: &str) -> Result<std::borrow::Cow<[u8]>> {

zed/src/editor/buffer_view.rs 🔗

@@ -1392,11 +1392,11 @@ mod tests {
 
     #[test]
     fn test_fold() -> Result<()> {
-        let mut app = App::new().unwrap();
-        let buffer = app.add_model(|_| {
-            Buffer::new(
-                0,
-                "
+        App::test((), |mut app| async move {
+            let buffer = app.add_model(|_| {
+                Buffer::new(
+                    0,
+                    "
                     impl Foo {
                         // Hello!
 
@@ -1411,18 +1411,19 @@ mod tests {
                         }
                     }
                 "
-                .unindent(),
-            )
-        });
-        let settings = settings::channel(&FontCache::new()).unwrap().1;
-        let (_, view) = app.add_window(|ctx| BufferView::for_buffer(buffer.clone(), settings, ctx));
-
-        view.update(&mut app, |view, ctx| {
-            view.select_ranges(Some(DisplayPoint::new(8, 0)..DisplayPoint::new(12, 0)), ctx)?;
-            view.fold(&(), ctx);
-            assert_eq!(
-                view.text(ctx.app()),
-                "
+                    .unindent(),
+                )
+            });
+            let settings = settings::channel(&FontCache::new()).unwrap().1;
+            let (_, view) =
+                app.add_window(|ctx| BufferView::for_buffer(buffer.clone(), settings, ctx));
+
+            view.update(&mut app, |view, ctx| {
+                view.select_ranges(Some(DisplayPoint::new(8, 0)..DisplayPoint::new(12, 0)), ctx)?;
+                view.fold(&(), ctx);
+                assert_eq!(
+                    view.text(ctx.app()),
+                    "
                     impl Foo {
                         // Hello!
 
@@ -1437,23 +1438,23 @@ mod tests {
                         }
                     }
                 "
-                .unindent(),
-            );
+                    .unindent(),
+                );
 
-            view.fold(&(), ctx);
-            assert_eq!(
-                view.text(ctx.app()),
-                "
+                view.fold(&(), ctx);
+                assert_eq!(
+                    view.text(ctx.app()),
+                    "
                     impl Foo {…
                     }
                 "
-                .unindent(),
-            );
+                    .unindent(),
+                );
 
-            view.unfold(&(), ctx);
-            assert_eq!(
-                view.text(ctx.app()),
-                "
+                view.unfold(&(), ctx);
+                assert_eq!(
+                    view.text(ctx.app()),
+                    "
                     impl Foo {
                         // Hello!
 
@@ -1468,51 +1469,54 @@ mod tests {
                         }
                     }
                 "
-                .unindent(),
-            );
+                    .unindent(),
+                );
 
-            view.unfold(&(), ctx);
-            assert_eq!(view.text(ctx.app()), buffer.as_ref(ctx).text());
+                view.unfold(&(), ctx);
+                assert_eq!(view.text(ctx.app()), buffer.as_ref(ctx).text());
 
-            Ok::<(), Error>(())
-        })?;
+                Ok::<(), Error>(())
+            })?;
 
-        Ok(())
+            Ok(())
+        })
     }
 
     #[test]
     fn test_move_cursor() -> Result<()> {
-        let mut app = App::new().unwrap();
-        let buffer = app.add_model(|_| Buffer::new(0, sample_text(6, 6)));
-        let settings = settings::channel(&FontCache::new()).unwrap().1;
-        let (_, view) = app.add_window(|ctx| BufferView::for_buffer(buffer.clone(), settings, ctx));
-
-        buffer.update(&mut app, |buffer, ctx| {
-            buffer.edit(
-                vec![
-                    Point::new(1, 0)..Point::new(1, 0),
-                    Point::new(1, 1)..Point::new(1, 1),
-                ],
-                "\t",
-                Some(ctx),
-            )
-        })?;
+        App::test((), |mut app| async move {
+            let buffer = app.add_model(|_| Buffer::new(0, sample_text(6, 6)));
+            let settings = settings::channel(&FontCache::new()).unwrap().1;
+            let (_, view) =
+                app.add_window(|ctx| BufferView::for_buffer(buffer.clone(), settings, ctx));
 
-        view.update(&mut app, |view, ctx| {
-            view.move_down(&(), ctx);
-            assert_eq!(
-                view.selections(ctx.app()),
-                &[DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0)]
-            );
-            view.move_right(&(), ctx);
-            assert_eq!(
-                view.selections(ctx.app()),
-                &[DisplayPoint::new(1, 4)..DisplayPoint::new(1, 4)]
-            );
-            Ok::<(), Error>(())
-        })?;
+            buffer.update(&mut app, |buffer, ctx| {
+                buffer.edit(
+                    vec![
+                        Point::new(1, 0)..Point::new(1, 0),
+                        Point::new(1, 1)..Point::new(1, 1),
+                    ],
+                    "\t",
+                    Some(ctx),
+                )
+            })?;
 
-        Ok(())
+            view.update(&mut app, |view, ctx| {
+                view.move_down(&(), ctx);
+                assert_eq!(
+                    view.selections(ctx.app()),
+                    &[DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0)]
+                );
+                view.move_right(&(), ctx);
+                assert_eq!(
+                    view.selections(ctx.app()),
+                    &[DisplayPoint::new(1, 4)..DisplayPoint::new(1, 4)]
+                );
+                Ok::<(), Error>(())
+            })?;
+
+            Ok(())
+        })
     }
 
     impl BufferView {

zed/src/editor/display_map/fold_map.rs 🔗

@@ -460,106 +460,109 @@ mod tests {
 
     #[test]
     fn test_basic_folds() -> Result<()> {
-        let mut app = App::new()?;
-        let buffer = app.add_model(|_| Buffer::new(0, sample_text(5, 6)));
-        let mut map = app.read(|app| FoldMap::new(buffer.clone(), app));
-
-        app.read(|app| {
-            map.fold(
-                vec![
-                    Point::new(0, 2)..Point::new(2, 2),
-                    Point::new(2, 4)..Point::new(4, 1),
-                ],
-                app,
-            )?;
-            assert_eq!(map.text(app), "aa…cc…eeeee");
-            Ok::<(), anyhow::Error>(())
-        })?;
-
-        let edits = buffer.update(&mut app, |buffer, ctx| {
-            let start_version = buffer.version.clone();
-            buffer.edit(
-                vec![
-                    Point::new(0, 0)..Point::new(0, 1),
-                    Point::new(2, 3)..Point::new(2, 3),
-                ],
-                "123",
-                Some(ctx),
-            )?;
-            Ok::<_, anyhow::Error>(buffer.edits_since(start_version).collect::<Vec<_>>())
-        })?;
-
-        app.read(|app| {
-            map.apply_edits(&edits, app)?;
-            assert_eq!(map.text(app), "123a…c123c…eeeee");
-            Ok::<(), anyhow::Error>(())
-        })?;
-
-        let edits = buffer.update(&mut app, |buffer, ctx| {
-            let start_version = buffer.version.clone();
-            buffer.edit(Some(Point::new(2, 6)..Point::new(4, 3)), "456", Some(ctx))?;
-            Ok::<_, anyhow::Error>(buffer.edits_since(start_version).collect::<Vec<_>>())
-        })?;
-
-        app.read(|app| {
-            map.apply_edits(&edits, app)?;
-            assert_eq!(map.text(app), "123a…c123456eee");
-
-            map.unfold(Some(Point::new(0, 4)..Point::new(0, 4)), app)?;
-            assert_eq!(map.text(app), "123aaaaa\nbbbbbb\nccc123456eee");
-
-            Ok(())
+        App::test((), |mut app| async move {
+            let buffer = app.add_model(|_| Buffer::new(0, sample_text(5, 6)));
+            let mut map = app.read(|app| FoldMap::new(buffer.clone(), app));
+
+            app.read(|app| {
+                map.fold(
+                    vec![
+                        Point::new(0, 2)..Point::new(2, 2),
+                        Point::new(2, 4)..Point::new(4, 1),
+                    ],
+                    app,
+                )?;
+                assert_eq!(map.text(app), "aa…cc…eeeee");
+                Ok::<(), anyhow::Error>(())
+            })?;
+
+            let edits = buffer.update(&mut app, |buffer, ctx| {
+                let start_version = buffer.version.clone();
+                buffer.edit(
+                    vec![
+                        Point::new(0, 0)..Point::new(0, 1),
+                        Point::new(2, 3)..Point::new(2, 3),
+                    ],
+                    "123",
+                    Some(ctx),
+                )?;
+                Ok::<_, anyhow::Error>(buffer.edits_since(start_version).collect::<Vec<_>>())
+            })?;
+
+            app.read(|app| {
+                map.apply_edits(&edits, app)?;
+                assert_eq!(map.text(app), "123a…c123c…eeeee");
+                Ok::<(), anyhow::Error>(())
+            })?;
+
+            let edits = buffer.update(&mut app, |buffer, ctx| {
+                let start_version = buffer.version.clone();
+                buffer.edit(Some(Point::new(2, 6)..Point::new(4, 3)), "456", Some(ctx))?;
+                Ok::<_, anyhow::Error>(buffer.edits_since(start_version).collect::<Vec<_>>())
+            })?;
+
+            app.read(|app| {
+                map.apply_edits(&edits, app)?;
+                assert_eq!(map.text(app), "123a…c123456eee");
+
+                map.unfold(Some(Point::new(0, 4)..Point::new(0, 4)), app)?;
+                assert_eq!(map.text(app), "123aaaaa\nbbbbbb\nccc123456eee");
+
+                Ok(())
+            })
         })
     }
 
     #[test]
     fn test_overlapping_folds() -> Result<()> {
-        let mut app = App::new()?;
-        let buffer = app.add_model(|_| Buffer::new(0, sample_text(5, 6)));
-        app.read(|app| {
-            let mut map = FoldMap::new(buffer.clone(), app);
-            map.fold(
-                vec![
-                    Point::new(0, 2)..Point::new(2, 2),
-                    Point::new(0, 4)..Point::new(1, 0),
-                    Point::new(1, 2)..Point::new(3, 2),
-                    Point::new(3, 1)..Point::new(4, 1),
-                ],
-                app,
-            )?;
-            assert_eq!(map.text(app), "aa…eeeee");
-            Ok(())
+        App::test((), |mut app| async move {
+            let buffer = app.add_model(|_| Buffer::new(0, sample_text(5, 6)));
+            app.read(|app| {
+                let mut map = FoldMap::new(buffer.clone(), app);
+                map.fold(
+                    vec![
+                        Point::new(0, 2)..Point::new(2, 2),
+                        Point::new(0, 4)..Point::new(1, 0),
+                        Point::new(1, 2)..Point::new(3, 2),
+                        Point::new(3, 1)..Point::new(4, 1),
+                    ],
+                    app,
+                )?;
+                assert_eq!(map.text(app), "aa…eeeee");
+                Ok(())
+            })
         })
     }
 
     #[test]
     fn test_merging_folds_via_edit() -> Result<()> {
-        let mut app = App::new()?;
-        let buffer = app.add_model(|_| Buffer::new(0, sample_text(5, 6)));
-        let mut map = app.read(|app| FoldMap::new(buffer.clone(), app));
-
-        app.read(|app| {
-            map.fold(
-                vec![
-                    Point::new(0, 2)..Point::new(2, 2),
-                    Point::new(3, 1)..Point::new(4, 1),
-                ],
-                app,
-            )?;
-            assert_eq!(map.text(app), "aa…cccc\nd…eeeee");
-            Ok::<(), anyhow::Error>(())
-        })?;
-
-        let edits = buffer.update(&mut app, |buffer, ctx| {
-            let start_version = buffer.version.clone();
-            buffer.edit(Some(Point::new(2, 2)..Point::new(3, 1)), "", Some(ctx))?;
-            Ok::<_, anyhow::Error>(buffer.edits_since(start_version).collect::<Vec<_>>())
-        })?;
-
-        app.read(|app| {
-            map.apply_edits(&edits, app)?;
-            assert_eq!(map.text(app), "aa…eeeee");
-            Ok(())
+        App::test((), |mut app| async move {
+            let buffer = app.add_model(|_| Buffer::new(0, sample_text(5, 6)));
+            let mut map = app.read(|app| FoldMap::new(buffer.clone(), app));
+
+            app.read(|app| {
+                map.fold(
+                    vec![
+                        Point::new(0, 2)..Point::new(2, 2),
+                        Point::new(3, 1)..Point::new(4, 1),
+                    ],
+                    app,
+                )?;
+                assert_eq!(map.text(app), "aa…cccc\nd…eeeee");
+                Ok::<(), anyhow::Error>(())
+            })?;
+
+            let edits = buffer.update(&mut app, |buffer, ctx| {
+                let start_version = buffer.version.clone();
+                buffer.edit(Some(Point::new(2, 2)..Point::new(3, 1)), "", Some(ctx))?;
+                Ok::<_, anyhow::Error>(buffer.edits_since(start_version).collect::<Vec<_>>())
+            })?;
+
+            app.read(|app| {
+                map.apply_edits(&edits, app)?;
+                assert_eq!(map.text(app), "aa…eeeee");
+                Ok(())
+            })
         })
     }
 
@@ -573,59 +576,62 @@ mod tests {
             println!("{:?}", seed);
             let mut rng = StdRng::seed_from_u64(seed);
 
-            let mut app = App::new()?;
-            let buffer = app.add_model(|_| {
-                let len = rng.gen_range(0..10);
-                let text = RandomCharIter::new(&mut rng).take(len).collect::<String>();
-                Buffer::new(0, text)
-            });
-            let mut map = app.read(|app| FoldMap::new(buffer.clone(), app));
+            App::test((), |mut app| async move {
+                let buffer = app.add_model(|_| {
+                    let len = rng.gen_range(0..10);
+                    let text = RandomCharIter::new(&mut rng).take(len).collect::<String>();
+                    Buffer::new(0, text)
+                });
+                let mut map = app.read(|app| FoldMap::new(buffer.clone(), app));
 
-            app.read(|app| {
-                let buffer = buffer.as_ref(app);
-
-                let fold_count = rng.gen_range(0..10);
-                let mut fold_ranges: Vec<Range<usize>> = Vec::new();
-                for _ in 0..fold_count {
-                    let end = rng.gen_range(0..buffer.len() + 1);
-                    let start = rng.gen_range(0..end + 1);
-                    fold_ranges.push(start..end);
-                }
+                app.read(|app| {
+                    let buffer = buffer.as_ref(app);
 
-                map.fold(fold_ranges, app)?;
+                    let fold_count = rng.gen_range(0..10);
+                    let mut fold_ranges: Vec<Range<usize>> = Vec::new();
+                    for _ in 0..fold_count {
+                        let end = rng.gen_range(0..buffer.len() + 1);
+                        let start = rng.gen_range(0..end + 1);
+                        fold_ranges.push(start..end);
+                    }
 
-                let mut expected_text = buffer.text();
-                for fold_range in map.merged_fold_ranges(app).into_iter().rev() {
-                    expected_text.replace_range(fold_range.start..fold_range.end, "…");
-                }
+                    map.fold(fold_ranges, app)?;
 
-                assert_eq!(map.text(app), expected_text);
+                    let mut expected_text = buffer.text();
+                    for fold_range in map.merged_fold_ranges(app).into_iter().rev() {
+                        expected_text.replace_range(fold_range.start..fold_range.end, "…");
+                    }
 
-                for fold_range in map.merged_fold_ranges(app) {
-                    let display_point =
-                        map.to_display_point(fold_range.start.to_point(buffer).unwrap());
-                    assert!(map.is_line_folded(display_point.row()));
-                }
+                    assert_eq!(map.text(app), expected_text);
 
-                Ok::<(), anyhow::Error>(())
-            })?;
+                    for fold_range in map.merged_fold_ranges(app) {
+                        let display_point =
+                            map.to_display_point(fold_range.start.to_point(buffer).unwrap());
+                        assert!(map.is_line_folded(display_point.row()));
+                    }
 
-            let edits = buffer.update(&mut app, |buffer, ctx| {
-                let start_version = buffer.version.clone();
-                let edit_count = rng.gen_range(1..10);
-                buffer.randomly_edit(&mut rng, edit_count, Some(ctx));
-                Ok::<_, anyhow::Error>(buffer.edits_since(start_version).collect::<Vec<_>>())
-            })?;
+                    Ok::<(), anyhow::Error>(())
+                })?;
 
-            app.read(|app| {
-                map.apply_edits(&edits, app)?;
+                let edits = buffer.update(&mut app, |buffer, ctx| {
+                    let start_version = buffer.version.clone();
+                    let edit_count = rng.gen_range(1..10);
+                    buffer.randomly_edit(&mut rng, edit_count, Some(ctx));
+                    Ok::<_, anyhow::Error>(buffer.edits_since(start_version).collect::<Vec<_>>())
+                })?;
 
-                let buffer = map.buffer.as_ref(app);
-                let mut expected_text = buffer.text();
-                for fold_range in map.merged_fold_ranges(app).into_iter().rev() {
-                    expected_text.replace_range(fold_range.start..fold_range.end, "…");
-                }
-                assert_eq!(map.text(app), expected_text);
+                app.read(|app| {
+                    map.apply_edits(&edits, app)?;
+
+                    let buffer = map.buffer.as_ref(app);
+                    let mut expected_text = buffer.text();
+                    for fold_range in map.merged_fold_ranges(app).into_iter().rev() {
+                        expected_text.replace_range(fold_range.start..fold_range.end, "…");
+                    }
+                    assert_eq!(map.text(app), expected_text);
+
+                    Ok::<(), anyhow::Error>(())
+                })?;
 
                 Ok::<(), anyhow::Error>(())
             })?;
@@ -636,26 +642,27 @@ mod tests {
 
     #[test]
     fn test_buffer_rows() -> Result<()> {
-        let mut app = App::new()?;
-        let text = sample_text(6, 6) + "\n";
-        let buffer = app.add_model(|_| Buffer::new(0, text));
-
-        app.read(|app| {
-            let mut map = FoldMap::new(buffer.clone(), app);
-
-            map.fold(
-                vec![
-                    Point::new(0, 2)..Point::new(2, 2),
-                    Point::new(3, 1)..Point::new(4, 1),
-                ],
-                app,
-            )?;
-
-            assert_eq!(map.text(app), "aa…cccc\nd…eeeee\nffffff\n");
-            assert_eq!(map.buffer_rows(0)?.collect::<Vec<_>>(), vec![0, 3, 5, 6]);
-            assert_eq!(map.buffer_rows(3)?.collect::<Vec<_>>(), vec![6]);
-
-            Ok(())
+        App::test((), |mut app| async move {
+            let text = sample_text(6, 6) + "\n";
+            let buffer = app.add_model(|_| Buffer::new(0, text));
+
+            app.read(|app| {
+                let mut map = FoldMap::new(buffer.clone(), app);
+
+                map.fold(
+                    vec![
+                        Point::new(0, 2)..Point::new(2, 2),
+                        Point::new(3, 1)..Point::new(4, 1),
+                    ],
+                    app,
+                )?;
+
+                assert_eq!(map.text(app), "aa…cccc\nd…eeeee\nffffff\n");
+                assert_eq!(map.buffer_rows(0)?.collect::<Vec<_>>(), vec![0, 3, 5, 6]);
+                assert_eq!(map.buffer_rows(3)?.collect::<Vec<_>>(), vec![6]);
+
+                Ok(())
+            })
         })
     }
 

zed/src/editor/display_map/mod.rs 🔗

@@ -296,46 +296,47 @@ mod tests {
 
     #[test]
     fn test_chars_at() -> Result<()> {
-        let mut app = App::new()?;
-        let text = sample_text(6, 6);
-        let buffer = app.add_model(|_| Buffer::new(0, text));
-        let map = app.add_model(|ctx| DisplayMap::new(buffer.clone(), 4, ctx));
-        buffer.update(&mut app, |buffer, ctx| {
-            buffer.edit(
-                vec![
-                    Point::new(1, 0)..Point::new(1, 0),
-                    Point::new(1, 1)..Point::new(1, 1),
-                    Point::new(2, 1)..Point::new(2, 1),
-                ],
-                "\t",
-                Some(ctx),
-            )
-        })?;
-
-        map.read(&app, |map, ctx| {
-            assert_eq!(
-                map.chars_at(DisplayPoint::new(1, 0), ctx)?
-                    .take(10)
-                    .collect::<String>(),
-                "    b   bb"
-            );
-            assert_eq!(
-                map.chars_at(DisplayPoint::new(1, 2), ctx)?
-                    .take(10)
-                    .collect::<String>(),
-                "  b   bbbb"
-            );
-            assert_eq!(
-                map.chars_at(DisplayPoint::new(1, 6), ctx)?
-                    .take(13)
-                    .collect::<String>(),
-                "  bbbbb\nc   c"
-            );
-
-            Ok::<(), Error>(())
-        })?;
-
-        Ok(())
+        App::test((), |mut app| async move {
+            let text = sample_text(6, 6);
+            let buffer = app.add_model(|_| Buffer::new(0, text));
+            let map = app.add_model(|ctx| DisplayMap::new(buffer.clone(), 4, ctx));
+            buffer.update(&mut app, |buffer, ctx| {
+                buffer.edit(
+                    vec![
+                        Point::new(1, 0)..Point::new(1, 0),
+                        Point::new(1, 1)..Point::new(1, 1),
+                        Point::new(2, 1)..Point::new(2, 1),
+                    ],
+                    "\t",
+                    Some(ctx),
+                )
+            })?;
+
+            map.read(&app, |map, ctx| {
+                assert_eq!(
+                    map.chars_at(DisplayPoint::new(1, 0), ctx)?
+                        .take(10)
+                        .collect::<String>(),
+                    "    b   bb"
+                );
+                assert_eq!(
+                    map.chars_at(DisplayPoint::new(1, 2), ctx)?
+                        .take(10)
+                        .collect::<String>(),
+                    "  b   bbbb"
+                );
+                assert_eq!(
+                    map.chars_at(DisplayPoint::new(1, 6), ctx)?
+                        .take(13)
+                        .collect::<String>(),
+                    "  bbbbb\nc   c"
+                );
+
+                Ok::<(), Error>(())
+            })?;
+
+            Ok(())
+        })
     }
 
     #[test]
@@ -363,12 +364,13 @@ mod tests {
 
     #[test]
     fn test_max_point() -> Result<()> {
-        let mut app = App::new()?;
-        let buffer = app.add_model(|_| Buffer::new(0, "aaa\n\t\tbbb"));
-        let map = app.add_model(|ctx| DisplayMap::new(buffer.clone(), 4, ctx));
-        map.read(&app, |map, app| {
-            assert_eq!(map.max_point(app), DisplayPoint::new(1, 11))
-        });
-        Ok(())
+        App::test((), |mut app| async move {
+            let buffer = app.add_model(|_| Buffer::new(0, "aaa\n\t\tbbb"));
+            let map = app.add_model(|ctx| DisplayMap::new(buffer.clone(), 4, ctx));
+            map.read(&app, |map, app| {
+                assert_eq!(map.max_point(app), DisplayPoint::new(1, 11))
+            });
+            Ok(())
+        })
     }
 }

zed/src/main.rs 🔗

@@ -1,80 +1,43 @@
 use fs::OpenOptions;
-use gpui::{
-    executor,
-    geometry::{rect::RectF, vector::vec2f},
-    platform::{current as platform, App as _, Runner as _, WindowOptions},
-    FontCache,
-};
+use gpui::platform::{current as platform, Runner as _};
 use log::LevelFilter;
 use simplelog::SimpleLogger;
-use std::{fs, mem, rc::Rc, sync::Arc};
+use std::{fs, mem, path::PathBuf};
 use zed::{
-    editor, settings,
+    assets, editor, settings,
     workspace::{self, OpenParams},
 };
 
 fn main() {
     init_logger();
 
-    let platform = Arc::new(platform::app());
-
-    let foreground = Rc::new(
-        executor::Foreground::platform(platform.dispatcher())
-            .expect("could not foreground create executor"),
-    );
-
-    let font_cache = FontCache::new();
-
-    let (settings_tx, settings_rx) = settings::channel(&font_cache).unwrap();
-
-    let mut app = gpui::App::new(As).unwrap();
-
-    platform::runner()
-        .on_finish_launching(move || {
-            log::info!("finish launching");
-
-            workspace::init(&mut app);
-            editor::init(&mut app);
-
-            if stdout_is_a_pty() {
-                platform.activate(true);
-            }
-
-            let paths = std::env::args()
-                .skip(1)
-                .filter_map(|arg| match fs::canonicalize(arg) {
-                    Ok(path) => Some(path),
-                    Err(error) => {
-                        log::error!("error parsing path argument: {}", error);
-                        None
-                    }
-                })
-                .collect::<Vec<_>>();
-
-            if !paths.is_empty() {
-                app.dispatch_global_action(
-                    "workspace:open_paths",
-                    OpenParams {
-                        paths,
-                        settings: settings_rx,
-                    },
-                );
-                mem::forget(app); // This is here until we hold on to the app for some reason
-            }
-
-            // let window = platform
-            //     .open_window(
-            //         WindowOptions {
-            //             bounds: RectF::new(vec2f(0., 0.), vec2f(1024., 768.)),
-            //             title: Some("Zed"),
-            //         },
-            //         foreground,
-            //     )
-            //     .expect("error opening window");
-
-            // mem::forget(window); // Leak window for now so it doesn't close
-        })
-        .run();
+    let app = gpui::App::new(assets::Assets).unwrap();
+    let (_, settings_rx) = settings::channel(&app.fonts()).unwrap();
+
+    {
+        let mut app = app.clone();
+        platform::runner()
+            .on_finish_launching(move || {
+                workspace::init(&mut app);
+                editor::init(&mut app);
+
+                if stdout_is_a_pty() {
+                    app.platform().activate(true);
+                }
+
+                let paths = collect_path_args();
+                if !paths.is_empty() {
+                    app.dispatch_global_action(
+                        "workspace:open_paths",
+                        OpenParams {
+                            paths,
+                            settings: settings_rx,
+                        },
+                    );
+                }
+            })
+            .run();
+    }
 }
 
 fn init_logger() {
@@ -101,3 +64,16 @@ fn init_logger() {
 fn stdout_is_a_pty() -> bool {
     unsafe { libc::isatty(libc::STDOUT_FILENO as i32) != 0 }
 }
+
+fn collect_path_args() -> Vec<PathBuf> {
+    std::env::args()
+        .skip(1)
+        .filter_map(|arg| match fs::canonicalize(arg) {
+            Ok(path) => Some(path),
+            Err(error) => {
+                log::error!("error parsing path argument: {}", error);
+                None
+            }
+        })
+        .collect::<Vec<_>>()
+}

zed/src/workspace/mod.rs 🔗

@@ -58,7 +58,7 @@ mod tests {
 
     #[test]
     fn test_open_paths_action() {
-        App::test(|mut app| async move {
+        App::test((), |mut app| async move {
             let settings = settings::channel(&FontCache::new()).unwrap().1;
 
             init(&mut app);

zed/src/workspace/workspace.rs 🔗

@@ -228,7 +228,7 @@ mod tests {
 
     #[test]
     fn test_open_entry() -> Result<(), Arc<anyhow::Error>> {
-        App::test(|mut app| async move {
+        App::test((), |mut app| async move {
             let dir = temp_tree(json!({
                 "a": {
                     "aa": "aa contents",

zed/src/workspace/workspace_view.rs 🔗

@@ -331,7 +331,7 @@ mod tests {
 
     #[test]
     fn test_open_entry() -> Result<()> {
-        App::test(|mut app| async move {
+        App::test((), |mut app| async move {
             let dir = temp_tree(json!({
                 "a": {
                     "aa": "aa contents",
@@ -399,7 +399,7 @@ mod tests {
 
     #[test]
     fn test_pane_actions() -> Result<()> {
-        App::test(|mut app| async move {
+        App::test((), |mut app| async move {
             pane::init(&mut app);
 
             let dir = temp_tree(json!({