Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better behaviour on resize #675

Merged
merged 3 commits into from
Dec 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 21 additions & 24 deletions src/painting/painter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@

/// 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)

Check warning on line 85 in src/painting/painter.rs

View check run for this annotation

Codecov / codecov/patch

src/painting/painter.rs#L85

Added line #L85 was not covered by tests
}

/// Sets the prompt origin position and screen size for a new line editor
Expand Down Expand Up @@ -151,8 +151,14 @@
// 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,
};

Check warning on line 158 in src/painting/painter.rs

View check run for this annotation

Codecov / codecov/patch

src/painting/painter.rs#L154-L158

Added lines #L154 - L158 were not covered by tests

// 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() {

Check warning on line 161 in src/painting/painter.rs

View check run for this annotation

Codecov / codecov/patch

src/painting/painter.rs#L161

Added line #L161 was not covered by tests
self.prompt_start_row = 0;
} else if required_lines >= remaining_lines {
let extra = required_lines.saturating_sub(remaining_lines);
Expand Down Expand Up @@ -400,31 +406,22 @@

/// 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.

// 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;

Check warning on line 423 in src/painting/painter.rs

View check run for this annotation

Codecov / codecov/patch

src/painting/painter.rs#L422-L423

Added lines #L422 - L423 were not covered by tests
}

// 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);
}

/// Writes `line` to the terminal with a following carriage return and newline
Expand Down
1 change: 1 addition & 0 deletions src/painting/prompt_lines.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use std::borrow::Cow;

/// Aggregate of prompt and input string used by `Painter`
#[derive(Debug)]

Check warning on line 10 in src/painting/prompt_lines.rs

View check run for this annotation

Codecov / codecov/patch

src/painting/prompt_lines.rs#L10

Added line #L10 was not covered by tests
pub(crate) struct PromptLines<'prompt> {
pub(crate) prompt_str_left: Cow<'prompt, str>,
pub(crate) prompt_str_right: Cow<'prompt, str>,
Expand Down