bubbles icon indicating copy to clipboard operation
bubbles copied to clipboard

feat(viewport): auto-wrap

Open kyu08 opened this issue 1 year ago • 13 comments

Resolves #479

The issue I experienced

I found that example app of viewport can't render properly if content has very long line.

If the content using in the example's was like below in the toggle, even if the content was scrolled to the bottom, the example can't render all contents. The content of last line(This is the last line.) is not rendered.

Content for reproduce

## test
test
## test
test
## test
test
## test
test
## test
test
## test
test
## test
test
## test
test
## test
test
## test
test
## test
test
## test
test
## test
test
## test
test
## test
test
## test
test
## test
test
## test
test
## test
test
## test
test
## test
test
## test
test
## test
test
## test
test
## test
test
## test
test

012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789

This is the last line.
image

What this PR fixes

This PR fixes the problem to fix height calculation method.

Without this change a very long line that exceeds width is not considered. New method considers it.

image

kyu08 avatar Aug 09 '24 09:08 kyu08

@caarlos0 [Gentle ping] If you have time to re-review this PR, please review my correction. If commits should be squashed I will do it. Thank you.

kyu08 avatar Aug 22 '24 02:08 kyu08

Hey @kyu08 thanks so much for this contribution. It looks good and all the tests are passing. Thank you as well for including a test with the changes, makes this PR super easy to review.

I just tried running some bubble tea examples that use viewport and found some issues. If you run the glamour example, then resize to a smaller window and scroll down, you'll see that there's a lot of extra whitespace. If you keep scrolling down you get a runtime error: slice bounds out of range [:41] with capacity 40.

Let me know if you're able to reproduce that issue :)

bashbunni avatar Aug 22 '24 16:08 bashbunni

Hey @kyu08 thanks so much for this contribution. It looks good and all the tests are passing. Thank you as well for including a test with the changes, makes this PR super easy to review.

Thanks for your kind words! I am also grateful to maintainers like you for making this project available.

Also, thank you for finding the bug.

If you run the glamour example, then resize to a smaller window and scroll down, you'll see that there's a lot of extra whitespace. If you keep scrolling down you get a runtime error: slice bounds out of range [:41] with capacity 40.

I fixed that issue ( eaff7e7f766c ) and the another issue that percentage counter is not working properly.( 5e1cef42305e )

I noticed that we should not use m.lines, but rather the lines that are actually displayed. As I wrote as code comment, if there is a line that is longer than the width, it will be displayed in multiple lines. But I didn't consider it at the start of this PR.

Could you re-review them please? (If my changes are okey, I can squash commits if needed.)

kyu08 avatar Aug 25 '24 16:08 kyu08

SetContent also needed to be fixed. eb7b9d5a0e1f

kyu08 avatar Aug 26 '24 01:08 kyu08

@bashbunni Hi, I would be very appreciate if you rereview my changes when you get a chance. Thank you.

kyu08 avatar Sep 04 '24 08:09 kyu08

Hey @kyu08 will do when I'm able to give some attention to bubbles in the next little bit. Usually I alternate focuses on a weekly basis, so will let you know when I'm on an open source maintenance week :D

bashbunni avatar Sep 05 '24 18:09 bashbunni

That said, I'm very eager to include this in v0.20.0, so will definitely be taking a look when I can

bashbunni avatar Sep 05 '24 18:09 bashbunni

@bashbunni Thanks so much for fixing naming and updating logics. It looks better than mine.

The tests failing seems like fixed by this:

diff --git a/viewport/viewport.go b/viewport/viewport.go
index 05e93ae..332134b 100644
--- a/viewport/viewport.go
+++ b/viewport/viewport.go
@@ -423,7 +423,7 @@ func wrap(lines []string, width int) []string {
 		// wrap lines (handles lines that could not be word wrapped)
 		wrap := ansi.Hardwrap(wrapWords, width, true)
 		// split string by new lines
-		wrapLines := strings.Split(strings.TrimSpace(wrap), "\n")
+		wrapLines := strings.Split(wrap, "\n")
 
 		out = append(out, wrapLines...)
 	}
diff --git a/viewport/viewport_test.go b/viewport/viewport_test.go
index 0dc7974..3863255 100644
--- a/viewport/viewport_test.go
+++ b/viewport/viewport_test.go
@@ -31,6 +31,11 @@ func TestWrap(t *testing.T) {
 			width: 12,
 			want:  []string{"hello bob, I", "like yogurt", "in the", "mornings."},
 		},
+		"whitespace of head of line is preserved": {
+			lines: []string{" aaa", "bbb", "ccc"},
+			width: 5,
+			want:  []string{" aaa", "bbb", "ccc"},
+		},
 	}

How about deleting strings.TrimSpace(wrap) like above? I think there is no problem because ansi.Wordwrap and ansi.Hardwrap trims spaces of tail of lines.

kyu08 avatar Sep 08 '24 09:09 kyu08

@bashbunni I pushed a diff I suggested and verify that unit tests have passed on my machine by running go test ./....

If you have a moment, could you please check this pr again? If there are no problems, I would appreciate it if you could merge this PR. Thank you.

kyu08 avatar Oct 12 '24 04:10 kyu08

Running into this when using glamour to render. Looking forward to the fix.

josebalius avatar Oct 14 '24 16:10 josebalius

Thanks for your attention to this one @kyu and for your keen attention to detail @bashbunni.

A couple quick questions:

  1. Does this PR wrap long lines at render time?
  2. Does manually wrapping long lines outside of this PR solve the issue?

meowgorithm avatar Oct 14 '24 18:10 meowgorithm

What I’m getting at is that first and foremost, it sounds like this issue can be solved by wrapping or truncating manually with Lip Gloss (iirc, historically this burden was on the user). I think we do indeed want to offer built-in options for the viewport not to accidentally break, however we probably want to offer a few different options as wrapping won’t always be want the user wants.

meowgorithm avatar Oct 14 '24 18:10 meowgorithm

Also, in the short term @kyu08 and @josebalius it's trivial auto-wrap text in your current implementations: see https://github.com/charmbracelet/bubbletea/pull/1185 for an example.

@meowgorithm thank you! ❤️

josebalius avatar Oct 15 '24 11:10 josebalius

Hey @kyu08 thank you so much for this contribution! Given that viewport is used in a wide variety of cases where it's rendering more than just text, this feature would be breaking for a lot of users.

Given that, we are going to close this PR, but will work on improving the UI of viewport in a non-breaking way. That will likely be with better truncation and potentially horizontal scrolling.

Thank you for your support 🫶

bashbunni avatar Dec 04 '24 19:12 bashbunni

@meowgorithm I'm sorry that I didn't reply to your review. I thought I have to take time to investigate scope to influenced by this PR to reply. But I could not take enough time.

@bashbunni OK. I have no objection to closing this PR. 👍 I understand that this PR may affect to use case like rendering elements other than text.

Thanks for reviewing!

kyu08 avatar Dec 05 '24 07:12 kyu08