Properly place the caret into the window of the file opened

Kirill Bulatov and Mikayla Maki created

co-authored-by: Mikayla Maki <mikayla.c.maki@gmail.com>

Change summary

crates/file_finder/src/file_finder.rs | 65 +++++++++++++++++-----------
1 file changed, 39 insertions(+), 26 deletions(-)

Detailed changes

crates/file_finder/src/file_finder.rs 🔗

@@ -1,4 +1,4 @@
-use editor::{scroll::autoscroll::Autoscroll, DisplayPoint, Editor};
+use editor::{scroll::autoscroll::Autoscroll, Bias, DisplayPoint, Editor};
 use fuzzy::PathMatch;
 use gpui::{
     actions, elements::*, AppContext, ModelHandle, MouseState, Task, ViewContext, WeakViewHandle,
@@ -308,41 +308,54 @@ impl PickerDelegate for FileFinderDelegate {
                     path: m.path.clone(),
                 };
 
-                workspace.update(cx, |workspace, cx| {
-                    workspace
-                        .open_path(project_path.clone(), None, true, cx)
-                        .detach_and_log_err(cx);
+                let open_task = workspace.update(cx, |workspace, cx| {
+                    workspace.open_path(project_path.clone(), None, true, cx)
                 });
 
-                workspace.update(cx, |workspace, cx| {
-                    if let Some(query) = &self.latest_search_query {
-                        let row = query.file_row;
-                        let column = query.file_column;
-                        if let Some(row) = row {
-                            if let Some(active_editor) = workspace
-                                .active_item(cx)
-                                .and_then(|active_item| active_item.downcast::<Editor>())
-                            {
-                                // TODO kb does not open proper lines for the first time
-                                active_editor.update(cx, |active_editor, cx| {
-                                    let snapshot = active_editor.snapshot(cx).display_snapshot;
+                let workspace = workspace.downgrade();
+
+                cx.spawn(|file_finder, mut cx| async move {
+                    let item = open_task.await.log_err()?;
+
+                    let (row, col) = file_finder
+                        .read_with(&cx, |file_finder, _| {
+                            file_finder
+                                .delegate()
+                                .latest_search_query
+                                .as_ref()
+                                .map(|query| (query.file_row, query.file_column))
+                        })
+                        .log_err()
+                        .flatten()?;
+
+                    if let Some(row) = row {
+                        if let Some(active_editor) = item.downcast::<Editor>() {
+                            active_editor
+                                .downgrade()
+                                .update(&mut cx, |editor, cx| {
+                                    let snapshot = editor.snapshot(cx).display_snapshot;
                                     let point = DisplayPoint::new(
                                         row.saturating_sub(1),
-                                        column.map(|column| column.saturating_sub(1)).unwrap_or(0),
+                                        col.map(|column| column.saturating_sub(1)).unwrap_or(0),
                                     )
                                     .to_point(&snapshot);
-                                    active_editor.change_selections(
-                                        Some(Autoscroll::center()),
-                                        cx,
-                                        |s| s.select_ranges([point..point]),
-                                    );
+                                    let point =
+                                        snapshot.buffer_snapshot.clip_point(point, Bias::Left);
+                                    editor.change_selections(Some(Autoscroll::center()), cx, |s| {
+                                        s.select_ranges([point..point])
+                                    });
                                 })
-                            }
+                                .log_err();
                         }
                     }
 
-                    workspace.dismiss_modal(cx);
-                });
+                    workspace
+                        .update(&mut cx, |workspace, cx| workspace.dismiss_modal(cx))
+                        .log_err();
+
+                    Some(())
+                })
+                .detach();
             }
         }
     }