ratatui-org / ratatui

Rust library that's all about cooking up terminal user interfaces (TUIs) 👨‍🍳🐀
https://ratatui.rs
MIT License
8.82k stars 263 forks source link

fix: render of &str and String doesn't respect area.width #1177

Closed thscharler closed 2 weeks ago

thscharler commented 3 weeks ago

Those two shouldn't write outside the given area I would think.

codecov[bot] commented 3 weeks ago

Codecov Report

All modified and coverable lines are covered by tests :white_check_mark:

Project coverage is 94.3%. Comparing base (d370aa7) to head (f8e5b6c).

Additional details and impacted files ```diff @@ Coverage Diff @@ ## main #1177 +/- ## ===================================== Coverage 94.3% 94.3% ===================================== Files 60 60 Lines 14677 14679 +2 ===================================== + Hits 13841 13843 +2 Misses 836 836 ```

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

matta commented 3 weeks ago

Personally, I'm not a big fan of str implementing Widget. There are many ways to interpret the intent, and it isn't clear what it'll actually do. Because of the way traits show up in rust docs, I'm not sure how to document the behavior.

Should a str Widget behave like a Span with no styling? Or a multi-line thing? What if the Str has newlines? Should the rendering word wrap within the area? It would be good to document the answer.

If a str Widget is basically a Span with no styling it would be nice to find a way to share more of this implementation with Span. See @joshka 's commit yesterday which fixes rendering zero-width characters -> d370aa7. Does that bug apply to Str widgets too? If this is a case it might be better to remove the str Widget impl and instead have an UnstyledSpan widget. People can then write draw(UnstyledSpan(my_str)) if they want to.

thscharler commented 3 weeks ago

Personally, I'm not a big fan of str implementing Widget. There are many ways to interpret the intent, and it isn't clear what it'll actually do. Because of the way traits show up in rust docs, I'm not sure how to document the behavior.

Should a str Widget behave like a Span with no styling? Or a multi-line thing? What if the Str has newlines? Should the rendering word wrap within the area? It would be good to document the answer.

I stumbled upon this implementation, and just tried it. Personally I wouldn't have expected it to handle newlines in any way and form.

But I agree that the behaviour should be documented.

If a str Widget is basically a Span with no styling it would be nice to find a way to share more of this implementation with Span. See @joshka 's commit yesterday which fixes rendering zero-width characters -> d370aa7. Does that bug apply to Str widgets too? If this is a case it might be better to remove the str Widget impl and instead have an UnstyledSpan widget. People can then write draw(UnstyledSpan(my_str)) if they want to.

Probably Buffer::set_string_n() should use the same algorithm as Span.

I looked at that one and wondered why graphemes(true) doesn't handle that case. As far as I understand http://www.unicode.org/reports/tr29/#Extend it shouldn't break at those zero width joiners. Or was it just a case of invalid data?