Add navigation deduping

Keith Simmons and Antonio Scandurra created

Co-authored-by: Antonio Scandurra <me@as-cii.com>

Change summary

crates/editor/src/editor.rs |  2 
crates/zed/src/zed.rs       | 46 +++++++++++++++++++++++++++++++++++++++
2 files changed, 47 insertions(+), 1 deletion(-)

Detailed changes

crates/editor/src/editor.rs 🔗

@@ -5060,7 +5060,7 @@ impl Editor {
         cx.notify();
     }
 
-    fn transact(
+    pub fn transact(
         &mut self,
         cx: &mut ViewContext<Self>,
         update: impl FnOnce(&mut Self, &mut ViewContext<Self>),

crates/zed/src/zed.rs 🔗

@@ -893,6 +893,52 @@ mod tests {
             (file3.clone(), DisplayPoint::new(0, 0))
         );
 
+        // Modify file to remove nav history location, and ensure duplicates are skipped
+        editor1.update(cx, |editor, cx| {
+            editor.select_display_ranges(&[DisplayPoint::new(15, 0)..DisplayPoint::new(15, 0)], cx)
+        });
+
+        for _ in 0..5 {
+            editor1.update(cx, |editor, cx| {
+                editor
+                    .select_display_ranges(&[DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0)], cx);
+            });
+            editor1.update(cx, |editor, cx| {
+                editor.select_display_ranges(
+                    &[DisplayPoint::new(13, 0)..DisplayPoint::new(13, 0)],
+                    cx,
+                )
+            });
+        }
+
+        editor1.update(cx, |editor, cx| {
+            editor.transact(cx, |editor, cx| {
+                editor.select_display_ranges(
+                    &[DisplayPoint::new(2, 0)..DisplayPoint::new(14, 0)],
+                    cx,
+                );
+                editor.insert("", cx);
+            })
+        });
+
+        editor1.update(cx, |editor, cx| {
+            editor.select_display_ranges(&[DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0)], cx)
+        });
+        workspace
+            .update(cx, |w, cx| Pane::go_back(w, None, cx))
+            .await;
+        assert_eq!(
+            active_location(&workspace, cx),
+            (file1.clone(), DisplayPoint::new(2, 0))
+        );
+        workspace
+            .update(cx, |w, cx| Pane::go_back(w, None, cx))
+            .await;
+        assert_eq!(
+            active_location(&workspace, cx),
+            (file1.clone(), DisplayPoint::new(3, 0))
+        );
+
         fn active_location(
             workspace: &ViewHandle<Workspace>,
             cx: &mut TestAppContext,