Fix relative paths not properly resolved in the terminal during cmd-click (#29289)

Closes https://github.com/zed-industries/zed/pull/28342
Closes https://github.com/zed-industries/zed/issues/28339
Fixes
https://github.com/zed-industries/zed/pull/29274#issuecomment-2824794396

Release Notes:

- Fixed relative paths not properly resolved in the terminal during
cmd-click
This commit is contained in:
Kirill Bulatov 2025-04-23 19:36:58 +03:00 committed by GitHub
parent 01bdd170ec
commit ef54b58346
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -115,6 +115,7 @@ pub struct TerminalView {
blinking_paused: bool, blinking_paused: bool,
blink_epoch: usize, blink_epoch: usize,
hover_target_tooltip: Option<String>, hover_target_tooltip: Option<String>,
hover_tooltip_update: Task<()>,
workspace_id: Option<WorkspaceId>, workspace_id: Option<WorkspaceId>,
show_breadcrumbs: bool, show_breadcrumbs: bool,
block_below_cursor: Option<Rc<BlockProperties>>, block_below_cursor: Option<Rc<BlockProperties>>,
@ -197,6 +198,7 @@ impl TerminalView {
blinking_paused: false, blinking_paused: false,
blink_epoch: 0, blink_epoch: 0,
hover_target_tooltip: None, hover_target_tooltip: None,
hover_tooltip_update: Task::ready(()),
workspace_id, workspace_id,
show_breadcrumbs: TerminalSettings::get_global(cx).toolbar.breadcrumbs, show_breadcrumbs: TerminalSettings::get_global(cx).toolbar.breadcrumbs,
block_below_cursor: None, block_below_cursor: None,
@ -844,7 +846,7 @@ fn subscribe_for_terminal_events(
let terminal_events_subscription = cx.subscribe_in( let terminal_events_subscription = cx.subscribe_in(
terminal, terminal,
window, window,
move |this, _, event, window, cx| match event { move |terminal_view, _, event, window, cx| match event {
Event::Wakeup => { Event::Wakeup => {
cx.notify(); cx.notify();
cx.emit(Event::Wakeup); cx.emit(Event::Wakeup);
@ -853,7 +855,7 @@ fn subscribe_for_terminal_events(
} }
Event::Bell => { Event::Bell => {
this.has_bell = true; terminal_view.has_bell = true;
cx.emit(Event::Wakeup); cx.emit(Event::Wakeup);
} }
@ -862,7 +864,7 @@ fn subscribe_for_terminal_events(
TerminalSettings::get_global(cx).blinking, TerminalSettings::get_global(cx).blinking,
TerminalBlink::TerminalControlled TerminalBlink::TerminalControlled
) { ) {
this.blinking_terminal_enabled = *blinking; terminal_view.blinking_terminal_enabled = *blinking;
} }
} }
@ -871,25 +873,46 @@ fn subscribe_for_terminal_events(
} }
Event::NewNavigationTarget(maybe_navigation_target) => { Event::NewNavigationTarget(maybe_navigation_target) => {
this.hover_target_tooltip = match maybe_navigation_target.as_ref() {
maybe_navigation_target None => {
.as_ref() terminal_view.hover_target_tooltip = None;
.and_then(|navigation_target| match navigation_target { terminal_view.hover_tooltip_update = Task::ready(());
MaybeNavigationTarget::Url(url) => Some(url.clone()), }
MaybeNavigationTarget::PathLike(path_like_target) => { Some(MaybeNavigationTarget::Url(url)) => {
let valid_files_to_open_task = possible_open_target( terminal_view.hover_target_tooltip = Some(url.clone());
&workspace, terminal_view.hover_tooltip_update = Task::ready(());
&path_like_target.terminal_dir, }
&path_like_target.maybe_path, Some(MaybeNavigationTarget::PathLike(path_like_target)) => {
cx, let valid_files_to_open_task = possible_open_target(
); &workspace,
Some(match smol::block_on(valid_files_to_open_task)? { &path_like_target.terminal_dir,
OpenTarget::File(path, _) | OpenTarget::Worktree(path, _) => { &path_like_target.maybe_path,
path.to_string(|path| path.to_string_lossy().to_string()) cx,
} );
})
} terminal_view.hover_tooltip_update =
}); cx.spawn(async move |terminal_view, cx| {
let file_to_open = valid_files_to_open_task.await;
terminal_view
.update(cx, |terminal_view, _| match file_to_open {
Some(
OpenTarget::File(path, _)
| OpenTarget::Worktree(path, _),
) => {
terminal_view.hover_target_tooltip =
Some(path.to_string(|path| {
path.to_string_lossy().to_string()
}));
}
None => {
terminal_view.hover_target_tooltip = None;
}
})
.ok();
});
}
}
cx.notify() cx.notify()
} }
@ -897,7 +920,7 @@ fn subscribe_for_terminal_events(
MaybeNavigationTarget::Url(url) => cx.open_url(url), MaybeNavigationTarget::Url(url) => cx.open_url(url),
MaybeNavigationTarget::PathLike(path_like_target) => { MaybeNavigationTarget::PathLike(path_like_target) => {
if this.hover_target_tooltip.is_none() { if terminal_view.hover_target_tooltip.is_none() {
return; return;
} }
let task_workspace = workspace.clone(); let task_workspace = workspace.clone();
@ -1207,9 +1230,12 @@ fn possible_open_target(
let fs = workspace.read(cx).project().read(cx).fs().clone(); let fs = workspace.read(cx).project().read(cx).fs().clone();
cx.background_spawn(async move { cx.background_spawn(async move {
for path_to_check in fs_paths_to_check { for mut path_to_check in fs_paths_to_check {
if let Some(metadata) = fs.metadata(&path_to_check.path).await.ok().flatten() { if let Some(fs_path_to_check) = fs.canonicalize(&path_to_check.path).await.ok() {
return Some(OpenTarget::File(path_to_check, metadata)); if let Some(metadata) = fs.metadata(&fs_path_to_check).await.ok().flatten() {
path_to_check.path = fs_path_to_check;
return Some(OpenTarget::File(path_to_check, metadata));
}
} }
} }