Welcome back! In the previous chapter, Output Visibility Context, we learned how to tell the shell when to show full output versus when to truncate it to save space.
Now, we will focus on how that output actually looks.
Terminals deal with raw text. Often, that text is ugly and hard to read.
Imagine your command returns a messy JSON object like this:
{"status":"ok","data":{"id":123,"url":"https://example.com"}}
Without Smart Rendering:
With Smart Rendering:
We need a component that acts like a "pair of glasses" for our terminalβmaking everything crisp, clear, and interactive.
The Smart Output Line performs three specific "magic tricks" on every line of text before showing it to you:
http:// or https:// and turns it into a clickable link.
The main component is called <OutputLine />. You rarely need to configure it deeply; you just feed it text.
import { OutputLine } from './OutputLine';
function MyCommandResult() {
const rawData = '{"user": "Alice", "website": "https://alice.com"}';
// The component automatically detects JSON and URLs
return (
<OutputLine
content={rawData}
linkifyUrls={true}
/>
);
}
What happens here? Instead of one flat line, the user sees:
{
"user": "Alice",
"website": "https://alice.com"
}
And https://alice.com will be clickable!
How does this assembly line work? Let's look at the flow of data.
When you pass a string to <OutputLine />, it goes through a pipeline of transformation functions.
Let's look at the actual code logic in OutputLine.tsx. We will break it down into the three specific steps mentioned above.
The shell attempts to parse every line. If it succeeds, it returns the "pretty" version. If it fails, it just returns the original text.
// utils/slowOperations.js (Simplified)
export function tryFormatJson(line: string): string {
try {
const parsed = JSON.parse(line);
// Return formatted JSON with 2-space indentation
return JSON.stringify(parsed, null, 2);
} catch {
// If it crashes, it wasn't JSON. Return original.
return line;
}
}
Explanation: We use a simple try/catch block. This ensures that normal text (like "Hello World") doesn't break the shell; it simply skips the JSON formatting step.
Next, we scan for URLs.
// OutputLine.tsx
const URL_REGEX = /https?:\/\/[^\s"'<>\\]+/g;
export function linkifyUrlsInText(content: string): string {
// Replace plain text URLs with Hyperlink objects
return content.replace(URL_REGEX, url => createHyperlink(url));
}
Explanation: This uses a Regular Expression (Regex) to find web addresses and wraps them in a helper that the terminal understands as a link.
The OutputLine component combines these steps with the logic we learned in Output Visibility Context.
// OutputLine.tsx
export function OutputLine({ content, verbose, linkifyUrls }) {
// 1. Get the "Expand" signal from Chapter 1
const expandShellOutput = useExpandShellOutput();
const shouldShowFull = verbose || expandShellOutput;
// 2. Run the formatting pipeline
const formattedContent = useMemo(() => {
let text = tryJsonFormatContent(content); // Step 1: JSON
if (linkifyUrls) {
text = linkifyUrlsInText(text); // Step 2: Links
}
// Step 3: Decide to Truncate or Show All
if (shouldShowFull) {
return stripUnderlineAnsi(text);
}
// If not full, cut it short based on terminal width
return renderTruncatedContent(text, columns);
}, [content, shouldShowFull, linkifyUrls]);
return <Text>{formattedContent}</Text>;
}
Explanation:
useExpandShellOutput() (from Chapter 1) to see if we are in "Full Attention" mode.tryJsonFormatContent.linkifyUrlsInText.renderTruncatedContent).
You might notice stripUnderlineAnsi in the code above.
export function stripUnderlineAnsi(content: string): string {
// Removes specific ANSI codes related to underlining
return content.replace(/\u001b\[4m/g, '');
}
Why? Sometimes, raw output contains style codes that "leak." For example, if a line starts an underline but never finishes it, the rest of your terminal might stay underlined forever! This function acts as a safety net to prevent that visual bug.
In this chapter, we explored Smart Output Line Rendering. We learned that:
Now that we can display static text beautifully, what happens when a command is still running? How do we show spinners, timers, and progress bars?
Next Chapter: Execution Progress Feedback
Generated by Code IQ