diff --git a/tui/Cargo.toml b/tui/Cargo.toml index 40d3c357..b577f349 100644 --- a/tui/Cargo.toml +++ b/tui/Cargo.toml @@ -22,6 +22,7 @@ oneshot = "0.1.8" portable-pty = "0.8.1" ratatui = "0.28.1" tui-term = "0.1.12" +chrono = "0.4.33" temp-dir = "0.1.14" unicode-width = "0.2.0" rand = { version = "0.8.5", optional = true } diff --git a/tui/src/running_command.rs b/tui/src/running_command.rs index 89daa755..785f8835 100644 --- a/tui/src/running_command.rs +++ b/tui/src/running_command.rs @@ -37,6 +37,7 @@ pub struct RunningCommand { writer: Box, /// Only set after the process has ended status: Option, + log_saved_path: Option, scroll_offset: usize, } @@ -78,9 +79,19 @@ impl FloatContent for RunningCommand { .style(Style::default()), ); - Block::default() + let mut block = Block::default() .borders(Borders::ALL) - .title_top(title_line.centered()) + .title_top(title_line.centered()); + + if let Some(log_path) = &self.log_saved_path { + block = + block.title_bottom(Line::from(format!(" Log saved: {} ", log_path)).centered()); + } else { + block = + block.title_bottom(Line::from(" Press 'l' to save command log ").centered()); + } + + block }; // Process the buffer and create the pseudo-terminal widget @@ -109,6 +120,11 @@ impl FloatContent for RunningCommand { KeyCode::PageDown => { self.scroll_offset = self.scroll_offset.saturating_sub(10); } + KeyCode::Char('l') => { + if let Ok(log_path) = self.save_log() { + self.log_saved_path = Some(log_path); + } + } // Pass other key events to the terminal _ => self.handle_passthrough_key_event(key), } @@ -235,6 +251,7 @@ impl RunningCommand { pty_master: pair.master, writer, status: None, + log_saved_path: None, scroll_offset: 0, } } @@ -282,6 +299,20 @@ impl RunningCommand { } } + fn save_log(&self) -> std::io::Result { + let mut log_path = std::env::temp_dir(); + log_path.push(format!( + "linutil_log_{}.log", + chrono::Local::now().format("%Y%m%d_%H%M%S") + )); + + let mut file = std::fs::File::create(&log_path)?; + let buffer = self.buffer.lock().unwrap(); + file.write_all(&buffer)?; + + Ok(log_path.to_string_lossy().into_owned()) + } + /// Convert the KeyEvent to pty key codes, and send them to the virtual terminal fn handle_passthrough_key_event(&mut self, key: &KeyEvent) { let input_bytes = match key.code {