summaryrefslogtreecommitdiff
path: root/packages/cli/src/ui/utils/MarkdownDisplay.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'packages/cli/src/ui/utils/MarkdownDisplay.tsx')
-rw-r--r--packages/cli/src/ui/utils/MarkdownDisplay.tsx53
1 files changed, 32 insertions, 21 deletions
diff --git a/packages/cli/src/ui/utils/MarkdownDisplay.tsx b/packages/cli/src/ui/utils/MarkdownDisplay.tsx
index 572ae12e..eb5dc453 100644
--- a/packages/cli/src/ui/utils/MarkdownDisplay.tsx
+++ b/packages/cli/src/ui/utils/MarkdownDisplay.tsx
@@ -21,7 +21,7 @@ interface MarkdownDisplayProps {
// Constants for Markdown parsing and rendering
const EMPTY_LINE_HEIGHT = 1;
-const CODE_BLOCK_PADDING = 1;
+const CODE_BLOCK_PREFIX_PADDING = 1;
const LIST_ITEM_PREFIX_PADDING = 1;
const LIST_ITEM_TEXT_FLEX_GROW = 1;
@@ -44,6 +44,7 @@ const MarkdownDisplayInternal: React.FC<MarkdownDisplayProps> = ({
const contentBlocks: React.ReactNode[] = [];
let inCodeBlock = false;
+ let lastLineEmpty = true;
let codeBlockContent: string[] = [];
let codeBlockLang: string | null = null;
let codeBlockFence = '';
@@ -51,6 +52,13 @@ const MarkdownDisplayInternal: React.FC<MarkdownDisplayProps> = ({
let tableRows: string[][] = [];
let tableHeaders: string[] = [];
+ function addContentBlock(block: React.ReactNode) {
+ if (block) {
+ contentBlocks.push(block);
+ lastLineEmpty = false;
+ }
+ }
+
lines.forEach((line, index) => {
const key = `line-${index}`;
@@ -61,7 +69,7 @@ const MarkdownDisplayInternal: React.FC<MarkdownDisplayProps> = ({
fenceMatch[1].startsWith(codeBlockFence[0]) &&
fenceMatch[1].length >= codeBlockFence.length
) {
- contentBlocks.push(
+ addContentBlock(
<RenderCodeBlock
key={key}
content={codeBlockContent}
@@ -104,7 +112,7 @@ const MarkdownDisplayInternal: React.FC<MarkdownDisplayProps> = ({
tableRows = [];
} else {
// Not a table, treat as regular text
- contentBlocks.push(
+ addContentBlock(
<Box key={key}>
<Text wrap="wrap">
<RenderInline text={line} />
@@ -128,7 +136,7 @@ const MarkdownDisplayInternal: React.FC<MarkdownDisplayProps> = ({
} else if (inTable && !tableRowMatch) {
// End of table
if (tableHeaders.length > 0 && tableRows.length > 0) {
- contentBlocks.push(
+ addContentBlock(
<RenderTable
key={`table-${contentBlocks.length}`}
headers={tableHeaders}
@@ -143,7 +151,7 @@ const MarkdownDisplayInternal: React.FC<MarkdownDisplayProps> = ({
// Process current line as normal
if (line.trim().length > 0) {
- contentBlocks.push(
+ addContentBlock(
<Box key={key}>
<Text wrap="wrap">
<RenderInline text={line} />
@@ -152,7 +160,7 @@ const MarkdownDisplayInternal: React.FC<MarkdownDisplayProps> = ({
);
}
} else if (hrMatch) {
- contentBlocks.push(
+ addContentBlock(
<Box key={key}>
<Text dimColor>---</Text>
</Box>,
@@ -198,12 +206,12 @@ const MarkdownDisplayInternal: React.FC<MarkdownDisplayProps> = ({
);
break;
}
- if (headerNode) contentBlocks.push(<Box key={key}>{headerNode}</Box>);
+ if (headerNode) addContentBlock(<Box key={key}>{headerNode}</Box>);
} else if (ulMatch) {
const leadingWhitespace = ulMatch[1];
const marker = ulMatch[2];
const itemText = ulMatch[3];
- contentBlocks.push(
+ addContentBlock(
<RenderListItem
key={key}
itemText={itemText}
@@ -216,7 +224,7 @@ const MarkdownDisplayInternal: React.FC<MarkdownDisplayProps> = ({
const leadingWhitespace = olMatch[1];
const marker = olMatch[2];
const itemText = olMatch[3];
- contentBlocks.push(
+ addContentBlock(
<RenderListItem
key={key}
itemText={itemText}
@@ -226,12 +234,15 @@ const MarkdownDisplayInternal: React.FC<MarkdownDisplayProps> = ({
/>,
);
} else {
- if (line.trim().length === 0) {
- if (contentBlocks.length > 0 && !inCodeBlock) {
- contentBlocks.push(<Box key={key} height={EMPTY_LINE_HEIGHT} />);
+ if (line.trim().length === 0 && !inCodeBlock) {
+ if (!lastLineEmpty) {
+ contentBlocks.push(
+ <Box key={`spacer-${index}`} height={EMPTY_LINE_HEIGHT} />,
+ );
+ lastLineEmpty = true;
}
} else {
- contentBlocks.push(
+ addContentBlock(
<Box key={key}>
<Text wrap="wrap">
<RenderInline text={line} />
@@ -243,7 +254,7 @@ const MarkdownDisplayInternal: React.FC<MarkdownDisplayProps> = ({
});
if (inCodeBlock) {
- contentBlocks.push(
+ addContentBlock(
<RenderCodeBlock
key="line-eof"
content={codeBlockContent}
@@ -257,7 +268,7 @@ const MarkdownDisplayInternal: React.FC<MarkdownDisplayProps> = ({
// Handle table at end of content
if (inTable && tableHeaders.length > 0 && tableRows.length > 0) {
- contentBlocks.push(
+ addContentBlock(
<RenderTable
key={`table-${contentBlocks.length}`}
headers={tableHeaders}
@@ -293,14 +304,14 @@ const RenderCodeBlockInternal: React.FC<RenderCodeBlockProps> = ({
if (isPending && availableTerminalHeight !== undefined) {
const MAX_CODE_LINES_WHEN_PENDING = Math.max(
0,
- availableTerminalHeight - CODE_BLOCK_PADDING * 2 - RESERVED_LINES,
+ availableTerminalHeight - RESERVED_LINES,
);
if (content.length > MAX_CODE_LINES_WHEN_PENDING) {
if (MAX_CODE_LINES_WHEN_PENDING < MIN_LINES_FOR_MESSAGE) {
// Not enough space to even show the message meaningfully
return (
- <Box padding={CODE_BLOCK_PADDING}>
+ <Box paddingLeft={CODE_BLOCK_PREFIX_PADDING}>
<Text color={Colors.Gray}>... code is being written ...</Text>
</Box>
);
@@ -310,10 +321,10 @@ const RenderCodeBlockInternal: React.FC<RenderCodeBlockProps> = ({
truncatedContent.join('\n'),
lang,
availableTerminalHeight,
- terminalWidth - CODE_BLOCK_PADDING * 2,
+ terminalWidth - CODE_BLOCK_PREFIX_PADDING,
);
return (
- <Box flexDirection="column" padding={CODE_BLOCK_PADDING}>
+ <Box paddingLeft={CODE_BLOCK_PREFIX_PADDING} flexDirection="column">
{colorizedTruncatedCode}
<Text color={Colors.Gray}>... generating more ...</Text>
</Box>
@@ -326,13 +337,13 @@ const RenderCodeBlockInternal: React.FC<RenderCodeBlockProps> = ({
fullContent,
lang,
availableTerminalHeight,
- terminalWidth - CODE_BLOCK_PADDING * 2,
+ terminalWidth - CODE_BLOCK_PREFIX_PADDING,
);
return (
<Box
+ paddingLeft={CODE_BLOCK_PREFIX_PADDING}
flexDirection="column"
- padding={CODE_BLOCK_PADDING}
width={terminalWidth}
flexShrink={0}
>