From e593e6dbef75d88dd16c4774b68b5ceddf501705 Mon Sep 17 00:00:00 2001 From: drew Date: Mon, 3 Aug 2026 16:00:51 +0400 Subject: [PATCH] fix: double result in $EDITOR Signed-off-by: drew --- ui/pager.go | 11 +++++++++++ ui/ui.go | 19 ++++++++++++++----- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/ui/pager.go b/ui/pager.go index 5c522e7..d09c865 100644 --- a/ui/pager.go +++ b/ui/pager.go @@ -133,6 +133,17 @@ func (m *pagerModel) setSize(w, h int) { } func (m *pagerModel) setContent(s string) { + // In high performance mode the viewport paints by inserting its visible + // lines at the top of the scroll area, which pushes whatever was painted + // before down instead of replacing it. Pad the content to the height of + // the viewport so that a repaint always covers the whole scroll area, + // otherwise documents shorter than the window would be shown once per + // render (i.e. twice after coming back from the editor). + if m.viewport.HighPerformanceRendering { + if lines := strings.Count(s, "\n") + 1; lines < m.viewport.Height { + s += strings.Repeat("\n", m.viewport.Height-lines) + } + } m.viewport.SetContent(s) } diff --git a/ui/ui.go b/ui/ui.go index 3537d3f..e0d1fd6 100644 --- a/ui/ui.go +++ b/ui/ui.go @@ -190,12 +190,14 @@ func (m model) Init() tea.Cmd { case stateShowStash: cmds = append(cmds, findLocalFiles(*m.common)) case stateShowDocument: - content, err := os.ReadFile(m.common.cfg.Path) - if err != nil { - log.Error("unable to read file", "file", m.common.cfg.Path, "error", err) - return func() tea.Msg { return errMsg{err} } + if m.pager.currentDocument.localPath != "" { + // Load through the usual path so the document body is kept in the + // model. Otherwise re-renders (on resize, for instance) would have + // nothing to render. + cmds = append(cmds, loadLocalMarkdown(&m.pager.currentDocument)) + break } - body := string(utils.RemoveFrontmatter(content)) + body := string(utils.RemoveFrontmatter([]byte(m.pager.currentDocument.Body))) cmds = append(cmds, renderWithGlamour(m.pager, body)) } @@ -262,6 +264,13 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { // Window size is received when starting up and on every resize case tea.WindowSizeMsg: + if m.common.width == msg.Width && m.common.height == msg.Height { + // Bubble Tea re-sends the window size after running an external + // process, such as the editor. Nothing changed, so there's no need + // to re-render, and re-rendering here would race with the reload + // of the document we're already doing. + return m, nil + } m.common.width = msg.Width m.common.height = msg.Height m.stash.setSize(msg.Width, msg.Height)