@@ -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
0 commit comments