Skip to content

Commit 3cd051a

Browse files
Thanh Nguyenprobably-neb
andauthored
terminal: Normalize path-like targets with leading .. (zed-industries#47289)
Fixes zed-industries#28339 ## What - Normalize cwd-relative path-like targets that include leading `..` before worktree lookup. - Update issue zed-industries#28339 tests to expect `WorktreeExact` for local and remote resolution. ## Why - Prevent terminal links like `../foo/bar.txt` from creating invalid entries; resolve to the correct worktree file instead. ## How to test - `cargo test -p terminal_view issue_28339 -- --nocapture` - Manual: open a workspace, run `echo ../foo/bar.txt` from a subdir in the terminal, then cmd/ctrl-click and confirm the correct file opens. ## Risk - Low: only changes terminal path-like resolution for `..` paths; expected to match normalized behavior. ## Checklist - [x] Tests run (`cargo test -p terminal_view issue_28339 -- --nocapture`) - [x] Docs updated (not needed) - [x] Backwards compatibility considered Release Notes: - Fixed an issue where relative paths starting with `..` would not resolve correctly when clicking the link in the terminal --------- Co-authored-by: Ben Kunkle <ben.kunkle@gmail.com>
1 parent b50de99 commit 3cd051a

File tree

1 file changed

+28
-17
lines changed

1 file changed

+28
-17
lines changed

crates/terminal_view/src/terminal_path_like_target.rs

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use std::path::PathBuf;
88
use terminal::PathLikeTarget;
99
use util::{
1010
ResultExt, debug_panic,
11-
paths::{PathStyle, PathWithPosition},
11+
paths::{PathStyle, PathWithPosition, normalize_lexically},
1212
rel_path::RelPath,
1313
};
1414
use workspace::{OpenOptions, OpenVisible, Workspace};
@@ -222,17 +222,33 @@ fn possible_open_target(
222222
}
223223
};
224224

225-
if let Ok(relative_path_to_check) =
226-
RelPath::new(&path_to_check.path, PathStyle::local())
227-
&& !worktree.read(cx).is_single_file()
228-
&& let Some(entry) = relative_cwd
229-
.clone()
230-
.and_then(|relative_cwd| {
231-
worktree
232-
.read(cx)
233-
.entry_for_path(&relative_cwd.join(&relative_path_to_check))
225+
// Normalize the path by joining with cwd if available (handles `.` and `..` segments)
226+
let normalized_path = if path_to_check.path.is_relative() {
227+
relative_cwd.as_ref().and_then(|relative_cwd| {
228+
let joined = relative_cwd
229+
.as_ref()
230+
.as_std_path()
231+
.join(&path_to_check.path);
232+
normalize_lexically(&joined).ok().and_then(|p| {
233+
RelPath::new(&p, PathStyle::local())
234+
.ok()
235+
.map(std::borrow::Cow::into_owned)
236+
})
237+
})
238+
} else {
239+
None
240+
};
241+
let original_path = RelPath::new(&path_to_check.path, PathStyle::local()).ok();
242+
243+
if !worktree.read(cx).is_single_file()
244+
&& let Some(entry) = normalized_path
245+
.as_ref()
246+
.and_then(|p| worktree.read(cx).entry_for_path(p))
247+
.or_else(|| {
248+
original_path
249+
.as_ref()
250+
.and_then(|p| worktree.read(cx).entry_for_path(p.as_ref()))
234251
})
235-
.or_else(|| worktree.read(cx).entry_for_path(&relative_path_to_check))
236252
{
237253
open_target = Some(OpenTarget::Worktree(
238254
PathWithPosition {
@@ -999,8 +1015,6 @@ mod tests {
9991015
}
10001016

10011017
// https://github.com/zed-industries/zed/issues/28339
1002-
// Note: These could all be found by WorktreeExact if we used
1003-
// `fs::normalize_path(&maybe_path)`
10041018
#[gpui::test]
10051019
async fn issue_28339(cx: &mut TestAppContext) {
10061020
test_path_likes!(
@@ -1051,17 +1065,14 @@ mod tests {
10511065
"../foo/bar.txt",
10521066
"/tmp/issue28339/foo/bar.txt",
10531067
"/tmp/issue28339/foo",
1054-
FileSystemBackground
1068+
WorktreeExact
10551069
);
10561070
}
10571071
)
10581072
}
10591073

10601074
// https://github.com/zed-industries/zed/issues/28339
1061-
// Note: These could all be found by WorktreeExact if we used
1062-
// `fs::normalize_path(&maybe_path)`
10631075
#[gpui::test]
1064-
#[should_panic(expected = "Hover target should not be `None`")]
10651076
async fn issue_28339_remote(cx: &mut TestAppContext) {
10661077
test_path_likes!(
10671078
cx,

0 commit comments

Comments
 (0)