diff --git a/viewport/viewport.go b/viewport/viewport.go index ee89208f..8ac3b9f4 100644 --- a/viewport/viewport.go +++ b/viewport/viewport.go @@ -7,6 +7,27 @@ import ( "github.com/charmbracelet/bubbles/key" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" + "github.com/muesli/reflow/wordwrap" + "github.com/muesli/reflow/wrap" +) + +// WrapType sets the type of line wrapping the viewport will have. +type WrapType int + +// Line wrap options. +const ( + // NoWrap leaves the lines as is. + NoWrap WrapType = iota + + // Wrap will try to wrap lines on words first + // and will wrap on characters if it encounters long words. + Wrap + + // SoftWrapOnly wraps lines on words only. + SoftWrapOnly + + // HardWrapOnly Wraps lines on characters only. + HardWrapOnly ) // New returns a new model with the given width and height as well as default @@ -52,6 +73,9 @@ type Model struct { // which is usually via the alternate screen buffer. HighPerformanceRendering bool + // Wrap sets the wrap mode for the viewport + Wrap WrapType + initialized bool lines []string } @@ -101,6 +125,16 @@ func (m Model) ScrollPercent() float64 { // Sync command should also be called. func (m *Model) SetContent(s string) { s = strings.ReplaceAll(s, "\r\n", "\n") // normalize line endings + + switch m.Wrap { + case Wrap: + s = wrap.String(wordwrap.String(s, m.Width), m.Width) + case SoftWrapOnly: + s = wordwrap.String(s, m.Width) + case HardWrapOnly: + s = wrap.String(s, m.Width) + } + m.lines = strings.Split(s, "\n") if m.YOffset > len(m.lines)-1 {