diff --git a/crates/project_panel/src/project_panel.rs b/crates/project_panel/src/project_panel.rs index cb62a7f04b..62d5da762a 100644 --- a/crates/project_panel/src/project_panel.rs +++ b/crates/project_panel/src/project_panel.rs @@ -497,6 +497,7 @@ impl ProjectPanel { if let Some((worktree, entry)) = self.selected_sub_entry(cx) { 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_dir = entry.is_dir(); let is_foldable = auto_fold_dirs && self.is_foldable(entry, worktree); @@ -976,6 +977,7 @@ impl ProjectPanel { }) = self.selection { let directory_id; + let new_entry_id = self.resolve_entry(entry_id); if let Some((worktree, expanded_dir_ids)) = self .project .read(cx) @@ -983,7 +985,7 @@ impl ProjectPanel { .zip(self.expanded_dir_ids.get_mut(&worktree_id)) { 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 { if entry.is_dir() { 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) { if let Some((worktree, entry)) = self.selected_sub_entry(cx) { if let Some(parent) = entry.path.parent() { + let worktree = worktree.read(cx); if let Some(parent_entry) = worktree.entry_for_path(parent) { self.selection = Some(SelectedEntry { worktree_id: worktree.id(), @@ -1406,7 +1409,6 @@ impl ProjectPanel { .clipboard .as_ref() .filter(|clipboard| !clipboard.items().is_empty())?; - enum PasteTask { Rename(Task>), Copy(Task>>), @@ -1416,7 +1418,7 @@ impl ProjectPanel { let clip_is_cut = clipboard_entries.is_cut(); for clipboard_entry in clipboard_entries.items() { 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 is_same_worktree = clipboard_entry.worktree_id == worktree_id; 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) { 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) { let abs_path = match &entry.canonical_path { 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() { @@ -1596,7 +1598,7 @@ impl ProjectPanel { if entry.is_dir() { let include_root = self.project.read(cx).visible_worktrees(cx).count() > 1; 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); Arc::from(full_path) } 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 { self.ancestors .get(&id) @@ -1756,12 +1760,12 @@ impl ProjectPanel { fn selected_sub_entry<'a>( &self, cx: &'a AppContext, - ) -> Option<(&'a Worktree, &'a project::Entry)> { + ) -> Option<(Model, &'a project::Entry)> { let (worktree, mut entry) = self.selected_entry_handle(cx)?; - let worktree = worktree.read(cx); let resolved_id = self.resolve_entry(entry.id); if resolved_id != entry.id { + let worktree = worktree.read(cx); entry = worktree.entry_for_id(resolved_id)?; } Some((worktree, entry)) @@ -1885,7 +1889,19 @@ impl ProjectPanel { } auto_folded_ancestors.clear(); 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 { id: NEW_ENTRY_ID, kind: new_entry_kind, @@ -2546,9 +2562,7 @@ impl ProjectPanel { h_flex().h_6().w_full().child(editor.clone()) } else { h_flex().h_6().map(|mut this| { - if let Some(folded_ancestors) = - is_active.then(|| self.ancestors.get(&entry_id)).flatten() - { + if let Some(folded_ancestors) = self.ancestors.get(&entry_id) { let components = Path::new(&file_name) .components() .map(|comp| { @@ -2592,9 +2606,10 @@ impl ProjectPanel { Label::new(component) .single_line() .color(filename_text_color) - .when(index == active_index, |this| { - this.underline(true) - }), + .when( + is_active && index == active_index, + |this| this.underline(true), + ), ); this = this.child(label);