Skip to content

Commit 53d325f

Browse files
committed
refactor(tui): address PR review feedback
- Rename CodeBlockCopyLabel -> CodeBlockCopyIcon (and related local variables) for naming consistency with other UI affordances. - Rename cached style ansiCodeBgMuted -> ansiCodeBlockCopyIcon to make its purpose explicit; it remains derived from theme-controlled colors (codeBg + TextMutedGray) so theme overrides flow through ResetStyles as before. - Replace the magic +2 in IncrementalRenderer.mergeCodeBlocks with a named joinSeparatorLines constant tied to joinPrefixAndTail's contract.
1 parent 6a3a4bb commit 53d325f

5 files changed

Lines changed: 37 additions & 35 deletions

File tree

pkg/tui/components/markdown/codeblock.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
package markdown
22

3-
// CodeBlockCopyLabel is the unicode glyph rendered at the top-right corner of
3+
// CodeBlockCopyIcon is the unicode glyph rendered at the top-right corner of
44
// every fenced code block. Clicking on it copies the block's raw content to
55
// the clipboard. It matches the glyph used for the message-level copy
66
// affordance so the visual language stays consistent; the two are
77
// disambiguated by line index, not by glyph.
8-
const CodeBlockCopyLabel = "\u2398"
8+
const CodeBlockCopyIcon = "\u2398"
99

1010
// CodeBlock describes a fenced code block emitted by the renderer.
1111
//
1212
// Line is the 0-indexed line, within the renderer's output, where the copy
13-
// label is rendered on the code block's top padding row. Content holds the
13+
// icon is rendered on the code block's top padding row. Content holds the
1414
// raw code (without ANSI styling) so callers can place it on the clipboard.
1515
type CodeBlock struct {
1616
Content string

pkg/tui/components/markdown/fast_renderer.go

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -117,19 +117,19 @@ type cachedStyles struct {
117117
styleCodeBg lipgloss.Style // kept only because chroma styles inherit its bg color
118118

119119
// ANSI styles (for fast inline rendering)
120-
ansiBold ansiStyle
121-
ansiItalic ansiStyle
122-
ansiBoldItal ansiStyle
123-
ansiStrike ansiStyle
124-
ansiCode ansiStyle
125-
ansiLink ansiStyle
126-
ansiLinkText ansiStyle
127-
ansiText ansiStyle // base document text style
128-
ansiHeadings [6]ansiStyle // heading styles for inline restoration
129-
ansiBlockquote ansiStyle // blockquote style for inline restoration
130-
ansiFootnote ansiStyle // footnote reference style
131-
ansiCodeBg ansiStyle // code block background (cached to avoid repeated buildAnsiStyle)
132-
ansiCodeBgMuted ansiStyle // muted foreground on code block background (for code-block chrome like copy label)
120+
ansiBold ansiStyle
121+
ansiItalic ansiStyle
122+
ansiBoldItal ansiStyle
123+
ansiStrike ansiStyle
124+
ansiCode ansiStyle
125+
ansiLink ansiStyle
126+
ansiLinkText ansiStyle
127+
ansiText ansiStyle // base document text style
128+
ansiHeadings [6]ansiStyle // heading styles for inline restoration
129+
ansiBlockquote ansiStyle // blockquote style for inline restoration
130+
ansiFootnote ansiStyle // footnote reference style
131+
ansiCodeBg ansiStyle // code block background (cached to avoid repeated buildAnsiStyle)
132+
ansiCodeBlockCopyIcon ansiStyle // muted foreground on code block background, used for the per-block copy icon
133133

134134
// Pre-rendered chrome (computed once, reused across renders)
135135
headingPrefixes [6]string // raw prefix strings (e.g. "## ") for width math
@@ -243,7 +243,7 @@ func getGlobalStyles() *cachedStyles {
243243
ansiBlockquote: buildAnsiStyle(blockquoteLipStyle),
244244
ansiFootnote: buildAnsiStyle(lipgloss.NewStyle().Foreground(styles.TextSecondary).Italic(true)),
245245
ansiCodeBg: buildAnsiStyle(codeBg),
246-
ansiCodeBgMuted: buildAnsiStyle(codeBg.Foreground(styles.TextMutedGray)),
246+
ansiCodeBlockCopyIcon: buildAnsiStyle(codeBg.Foreground(styles.TextMutedGray)),
247247
headingPrefixes: headingPrefixes,
248248
styledHeadingPrefixes: styledPrefixes,
249249
styledHeadingContIndent: styledContIndents,
@@ -1936,16 +1936,16 @@ func (p *parser) renderCodeBlockWithIndent(code, lang, indent string, availableW
19361936
// back to this block's raw content.
19371937
topLine := strings.Count(p.out.String(), "\n")
19381938
p.out.WriteString(indent)
1939-
labelWidth := runewidth.StringWidth(CodeBlockCopyLabel)
1940-
leftFill := max(availableWidth-paddingRight-labelWidth, 0)
1941-
if availableWidth >= labelWidth+paddingRight {
1939+
iconWidth := runewidth.StringWidth(CodeBlockCopyIcon)
1940+
leftFill := max(availableWidth-paddingRight-iconWidth, 0)
1941+
if availableWidth >= iconWidth+paddingRight {
19421942
bgStyle.renderTo(&p.out, spaces(leftFill))
1943-
p.styles.ansiCodeBgMuted.renderTo(&p.out, CodeBlockCopyLabel)
1943+
p.styles.ansiCodeBlockCopyIcon.renderTo(&p.out, CodeBlockCopyIcon)
19441944
if paddingRight > 0 {
19451945
bgStyle.renderTo(&p.out, spaces(paddingRight))
19461946
}
19471947
} else {
1948-
// Too narrow for the label; fall back to a plain top padding row.
1948+
// Too narrow for the icon; fall back to a plain top padding row.
19491949
bgStyle.renderTo(&p.out, fullWidthPad)
19501950
}
19511951
p.out.WriteByte('\n')

pkg/tui/components/markdown/fast_renderer_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2045,7 +2045,7 @@ func TestFastRendererCodeBlocksReturnsRawContent(t *testing.T) {
20452045
lines := strings.Split(out, "\n")
20462046
for _, b := range blocks {
20472047
require.Less(t, b.Line, len(lines), "code block line index out of range")
2048-
assert.Contains(t, stripANSI(lines[b.Line]), CodeBlockCopyLabel,
2048+
assert.Contains(t, stripANSI(lines[b.Line]), CodeBlockCopyIcon,
20492049
"line %d should contain the code block copy label", b.Line)
20502050
}
20512051

@@ -2076,6 +2076,6 @@ func TestIncrementalRendererCodeBlocksAggregate(t *testing.T) {
20762076
lines := strings.Split(out, "\n")
20772077
for _, b := range blocks2 {
20782078
require.Less(t, b.Line, len(lines))
2079-
assert.Contains(t, stripANSI(lines[b.Line]), CodeBlockCopyLabel)
2079+
assert.Contains(t, stripANSI(lines[b.Line]), CodeBlockCopyIcon)
20802080
}
20812081
}

pkg/tui/components/markdown/incremental.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -217,10 +217,15 @@ func (r *IncrementalRenderer) joinPrefixAndTail(prefix, tail string) string {
217217
return b.String()
218218
}
219219

220+
// joinSeparatorLines is the number of extra rendered lines that
221+
// joinPrefixAndTail inserts between the prefix output and the tail output:
222+
// one to terminate the prefix's final (untrailing-newlined) line, and one
223+
// blank-padded separator line. Keep this in sync with joinPrefixAndTail.
224+
const joinSeparatorLines = 2
225+
220226
// mergeCodeBlocks returns the union of code blocks from a cached prefix output
221-
// and a freshly rendered tail. Tail block line indices are shifted by the
222-
// number of lines in the prefix plus one for the blank separator inserted by
223-
// joinPrefixAndTail.
227+
// and a freshly rendered tail. Tail block line indices are shifted past the
228+
// prefix's lines and the separator that joinPrefixAndTail inserts.
224229
func (r *IncrementalRenderer) mergeCodeBlocks(prefixOut string, prefixBlocks, tailBlocks []CodeBlock) []CodeBlock {
225230
if len(prefixBlocks) == 0 && len(tailBlocks) == 0 {
226231
return nil
@@ -232,10 +237,7 @@ func (r *IncrementalRenderer) mergeCodeBlocks(prefixOut string, prefixBlocks, ta
232237
}
233238
offset := 0
234239
if prefixOut != "" {
235-
// Number of lines in prefix (FastRenderer trims its trailing newline so
236-
// the count is newlines + 1) plus one for the blank separator inserted
237-
// by joinPrefixAndTail.
238-
offset = strings.Count(prefixOut, "\n") + 2
240+
offset = strings.Count(prefixOut, "\n") + joinSeparatorLines
239241
}
240242
for _, b := range tailBlocks {
241243
out = append(out, CodeBlock{Content: b.Content, Line: b.Line + offset})

pkg/tui/components/messages/messages.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1766,13 +1766,13 @@ func (m *model) codeBlockAt(msgIdx, localLine, col int) (string, bool) {
17661766
return "", false
17671767
}
17681768
plainLine := ansi.Strip(item.lines[localLine])
1769-
before, _, found := strings.Cut(plainLine, markdown.CodeBlockCopyLabel)
1769+
before, _, found := strings.Cut(plainLine, markdown.CodeBlockCopyIcon)
17701770
if !found {
17711771
return "", false
17721772
}
1773-
labelStart := ansi.StringWidth(before)
1774-
labelEnd := labelStart + ansi.StringWidth(markdown.CodeBlockCopyLabel)
1775-
if col < labelStart || col >= labelEnd {
1773+
iconStart := ansi.StringWidth(before)
1774+
iconEnd := iconStart + ansi.StringWidth(markdown.CodeBlockCopyIcon)
1775+
if col < iconStart || col >= iconEnd {
17761776
return "", false
17771777
}
17781778
return target.Content, true

0 commit comments

Comments
 (0)