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

viewport: wrapped lines keep style until resized #681

Open
bevicted opened this issue Nov 27, 2024 · 3 comments
Open

viewport: wrapped lines keep style until resized #681

bevicted opened this issue Nov 27, 2024 · 3 comments
Assignees
Labels
question Further information is requested

Comments

@bevicted
Copy link

Describe the bug
Styling seems to get "stuck" for wrapped lines in viewport. This gets corrected every time I resize the window.

Note that whatever happens, the first and last lines work as intended.

As a little extra: I tried what happens with HighPerformanceRendering set to true, but nothing seems to get rendered.

Setup
Please complete the following information along with version numbers, if applicable.

  • OS: MacOS
  • Shell: zsh
  • Terminal Emulator: alacritty
  • Terminal Multiplexer: tmux
  • Locale: en_US.UTF-8

To Reproduce
Steps to reproduce the behavior:

  1. create viewport with a list of long strings, a cursor and highlight styling
  2. initialise
  3. move cursor

Source Code
Relevant code parts (cut some logic out of it which doesn't change styling/rendering):

func (li *LogInspector) Update(msg tea.Msg) (*LogInspector, tea.Cmd) {
  // logic to move cursor with keys
}

func (li *LogInspector) View() string {
        // note: same result without applying a width style here
	return lipgloss.NewStyle().Width(li.width).Render(li.viewport.View())
}

func (li *LogInspector) updateViewport() {
	var sb strings.Builder

	for i := range li.logs {
		sb.WriteString(li.renderLog(i))
	}

	li.viewport.SetContent(sb.String())
}


func (li *LogInspector) renderLog(idx int) string {
	logLine := li.logs[idx]

	if idx == li.cursor {
		logLine = highlightStyle.Render(logLine)
	}

	return logLine + "\n"
}

Expected behavior
Styling to change.

Screenshots
initially correct:
image

after moving the cursor one down:
image

after resizing my window:
image

Additional context
N/A

@bevicted
Copy link
Author

bevicted commented Nov 27, 2024

Annoyingly I found a fix right after posting this:

If I modify my render func

From this:

func (li *LogInspector) renderLog(idx int) string {
	logLine := li.logs[idx]

	if idx == li.cursor {
		logLine = highlightStyle.Render(logLine)
	}

	return logLine + "\n"
}

To this

func (li *LogInspector) renderLog(idx int) string {
	logLine := li.logs[idx]

	logLine = lipgloss.NewStyle().Width(li.width).Render(logLine)

	if idx == li.cursor {
		logLine = highlightStyle.Render(logLine)
	}

	return logLine + "\n"
}

Highighting now works as expected

Adding the highlight first though produces the same issue as originally described

func (li *LogInspector) renderLog(idx int) string {
	logLine := li.logs[idx]

	if idx == li.cursor {
		logLine = highlightStyle.Render(logLine)
	}

	logLine = lipgloss.NewStyle().Width(li.width).Render(logLine)

	return logLine + "\n"
}

@bashbunni
Copy link
Member

It looks like in the original example you're styling the text before wrapping it. I would expect that to cause some issues with the highlighted style not reaching the right rows.

@bevicted do you think this is a viewport bug or are you satisfied with your fix? If it's a bug, it would be really helpful to get a minimal reproducible example from you so we can try and debug on our end :)

@bashbunni bashbunni self-assigned this Dec 4, 2024
@bashbunni bashbunni added the question Further information is requested label Dec 5, 2024
@bevicted
Copy link
Author

bevicted commented Dec 6, 2024

Hey @bashbunni

My main issue here is when I create the viewport, I set the dimensions via viewport.New(w, h), upon resize I update these fields directly viewport.Width = width, yet I encounter this issue if I do not set the width of the strings contained within, via lipgloss. I would assume that since I set the size for the viewport and it automatically wraps my lines, that styling would work on wrapped lines.

Now I set every width directly and in addition carry a widthStyle lipgloss style on my struct which is yet another size to update and apply to everything.

I guess my problem is twofold:

  • m.Width m.Height vs style.Width() style.Height() is unclear to me, I would like to stick with one but I found that sometimes I need to experiment to decide which one I need or in this case, both.
  • viewport is trying to do a lot here but only goes halfway
    • either go full in and try to handle styles when wrapping lines
    • or just drop auto line wrapping and leave it up to the user to implement it

I would honestly prefer if auto line wrapping would be just dropped as it's literally one line to do with lipgloss, and would be a lot easier on viewport's code, however I would expect a note on style.Width() that wrapping may break styling that's applied before it. (Which viewport does automatically)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants