From 170357a1a3b96dab05680d6e33879919d33cbb2d Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Fri, 11 Feb 2022 15:21:05 -0500 Subject: [PATCH] feat: render markdown files using glamour Fixes: https://github.com/charmbracelet/soft-serve/issues/87 --- internal/tui/bubbles/git/about/bubble.go | 38 ++++----------------- internal/tui/bubbles/git/log/bubble.go | 6 ++-- internal/tui/bubbles/git/refs/bubble.go | 6 ++-- internal/tui/bubbles/git/tree/bubble.go | 26 +++++++++----- internal/tui/bubbles/git/types/formatter.go | 27 +++++++++++++++ 5 files changed, 58 insertions(+), 45 deletions(-) diff --git a/internal/tui/bubbles/git/about/bubble.go b/internal/tui/bubbles/git/about/bubble.go index 52255bb85..68e5f666e 100644 --- a/internal/tui/bubbles/git/about/bubble.go +++ b/internal/tui/bubbles/git/about/bubble.go @@ -3,11 +3,9 @@ package about import ( "github.com/charmbracelet/bubbles/viewport" tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/glamour" "github.com/charmbracelet/soft-serve/internal/tui/bubbles/git/types" vp "github.com/charmbracelet/soft-serve/internal/tui/bubbles/git/viewport" "github.com/charmbracelet/soft-serve/internal/tui/style" - "github.com/muesli/reflow/wrap" ) type Bubble struct { @@ -45,7 +43,7 @@ func (b *Bubble) Update(msg tea.Msg) (tea.Model, tea.Cmd) { // XXX: if we find that longer readmes take more than a few // milliseconds to render we may need to move Glamour rendering into a // command. - md, err := b.glamourize(b.repo.GetReadme()) + md, err := b.glamourize() if err != nil { return b, nil } @@ -83,8 +81,13 @@ func (b *Bubble) Help() []types.HelpEntry { } } +func (b *Bubble) glamourize() (string, error) { + w := b.width - b.widthMargin - b.styles.RepoBody.GetHorizontalFrameSize() + return types.Glamourize(w, b.repo.GetReadme()) +} + func (b *Bubble) setupCmd() tea.Msg { - md, err := b.glamourize(b.repo.GetReadme()) + md, err := b.glamourize() if err != nil { return types.ErrMsg{err} } @@ -92,30 +95,3 @@ func (b *Bubble) setupCmd() tea.Msg { b.GotoTop() return nil } - -func (b *Bubble) glamourize(md string) (string, error) { - w := b.width - b.widthMargin - b.styles.RepoBody.GetHorizontalFrameSize() - if w > types.GlamourMaxWidth { - w = types.GlamourMaxWidth - } - tr, err := glamour.NewTermRenderer( - glamour.WithStyles(types.DefaultStyles()), - glamour.WithWordWrap(w), - ) - - if err != nil { - return "", err - } - mdt, err := tr.Render(md) - if err != nil { - return "", err - } - // For now, hard-wrap long lines in Glamour that would otherwise break the - // layout when wrapping. This may be due to #43 in Reflow, which has to do - // with a bug in the way lines longer than the given width are wrapped. - // - // https://github.com/muesli/reflow/issues/43 - // - // TODO: solve this upstream in Glamour/Reflow. - return wrap.String(mdt, w), nil -} diff --git a/internal/tui/bubbles/git/log/bubble.go b/internal/tui/bubbles/git/log/bubble.go index 25182e0c9..af9cb9e27 100644 --- a/internal/tui/bubbles/git/log/bubble.go +++ b/internal/tui/bubbles/git/log/bubble.go @@ -99,8 +99,8 @@ type Bubble struct { error types.ErrMsg } -func NewBubble(repo types.Repo, style *style.Styles, width, widthMargin, height, heightMargin int) *Bubble { - l := list.New([]list.Item{}, itemDelegate{style}, width-widthMargin, height-heightMargin) +func NewBubble(repo types.Repo, styles *style.Styles, width, widthMargin, height, heightMargin int) *Bubble { + l := list.New([]list.Item{}, itemDelegate{styles}, width-widthMargin, height-heightMargin) l.SetShowFilter(false) l.SetShowHelp(false) l.SetShowPagination(false) @@ -115,7 +115,7 @@ func NewBubble(repo types.Repo, style *style.Styles, width, widthMargin, height, Viewport: &viewport.Model{}, }, repo: repo, - style: style, + style: styles, state: logState, width: width, widthMargin: widthMargin, diff --git a/internal/tui/bubbles/git/refs/bubble.go b/internal/tui/bubbles/git/refs/bubble.go index 503f966c6..edbaecf3c 100644 --- a/internal/tui/bubbles/git/refs/bubble.go +++ b/internal/tui/bubbles/git/refs/bubble.go @@ -75,8 +75,8 @@ type Bubble struct { heightMargin int } -func NewBubble(repo types.Repo, style *style.Styles, width, widthMargin, height, heightMargin int) *Bubble { - l := list.NewModel([]list.Item{}, itemDelegate{style}, width-widthMargin, height-heightMargin) +func NewBubble(repo types.Repo, styles *style.Styles, width, widthMargin, height, heightMargin int) *Bubble { + l := list.NewModel([]list.Item{}, itemDelegate{styles}, width-widthMargin, height-heightMargin) l.SetShowFilter(false) l.SetShowHelp(false) l.SetShowPagination(false) @@ -86,7 +86,7 @@ func NewBubble(repo types.Repo, style *style.Styles, width, widthMargin, height, l.DisableQuitKeybindings() b := &Bubble{ repo: repo, - style: style, + style: styles, width: width, height: height, widthMargin: widthMargin, diff --git a/internal/tui/bubbles/git/tree/bubble.go b/internal/tui/bubbles/git/tree/bubble.go index b8ed115c3..1d46a48c5 100644 --- a/internal/tui/bubbles/git/tree/bubble.go +++ b/internal/tui/bubbles/git/tree/bubble.go @@ -130,8 +130,8 @@ type Bubble struct { lastSelected []int } -func NewBubble(repo types.Repo, style *style.Styles, width, widthMargin, height, heightMargin int) *Bubble { - l := list.New([]list.Item{}, itemDelegate{style}, width-widthMargin, height-heightMargin) +func NewBubble(repo types.Repo, styles *style.Styles, width, widthMargin, height, heightMargin int) *Bubble { + l := list.New([]list.Item{}, itemDelegate{styles}, width-widthMargin, height-heightMargin) l.SetShowFilter(false) l.SetShowHelp(false) l.SetShowPagination(false) @@ -146,7 +146,7 @@ func NewBubble(repo types.Repo, style *style.Styles, width, widthMargin, height, Viewport: &viewport.Model{}, }, repo: repo, - style: style, + style: styles, width: width, height: height, widthMargin: widthMargin, @@ -337,12 +337,22 @@ func (b *Bubble) renderFile(m fileMsg) string { Code: c, Language: lang, } - r := strings.Builder{} - err := formatter.Render(&r, types.RenderCtx) - if err != nil { - s.WriteString(err.Error()) + if lang == "markdown" { + w := b.width - b.widthMargin - b.style.RepoBody.GetHorizontalFrameSize() + md, err := types.Glamourize(w, c) + if err != nil { + s.WriteString(err.Error()) + } else { + s.WriteString(md) + } } else { - s.WriteString(r.String()) + r := strings.Builder{} + err := formatter.Render(&r, types.RenderCtx) + if err != nil { + s.WriteString(err.Error()) + } else { + s.WriteString(r.String()) + } } } return b.style.TreeFileContent.Copy().Width(b.width - b.widthMargin).Render(s.String()) diff --git a/internal/tui/bubbles/git/types/formatter.go b/internal/tui/bubbles/git/types/formatter.go index 7356581d1..ea3197a22 100644 --- a/internal/tui/bubbles/git/types/formatter.go +++ b/internal/tui/bubbles/git/types/formatter.go @@ -3,6 +3,7 @@ package types import ( "github.com/charmbracelet/glamour" gansi "github.com/charmbracelet/glamour/ansi" + "github.com/muesli/reflow/wrap" "github.com/muesli/termenv" ) @@ -34,3 +35,29 @@ func NewRenderCtx(worldwrap int) gansi.RenderContext { WordWrap: worldwrap, }) } + +func Glamourize(w int, md string) (string, error) { + if w > GlamourMaxWidth { + w = GlamourMaxWidth + } + tr, err := glamour.NewTermRenderer( + glamour.WithStyles(DefaultStyles()), + glamour.WithWordWrap(w), + ) + + if err != nil { + return "", err + } + mdt, err := tr.Render(md) + if err != nil { + return "", err + } + // For now, hard-wrap long lines in Glamour that would otherwise break the + // layout when wrapping. This may be due to #43 in Reflow, which has to do + // with a bug in the way lines longer than the given width are wrapped. + // + // https://github.com/muesli/reflow/issues/43 + // + // TODO: solve this upstream in Glamour/Reflow. + return wrap.String(mdt, w), nil +}