Merge branch 'master' into copy-paste

Antonio Scandurra created

Change summary

gpui/src/app.rs                     |  40 +++++++----
zed/src/editor/buffer/mod.rs        |   2 
zed/src/editor/buffer_view.rs       | 101 +++++++++++++++++-------------
zed/src/editor/display_map/mod.rs   |   8 +-
zed/src/file_finder.rs              |   6 
zed/src/workspace/mod.rs            |   4 
zed/src/workspace/pane.rs           |   9 +-
zed/src/workspace/workspace.rs      |   4 
zed/src/workspace/workspace_view.rs |  10 +-
zed/src/worktree/worktree.rs        |   2 
10 files changed, 102 insertions(+), 84 deletions(-)

Detailed changes

gpui/src/app.rs 🔗

@@ -1499,14 +1499,6 @@ impl<'a, T: Entity> ModelContext<'a, T> {
         }
     }
 
-    pub fn app(&self) -> &AppContext {
-        &self.app.ctx
-    }
-
-    pub fn app_mut(&mut self) -> &mut MutableAppContext {
-        self.app
-    }
-
     pub fn background_executor(&self) -> &Arc<executor::Background> {
         &self.app.ctx.background
     }
@@ -1644,6 +1636,18 @@ impl<'a, T: Entity> ModelContext<'a, T> {
     }
 }
 
+impl<M> AsRef<AppContext> for ModelContext<'_, M> {
+    fn as_ref(&self) -> &AppContext {
+        &self.app.ctx
+    }
+}
+
+impl<M> AsMut<MutableAppContext> for ModelContext<'_, M> {
+    fn as_mut(&mut self) -> &mut MutableAppContext {
+        self.app
+    }
+}
+
 impl<M> ReadModel for ModelContext<'_, M> {
     fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
         self.app.read_model(handle)
@@ -1689,14 +1693,6 @@ impl<'a, T: View> ViewContext<'a, T> {
         self.window_id
     }
 
-    pub fn app(&self) -> &AppContext {
-        &self.app.ctx
-    }
-
-    pub fn app_mut(&mut self) -> &mut MutableAppContext {
-        self.app
-    }
-
     pub fn background_executor(&self) -> &Arc<executor::Background> {
         &self.app.ctx.background
     }
@@ -1899,6 +1895,18 @@ impl<'a, T: View> ViewContext<'a, T> {
     }
 }
 
+impl<M> AsRef<AppContext> for ViewContext<'_, M> {
+    fn as_ref(&self) -> &AppContext {
+        &self.app.ctx
+    }
+}
+
+impl<M> AsMut<MutableAppContext> for ViewContext<'_, M> {
+    fn as_mut(&mut self) -> &mut MutableAppContext {
+        self.app
+    }
+}
+
 impl<V> ReadModel for ViewContext<'_, V> {
     fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
         self.app.read_model(handle)

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

@@ -447,7 +447,7 @@ impl Buffer {
         if let Some(file) = &self.file {
             let snapshot = self.snapshot();
             let version = self.version.clone();
-            let save_task = file.save(snapshot, ctx.app());
+            let save_task = file.save(snapshot, ctx.as_ref());
             let task = ctx.spawn(save_task, |me, save_result, ctx| {
                 if save_result.is_ok() {
                     me.did_save(version, ctx);

zed/src/editor/buffer_view.rs 🔗

@@ -311,7 +311,7 @@ impl BufferView {
 
         let display_map = self.display_map.read(ctx);
         let cursor = display_map
-            .anchor_before(position, Bias::Left, ctx.app())
+            .anchor_before(position, Bias::Left, ctx.as_ref())
             .unwrap();
         let selection = Selection {
             start: cursor.clone(),
@@ -336,7 +336,9 @@ impl BufferView {
     ) {
         let buffer = self.buffer.read(ctx);
         let map = self.display_map.read(ctx);
-        let cursor = map.anchor_before(position, Bias::Left, ctx.app()).unwrap();
+        let cursor = map
+            .anchor_before(position, Bias::Left, ctx.as_ref())
+            .unwrap();
         if let Some(selection) = self.pending_selection.as_mut() {
             selection.set_head(buffer, cursor);
         } else {
@@ -351,8 +353,8 @@ impl BufferView {
 
     fn end_selection(&mut self, ctx: &mut ViewContext<Self>) {
         if let Some(selection) = self.pending_selection.take() {
-            let ix = self.selection_insertion_index(&selection.start, ctx.app());
-            let mut selections = self.selections(ctx.app()).to_vec();
+            let ix = self.selection_insertion_index(&selection.start, ctx.as_ref());
+            let mut selections = self.selections(ctx.as_ref()).to_vec();
             selections.insert(ix, selection);
             self.update_selections(selections, ctx);
         } else {
@@ -392,8 +394,8 @@ impl BufferView {
         let mut selections = Vec::new();
         for range in ranges {
             selections.push(Selection {
-                start: map.anchor_after(range.start, Bias::Left, ctx.app())?,
-                end: map.anchor_before(range.end, Bias::Left, ctx.app())?,
+                start: map.anchor_after(range.start, Bias::Left, ctx.as_ref())?,
+                end: map.anchor_before(range.end, Bias::Left, ctx.as_ref())?,
                 reversed: false,
                 goal_column: None,
             });
@@ -406,7 +408,7 @@ impl BufferView {
         let mut offset_ranges = SmallVec::<[Range<usize>; 32]>::new();
         {
             let buffer = self.buffer.read(ctx);
-            for selection in self.selections(ctx.app()) {
+            for selection in self.selections(ctx.as_ref()) {
                 let start = selection.start.to_offset(buffer).unwrap();
                 let end = selection.end.to_offset(buffer).unwrap();
                 offset_ranges.push(start..end);
@@ -456,18 +458,21 @@ impl BufferView {
 
     pub fn backspace(&mut self, _: &(), ctx: &mut ViewContext<Self>) {
         self.start_transaction(ctx);
-        let mut selections = self.selections(ctx.app()).to_vec();
+        let mut selections = self.selections(ctx.as_ref()).to_vec();
         {
             let buffer = self.buffer.read(ctx);
             let map = self.display_map.read(ctx);
             for selection in &mut selections {
                 if selection.range(buffer).is_empty() {
-                    let head = selection.head().to_display_point(map, ctx.app()).unwrap();
+                    let head = selection
+                        .head()
+                        .to_display_point(map, ctx.as_ref())
+                        .unwrap();
                     let cursor = map
                         .anchor_before(
-                            movement::left(map, head, ctx.app()).unwrap(),
+                            movement::left(map, head, ctx.as_ref()).unwrap(),
                             Bias::Left,
-                            ctx.app(),
+                            ctx.as_ref(),
                         )
                         .unwrap();
                     selection.set_head(&buffer, cursor);
@@ -485,7 +490,7 @@ impl BufferView {
     pub fn cut(&mut self, _: &(), ctx: &mut ViewContext<Self>) {
         self.start_transaction(ctx);
         let mut text = String::new();
-        let mut selections = self.selections(ctx.app()).to_vec();
+        let mut selections = self.selections(ctx.as_ref()).to_vec();
         let mut clipboard_selections = Vec::with_capacity(selections.len());
         {
             let buffer = self.buffer.read(ctx);
@@ -516,7 +521,7 @@ impl BufferView {
         self.insert(&String::new(), ctx);
         self.end_transaction(ctx);
 
-        ctx.app_mut()
+        ctx.as_mut()
             .write_to_clipboard(ClipboardItem::new(text).with_metadata(clipboard_selections));
     }
 
@@ -524,7 +529,7 @@ impl BufferView {
         let buffer = self.buffer.read(ctx);
         let max_point = buffer.max_point();
         let mut text = String::new();
-        let selections = self.selections(ctx.app());
+        let selections = self.selections(ctx.as_ref());
         let mut clipboard_selections = Vec::with_capacity(selections.len());
         for selection in selections {
             let mut start = selection.start.to_point(buffer).expect("invalid start");
@@ -545,15 +550,15 @@ impl BufferView {
             });
         }
 
-        ctx.app_mut()
+        ctx.as_mut()
             .write_to_clipboard(ClipboardItem::new(text).with_metadata(clipboard_selections));
     }
 
     pub fn paste(&mut self, _: &(), ctx: &mut ViewContext<Self>) {
-        if let Some(item) = ctx.app_mut().read_from_clipboard() {
+        if let Some(item) = ctx.as_mut().read_from_clipboard() {
             let clipboard_text = item.text();
             if let Some(clipboard_selections) = item.metadata::<Vec<ClipboardSelection>>() {
-                let selections_len = self.selections(ctx.app()).len();
+                let selections_len = self.selections(ctx.as_ref()).len();
                 if clipboard_selections.len() == selections_len {
                     // If there are the same number of selections as there were at the time that
                     // this clipboard data was written, then paste one slice of the clipboard text
@@ -585,7 +590,7 @@ impl BufferView {
         ctx: &mut ViewContext<Self>,
     ) {
         self.start_transaction(ctx);
-        let selections = self.selections(ctx.app()).to_vec();
+        let selections = self.selections(ctx.as_ref()).to_vec();
         let mut new_selections = Vec::with_capacity(selections.len());
         let mut clipboard_offset = 0;
         for (selection, clipboard_selection) in selections.iter().zip(clipboard_selections) {
@@ -648,7 +653,7 @@ impl BufferView {
     }
 
     pub fn move_left(&mut self, _: &(), ctx: &mut ViewContext<Self>) {
-        let app = ctx.app();
+        let app = ctx.as_ref();
         let mut selections = self.selections(app).to_vec();
         {
             let map = self.display_map.read(app);
@@ -674,17 +679,20 @@ impl BufferView {
     }
 
     pub fn select_left(&mut self, _: &(), ctx: &mut ViewContext<Self>) {
-        let mut selections = self.selections(ctx.app()).to_vec();
+        let mut selections = self.selections(ctx.as_ref()).to_vec();
         {
             let buffer = self.buffer.read(ctx);
             let map = self.display_map.read(ctx);
             for selection in &mut selections {
-                let head = selection.head().to_display_point(map, ctx.app()).unwrap();
+                let head = selection
+                    .head()
+                    .to_display_point(map, ctx.as_ref())
+                    .unwrap();
                 let cursor = map
                     .anchor_before(
-                        movement::left(map, head, ctx.app()).unwrap(),
+                        movement::left(map, head, ctx.as_ref()).unwrap(),
                         Bias::Left,
-                        ctx.app(),
+                        ctx.as_ref(),
                     )
                     .unwrap();
                 selection.set_head(&buffer, cursor);
@@ -696,9 +704,9 @@ impl BufferView {
     }
 
     pub fn move_right(&mut self, _: &(), ctx: &mut ViewContext<Self>) {
-        let mut selections = self.selections(ctx.app()).to_vec();
+        let mut selections = self.selections(ctx.as_ref()).to_vec();
         {
-            let app = ctx.app();
+            let app = ctx.as_ref();
             let map = self.display_map.read(app);
             for selection in &mut selections {
                 let start = selection.start.to_display_point(map, app).unwrap();
@@ -722,13 +730,16 @@ impl BufferView {
     }
 
     pub fn select_right(&mut self, _: &(), ctx: &mut ViewContext<Self>) {
-        let mut selections = self.selections(ctx.app()).to_vec();
+        let mut selections = self.selections(ctx.as_ref()).to_vec();
         {
-            let app = ctx.app();
+            let app = ctx.as_ref();
             let buffer = self.buffer.read(app);
             let map = self.display_map.read(app);
             for selection in &mut selections {
-                let head = selection.head().to_display_point(map, ctx.app()).unwrap();
+                let head = selection
+                    .head()
+                    .to_display_point(map, ctx.as_ref())
+                    .unwrap();
                 let cursor = map
                     .anchor_before(movement::right(map, head, app).unwrap(), Bias::Right, app)
                     .unwrap();
@@ -744,9 +755,9 @@ impl BufferView {
         if self.single_line {
             ctx.propagate_action();
         } else {
-            let mut selections = self.selections(ctx.app()).to_vec();
+            let mut selections = self.selections(ctx.as_ref()).to_vec();
             {
-                let app = ctx.app();
+                let app = ctx.as_ref();
                 let map = self.display_map.read(app);
                 for selection in &mut selections {
                     let start = selection.start.to_display_point(map, app).unwrap();
@@ -773,9 +784,9 @@ impl BufferView {
         if self.single_line {
             ctx.propagate_action();
         } else {
-            let mut selections = self.selections(ctx.app()).to_vec();
+            let mut selections = self.selections(ctx.as_ref()).to_vec();
             {
-                let app = ctx.app();
+                let app = ctx.as_ref();
                 let buffer = self.buffer.read(app);
                 let map = self.display_map.read(app);
                 for selection in &mut selections {
@@ -795,9 +806,9 @@ impl BufferView {
         if self.single_line {
             ctx.propagate_action();
         } else {
-            let mut selections = self.selections(ctx.app()).to_vec();
+            let mut selections = self.selections(ctx.as_ref()).to_vec();
             {
-                let app = ctx.app();
+                let app = ctx.as_ref();
                 let map = self.display_map.read(app);
                 for selection in &mut selections {
                     let start = selection.start.to_display_point(map, app).unwrap();
@@ -824,9 +835,9 @@ impl BufferView {
         if self.single_line {
             ctx.propagate_action();
         } else {
-            let mut selections = self.selections(ctx.app()).to_vec();
+            let mut selections = self.selections(ctx.as_ref()).to_vec();
             {
-                let app = ctx.app();
+                let app = ctx.as_ref();
                 let buffer = self.buffer.read(app);
                 let map = self.display_map.read(app);
                 for selection in &mut selections {
@@ -969,7 +980,7 @@ impl BufferView {
 
         let mut fold_ranges = Vec::new();
 
-        let app = ctx.app();
+        let app = ctx.as_ref();
         let map = self.display_map.read(app);
         for selection in self.selections(app) {
             let (start, end) = selection.display_range(map, app).sorted();
@@ -999,7 +1010,7 @@ impl BufferView {
     pub fn unfold(&mut self, _: &(), ctx: &mut ViewContext<Self>) {
         use super::RangeExt;
 
-        let app = ctx.app();
+        let app = ctx.as_ref();
         let map = self.display_map.read(app);
         let buffer = self.buffer.read(app);
         let ranges = self
@@ -1083,7 +1094,7 @@ impl BufferView {
         self.display_map.update(ctx, |map, ctx| {
             let buffer = self.buffer.read(ctx);
             let ranges = self
-                .selections(ctx.app())
+                .selections(ctx.as_ref())
                 .iter()
                 .map(|s| s.range(buffer))
                 .collect::<Vec<_>>();
@@ -1601,7 +1612,7 @@ mod tests {
                 .unwrap();
                 view.fold(&(), ctx);
                 assert_eq!(
-                    view.text(ctx.app()),
+                    view.text(ctx.as_ref()),
                     "
                     impl Foo {
                         // Hello!
@@ -1622,7 +1633,7 @@ mod tests {
 
                 view.fold(&(), ctx);
                 assert_eq!(
-                    view.text(ctx.app()),
+                    view.text(ctx.as_ref()),
                     "
                     impl Foo {…
                     }
@@ -1632,7 +1643,7 @@ mod tests {
 
                 view.unfold(&(), ctx);
                 assert_eq!(
-                    view.text(ctx.app()),
+                    view.text(ctx.as_ref()),
                     "
                     impl Foo {
                         // Hello!
@@ -1652,7 +1663,7 @@ mod tests {
                 );
 
                 view.unfold(&(), ctx);
-                assert_eq!(view.text(ctx.app()), buffer.read(ctx).text());
+                assert_eq!(view.text(ctx.as_ref()), buffer.read(ctx).text());
             });
         });
     }
@@ -1679,12 +1690,12 @@ mod tests {
             view.update(app, |view, ctx| {
                 view.move_down(&(), ctx);
                 assert_eq!(
-                    view.selection_ranges(ctx.app()),
+                    view.selection_ranges(ctx.as_ref()),
                     &[DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0)]
                 );
                 view.move_right(&(), ctx);
                 assert_eq!(
-                    view.selection_ranges(ctx.app()),
+                    view.selection_ranges(ctx.as_ref()),
                     &[DisplayPoint::new(1, 4)..DisplayPoint::new(1, 4)]
                 );
                 Ok::<(), Error>(())

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

@@ -29,7 +29,7 @@ impl DisplayMap {
 
         DisplayMap {
             buffer: buffer.clone(),
-            fold_map: FoldMap::new(buffer, ctx.app()),
+            fold_map: FoldMap::new(buffer, ctx.as_ref()),
             tab_size,
         }
     }
@@ -39,7 +39,7 @@ impl DisplayMap {
         ranges: impl IntoIterator<Item = Range<T>>,
         ctx: &mut ModelContext<Self>,
     ) -> Result<()> {
-        self.fold_map.fold(ranges, ctx.app())?;
+        self.fold_map.fold(ranges, ctx.as_ref())?;
         ctx.notify();
         Ok(())
     }
@@ -49,7 +49,7 @@ impl DisplayMap {
         ranges: impl IntoIterator<Item = Range<T>>,
         ctx: &mut ModelContext<Self>,
     ) -> Result<()> {
-        self.fold_map.unfold(ranges, ctx.app())?;
+        self.fold_map.unfold(ranges, ctx.as_ref())?;
         ctx.notify();
         Ok(())
     }
@@ -125,7 +125,7 @@ impl DisplayMap {
 
     fn handle_buffer_event(&mut self, event: &buffer::Event, ctx: &mut ModelContext<Self>) {
         match event {
-            buffer::Event::Edited(edits) => self.fold_map.apply_edits(edits, ctx.app()).unwrap(),
+            buffer::Event::Edited(edits) => self.fold_map.apply_edits(edits, ctx.as_ref()).unwrap(),
             _ => {}
         }
     }

zed/src/file_finder.rs 🔗

@@ -287,7 +287,7 @@ impl FileFinder {
     }
 
     fn workspace_updated(&mut self, _: ModelHandle<Workspace>, ctx: &mut ViewContext<Self>) {
-        self.spawn_search(self.query_buffer.read(ctx).text(ctx.app()), ctx);
+        self.spawn_search(self.query_buffer.read(ctx).text(ctx.as_ref()), ctx);
     }
 
     fn on_query_buffer_event(
@@ -299,7 +299,7 @@ impl FileFinder {
         use buffer_view::Event::*;
         match event {
             Edited => {
-                let query = self.query_buffer.read(ctx).text(ctx.app());
+                let query = self.query_buffer.read(ctx).text(ctx.as_ref());
                 if query.is_empty() {
                     self.latest_search_id = util::post_inc(&mut self.search_count);
                     self.matches.clear();
@@ -345,7 +345,7 @@ impl FileFinder {
     }
 
     fn spawn_search(&mut self, query: String, ctx: &mut ViewContext<Self>) {
-        let worktrees = self.worktrees(ctx.app());
+        let worktrees = self.worktrees(ctx.as_ref());
         let search_id = util::post_inc(&mut self.search_count);
         let task = ctx.background_executor().spawn(async move {
             let matches = match_paths(worktrees.as_slice(), &query, false, false, 100);

zed/src/workspace/mod.rs 🔗

@@ -51,8 +51,8 @@ fn open_paths(params: &OpenParams, app: &mut MutableAppContext) {
     for window_id in app.window_ids().collect::<Vec<_>>() {
         if let Some(handle) = app.root_view::<WorkspaceView>(window_id) {
             if handle.update(app, |view, ctx| {
-                if view.contains_paths(&params.paths, ctx.app()) {
-                    view.open_paths(&params.paths, ctx.app_mut());
+                if view.contains_paths(&params.paths, ctx.as_ref()) {
+                    view.open_paths(&params.paths, ctx.as_mut());
                     log::info!("open paths on existing workspace");
                     true
                 } else {

zed/src/workspace/pane.rs 🔗

@@ -110,11 +110,10 @@ impl Pane {
         entry_id: (usize, usize),
         ctx: &mut ViewContext<Self>,
     ) -> bool {
-        if let Some(index) = self
-            .items
-            .iter()
-            .position(|item| item.entry_id(ctx.app()).map_or(false, |id| id == entry_id))
-        {
+        if let Some(index) = self.items.iter().position(|item| {
+            item.entry_id(ctx.as_ref())
+                .map_or(false, |id| id == entry_id)
+        }) {
             self.activate_item(index, ctx);
             true
         } else {

zed/src/workspace/workspace.rs 🔗

@@ -153,8 +153,8 @@ impl Workspace {
             .ok_or(anyhow!("worktree {} does not exist", entry.0,))?;
 
         let replica_id = self.replica_id;
-        let file = worktree.file(entry.1, ctx.app())?;
-        let history = file.load_history(ctx.app());
+        let file = worktree.file(entry.1, ctx.as_ref())?;
+        let history = file.load_history(ctx.as_ref());
         let buffer = async move { Ok(Buffer::from_history(replica_id, file, history.await?)) };
 
         let (mut tx, rx) = watch::channel(None);

zed/src/workspace/workspace_view.rs 🔗

@@ -214,7 +214,7 @@ impl WorkspaceView {
                     me.loading_entries.remove(&entry);
                     match item {
                         Ok(item) => {
-                            let item_view = item.add_view(ctx.window_id(), settings, ctx.app_mut());
+                            let item_view = item.add_view(ctx.window_id(), settings, ctx.as_mut());
                             me.add_item(item_view, ctx);
                         }
                         Err(error) => {
@@ -243,7 +243,7 @@ impl WorkspaceView {
     pub fn save_active_item(&mut self, _: &(), ctx: &mut ViewContext<Self>) {
         self.active_pane.update(ctx, |pane, ctx| {
             if let Some(item) = pane.active_item() {
-                let task = item.save(ctx.app_mut());
+                let task = item.save(ctx.as_mut());
                 ctx.spawn(task, |_, result, _| {
                     if let Err(e) = result {
                         // TODO - present this error to the user
@@ -259,7 +259,7 @@ impl WorkspaceView {
         match to_string_pretty(&ctx.debug_elements()) {
             Ok(json) => {
                 let kib = json.len() as f32 / 1024.;
-                ctx.app_mut().write_to_clipboard(ClipboardItem::new(json));
+                ctx.as_mut().write_to_clipboard(ClipboardItem::new(json));
                 log::info!(
                     "copied {:.1} KiB of element debug JSON to the clipboard",
                     kib
@@ -324,7 +324,7 @@ impl WorkspaceView {
         let new_pane = self.add_pane(ctx);
         self.activate_pane(new_pane.clone(), ctx);
         if let Some(item) = pane.read(ctx).active_item() {
-            if let Some(clone) = item.clone_on_split(ctx.app_mut()) {
+            if let Some(clone) = item.clone_on_split(ctx.as_mut()) {
                 self.add_item(clone, ctx);
             }
         }
@@ -352,7 +352,7 @@ impl WorkspaceView {
 
     fn add_item(&self, item: Box<dyn ItemViewHandle>, ctx: &mut ViewContext<Self>) {
         let active_pane = self.active_pane();
-        item.set_parent_pane(&active_pane, ctx.app_mut());
+        item.set_parent_pane(&active_pane, ctx.as_mut());
         active_pane.update(ctx, |pane, ctx| {
             let item_idx = pane.add_item(item, ctx);
             pane.activate_item(item_idx, ctx);

zed/src/worktree/worktree.rs 🔗

@@ -710,7 +710,7 @@ mod test {
             let file_id = entry.entry_id;
 
             tree.update(&mut app, |tree, ctx| {
-                smol::block_on(tree.save(file_id, buffer.snapshot(), ctx.app())).unwrap()
+                smol::block_on(tree.save(file_id, buffer.snapshot(), ctx.as_ref())).unwrap()
             });
 
             let history = app