Add a right-click context menu to file rows

Renaming, archiving and deleting a file all lived in buttons under the
list, and all of them required selecting the file first. The same
operations are now on the row itself: right-click a file for Rename,
Copy path, Archive and Delete.

The menu records what was picked rather than acting on it, because the
list is drawn inside a closure still borrowing `self` — the same
deferred pattern the click and drag-drop handling already use. Right-
clicking selects the row first, so the menu always acts on the file you
clicked; selecting is a no-op when it is already current, so this cannot
reload the buffer out from under an unsaved edit.

Rename opens a focused dialog with the path pre-filled, and stays open
if the name is rejected so a clash does not cost what was typed;
rename_selected reports success for that. Delete asks first.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GBWj9TphFMCoh7VHaSRnvQ
This commit is contained in:
landon
2026-09-07 11:57:49 -05:00
parent 70046b0382
commit aa050cf411
4 changed files with 262 additions and 7 deletions
+18
View File
@@ -196,6 +196,13 @@ pub struct App {
new_name: String,
rename_input: String,
pending_delete: bool,
/// Whether the rename dialog opened from a file row's context menu is up.
show_rename: bool,
/// Set alongside `show_rename` so the dialog's box takes focus on the frame
/// it appears, rather than needing a click before you can type.
rename_focus: bool,
/// Whether the delete confirmation opened from that menu is up.
confirm_delete: bool,
status: String,
show_log: bool,
git_log: String,
@@ -361,6 +368,9 @@ impl App {
new_name: String::new(),
rename_input: String::new(),
pending_delete: false,
show_rename: false,
rename_focus: false,
confirm_delete: false,
status: String::new(),
show_log: false,
git_log: String::new(),
@@ -516,6 +526,14 @@ impl eframe::App for App {
self.template_settings_window(ctx);
}
if self.show_rename {
self.rename_window(ctx);
}
if self.confirm_delete {
self.confirm_delete_window(ctx);
}
if self.show_new_project {
self.new_project_window(ctx);
}