diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-07-24 04:00:13 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-07-24 04:00:13 +0300 |
| commit | c0fb777ed7c7950c6a2f397113c1842c2e679306 (patch) | |
| tree | 56a1b58314e292433946c1eed5c025abb832595f /src/pane/terminal/windows_recent_fallback.rs | |
| parent | e608a75159fc5cca70485d83ffb8ee681c9da385 (diff) | |
fix: report truncated pane reads
refs #1717
Diffstat (limited to 'src/pane/terminal/windows_recent_fallback.rs')
| -rw-r--r-- | src/pane/terminal/windows_recent_fallback.rs | 50 |
1 files changed, 33 insertions, 17 deletions
diff --git a/src/pane/terminal/windows_recent_fallback.rs b/src/pane/terminal/windows_recent_fallback.rs index c9a02f67..caa3b9f7 100644 --- a/src/pane/terminal/windows_recent_fallback.rs +++ b/src/pane/terminal/windows_recent_fallback.rs @@ -1,4 +1,4 @@ -use super::{ghostty_line_from_cells, GhosttyPaneCore}; +use super::{ghostty_line_from_cells, GhosttyPaneCore, TerminalReadSnapshot}; const CACHE_LINES: usize = 2000; @@ -44,9 +44,13 @@ pub(super) fn update(core: &mut GhosttyPaneCore) { core.recent_fallback.usable = true; } -pub(super) fn recent_text(core: &GhosttyPaneCore, lines: usize, unwrap: bool) -> String { +pub(super) fn recent_text( + core: &GhosttyPaneCore, + lines: usize, + unwrap: bool, +) -> TerminalReadSnapshot { if !primary_screen_active(core) { - return String::new(); + return TerminalReadSnapshot::default(); } if unwrap { unwrapped_text(core, lines) @@ -62,9 +66,9 @@ fn primary_screen_active(core: &GhosttyPaneCore) -> bool { ) } -fn wrapped_text(core: &GhosttyPaneCore, lines: usize) -> String { +fn wrapped_text(core: &GhosttyPaneCore, lines: usize) -> TerminalReadSnapshot { if !core.recent_fallback.usable { - return String::new(); + return TerminalReadSnapshot::default(); } let rows: Vec<&str> = core .recent_fallback @@ -72,16 +76,24 @@ fn wrapped_text(core: &GhosttyPaneCore, lines: usize) -> String { .iter() .map(|line| line.text.as_str()) .collect(); - cache_text(&rows, lines) + TerminalReadSnapshot { + text: cache_text(&rows, lines), + truncated: rows.len() > lines, + } } -fn unwrapped_text(core: &GhosttyPaneCore, lines: usize) -> String { +fn unwrapped_text(core: &GhosttyPaneCore, lines: usize) -> TerminalReadSnapshot { if !core.recent_fallback.usable { - return String::new(); + return TerminalReadSnapshot::default(); } - let unwrapped = unwrap_render_lines(&core.recent_fallback.rows); + let rendered_rows = &core.recent_fallback.rows; + let start = rendered_rows.len().saturating_sub(lines); + let unwrapped = unwrap_render_lines(&rendered_rows[start..]); let rows: Vec<&str> = unwrapped.iter().map(String::as_str).collect(); - cache_text(&rows, lines) + TerminalReadSnapshot { + text: cache_text(&rows, rows.len()), + truncated: rendered_rows.len() > lines, + } } fn viewport_is_at_bottom(core: &GhosttyPaneCore) -> bool { @@ -298,8 +310,8 @@ mod tests { pane.process_pty_bytes(pane_id, 0, b"new output\r\n", &tx); let core = pane.core.lock().unwrap(); - assert_eq!(recent_text(&core, 3, false), ""); - assert_eq!(recent_text(&core, 3, true), ""); + assert_eq!(recent_text(&core, 3, false).text, ""); + assert_eq!(recent_text(&core, 3, true).text, ""); } #[test] @@ -311,12 +323,12 @@ mod tests { pane.seed_history_ansi("seeded history\r\n"); let core = pane.core.lock().unwrap(); - assert!(recent_text(&core, 3, false).contains("seeded history")); - assert!(recent_text(&core, 3, true).contains("seeded history")); + assert!(recent_text(&core, 3, false).text.contains("seeded history")); + assert!(recent_text(&core, 3, true).text.contains("seeded history")); } #[test] - fn recent_ansi_unwrapped_uses_unwrapped_render_cache() { + fn recent_ansi_unwrapped_limits_rendered_rows_before_unwrapping() { let (tx, _rx) = mpsc::channel(4); let terminal = crate::ghostty::Terminal::new(40, 3, 1024).unwrap(); let pane = GhosttyPaneTerminal::new(terminal, tx).unwrap(); @@ -324,13 +336,17 @@ mod tests { { let mut core = pane.core.lock().unwrap(); core.recent_fallback.rows = vec![ + rendered_line("older", false, false), rendered_line("wrapped", true, false), rendered_line("rows", false, true), + rendered_line("last", false, false), ]; core.recent_fallback.usable = true; } - assert_eq!(pane.recent_ansi(2), "wrapped\nrows\n"); - assert_eq!(pane.recent_unwrapped_ansi(2), "wrappedrows\n"); + let snapshot = pane.recent_unwrapped_ansi_snapshot(3); + assert_eq!(snapshot.text, "wrappedrows\nlast\n"); + assert!(snapshot.truncated); + assert_eq!(pane.recent_ansi(3), "wrapped\nrows\nlast\n"); } } |
