project panel: Fix interactions with auto-folded directories (#19723)
Closes https://github.com/zed-industries/zed/issues/19566 Release Notes: - N/A --------- Co-authored-by: Peter Tripp <peter@zed.dev>
This commit is contained in:
parent
6eb6788201
commit
3617873431
1 changed files with 30 additions and 15 deletions
|
@ -497,6 +497,7 @@ impl ProjectPanel {
|
||||||
|
|
||||||
if let Some((worktree, entry)) = self.selected_sub_entry(cx) {
|
if let Some((worktree, entry)) = self.selected_sub_entry(cx) {
|
||||||
let auto_fold_dirs = ProjectPanelSettings::get_global(cx).auto_fold_dirs;
|
let auto_fold_dirs = ProjectPanelSettings::get_global(cx).auto_fold_dirs;
|
||||||
|
let worktree = worktree.read(cx);
|
||||||
let is_root = Some(entry) == worktree.root_entry();
|
let is_root = Some(entry) == worktree.root_entry();
|
||||||
let is_dir = entry.is_dir();
|
let is_dir = entry.is_dir();
|
||||||
let is_foldable = auto_fold_dirs && self.is_foldable(entry, worktree);
|
let is_foldable = auto_fold_dirs && self.is_foldable(entry, worktree);
|
||||||
|
@ -976,6 +977,7 @@ impl ProjectPanel {
|
||||||
}) = self.selection
|
}) = self.selection
|
||||||
{
|
{
|
||||||
let directory_id;
|
let directory_id;
|
||||||
|
let new_entry_id = self.resolve_entry(entry_id);
|
||||||
if let Some((worktree, expanded_dir_ids)) = self
|
if let Some((worktree, expanded_dir_ids)) = self
|
||||||
.project
|
.project
|
||||||
.read(cx)
|
.read(cx)
|
||||||
|
@ -983,7 +985,7 @@ impl ProjectPanel {
|
||||||
.zip(self.expanded_dir_ids.get_mut(&worktree_id))
|
.zip(self.expanded_dir_ids.get_mut(&worktree_id))
|
||||||
{
|
{
|
||||||
let worktree = worktree.read(cx);
|
let worktree = worktree.read(cx);
|
||||||
if let Some(mut entry) = worktree.entry_for_id(entry_id) {
|
if let Some(mut entry) = worktree.entry_for_id(new_entry_id) {
|
||||||
loop {
|
loop {
|
||||||
if entry.is_dir() {
|
if entry.is_dir() {
|
||||||
if let Err(ix) = expanded_dir_ids.binary_search(&entry.id) {
|
if let Err(ix) = expanded_dir_ids.binary_search(&entry.id) {
|
||||||
|
@ -1273,6 +1275,7 @@ impl ProjectPanel {
|
||||||
fn select_parent(&mut self, _: &SelectParent, cx: &mut ViewContext<Self>) {
|
fn select_parent(&mut self, _: &SelectParent, cx: &mut ViewContext<Self>) {
|
||||||
if let Some((worktree, entry)) = self.selected_sub_entry(cx) {
|
if let Some((worktree, entry)) = self.selected_sub_entry(cx) {
|
||||||
if let Some(parent) = entry.path.parent() {
|
if let Some(parent) = entry.path.parent() {
|
||||||
|
let worktree = worktree.read(cx);
|
||||||
if let Some(parent_entry) = worktree.entry_for_path(parent) {
|
if let Some(parent_entry) = worktree.entry_for_path(parent) {
|
||||||
self.selection = Some(SelectedEntry {
|
self.selection = Some(SelectedEntry {
|
||||||
worktree_id: worktree.id(),
|
worktree_id: worktree.id(),
|
||||||
|
@ -1406,7 +1409,6 @@ impl ProjectPanel {
|
||||||
.clipboard
|
.clipboard
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.filter(|clipboard| !clipboard.items().is_empty())?;
|
.filter(|clipboard| !clipboard.items().is_empty())?;
|
||||||
|
|
||||||
enum PasteTask {
|
enum PasteTask {
|
||||||
Rename(Task<Result<CreatedEntry>>),
|
Rename(Task<Result<CreatedEntry>>),
|
||||||
Copy(Task<Result<Option<Entry>>>),
|
Copy(Task<Result<Option<Entry>>>),
|
||||||
|
@ -1416,7 +1418,7 @@ impl ProjectPanel {
|
||||||
let clip_is_cut = clipboard_entries.is_cut();
|
let clip_is_cut = clipboard_entries.is_cut();
|
||||||
for clipboard_entry in clipboard_entries.items() {
|
for clipboard_entry in clipboard_entries.items() {
|
||||||
let new_path =
|
let new_path =
|
||||||
self.create_paste_path(clipboard_entry, self.selected_entry_handle(cx)?, cx)?;
|
self.create_paste_path(clipboard_entry, self.selected_sub_entry(cx)?, cx)?;
|
||||||
let clip_entry_id = clipboard_entry.entry_id;
|
let clip_entry_id = clipboard_entry.entry_id;
|
||||||
let is_same_worktree = clipboard_entry.worktree_id == worktree_id;
|
let is_same_worktree = clipboard_entry.worktree_id == worktree_id;
|
||||||
let relative_worktree_source_path = if !is_same_worktree {
|
let relative_worktree_source_path = if !is_same_worktree {
|
||||||
|
@ -1558,7 +1560,7 @@ impl ProjectPanel {
|
||||||
|
|
||||||
fn reveal_in_finder(&mut self, _: &RevealInFileManager, cx: &mut ViewContext<Self>) {
|
fn reveal_in_finder(&mut self, _: &RevealInFileManager, cx: &mut ViewContext<Self>) {
|
||||||
if let Some((worktree, entry)) = self.selected_sub_entry(cx) {
|
if let Some((worktree, entry)) = self.selected_sub_entry(cx) {
|
||||||
cx.reveal_path(&worktree.abs_path().join(&entry.path));
|
cx.reveal_path(&worktree.read(cx).abs_path().join(&entry.path));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1573,7 +1575,7 @@ impl ProjectPanel {
|
||||||
if let Some((worktree, entry)) = self.selected_sub_entry(cx) {
|
if let Some((worktree, entry)) = self.selected_sub_entry(cx) {
|
||||||
let abs_path = match &entry.canonical_path {
|
let abs_path = match &entry.canonical_path {
|
||||||
Some(canonical_path) => Some(canonical_path.to_path_buf()),
|
Some(canonical_path) => Some(canonical_path.to_path_buf()),
|
||||||
None => worktree.absolutize(&entry.path).ok(),
|
None => worktree.read(cx).absolutize(&entry.path).ok(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let working_directory = if entry.is_dir() {
|
let working_directory = if entry.is_dir() {
|
||||||
|
@ -1596,7 +1598,7 @@ impl ProjectPanel {
|
||||||
if entry.is_dir() {
|
if entry.is_dir() {
|
||||||
let include_root = self.project.read(cx).visible_worktrees(cx).count() > 1;
|
let include_root = self.project.read(cx).visible_worktrees(cx).count() > 1;
|
||||||
let dir_path = if include_root {
|
let dir_path = if include_root {
|
||||||
let mut full_path = PathBuf::from(worktree.root_name());
|
let mut full_path = PathBuf::from(worktree.read(cx).root_name());
|
||||||
full_path.push(&entry.path);
|
full_path.push(&entry.path);
|
||||||
Arc::from(full_path)
|
Arc::from(full_path)
|
||||||
} else {
|
} else {
|
||||||
|
@ -1730,6 +1732,8 @@ impl ProjectPanel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Finds the currently selected subentry for a given leaf entry id. If a given entry
|
||||||
|
/// has no ancestors, the project entry ID that's passed in is returned as-is.
|
||||||
fn resolve_entry(&self, id: ProjectEntryId) -> ProjectEntryId {
|
fn resolve_entry(&self, id: ProjectEntryId) -> ProjectEntryId {
|
||||||
self.ancestors
|
self.ancestors
|
||||||
.get(&id)
|
.get(&id)
|
||||||
|
@ -1756,12 +1760,12 @@ impl ProjectPanel {
|
||||||
fn selected_sub_entry<'a>(
|
fn selected_sub_entry<'a>(
|
||||||
&self,
|
&self,
|
||||||
cx: &'a AppContext,
|
cx: &'a AppContext,
|
||||||
) -> Option<(&'a Worktree, &'a project::Entry)> {
|
) -> Option<(Model<Worktree>, &'a project::Entry)> {
|
||||||
let (worktree, mut entry) = self.selected_entry_handle(cx)?;
|
let (worktree, mut entry) = self.selected_entry_handle(cx)?;
|
||||||
|
|
||||||
let worktree = worktree.read(cx);
|
|
||||||
let resolved_id = self.resolve_entry(entry.id);
|
let resolved_id = self.resolve_entry(entry.id);
|
||||||
if resolved_id != entry.id {
|
if resolved_id != entry.id {
|
||||||
|
let worktree = worktree.read(cx);
|
||||||
entry = worktree.entry_for_id(resolved_id)?;
|
entry = worktree.entry_for_id(resolved_id)?;
|
||||||
}
|
}
|
||||||
Some((worktree, entry))
|
Some((worktree, entry))
|
||||||
|
@ -1885,7 +1889,19 @@ impl ProjectPanel {
|
||||||
}
|
}
|
||||||
auto_folded_ancestors.clear();
|
auto_folded_ancestors.clear();
|
||||||
visible_worktree_entries.push(entry.clone());
|
visible_worktree_entries.push(entry.clone());
|
||||||
if Some(entry.id) == new_entry_parent_id {
|
let precedes_new_entry = if let Some(new_entry_id) = new_entry_parent_id {
|
||||||
|
entry.id == new_entry_id || {
|
||||||
|
self.ancestors.get(&entry.id).map_or(false, |entries| {
|
||||||
|
entries
|
||||||
|
.ancestors
|
||||||
|
.iter()
|
||||||
|
.any(|entry_id| *entry_id == new_entry_id)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
|
if precedes_new_entry {
|
||||||
visible_worktree_entries.push(Entry {
|
visible_worktree_entries.push(Entry {
|
||||||
id: NEW_ENTRY_ID,
|
id: NEW_ENTRY_ID,
|
||||||
kind: new_entry_kind,
|
kind: new_entry_kind,
|
||||||
|
@ -2546,9 +2562,7 @@ impl ProjectPanel {
|
||||||
h_flex().h_6().w_full().child(editor.clone())
|
h_flex().h_6().w_full().child(editor.clone())
|
||||||
} else {
|
} else {
|
||||||
h_flex().h_6().map(|mut this| {
|
h_flex().h_6().map(|mut this| {
|
||||||
if let Some(folded_ancestors) =
|
if let Some(folded_ancestors) = self.ancestors.get(&entry_id) {
|
||||||
is_active.then(|| self.ancestors.get(&entry_id)).flatten()
|
|
||||||
{
|
|
||||||
let components = Path::new(&file_name)
|
let components = Path::new(&file_name)
|
||||||
.components()
|
.components()
|
||||||
.map(|comp| {
|
.map(|comp| {
|
||||||
|
@ -2592,9 +2606,10 @@ impl ProjectPanel {
|
||||||
Label::new(component)
|
Label::new(component)
|
||||||
.single_line()
|
.single_line()
|
||||||
.color(filename_text_color)
|
.color(filename_text_color)
|
||||||
.when(index == active_index, |this| {
|
.when(
|
||||||
this.underline(true)
|
is_active && index == active_index,
|
||||||
}),
|
|this| this.underline(true),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
this = this.child(label);
|
this = this.child(label);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue