From 753467db5b10112385b4c4d23fc6eb2907300b53 Mon Sep 17 00:00:00 2001 From: Levi Neely <141506390+lneely@users.noreply.github.com> Date: Sun, 2 Aug 2026 11:13:22 +0200 Subject: [PATCH] fix: preserve pre-fence text and post-fence content in rendered blocks When a fence () closes inside a block, prepend any content that came before the fence to renderedHtml so both text and the highlighted fence show up. When content is appended after the fence, keep renderedHtml in sync by appending the escaped text. This prevents the fence from 'eating' surrounding content. --- gui/chatblockmodel.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/gui/chatblockmodel.cpp b/gui/chatblockmodel.cpp index ebc1698..360b66c 100644 --- a/gui/chatblockmodel.cpp +++ b/gui/chatblockmodel.cpp @@ -224,8 +224,15 @@ void ChatBlockModel::appendContent(const QString &line) if (!last.content.isEmpty()) last.content += '\n'; last.content += line; + // Keep renderedHtml in sync if a fence was rendered earlier + // in this block, so post-fence content isn't invisible. + if (!last.renderedHtml.isEmpty()) { + if (!last.renderedHtml.endsWith('\n')) + last.renderedHtml += '\n'; + last.renderedHtml += line.toHtmlEscaped(); + } QModelIndex idx = index(m_blocks.size() - 1); - emit dataChanged(idx, idx, {ContentRole}); + emit dataChanged(idx, idx, {ContentRole, RenderedHtmlRole}); } void ChatBlockModel::processLine(const QString &line) @@ -248,7 +255,13 @@ void ChatBlockModel::processLine(const QString &line) if (!m_blocks.isEmpty()) { ChatBlock &last = m_blocks.last(); - last.renderedHtml = rendered; + // Prepend any content that came before the fence so it + // isn't lost — the view uses renderedHtml exclusively + // when non-empty. + if (!last.content.isEmpty()) + last.renderedHtml = escapeHtml(last.content) + '\n' + rendered; + else + last.renderedHtml = rendered; QModelIndex idx = index(m_blocks.size() - 1); emit dataChanged(idx, idx, {RenderedHtmlRole}); }