Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes and improvements to pane context menu #21000

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 38 additions & 14 deletions crates/workspace/src/pane.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ pub struct RevealInProjectPanel {
pub entry_id: Option<u64>,
}

#[derive(Clone, PartialEq, Debug, Deserialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct RevealInFileManager {}

#[derive(Default, PartialEq, Clone, Deserialize)]
pub struct DeploySearch {
#[serde(default)]
Expand All @@ -161,6 +165,7 @@ impl_actions!(
CloseInactiveItems,
ActivateItem,
RevealInProjectPanel,
RevealInFileManager,
DeploySearch,
]
);
Expand Down Expand Up @@ -2212,7 +2217,9 @@ impl Pane {
.read(cx)
.item_for_entry(entry, cx)
.and_then(|item| item.project_path(cx))
.map(|project_path| project_path.path);
.map(|project_path| project_path.path)
.map_or(None, |path| if path.exists() { Some(path) } else { None });
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I followed it down to this

pub fn find_worktree(
&self,
abs_path: &Path,
cx: &AppContext,
) -> Option<(Model<Worktree>, PathBuf)> {
for tree in self.worktrees() {
if let Ok(relative_path) = abs_path.strip_prefix(tree.read(cx).abs_path()) {
return Some((tree.clone(), relative_path.into()));
}
}
None
}

I am not familiar how Worktrees work yet, but it seems that even for a single out-of-project file Worktree is created with the same Path. Meaning this Path::strip_prefix() will nuke whole path and we'll be left with empty string.

I considered checking paths here for equality and returning None if they're equal. This code is pretty low level and I don't know if this would be correct thing to do.

let has_relative_path = relative_path.is_some();
Copy link
Contributor Author

@Poldraunic Poldraunic Nov 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is also sus. when_some() call requires moving value, but the same value is used to check in two different places. I don't know what would be an idiomatic way. Calling clone() would be fine, I guess? But for this check I don't need a value at all.


let entry_id = entry.to_proto();
menu = menu
Expand Down Expand Up @@ -2241,19 +2248,36 @@ impl Pane {
})
.map(pin_tab_entries)
.separator()
.entry(
"Reveal In Project Panel",
Some(Box::new(RevealInProjectPanel {
entry_id: Some(entry_id),
})),
cx.handler_for(&pane, move |pane, cx| {
pane.project.update(cx, |_, cx| {
cx.emit(project::Event::RevealInProjectPanel(
ProjectEntryId::from_proto(entry_id),
))
});
}),
)
.when(has_relative_path, |menu| {
menu.entry(
"Reveal In Project Panel",
Some(Box::new(RevealInProjectPanel {
entry_id: Some(entry_id),
})),
cx.handler_for(&pane, move |pane, cx| {
pane.project.update(cx, |_, cx| {
cx.emit(project::Event::RevealInProjectPanel(
ProjectEntryId::from_proto(entry_id),
))
});
}),
)
})
.when_some(parent_abs_path.clone(), |menu, parent_abs_path| {
let reveal_in_finder_label = if cfg!(target_os = "macos") {
"Reveal in Finder"
} else {
"Reveal in File Manager"
};

menu.entry(
reveal_in_finder_label,
Some(Box::new(RevealInFileManager {})),
cx.handler_for(&pane, move |_, cx| {
cx.reveal_path(&parent_abs_path);
}),
)
})
.when_some(parent_abs_path, |menu, parent_abs_path| {
menu.entry(
"Open in Terminal",
Expand Down
Loading