From 6cfc48de34459b6f54c21d974fea69e41d79bb2d Mon Sep 17 00:00:00 2001 From: FujiApple Date: Tue, 5 Nov 2024 21:50:14 +0800 Subject: [PATCH] feat(tui): add `quit-preserve-screen` key binding --- crates/trippy-tui/src/config/binding.rs | 15 +++++++++++++++ crates/trippy-tui/src/config/file.rs | 2 ++ crates/trippy-tui/src/frontend.rs | 16 +++++++++++++--- crates/trippy-tui/src/frontend/binding.rs | 2 ++ ...tests__output@tui_binding_commands_match.snap | 2 +- trippy-config-sample.toml | 1 + 6 files changed, 34 insertions(+), 4 deletions(-) diff --git a/crates/trippy-tui/src/config/binding.rs b/crates/trippy-tui/src/config/binding.rs index dde1da652..371975fc9 100644 --- a/crates/trippy-tui/src/config/binding.rs +++ b/crates/trippy-tui/src/config/binding.rs @@ -47,6 +47,7 @@ pub struct TuiBindings { pub toggle_as_info: TuiKeyBinding, pub toggle_hop_details: TuiKeyBinding, pub quit: TuiKeyBinding, + pub quit_preserve_screen: TuiKeyBinding, } impl Default for TuiBindings { @@ -98,6 +99,10 @@ impl Default for TuiBindings { toggle_as_info: TuiKeyBinding::new(KeyCode::Char('z')), toggle_hop_details: TuiKeyBinding::new(KeyCode::Char('d')), quit: TuiKeyBinding::new(KeyCode::Char('q')), + quit_preserve_screen: TuiKeyBinding::new_with_modifier( + KeyCode::Char('q'), + KeyModifiers::SHIFT, + ), } } } @@ -151,6 +156,10 @@ impl TuiBindings { (self.toggle_as_info, TuiCommandItem::ToggleASInfo), (self.toggle_hop_details, TuiCommandItem::ToggleHopDetails), (self.quit, TuiCommandItem::Quit), + ( + self.quit_preserve_screen, + TuiCommandItem::QuitPreserveScreen, + ), ] .iter() .fold( @@ -326,6 +335,10 @@ impl From<(HashMap, ConfigBindings)> for TuiBindi .get(&TuiCommandItem::Quit) .or(cfg.quit.as_ref()) .unwrap_or(&Self::default().quit), + quit_preserve_screen: *cmd_items + .get(&TuiCommandItem::QuitPreserveScreen) + .or(cfg.quit_preserve_screen.as_ref()) + .unwrap_or(&Self::default().quit_preserve_screen), } } } @@ -628,4 +641,6 @@ pub enum TuiCommandItem { ToggleHopDetails, /// Quit the application. Quit, + /// Quit the application and preserve the screen. + QuitPreserveScreen, } diff --git a/crates/trippy-tui/src/config/file.rs b/crates/trippy-tui/src/config/file.rs index 25b367a73..acada47e5 100644 --- a/crates/trippy-tui/src/config/file.rs +++ b/crates/trippy-tui/src/config/file.rs @@ -398,6 +398,7 @@ pub struct ConfigBindings { pub toggle_as_info: Option, pub toggle_hop_details: Option, pub quit: Option, + pub quit_preserve_screen: Option, } impl Default for ConfigBindings { @@ -442,6 +443,7 @@ impl Default for ConfigBindings { toggle_as_info: Some(bindings.toggle_as_info), toggle_hop_details: Some(bindings.toggle_hop_details), quit: Some(bindings.quit), + quit_preserve_screen: Some(bindings.quit_preserve_screen), } } } diff --git a/crates/trippy-tui/src/frontend.rs b/crates/trippy-tui/src/frontend.rs index 7dbc0d69e..4fd0fda68 100644 --- a/crates/trippy-tui/src/frontend.rs +++ b/crates/trippy-tui/src/frontend.rs @@ -47,7 +47,7 @@ pub fn run_frontend( let mut app = TuiApp::new(tui_config, resolver, geoip_lookup, traces); let res = run_app(&mut terminal, &mut app); disable_raw_mode()?; - if preserve_screen { + if preserve_screen || matches!(res, Ok(ExitAction::PreserveScreen)) { terminal.set_cursor_position(Position::new(0, terminal.size()?.height))?; terminal.backend_mut().append_lines(1)?; } else { @@ -60,8 +60,16 @@ pub fn run_frontend( Ok(()) } +/// The exit action to take when the frontend exits. +enum ExitAction { + /// Exit the frontend normally. + Normal, + /// Preserve the screen on exit. + PreserveScreen, +} + #[allow(clippy::too_many_lines, clippy::cognitive_complexity)] -fn run_app(terminal: &mut Terminal, app: &mut TuiApp) -> io::Result<()> { +fn run_app(terminal: &mut Terminal, app: &mut TuiApp) -> io::Result { loop { if app.frozen_start.is_none() { app.snapshot_trace_data(); @@ -221,7 +229,9 @@ fn run_app(terminal: &mut Terminal, app: &mut TuiApp) -> io::Resu } else if bindings.toggle_hop_details.check(key) { app.toggle_hop_details(); } else if bindings.quit.check(key) || CTRL_C.check(key) { - return Ok(()); + return Ok(ExitAction::Normal); + } else if bindings.quit_preserve_screen.check(key) { + return Ok(ExitAction::PreserveScreen); } } } diff --git a/crates/trippy-tui/src/frontend/binding.rs b/crates/trippy-tui/src/frontend/binding.rs index 8e0189b98..f74aea421 100644 --- a/crates/trippy-tui/src/frontend/binding.rs +++ b/crates/trippy-tui/src/frontend/binding.rs @@ -43,6 +43,7 @@ pub struct Bindings { pub toggle_as_info: KeyBinding, pub toggle_hop_details: KeyBinding, pub quit: KeyBinding, + pub quit_preserve_screen: KeyBinding, } impl From for Bindings { @@ -85,6 +86,7 @@ impl From for Bindings { toggle_as_info: KeyBinding::from(value.toggle_as_info), toggle_hop_details: KeyBinding::from(value.toggle_hop_details), quit: KeyBinding::from(value.quit), + quit_preserve_screen: KeyBinding::from(value.quit_preserve_screen), } } } diff --git a/crates/trippy-tui/tests/resources/snapshots/trippy_tui__print__tests__output@tui_binding_commands_match.snap b/crates/trippy-tui/tests/resources/snapshots/trippy_tui__print__tests__output@tui_binding_commands_match.snap index 21d0a648a..01e183af1 100644 --- a/crates/trippy-tui/tests/resources/snapshots/trippy_tui__print__tests__output@tui_binding_commands_match.snap +++ b/crates/trippy-tui/tests/resources/snapshots/trippy_tui__print__tests__output@tui_binding_commands_match.snap @@ -1,4 +1,4 @@ --- source: crates/trippy-tui/src/print.rs --- -TUIbindingcommands:toggle-help,toggle-help-alt,toggle-settings,toggle-settings-tui,toggle-settings-trace,toggle-settings-dns,toggle-settings-geoip,toggle-settings-bindings,toggle-settings-theme,toggle-settings-columns,next-hop,previous-hop,next-trace,previous-trace,next-hop-address,previous-hop-address,address-mode-ip,address-mode-host,address-mode-both,toggle-freeze,toggle-chart,toggle-map,toggle-flows,toggle-privacy,expand-privacy,contract-privacy,expand-hosts,expand-hosts-max,contract-hosts,contract-hosts-min,chart-zoom-in,chart-zoom-out,clear-trace-data,clear-dns-cache,clear-selection,toggle-as-info,toggle-hop-details,quit +TUIbindingcommands:toggle-help,toggle-help-alt,toggle-settings,toggle-settings-tui,toggle-settings-trace,toggle-settings-dns,toggle-settings-geoip,toggle-settings-bindings,toggle-settings-theme,toggle-settings-columns,next-hop,previous-hop,next-trace,previous-trace,next-hop-address,previous-hop-address,address-mode-ip,address-mode-host,address-mode-both,toggle-freeze,toggle-chart,toggle-map,toggle-flows,toggle-privacy,expand-privacy,contract-privacy,expand-hosts,expand-hosts-max,contract-hosts,contract-hosts-min,chart-zoom-in,chart-zoom-out,clear-trace-data,clear-dns-cache,clear-selection,toggle-as-info,toggle-hop-details,quit,quit-preserve-screen diff --git a/trippy-config-sample.toml b/trippy-config-sample.toml index 34439c79f..4e58b4de5 100644 --- a/trippy-config-sample.toml +++ b/trippy-config-sample.toml @@ -424,3 +424,4 @@ clear-selection = "esc" toggle-as-info = "z" toggle-hop-details = "d" quit = "q" +quit-preserve-screen = "shift+q"