diff --git a/local/recipes/tui/tlc/source/src/config.rs b/local/recipes/tui/tlc/source/src/config.rs index 69b338e7b6..ef6f1846e0 100644 --- a/local/recipes/tui/tlc/source/src/config.rs +++ b/local/recipes/tui/tlc/source/src/config.rs @@ -306,6 +306,8 @@ pub struct RuntimeConfig { pub auto_save_setup: Option, /// Require an explicit confirmation before delete. pub safe_delete: Option, + /// Require an explicit confirmation before executing commands. + pub safe_execute: Option, /// Pause and display output after a shell command finishes. pub pause_after_run: Option, } @@ -326,6 +328,7 @@ impl Default for RuntimeConfig { verbose_ops: Some(false), auto_save_setup: Some(false), safe_delete: Some(true), + safe_execute: Some(false), pause_after_run: Some(false), } } diff --git a/local/recipes/tui/tlc/source/src/filemanager/dialog_ops.rs b/local/recipes/tui/tlc/source/src/filemanager/dialog_ops.rs index eaab62a8c8..bf0798d0ae 100644 --- a/local/recipes/tui/tlc/source/src/filemanager/dialog_ops.rs +++ b/local/recipes/tui/tlc/source/src/filemanager/dialog_ops.rs @@ -985,6 +985,7 @@ Err(e) => self.status.set_error(format!("view: {e}")), | Some(DialogState::Encoding(_)) | Some(DialogState::Connection(_)) | Some(DialogState::Sort(_)) + | Some(DialogState::Confirm(_)) | Some(DialogState::Progress(_)) => { // These are closed by their own apply_*_outcome // helpers before this function is called; they @@ -1420,6 +1421,7 @@ fn dialog_label(d: &DialogState) -> String { DialogState::Encoding(_) => "Display encoding".to_string(), DialogState::Connection(_) => "Network connection".to_string(), DialogState::Sort(_) => "Sort order".to_string(), + DialogState::Confirm(_) => "Confirmation".to_string(), DialogState::Progress(_) => "Progress".to_string(), } } \ No newline at end of file diff --git a/local/recipes/tui/tlc/source/src/filemanager/dispatch.rs b/local/recipes/tui/tlc/source/src/filemanager/dispatch.rs index 7ddc7d0e3a..4fcbd90ff4 100644 --- a/local/recipes/tui/tlc/source/src/filemanager/dispatch.rs +++ b/local/recipes/tui/tlc/source/src/filemanager/dispatch.rs @@ -951,6 +951,29 @@ impl FileManager { } consumed = true; } + Some(DialogState::Confirm(d)) => { + use crate::filemanager::confirm_dialog::ConfirmResult; + let r = d.handle_key(key); + match r { + ConfirmResult::Confirm(settings) => { + self.runtime.safe_delete = Some(settings.confirm_delete); + self.runtime.safe_execute = Some(settings.confirm_execute); + self.status.set_message(format!( + "Confirm: delete={} overwrite={} execute={} exit={}", + if settings.confirm_delete { "ON" } else { "off" }, + if settings.confirm_overwrite { "ON" } else { "off" }, + if settings.confirm_execute { "ON" } else { "off" }, + if settings.confirm_exit { "ON" } else { "off" }, + )); + self.dialog = None; + } + ConfirmResult::Cancel => { + self.dialog = None; + } + ConfirmResult::Running => {} + } + consumed = true; + } None => return false, } // Apply captured outcomes. diff --git a/local/recipes/tui/tlc/source/src/filemanager/mod.rs b/local/recipes/tui/tlc/source/src/filemanager/mod.rs index 6654960294..4df4341eee 100644 --- a/local/recipes/tui/tlc/source/src/filemanager/mod.rs +++ b/local/recipes/tui/tlc/source/src/filemanager/mod.rs @@ -356,6 +356,8 @@ pub enum DialogState { Connection(Box), /// Alt-Shift-T — sort order dialog. Sort(Box), + /// F9 → Options → Confirmation — per-operation confirm toggles. + Confirm(Box), /// F5/F6/F8 — live progress dialog for background copy/move/delete. Progress(Box), } @@ -418,6 +420,7 @@ impl DialogState { DialogState::Encoding(_) => false, DialogState::Connection(_) => false, DialogState::Sort(_) => false, + DialogState::Confirm(_) => false, DialogState::Progress(_) => false, } } diff --git a/local/recipes/tui/tlc/source/src/filemanager/render.rs b/local/recipes/tui/tlc/source/src/filemanager/render.rs index 9ddb1dbd35..e26bef54c5 100644 --- a/local/recipes/tui/tlc/source/src/filemanager/render.rs +++ b/local/recipes/tui/tlc/source/src/filemanager/render.rs @@ -180,6 +180,7 @@ impl FileManager { DialogState::Encoding(d) => d.render(frame, dialog_area, &self.theme), DialogState::Connection(d) => d.render(frame, dialog_area, &self.theme), DialogState::Sort(d) => d.render(frame, dialog_area, &self.theme), + DialogState::Confirm(d) => d.render(frame, dialog_area, &self.theme), DialogState::Progress(d) => d.render(frame, dialog_area, &self.theme), } }