diff options
| author | akbash <akbash@herdr.dev> | 2026-09-02 23:19:59 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-09-02 23:19:59 +0300 |
| commit | 45484aab84430ac2b18c7bbf44aba15f2b039677 (patch) | |
| tree | 58f289bf743ed3de0c2179e3d290b17e265e5372 /src/pane | |
| parent | e22cba35ef7b405758097a5f9436aae8fb4caaf0 (diff) | |
fix: include short viewport output in recent reads (#3448)
refs #3444
Co-authored-by: akbash-bot <300245827+akbash-bot@users.noreply.github.com>
Diffstat (limited to 'src/pane')
| -rw-r--r-- | src/pane/terminal.rs | 53 |
1 files changed, 52 insertions, 1 deletions
diff --git a/src/pane/terminal.rs b/src/pane/terminal.rs index df84e5cb..154a9539 100644 --- a/src/pane/terminal.rs +++ b/src/pane/terminal.rs @@ -2807,7 +2807,34 @@ fn ghostty_recent_read_range( if total_rows == 0 || cols == 0 || lines == 0 { return Ok(None); } - let end = total_rows.saturating_sub(1); + + let physical_end = total_rows.saturating_sub(1); + if terminal.active_screen()? != crate::ghostty::ActiveScreen::Primary { + let start = physical_end.saturating_add(1).saturating_sub(lines); + return Ok(Some((start, physical_end, cols))); + } + + let rows = usize::from(terminal.rows()?); + if rows == 0 { + return Ok(None); + } + let viewport_start = total_rows.saturating_sub(rows); + let cursor_row = viewport_start + .saturating_add(usize::from(terminal.cursor_y()?)) + .min(total_rows.saturating_sub(1)); + let mut last_content_row = None; + for row in (viewport_start..total_rows).rev() { + if !ghostty_screen_row(terminal, cols, row as u32)? + .trim() + .is_empty() + { + last_content_row = Some(row); + break; + } + } + let end = last_content_row + .map(|row| row.max(cursor_row)) + .unwrap_or_else(|| total_rows.saturating_sub(1)); let start = end.saturating_add(1).saturating_sub(lines); Ok(Some((start, end, cols))) } @@ -5243,6 +5270,30 @@ mod tests { } #[test] + fn recent_reads_include_viewport_before_scrollback_exists() { + let (tx, _rx) = mpsc::channel(4); + let mut terminal = + crate::ghostty::Terminal::new(20, 20, crate::config::DEFAULT_SCROLLBACK_LIMIT_BYTES) + .unwrap(); + terminal.write(b"hello123"); + let pane = GhosttyPaneTerminal::new(terminal, tx).unwrap(); + + assert_eq!(pane.recent_text(3), "hello123\n"); + assert_eq!(pane.recent_unwrapped_text(3), "hello123"); + } + + #[test] + fn alternate_screen_recent_reads_keep_physical_row_ranges() { + let (tx, _rx) = mpsc::channel(4); + let mut terminal = crate::ghostty::Terminal::new(20, 20, 100).unwrap(); + terminal.write(b"\x1b[?1049hhello123"); + let pane = GhosttyPaneTerminal::new(terminal, tx).unwrap(); + + assert_eq!(pane.recent_text(3), ""); + assert_eq!(pane.recent_unwrapped_text(3), ""); + } + + #[test] fn recent_unwrapped_text_ignores_soft_wraps() { let (tx, _rx) = mpsc::channel(4); let mut terminal = crate::ghostty::Terminal::new(5, 3, 100).unwrap(); |
