-
Notifications
You must be signed in to change notification settings - Fork 0
/
grep.ts
97 lines (80 loc) · 2.56 KB
/
grep.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
type GrepOptions = {
context?: number | { before?: number; after?: number };
colors?: boolean;
caseSensitive?: boolean;
multiline?: boolean;
};
function grep(
content: string | string[],
matchPattern: string,
options?: GrepOptions
): string[] {
const lines: string[] = Array.isArray(content)
? content
: content.split("\n");
const {
context = 0,
colors = false,
caseSensitive = false,
multiline = false,
} = options || {};
const contextBefore =
typeof context === "number" ? context : context.before || 0;
const contextAfter =
typeof context === "number" ? context : context.after || 0;
const pattern = caseSensitive ? matchPattern : matchPattern.toLowerCase();
const matches: string[] = [];
for (let i = 0; i < lines.length; i++) {
const lineContent = multiline
? lines[i]
: caseSensitive
? lines[i]
: lines[i].toLowerCase();
if (lineContent.includes(pattern)) {
const from = Math.max(i - contextBefore, 0);
const to = Math.min(i + contextAfter + 1, lines.length);
for (let j = from; j < i; j++) {
matches.push(formatLine(lines[j], "", colors));
}
matches.push(formatLine(lines[i], pattern, colors, caseSensitive));
for (let j = i + 1; j < to; j++) {
matches.push(formatLine(lines[j], "", colors));
}
// Adjust the index to skip lines added as after context to avoid duplication
i += contextAfter;
}
}
return matches;
}
function formatLine(
line: string,
pattern: string,
colors: boolean,
caseSensitive: boolean = false
): string {
if (!colors || pattern === "") {
return line;
}
// Pattern highlighting
const regex = new RegExp(pattern, caseSensitive ? "g" : "gi");
return line.replace(regex, (match) => `\x1b[42m\x1b[30m${match}\x1b[0m`);
}
// Usage example
const content = `This project is powered by [@marko/run](https://github.com/marko-js/run).
- Run \`pnpm run dev\` to start the development server
- Run \`pnpm run build\` to build a production-ready node.js server
- Run \`pnpm run preview\` to run the production server
The Storybook Links addon can be used to create links that navigate between stories in Storybook.
[Create a custom ChatGPT to create stories](https://storybook.js.org/blog/build-your-own-storybook-gpt/)
Speeding up Development`;
console.log(
"CONTENT -----------------",
content,
"--------------------------------------"
);
const matchedLines = grep(content, "dev", {
context: { before: 3, after: 5 },
colors: true,
multiline: true,
});
console.log(matchedLines);