diff --git a/local/recipes/tui/tlc/source/src/filemanager/external_panelize.rs b/local/recipes/tui/tlc/source/src/filemanager/external_panelize.rs index ca6a9facf5..21f5f1158f 100644 --- a/local/recipes/tui/tlc/source/src/filemanager/external_panelize.rs +++ b/local/recipes/tui/tlc/source/src/filemanager/external_panelize.rs @@ -46,6 +46,10 @@ pub struct ExternalPanelizeDialog { last_error: Option, /// Last stderr captured from the command (for the status line). last_stderr: Option, + /// Previous successfully-run commands, most recent last. + history: Vec, + /// Current position in history when navigating (None = live input). + history_idx: Option, } impl ExternalPanelizeDialog { @@ -59,6 +63,8 @@ impl ExternalPanelizeDialog { command, last_error: None, last_stderr: None, + history: Vec::new(), + history_idx: None, } } @@ -85,13 +91,35 @@ impl ExternalPanelizeDialog { match key { Key::ESCAPE => ExternalPanelizeOutcome::Cancel, Key::ENTER => self.run_command(), + // Up/Down arrow — navigate command history. + k if k.code == 0x2191 || k.code == 0x2193 => { + self.navigate_history(k.code == 0x2191); + ExternalPanelizeOutcome::Running + } _ => { let _ = self.command.handle_key(key); + self.history_idx = None; // exit history mode on typing ExternalPanelizeOutcome::Running } } } + /// Navigate command history. `up` = true means go backward (older + /// entries), false = go forward (newer). + fn navigate_history(&mut self, up: bool) { + if self.history.is_empty() { + return; + } + let new_idx = match self.history_idx { + Some(i) if up => i.saturating_sub(1), + Some(i) => (i + 1).min(self.history.len() - 1), + None if up => self.history.len() - 1, + None => return, // at live input, down does nothing + }; + self.history_idx = Some(new_idx); + self.command.set_text(self.history[new_idx].clone()); + } + /// Run the current command (if non-empty) and translate the result /// into an [`ExternalPanelizeOutcome`]. fn run_command(&mut self) -> ExternalPanelizeOutcome { @@ -113,6 +141,10 @@ impl ExternalPanelizeDialog { self.last_error = Some("command produced no paths".to_string()); ExternalPanelizeOutcome::Empty } else { + // Push to history on success, dedup consecutive entries. + if self.history.last() != Some(&cmd) { + self.history.push(cmd); + } self.last_error = None; ExternalPanelizeOutcome::Apply(paths) } @@ -143,6 +175,11 @@ impl ExternalPanelizeDialog { .split(inner); let hint = Line::from(vec![ + Span::styled("↑↓", Style::default().fg(theme.info)), + Span::styled( + " history ", + Style::default().fg(theme.hidden), + ), Span::styled("Enter", Style::default().fg(theme.warning)), Span::styled( format!(" {} ", crate::locale::t("dialog_action_select")),