From 4e13900c095462474e633addcd8ea417540c1b26 Mon Sep 17 00:00:00 2001 From: Thorsten Ball Date: Fri, 13 Sep 2024 13:58:12 -0400 Subject: [PATCH] editor: In OpenFile check if file with path_suffix exists Co-authored-by: Abdelhakim Qbaich --- crates/editor/src/hover_links.rs | 69 +++++++++++++++++++++++++++----- crates/language/src/language.rs | 4 ++ 2 files changed, 64 insertions(+), 9 deletions(-) diff --git a/crates/editor/src/hover_links.rs b/crates/editor/src/hover_links.rs index 86c17625e1ef9..3f590273df8e8 100644 --- a/crates/editor/src/hover_links.rs +++ b/crates/editor/src/hover_links.rs @@ -713,17 +713,42 @@ pub(crate) async fn find_file( cx: &mut AsyncWindowContext, ) -> Option<(Range, ResolvedPath)> { let snapshot = buffer.update(cx, |buffer, _| buffer.snapshot()).ok()?; - + let scope = snapshot.language_scope_at(position); let (range, candidate_file_path) = surrounding_filename(snapshot, position)?; - let existing_path = project - .update(cx, |project, cx| { - project.resolve_existing_file_path(&candidate_file_path, buffer, cx) - }) - .ok()? - .await?; + async fn check_path( + candidate_file_path: &str, + project: &Model, + buffer: &Model, + cx: &mut AsyncWindowContext, + ) -> Option { + project + .update(cx, |project, cx| { + project.resolve_existing_file_path(&candidate_file_path, buffer, cx) + }) + .ok()? + .await + } - Some((range, existing_path)) + if let Some(existing_path) = check_path(&candidate_file_path, &project, buffer, cx).await { + return Some((range, existing_path)); + } + + if let Some(scope) = scope { + for suffix in scope.path_suffixes() { + if candidate_file_path.ends_with(format!(".{suffix}").as_str()) { + continue; + } + + let suffixed_candidate = format!("{candidate_file_path}.{suffix}"); + if let Some(existing_path) = check_path(&suffixed_candidate, &project, buffer, cx).await + { + return Some((range, existing_path)); + } + } + } + + None } fn surrounding_filename( @@ -1490,7 +1515,8 @@ mod tests { You can't go to a file that does_not_exist.txt. Go to file2.rs if you want. Or go to ../dir/file2.rs if you want. - Or go to /root/dir/file2.rs if project is local.ˇ + Or go to /root/dir/file2.rs if project is local. + Or go to /root/dir/file2 if this is a Rust file.ˇ "}); // File does not exist @@ -1499,6 +1525,7 @@ mod tests { Go to file2.rs if you want. Or go to ../dir/file2.rs if you want. Or go to /root/dir/file2.rs if project is local. + Or go to /root/dir/file2 if this is a Rust file. "}); cx.simulate_mouse_move(screen_coord, None, Modifiers::secondary_key()); // No highlight @@ -1517,6 +1544,7 @@ mod tests { Go to fˇile2.rs if you want. Or go to ../dir/file2.rs if you want. Or go to /root/dir/file2.rs if project is local. + Or go to /root/dir/file2 if this is a Rust file. "}); cx.simulate_mouse_move(screen_coord, None, Modifiers::secondary_key()); @@ -1525,6 +1553,7 @@ mod tests { Go to «file2.rsˇ» if you want. Or go to ../dir/file2.rs if you want. Or go to /root/dir/file2.rs if project is local. + Or go to /root/dir/file2 if this is a Rust file. "}); // Moving the mouse over a relative path that does exist should highlight it @@ -1533,6 +1562,7 @@ mod tests { Go to file2.rs if you want. Or go to ../dir/fˇile2.rs if you want. Or go to /root/dir/file2.rs if project is local. + Or go to /root/dir/file2 if this is a Rust file. "}); cx.simulate_mouse_move(screen_coord, None, Modifiers::secondary_key()); @@ -1541,6 +1571,7 @@ mod tests { Go to file2.rs if you want. Or go to «../dir/file2.rsˇ» if you want. Or go to /root/dir/file2.rs if project is local. + Or go to /root/dir/file2 if this is a Rust file. "}); // Moving the mouse over an absolute path that does exist should highlight it @@ -1549,6 +1580,7 @@ mod tests { Go to file2.rs if you want. Or go to ../dir/file2.rs if you want. Or go to /root/diˇr/file2.rs if project is local. + Or go to /root/dir/file2 if this is a Rust file. "}); cx.simulate_mouse_move(screen_coord, None, Modifiers::secondary_key()); @@ -1557,6 +1589,25 @@ mod tests { Go to file2.rs if you want. Or go to ../dir/file2.rs if you want. Or go to «/root/dir/file2.rsˇ» if project is local. + Or go to /root/dir/file2 if this is a Rust file. + "}); + + // Moving the mouse over a path that exists, if we add the language-specific suffix, it should highlight it + let screen_coord = cx.pixel_position(indoc! {" + You can't go to a file that does_not_exist.txt. + Go to file2.rs if you want. + Or go to ../dir/file2.rs if you want. + Or go to /root/dir/file2.rs if project is local. + Or go to /root/diˇr/file2 if this is a Rust file. + "}); + + cx.simulate_mouse_move(screen_coord, None, Modifiers::secondary_key()); + cx.assert_editor_text_highlights::(indoc! {" + You can't go to a file that does_not_exist.txt. + Go to file2.rs if you want. + Or go to ../dir/file2.rs if you want. + Or go to /root/dir/file2.rs if project is local. + Or go to «/root/dir/file2ˇ» if this is a Rust file. "}); cx.simulate_click(screen_coord, Modifiers::secondary_key()); diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index cd39490d0bbdf..3112d88aa5543 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -1410,6 +1410,10 @@ impl Language { } impl LanguageScope { + pub fn path_suffixes(&self) -> &[String] { + &self.language.path_suffixes() + } + pub fn language_name(&self) -> LanguageName { self.language.config.name.clone() }