Skip to content

Commit 399006d

Browse files
authored
Merge pull request #53 from constructive-io/devin/1767654217-visual-diff
feat: add visual-diff package with syntax highlighting
2 parents d4cfa16 + 25f57a2 commit 399006d

25 files changed

Lines changed: 3307 additions & 0 deletions

packages/visual-diff/README.md

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
# @interweb/visual-diff
2+
3+
Beautiful visual diff with syntax highlighting for terminal and HTML output.
4+
5+
## Features
6+
7+
- Line-by-line diff computation with LCS algorithm
8+
- Syntax highlighting for 15+ languages (JavaScript, TypeScript, Python, SQL, Go, Rust, and more)
9+
- Beautiful terminal output with ANSI colors
10+
- HTML output with dark/light mode support
11+
- 6 built-in themes (default, github, monokai, dracula, nord, minimal)
12+
- Customizable themes and styling
13+
- Side-by-side and unified diff views
14+
- Parse and create unified diff format
15+
16+
## Installation
17+
18+
```bash
19+
npm install @interweb/visual-diff
20+
# or
21+
pnpm add @interweb/visual-diff
22+
# or
23+
yarn add @interweb/visual-diff
24+
```
25+
26+
## Quick Start
27+
28+
```typescript
29+
import { diff, renderTerminal, renderHtml } from '@interweb/visual-diff';
30+
31+
const oldCode = `function hello() {
32+
console.log("Hello");
33+
}`;
34+
35+
const newCode = `function hello() {
36+
console.log("Hello, World!");
37+
}`;
38+
39+
// Compute the diff
40+
const result = diff(oldCode, newCode);
41+
42+
// Render to terminal with syntax highlighting
43+
console.log(renderTerminal(result, {
44+
language: 'javascript',
45+
theme: 'dracula'
46+
}));
47+
48+
// Render to HTML
49+
const html = renderHtml(result, {
50+
language: 'javascript',
51+
darkMode: true
52+
});
53+
```
54+
55+
## API
56+
57+
### Diff Functions
58+
59+
#### `diff(oldContent, newContent, options?)`
60+
61+
Computes the diff between two strings.
62+
63+
```typescript
64+
const result = diff(oldContent, newContent, {
65+
context: 3, // Number of context lines (default: 3)
66+
ignoreWhitespace: false, // Ignore whitespace differences
67+
ignoreCase: false // Ignore case differences
68+
});
69+
```
70+
71+
#### `diffFiles(oldContent, newContent, oldFile, newFile, options?)`
72+
73+
Computes diff with file metadata and auto-detected language.
74+
75+
```typescript
76+
const result = diffFiles(
77+
oldContent,
78+
newContent,
79+
'src/old.ts',
80+
'src/new.ts'
81+
);
82+
// result.language will be 'typescript'
83+
```
84+
85+
### Render Functions
86+
87+
#### `renderTerminal(result, options?)`
88+
89+
Renders diff to terminal with ANSI colors.
90+
91+
```typescript
92+
const output = renderTerminal(result, {
93+
theme: 'github', // Theme name or custom theme
94+
showLineNumbers: true, // Show line numbers
95+
syntaxHighlight: true, // Enable syntax highlighting
96+
language: 'typescript', // Override language detection
97+
colorize: true // Enable ANSI colors
98+
});
99+
```
100+
101+
#### `renderHtml(result, options?)`
102+
103+
Renders diff to HTML.
104+
105+
```typescript
106+
const html = renderHtml(result, {
107+
theme: 'monokai',
108+
darkMode: true,
109+
className: 'my-diff',
110+
inlineStyles: true,
111+
syntaxHighlight: true
112+
});
113+
```
114+
115+
#### `renderHtmlDocument(result, options?)`
116+
117+
Renders a complete HTML document with the diff.
118+
119+
#### `renderHtmlSideBySide(result, options?)`
120+
121+
Renders diff in side-by-side layout.
122+
123+
### Themes
124+
125+
Built-in themes:
126+
- `default` - Clean default theme
127+
- `github` - GitHub-style colors
128+
- `monokai` - Monokai editor theme
129+
- `dracula` - Dracula theme
130+
- `nord` - Nord color palette
131+
- `minimal` - Minimal styling
132+
133+
#### Custom Themes
134+
135+
```typescript
136+
import { createTheme } from '@interweb/visual-diff';
137+
138+
const myTheme = createTheme('custom', {
139+
added: { fg: 'cyan', bold: true },
140+
removed: { fg: 'yellow' },
141+
syntax: {
142+
keyword: { fg: 'magenta', bold: true },
143+
string: { fg: 'green' }
144+
}
145+
});
146+
147+
renderTerminal(result, { theme: myTheme });
148+
```
149+
150+
### Syntax Highlighting
151+
152+
Supported languages:
153+
- JavaScript / TypeScript
154+
- Python
155+
- JSON
156+
- HTML / XML
157+
- CSS / SCSS
158+
- SQL
159+
- YAML
160+
- Markdown
161+
- Go
162+
- Rust
163+
- Java
164+
- C / C++
165+
- Shell / Bash
166+
167+
#### Language Detection
168+
169+
```typescript
170+
import { detectLanguage } from '@interweb/visual-diff';
171+
172+
detectLanguage('file.ts'); // 'typescript'
173+
detectLanguage('file.py'); // 'python'
174+
detectLanguage('file.sql'); // 'sql'
175+
```
176+
177+
### Unified Diff Format
178+
179+
```typescript
180+
import { createUnifiedDiff, parseUnifiedDiff } from '@interweb/visual-diff';
181+
182+
// Create unified diff string
183+
const unified = createUnifiedDiff(result);
184+
185+
// Parse unified diff string
186+
const parsed = parseUnifiedDiff(unifiedDiffString);
187+
```
188+
189+
### Utilities
190+
191+
```typescript
192+
import { hasDifferences, countChanges } from '@interweb/visual-diff';
193+
194+
// Check if there are any differences
195+
if (hasDifferences(result)) {
196+
// Get counts
197+
const { additions, deletions } = countChanges(result);
198+
console.log(`+${additions} -${deletions}`);
199+
}
200+
```
201+
202+
## License
203+
204+
MIT

0 commit comments

Comments
 (0)