editor: Fix navigate back for locations opened via preview item (#26943)

Smit Barmase created

Closes #25458

When navigating code from a preview tab with
`enable_preview_from_code_navigation` set to `true`, "Go Back" from a
newly opened tab could focus on the tab to the right instead of
returning to the original preview tab.

Before, we killed the existing preview tab before opening a new one,
which breaking history as the new tab had no reference to the old one.
This caused navigation to shift to the next tab on the right.

Now, we first add the new tab at the preview index, and then kill the
existing preview tab. This preserves the history by linking new preview
tab to existing tab.

Release Notes:

- Fixes an issue where navigating code from a preview tab with
`enable_preview_from_code_navigation` set to `true`, "Go Back" from a
newly opened tab could focus on the tab to the right instead of
returning to the original preview tab.

Change summary

crates/editor/src/editor.rs  | 22 +++++++++++++++-------
crates/workspace/src/pane.rs |  2 +-
2 files changed, 16 insertions(+), 8 deletions(-)

Detailed changes

crates/editor/src/editor.rs 🔗

@@ -12448,14 +12448,22 @@ impl Editor {
         if split {
             workspace.split_item(SplitDirection::Right, item.clone(), window, cx);
         } else {
-            let destination_index = workspace.active_pane().update(cx, |pane, cx| {
-                if PreviewTabsSettings::get_global(cx).enable_preview_from_code_navigation {
-                    pane.close_current_preview_item(window, cx)
-                } else {
-                    None
+            if PreviewTabsSettings::get_global(cx).enable_preview_from_code_navigation {
+                let (preview_item_id, preview_item_idx) =
+                    workspace.active_pane().update(cx, |pane, _| {
+                        (pane.preview_item_id(), pane.preview_item_idx())
+                    });
+
+                workspace.add_item_to_active_pane(item.clone(), preview_item_idx, true, window, cx);
+
+                if let Some(preview_item_id) = preview_item_id {
+                    workspace.active_pane().update(cx, |pane, cx| {
+                        pane.remove_item(preview_item_id, false, false, window, cx);
+                    });
                 }
-            });
-            workspace.add_item_to_active_pane(item.clone(), destination_index, true, window, cx);
+            } else {
+                workspace.add_item_to_active_pane(item.clone(), None, true, window, cx);
+            }
         }
         workspace.active_pane().update(cx, |pane, cx| {
             pane.set_preview_item_id(Some(item_id), cx);

crates/workspace/src/pane.rs 🔗

@@ -805,7 +805,7 @@ impl Pane {
             .cloned()
     }
 
-    fn preview_item_idx(&self) -> Option<usize> {
+    pub fn preview_item_idx(&self) -> Option<usize> {
         if let Some(preview_item_id) = self.preview_item_id {
             self.items
                 .iter()