Skip to content

Commit bf4e2d6

Browse files
koki-developclaude
andcommitted
feat: Add reusable indent utility function with tests
- Create indent function in src/lib/util.ts with options-based API - Add comprehensive test suite in src/lib/util.spec.ts using bun:test - Refactor MessageItem to use shared indent function for multi-line user messages - Support skipFirstLine option for flexible indentation patterns 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent bfce20e commit bf4e2d6

File tree

3 files changed

+59
-1
lines changed

3 files changed

+59
-1
lines changed

src/components/MessageItem.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Box, Text } from "ink";
22
import type React from "react";
3+
import { indent } from "../lib/util";
34
import type { Message } from "./types";
45

56
interface MessageItemProps {
@@ -12,7 +13,7 @@ export const MessageItem: React.FC<MessageItemProps> = ({ message }) => {
1213
return (
1314
<Box marginBottom={1} paddingLeft={isUser ? 0 : 2}>
1415
<Text color={isUser ? "gray" : "cyan"}>
15-
{isUser ? `> ${message.text}` : message.text}
16+
{isUser ? `> ${indent(message.text)}` : message.text}
1617
</Text>
1718
</Box>
1819
);

src/lib/util.spec.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { describe, expect, test } from "bun:test";
2+
import { indent } from "./util";
3+
4+
describe("indent", () => {
5+
test("should indent all lines except first by default", () => {
6+
const input = "first line\nsecond line\nthird line";
7+
const expected = "first line\n second line\n third line";
8+
expect(indent(input)).toBe(expected);
9+
});
10+
11+
test("should indent all lines when skipFirstLine is false", () => {
12+
const input = "first line\nsecond line\nthird line";
13+
const expected = " first line\n second line\n third line";
14+
expect(indent(input, { skipFirstLine: false })).toBe(expected);
15+
});
16+
17+
test("should handle single line text", () => {
18+
const input = "single line";
19+
const expected = "single line";
20+
expect(indent(input)).toBe(expected);
21+
});
22+
23+
test("should handle empty string", () => {
24+
const input = "";
25+
const expected = "";
26+
expect(indent(input)).toBe(expected);
27+
});
28+
29+
test("should handle empty lines", () => {
30+
const input = "first line\n\nthird line";
31+
const expected = "first line\n \n third line";
32+
expect(indent(input)).toBe(expected);
33+
});
34+
35+
test("should work with empty options", () => {
36+
const input = "first line\nsecond line";
37+
const expected = "first line\n second line";
38+
expect(indent(input, {})).toBe(expected);
39+
});
40+
});

src/lib/util.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
interface IndentOptions {
2+
skipFirstLine?: boolean;
3+
}
4+
5+
export function indent(text: string, options: IndentOptions = {}): string {
6+
const { skipFirstLine = true } = options;
7+
const lines = text.split("\n");
8+
9+
return lines
10+
.map((line, index) => {
11+
if (skipFirstLine && index === 0) {
12+
return line;
13+
}
14+
return ` ${line}`;
15+
})
16+
.join("\n");
17+
}

0 commit comments

Comments
 (0)