Skip to content

Commit a4bfaa5

Browse files
danielsomerfieldDaniel Somerfield
andauthored
Better behaviour on resize (#675)
* First shot at resolving the resizing issues with terminals * Comment for known bug * Checking the start row repeatedly to see how it affects performance --------- Co-authored-by: Daniel Somerfield <[email protected]>
1 parent 0046da9 commit a4bfaa5

File tree

2 files changed

+22
-24
lines changed

2 files changed

+22
-24
lines changed

src/painting/painter.rs

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ impl Painter {
8282

8383
/// Returns the available lines from the prompt down
8484
pub fn remaining_lines(&self) -> u16 {
85-
self.screen_height() - self.prompt_start_row
85+
self.screen_height().saturating_sub(self.prompt_start_row)
8686
}
8787

8888
/// Sets the prompt origin position and screen size for a new line editor
@@ -151,8 +151,14 @@ impl Painter {
151151
// Marking the painter state as larger buffer to avoid animations
152152
self.large_buffer = required_lines >= screen_height;
153153

154+
// This might not be terribly performant. Testing it out
155+
let is_reset = || match cursor::position() {
156+
Ok(position) => position.1 < self.prompt_start_row,
157+
Err(_) => false,
158+
};
159+
154160
// Moving the start position of the cursor based on the size of the required lines
155-
if self.large_buffer {
161+
if self.large_buffer || is_reset() {
156162
self.prompt_start_row = 0;
157163
} else if required_lines >= remaining_lines {
158164
let extra = required_lines.saturating_sub(remaining_lines);
@@ -400,31 +406,22 @@ impl Painter {
400406

401407
/// Updates prompt origin and offset to handle a screen resize event
402408
pub(crate) fn handle_resize(&mut self, width: u16, height: u16) {
403-
let prev_terminal_size = self.terminal_size;
404-
let prev_prompt_row = self.prompt_start_row;
405-
406409
self.terminal_size = (width, height);
407410

408-
if prev_prompt_row < height
409-
&& height <= prev_terminal_size.1
410-
&& width == prev_terminal_size.0
411-
{
412-
// The terminal got smaller in height but the start of the prompt is still visible
413-
// The width didn't change
414-
return;
411+
// `cursor::position() is blocking and can timeout.
412+
// The question is whether we can afford it. If not, perhaps we should use it in some scenarios but not others
413+
// The problem is trying to calculate this internally doesn't seem to be reliable because terminals might
414+
// have additional text in their buffer that messes with the offset on scroll.
415+
// It seems like it _should_ be ok because it only happens on resize.
416+
417+
// Known bug: on iterm2 and kitty, clearing the screen via CMD-K doesn't reset
418+
// the position. Might need to special-case this.
419+
//
420+
// I assume this is a bug with the position() call but haven't figured that
421+
// out yet.
422+
if let Ok(position) = cursor::position() {
423+
self.prompt_start_row = position.1;
415424
}
416-
417-
// Either:
418-
// - The terminal got larger in height
419-
// - Note: if the terminal doesn't have sufficient history, this will leave a trail
420-
// of previous prompts currently.
421-
// - Note: if the the prompt contains multiple lines, this will leave a trail of
422-
// previous prompts currently.
423-
// - The terminal got smaller in height and the whole prompt is no longer visible
424-
// - Note: if the the prompt contains multiple lines, this will leave a trail of
425-
// previous prompts currently.
426-
// - The width changed
427-
self.prompt_start_row = height.saturating_sub(1);
428425
}
429426

430427
/// Writes `line` to the terminal with a following carriage return and newline

src/painting/prompt_lines.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crate::{
77
use std::borrow::Cow;
88

99
/// Aggregate of prompt and input string used by `Painter`
10+
#[derive(Debug)]
1011
pub(crate) struct PromptLines<'prompt> {
1112
pub(crate) prompt_str_left: Cow<'prompt, str>,
1213
pub(crate) prompt_str_right: Cow<'prompt, str>,

0 commit comments

Comments
 (0)