Skip to content

Commit

Permalink
Merge pull request #13 from wadackel/fix/wrap-display
Browse files Browse the repository at this point in the history
fix: fixes rendering bug when line wrapping occurs
  • Loading branch information
wadackel authored Jan 14, 2024
2 parents cbfe6ca + 7ec497c commit 77b2347
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 4 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ documentation = "https://docs.rs/promptuity"

[dependencies]
crossterm = "0.27.0"
strip-ansi-escapes = "0.2.0"
thiserror = "1.0.50"
unicode-width = "0.1.11"

Expand Down
34 changes: 34 additions & 0 deletions src/style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
/// [`Color`] re-exports from [`crossterm::style::Color`].
pub use crossterm::style::Color;
use crossterm::style::{Attribute, Attributes, ContentStyle, Stylize};
use unicode_width::UnicodeWidthChar;

/// A styling utility for strings wrapped in [`crossterm::style::ContentStyle`].
#[derive(Debug)]
Expand Down Expand Up @@ -166,3 +167,36 @@ impl<'a, 'b> std::fmt::Display for Symbol<'a, 'b> {
}
}
}

/// A utility function to wrap text at a specified character count.
///
/// # Examples
///
/// ```
/// use promptuity::style::wrap_text;
///
/// let text = "This is a long text that will be wrapped at 10 characters.";
///
/// assert_eq!(wrap_text(text, 10), "This is a \nlong text \nthat will \nbe wrapped\n at 10 cha\nracters.");
/// ```
pub fn wrap_text(input: &str, col: u16) -> String {
let mut output = String::new();
let mut cw = 0;

for (_, c) in input.char_indices() {
let w = c.width().unwrap_or(0);
if c == '\n' {
cw = 0;
output.push(c);
continue;
}
if cw + w > col as usize {
output.push('\n');
cw = 0;
}
output.push(c);
cw += w;
}

output
}
10 changes: 8 additions & 2 deletions src/themes/fancy.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use strip_ansi_escapes::strip_str;

use crate::style::*;
use crate::{
Error, InputCursor, PromptBody, PromptInput, PromptState, RenderSnapshot, Terminal, Theme,
Expand Down Expand Up @@ -244,7 +246,9 @@ impl<W: std::io::Write> Theme<W> for FancyTheme {
output.push_str(&self.fmt_body_active(Color::Cyan, payload.body));
output.push_str(&self.fmt_end(Color::Cyan, true));

self.prev_lines = output.lines().count() as u16;
self.prev_lines = wrap_text(&strip_str(&output), term.size()?.width)
.lines()
.count() as u16;
}

PromptState::Error(msg) | PromptState::Fatal(msg) => {
Expand Down Expand Up @@ -278,7 +282,9 @@ impl<W: std::io::Write> Theme<W> for FancyTheme {
self.fmt_error(msg.clone()),
));

self.prev_lines = output.lines().count() as u16;
self.prev_lines = wrap_text(&strip_str(&output), term.size()?.width)
.lines()
.count() as u16;
}

PromptState::Submit => {
Expand Down
10 changes: 8 additions & 2 deletions src/themes/minimal.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use strip_ansi_escapes::strip_str;

use crate::style::*;
use crate::{Error, InputCursor, PromptBody, PromptInput, PromptState, Terminal, Theme};

Expand Down Expand Up @@ -184,7 +186,9 @@ impl<W: std::io::Write> Theme<W> for MinimalTheme {
output.push_str(&self.fmt_body_active(payload.body));
output.push_str(&self.fmt_hint(payload.hint));

self.prev_lines = output.lines().count() as u16;
self.prev_lines = wrap_text(&strip_str(&output), term.size()?.width)
.lines()
.count() as u16;
}

PromptState::Error(msg) | PromptState::Fatal(msg) => {
Expand All @@ -204,7 +208,9 @@ impl<W: std::io::Write> Theme<W> for MinimalTheme {
output.push_str(&self.fmt_error(msg.clone()));
output.push_str(&self.fmt_hint(payload.hint));

self.prev_lines = output.lines().count() as u16;
self.prev_lines = wrap_text(&strip_str(&output), term.size()?.width)
.lines()
.count() as u16;
}

PromptState::Submit => {
Expand Down

0 comments on commit 77b2347

Please sign in to comment.