From 54c1e77aff03eeb7f203256dd760269404faae4f Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Wed, 10 May 2023 15:03:51 +0300 Subject: [PATCH] Move the caret to the opened file --- crates/file_finder/src/file_finder.rs | 83 +++++++++++++++++++++------ 1 file changed, 65 insertions(+), 18 deletions(-) diff --git a/crates/file_finder/src/file_finder.rs b/crates/file_finder/src/file_finder.rs index 62eae72cc59c62441c6c479a9177228ddc5fe6b4..8181d6a1f0b8d2cb02b9fc16da594b6de10ffffd 100644 --- a/crates/file_finder/src/file_finder.rs +++ b/crates/file_finder/src/file_finder.rs @@ -1,3 +1,4 @@ +use editor::{scroll::autoscroll::Autoscroll, DisplayPoint, Editor}; use fuzzy::PathMatch; use gpui::{ actions, elements::*, AppContext, ModelHandle, MouseState, Task, ViewContext, WeakViewHandle, @@ -60,12 +61,12 @@ pub enum Event { Dismissed, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone)] struct FileSearchQuery { raw_query: String, file_path_end: Option, - file_row: Option, - file_column: Option, + file_row: Option, + file_column: Option, } impl FileSearchQuery { @@ -77,30 +78,43 @@ impl FileSearchQuery { file_column: None, }; - let mut possible_path_and_coordinates = raw_query.as_str().rsplitn(3, ':').fuse(); + let mut possible_path_and_coordinates = + // TODO kb go_to_line.rs uses ',' as a separator?? + raw_query.as_str().splitn(3, ':').map(str::trim).fuse(); match ( possible_path_and_coordinates.next(), possible_path_and_coordinates.next(), possible_path_and_coordinates.next(), ) { - (Some(column_number_str), Some(row_number_str), Some(file_path_part)) => Self { + (Some(file_path_part), Some(row_number_str), Some(column_number_str)) + if !row_number_str.is_empty() && !column_number_str.is_empty() => + { + Self { + file_path_end: Some(file_path_part.len()), + file_row: match row_number_str.parse().ok() { + None => return fallback_query, + row => row, + }, + file_column: match column_number_str.parse().ok() { + None => return fallback_query, + column => column, + }, + raw_query, + } + } + (Some(file_path_part), Some(row_number_str), _) if !row_number_str.is_empty() => Self { file_path_end: Some(file_path_part.len()), file_row: match row_number_str.parse().ok() { None => return fallback_query, row => row, }, - file_column: match column_number_str.parse().ok() { - None => return fallback_query, - column => column, - }, + file_column: None, raw_query, }, - (Some(row_number_str), Some(file_path_part), None) => Self { + // Covers inputs like `foo.rs:` trimming all extra colons + (Some(file_path_part), _, _) => Self { file_path_end: Some(file_path_part.len()), - file_row: match row_number_str.parse().ok() { - None => return fallback_query, - row => row, - }, + file_row: None, file_column: None, raw_query, }, @@ -229,7 +243,13 @@ impl FileFinderDelegate { ) { if search_id >= self.latest_search_id { self.latest_search_id = search_id; - if self.latest_search_did_cancel && Some(&query) == self.latest_search_query.as_ref() { + if self.latest_search_did_cancel + && Some(query.path_query()) + == self + .latest_search_query + .as_ref() + .map(|query| query.path_query()) + { util::extend_sorted(&mut self.matches, matches.into_iter(), 100, |a, b| b.cmp(a)); } else { self.matches = matches; @@ -290,12 +310,39 @@ impl PickerDelegate for FileFinderDelegate { workspace.update(cx, |workspace, cx| { workspace - // TODO kb need to pass row and column here - // use self.latest_search_query .open_path(project_path.clone(), None, true, cx) .detach_and_log_err(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::()) + { + // 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 point = DisplayPoint::new( + row.saturating_sub(1), + column.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]), + ); + }) + } + } + } + workspace.dismiss_modal(cx); - }) + }); } } }