diff --git a/go.mod b/go.mod index db48099..49a2839 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,6 @@ require ( github.com/charmbracelet/x/ansi v0.8.0 github.com/charmbracelet/x/editor v0.1.0 github.com/charmbracelet/x/term v0.2.1 - github.com/muesli/reflow v0.3.0 github.com/muesli/roff v0.1.0 github.com/muesli/termenv v0.15.3-0.20241211131612-0d230cb6eb15 github.com/rivo/uniseg v0.4.7 @@ -40,6 +39,7 @@ require ( github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/mango v0.2.0 // indirect + github.com/muesli/reflow v0.3.0 // indirect github.com/yuin/goldmark v1.7.4 // indirect github.com/yuin/goldmark-emoji v1.0.4 // indirect golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect diff --git a/pager/pager.go b/pager/pager.go index 42116bd..6b38403 100644 --- a/pager/pager.go +++ b/pager/pager.go @@ -13,7 +13,7 @@ import ( "github.com/charmbracelet/bubbles/viewport" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" - "github.com/muesli/reflow/truncate" + "github.com/charmbracelet/x/ansi" ) type keymap struct { @@ -146,17 +146,21 @@ func (m *model) processText(msg tea.WindowSizeMsg) { if m.showLineNumbers { text.WriteString(m.lineNumberStyle.Render(fmt.Sprintf("%4d │ ", i+1))) } - for m.softWrap && lipgloss.Width(line) > m.maxWidth { - truncatedLine := truncate.String(line, uint(m.maxWidth)) //nolint: gosec - text.WriteString(textStyle.Render(truncatedLine)) - text.WriteString("\n") - if m.showLineNumbers { - text.WriteString(m.lineNumberStyle.Render(" │ ")) + idx := 0 + if w := ansi.StringWidth(line); m.softWrap && w > m.maxWidth { + for w > idx { + if m.showLineNumbers && idx != 0 { + text.WriteString(m.lineNumberStyle.Render(" │ ")) + } + truncatedLine := ansi.Cut(line, idx, m.maxWidth+idx) + idx += m.maxWidth + text.WriteString(textStyle.Render(truncatedLine)) + text.WriteString("\n") } - line = strings.Replace(line, truncatedLine, "", 1) + } else { + text.WriteString(textStyle.Render(line)) //nolint: gosec + text.WriteString("\n") } - text.WriteString(textStyle.Render(truncate.String(line, uint(m.maxWidth)))) //nolint: gosec - text.WriteString("\n") } diffHeight := m.viewport.Height - lipgloss.Height(text.String()) diff --git a/pager/search.go b/pager/search.go index e32260d..be59a53 100644 --- a/pager/search.go +++ b/pager/search.go @@ -8,7 +8,7 @@ import ( "github.com/charmbracelet/bubbles/textinput" "github.com/charmbracelet/gum/internal/utils" "github.com/charmbracelet/lipgloss" - "github.com/muesli/reflow/truncate" + "github.com/charmbracelet/x/ansi" ) type search struct { @@ -150,14 +150,18 @@ func (s *search) PrevMatch(m *model) { func softWrapEm(str string, maxWidth int, softWrap bool) string { var text strings.Builder for _, line := range strings.Split(str, "\n") { - for softWrap && lipgloss.Width(line) > maxWidth { - truncatedLine := truncate.String(line, uint(maxWidth)) //nolint: gosec - text.WriteString(truncatedLine) + idx := 0 + if w := ansi.StringWidth(line); softWrap && w > maxWidth { + for w > idx { + truncatedLine := ansi.Cut(line, idx, maxWidth+idx) + idx += maxWidth + text.WriteString(truncatedLine) + text.WriteString("\n") + } + } else { + text.WriteString(line) //nolint: gosec text.WriteString("\n") - line = strings.Replace(line, truncatedLine, "", 1) } - text.WriteString(truncate.String(line, uint(maxWidth))) //nolint: gosec - text.WriteString("\n") } return text.String()