Browse Source

fix space remaining mis calc in cli frame causing tears (#3371)

Jonathan Kelley 6 months ago
parent
commit
95cde59606
1 changed files with 21 additions and 10 deletions
  1. 21 10
      packages/cli/src/serve/output.rs

+ 21 - 10
packages/cli/src/serve/output.rs

@@ -788,7 +788,26 @@ impl Output {
             .saturating_sub(frame_rect.y + frame_rect.height);
 
         // Calculate how many lines we need to push back
-        let to_push = max_scrollback.saturating_sub(remaining_space);
+        // - to_push equals lines_printed when the frame is at the bottom
+        // - to_push is zero when the remaining space is greater/equal than the scrollback (the frame will get pushed naturally)
+        let mut padding = max_scrollback.saturating_sub(remaining_space);
+
+        // The only reliable way we can force the terminal downards is through "insert_before"
+        // If we need to push the terminal down, we'll use this method with the number of lines
+        // Ratatui will handle this rest.
+        // FIXME(jon): eventuallay insert_before will get scroll regions, breaking this, but making the logic here simpler
+        if padding == 0 {
+            terminal.insert_before(remaining_space.min(lines_printed), |_| {})?;
+
+            // Determine what extra padding is remaining after we've shifted the terminal down
+            // this will be the distance between the final line and the top of the frame, only if the
+            // final line has extended into the frame
+            let frame_top = term_size.height - actual_vh_height;
+            let end_y = (frame_rect.y + lines_printed).min(term_size.height);
+            if end_y > frame_top {
+                padding = end_y.saturating_sub(frame_top);
+            }
+        }
 
         // Wipe the viewport clean so it doesn't tear
         crossterm::queue!(
@@ -797,14 +816,6 @@ impl Output {
             crossterm::terminal::Clear(ClearType::FromCursorDown),
         )?;
 
-        // The only reliable way we can force the terminal downards is through "insert_before"
-        // If we need to push the terminal down, we'll use this method with the number of lines
-        // Ratatui will handle this rest.
-        // FIXME(jon): eventually insert_before will get scroll regions, breaking this, but making the logic here simpler
-        if to_push == 0 {
-            terminal.insert_before(lines_printed, |_| {})?;
-        }
-
         // Start printing the log by writing on top of the topmost line
         for (idx, line) in lines.into_iter().enumerate() {
             // Move the cursor to the correct line offset but don't go past the bottom of the terminal
@@ -819,7 +830,7 @@ impl Output {
         }
 
         // Scroll the terminal if we need to
-        for _ in 0..to_push {
+        for _ in 0..padding {
             crossterm::queue!(
                 std::io::stdout(),
                 crossterm::cursor::MoveTo(0, term_size.height - 1),