gardesk/garfield / 8dc3328

Browse files

fix: Keep Both paste now properly selects and renames file

- Fix directory copy to use unique name (was using original name)
- Make select_by_name more robust: try exact, case-insensitive, path match
- Add fallback status message with F2 hint if auto-select fails
- Show "Pasted as 'name' - press F2 to rename" when select fails
Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
8dc3328fb668b8cbd2ed308add1d2673bcc68147
Parents
38b547c
Tree
98a4f4e

2 changed files

StatusFile+-
M garfield/src/app.rs 27 2
M garfield/src/ui/tab.rs 8 1
garfield/src/app.rsmodified
@@ -1595,10 +1595,24 @@ impl App {
15951595
                 let unique_name = make_unique_name(&pending.dest_dir, &name_str);
15961596
                 let final_dest = pending.dest_dir.join(&unique_name);
15971597
 
1598
+                // Perform the copy/move with the unique name
15981599
                 let result = match pending.operation {
15991600
                     ClipboardOperation::Copy => {
16001601
                         if conflict_file.is_dir() {
1601
-                            garfield::core::copy_path(&conflict_file, &pending.dest_dir)
1602
+                            // For directories, copy then rename to unique name
1603
+                            match garfield::core::copy_path(&conflict_file, &pending.dest_dir) {
1604
+                                Ok(copied_path) => {
1605
+                                    // Rename to unique name if different
1606
+                                    if copied_path != final_dest {
1607
+                                        std::fs::rename(&copied_path, &final_dest)
1608
+                                            .map(|_| final_dest.clone())
1609
+                                            .or(Ok(copied_path))
1610
+                                    } else {
1611
+                                        Ok(copied_path)
1612
+                                    }
1613
+                                }
1614
+                                Err(e) => Err(e),
1615
+                            }
16021616
                         } else {
16031617
                             std::fs::copy(&conflict_file, &final_dest).map(|_| final_dest.clone())
16041618
                         }
@@ -1631,14 +1645,25 @@ impl App {
16311645
                     self.refresh();
16321646
 
16331647
                     // Select the newly pasted file and start rename
1634
-                    if let Some(pane) = self.focused_pane_mut() {
1648
+                    let found = if let Some(pane) = self.focused_pane_mut() {
16351649
                         if let Some(tab) = pane.active_tab_mut() {
16361650
                             // Find and select the file by name
16371651
                             if tab.select_by_name(&unique_name) {
16381652
                                 // Start rename with the suggested name pre-populated
16391653
                                 tab.start_rename_with_text(&unique_name);
1654
+                                true
1655
+                            } else {
1656
+                                false
16401657
                             }
1658
+                        } else {
1659
+                            false
16411660
                         }
1661
+                    } else {
1662
+                        false
1663
+                    };
1664
+
1665
+                    if !found {
1666
+                        self.status_bar.set_status_message(format!("Pasted as '{}' - press F2 to rename", unique_name));
16421667
                     }
16431668
 
16441669
                     // Store remaining conflicts if not apply_to_all
garfield/src/ui/tab.rsmodified
@@ -500,7 +500,14 @@ impl Tab {
500500
     /// Select a file by name. Returns true if found and selected.
501501
     pub fn select_by_name(&mut self, name: &str) -> bool {
502502
         let entries = self.visible_entries();
503
-        if let Some(index) = entries.iter().position(|e| e.name == name) {
503
+        // Try exact match first
504
+        let index = entries.iter().position(|e| e.name == name)
505
+            // Then try case-insensitive match
506
+            .or_else(|| entries.iter().position(|e| e.name.eq_ignore_ascii_case(name)))
507
+            // Then try matching the end of the path
508
+            .or_else(|| entries.iter().position(|e| e.path.ends_with(name)));
509
+
510
+        if let Some(index) = index {
504511
             match self.view_mode {
505512
                 ViewMode::List => self.list_view.set_focused(index),
506513
                 ViewMode::Grid => self.grid_view.set_focused(index),