project_panel: Fix appending copy marker for directory at wrong position (#48845)

Bing Wang and Smit Barmase created

Closes #48765 


Release Notes:

- Fixed appends copy marker for copied file in the wrong position of
filename

---------

Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>

Change summary

crates/project_panel/src/project_panel.rs       | 23 ++++++---
crates/project_panel/src/project_panel_tests.rs | 44 +++++++++++++++++-
2 files changed, 57 insertions(+), 10 deletions(-)

Detailed changes

crates/project_panel/src/project_panel.rs 🔗

@@ -3060,16 +3060,25 @@ impl ProjectPanel {
         if target_entry.is_file() || (target_entry.is_dir() && target_entry.id == source.entry_id) {
             new_path.pop();
         }
-        let clipboard_entry_file_name = self
+
+        let source_worktree = self
             .project
             .read(cx)
-            .path_for_entry(source.entry_id, cx)?
-            .path
-            .file_name()?
-            .to_string();
+            .worktree_for_entry(source.entry_id, cx)?;
+        let source_entry = source_worktree.read(cx).entry_for_id(source.entry_id)?;
+
+        let clipboard_entry_file_name = source_entry.path.file_name()?.to_string();
         new_path.push(RelPath::unix(&clipboard_entry_file_name).unwrap());
-        let extension = new_path.extension().map(|s| s.to_string());
-        let file_name_without_extension = new_path.file_stem()?.to_string();
+
+        let (extension, file_name_without_extension) = if source_entry.is_file() {
+            (
+                new_path.extension().map(|s| s.to_string()),
+                new_path.file_stem()?.to_string(),
+            )
+        } else {
+            (None, clipboard_entry_file_name.clone())
+        };
+
         let file_name_len = file_name_without_extension.len();
         let mut disambiguation_range = None;
         let mut ix = 0;

crates/project_panel/src/project_panel_tests.rs 🔗

@@ -1635,7 +1635,10 @@ async fn test_copy_paste_directory(cx: &mut gpui::TestAppContext) {
                     "four.txt": "",
                 }
             },
-            "b": {}
+            "b": {},
+            "d.1.20": {
+                "default.conf": "",
+            }
         }),
     )
     .await;
@@ -1688,6 +1691,7 @@ async fn test_copy_paste_directory(cx: &mut gpui::TestAppContext) {
             "                  three.txt",
             "              one.txt",
             "              two.txt",
+            "    > d.1.20",
         ]
     );
 
@@ -1709,7 +1713,8 @@ async fn test_copy_paste_directory(cx: &mut gpui::TestAppContext) {
             "                  four.txt",
             "                  three.txt",
             "              one.txt",
-            "              two.txt"
+            "              two.txt",
+            "    > d.1.20",
         ]
     );
 
@@ -1732,7 +1737,8 @@ async fn test_copy_paste_directory(cx: &mut gpui::TestAppContext) {
             "                  four.txt",
             "                  three.txt",
             "              one.txt",
-            "              two.txt"
+            "              two.txt",
+            "    > d.1.20",
         ]
     );
 
@@ -1760,8 +1766,40 @@ async fn test_copy_paste_directory(cx: &mut gpui::TestAppContext) {
             "        > inner_dir",
             "          one.txt",
             "          two.txt",
+            "    > d.1.20",
         ]
     );
+
+    select_path(&panel, "root/d.1.20", cx);
+    panel.update_in(cx, |panel, window, cx| {
+        panel.copy(&Default::default(), window, cx);
+        panel.paste(&Default::default(), window, cx);
+    });
+    cx.executor().run_until_parked();
+    assert_eq!(
+        visible_entries_as_strings(&panel, 0..50, cx),
+        &[
+            //
+            "v root",
+            "    > a",
+            "    v b",
+            "        v a",
+            "            v inner_dir",
+            "                  four.txt",
+            "                  three.txt",
+            "              one.txt",
+            "              two.txt",
+            "    v c",
+            "        > a",
+            "        > inner_dir",
+            "          one.txt",
+            "          two.txt",
+            "    v d.1.20",
+            "          default.conf",
+            "    > [EDITOR: 'd.1.20 copy']  <== selected",
+        ],
+        "Dotted directory names should not be split at the dot when disambiguating"
+    );
 }
 
 #[gpui::test]