mirror of
https://github.com/nushell/reedline.git
synced 2024-09-11 15:55:50 +03:00
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 <daniel.somerfield@hatchdata.com>
This commit is contained in:
parent
0046da98b5
commit
a4bfaa512b
@ -82,7 +82,7 @@ impl Painter {
|
||||
|
||||
/// Returns the available lines from the prompt down
|
||||
pub fn remaining_lines(&self) -> u16 {
|
||||
self.screen_height() - self.prompt_start_row
|
||||
self.screen_height().saturating_sub(self.prompt_start_row)
|
||||
}
|
||||
|
||||
/// Sets the prompt origin position and screen size for a new line editor
|
||||
@ -151,8 +151,14 @@ impl Painter {
|
||||
// Marking the painter state as larger buffer to avoid animations
|
||||
self.large_buffer = required_lines >= screen_height;
|
||||
|
||||
// This might not be terribly performant. Testing it out
|
||||
let is_reset = || match cursor::position() {
|
||||
Ok(position) => position.1 < self.prompt_start_row,
|
||||
Err(_) => false,
|
||||
};
|
||||
|
||||
// Moving the start position of the cursor based on the size of the required lines
|
||||
if self.large_buffer {
|
||||
if self.large_buffer || is_reset() {
|
||||
self.prompt_start_row = 0;
|
||||
} else if required_lines >= remaining_lines {
|
||||
let extra = required_lines.saturating_sub(remaining_lines);
|
||||
@ -400,31 +406,22 @@ impl Painter {
|
||||
|
||||
/// Updates prompt origin and offset to handle a screen resize event
|
||||
pub(crate) fn handle_resize(&mut self, width: u16, height: u16) {
|
||||
let prev_terminal_size = self.terminal_size;
|
||||
let prev_prompt_row = self.prompt_start_row;
|
||||
|
||||
self.terminal_size = (width, height);
|
||||
|
||||
if prev_prompt_row < height
|
||||
&& height <= prev_terminal_size.1
|
||||
&& width == prev_terminal_size.0
|
||||
{
|
||||
// The terminal got smaller in height but the start of the prompt is still visible
|
||||
// The width didn't change
|
||||
return;
|
||||
}
|
||||
// `cursor::position() is blocking and can timeout.
|
||||
// The question is whether we can afford it. If not, perhaps we should use it in some scenarios but not others
|
||||
// The problem is trying to calculate this internally doesn't seem to be reliable because terminals might
|
||||
// have additional text in their buffer that messes with the offset on scroll.
|
||||
// It seems like it _should_ be ok because it only happens on resize.
|
||||
|
||||
// Either:
|
||||
// - The terminal got larger in height
|
||||
// - Note: if the terminal doesn't have sufficient history, this will leave a trail
|
||||
// of previous prompts currently.
|
||||
// - Note: if the the prompt contains multiple lines, this will leave a trail of
|
||||
// previous prompts currently.
|
||||
// - The terminal got smaller in height and the whole prompt is no longer visible
|
||||
// - Note: if the the prompt contains multiple lines, this will leave a trail of
|
||||
// previous prompts currently.
|
||||
// - The width changed
|
||||
self.prompt_start_row = height.saturating_sub(1);
|
||||
// Known bug: on iterm2 and kitty, clearing the screen via CMD-K doesn't reset
|
||||
// the position. Might need to special-case this.
|
||||
//
|
||||
// I assume this is a bug with the position() call but haven't figured that
|
||||
// out yet.
|
||||
if let Ok(position) = cursor::position() {
|
||||
self.prompt_start_row = position.1;
|
||||
}
|
||||
}
|
||||
|
||||
/// Writes `line` to the terminal with a following carriage return and newline
|
||||
|
@ -7,6 +7,7 @@ use crate::{
|
||||
use std::borrow::Cow;
|
||||
|
||||
/// Aggregate of prompt and input string used by `Painter`
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct PromptLines<'prompt> {
|
||||
pub(crate) prompt_str_left: Cow<'prompt, str>,
|
||||
pub(crate) prompt_str_right: Cow<'prompt, str>,
|
||||
|
Loading…
Reference in New Issue
Block a user