Skip to content

Commit e52b848

Browse files
authored
Merge pull request #121 from Lruihao/master
增加支持 ignoreMatchingLines 属性
2 parents 538b3aa + 0ec8ec8 commit e52b848

9 files changed

Lines changed: 92 additions & 27 deletions

File tree

README-zh.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,14 +121,23 @@ Vue.use(CodeDiff)
121121
| maxHeight | 组件最大高度,例如 300px | string | - | undefined |
122122
| filename | 文件名 | string | - | undefined |
123123
| newFilename | 新文件文件名 | string | - | undefined |
124+
| hideHeader | 隐藏头部栏 | boolean | - | false |
125+
| hideStat | 隐藏头部栏中的统计信息 | boolean | - | false |
124126
| theme | 用于切换日间模式/夜间模式 | ThemeType | light , dark | light |
127+
| ignoreMatchingLines | 给出一个模式来忽略匹配行,例如:'(time\|token)' | string | - | |
125128

126129
## 组件事件
127130

128131
| Name | Description | Type |
129132
| ---- | --------------- | ------------------------------------------------------------------------------- |
130133
| diff | diff 完成后触发 | (result: {stat: { isChanged: boolean, addNum: number, delNum: number}}) => void |
131134

135+
## 组件插槽
136+
137+
| Name | Description |
138+
| ---- | ------------------------------- |
139+
| stat | 自定义统计内容,参数为 { stat } |
140+
132141
## 拓展高亮语言
133142

134143
为了减小打包后的体积,系统默认仅支持以下常用语言

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,14 +123,23 @@ Not recommended, but the relevant capabilities are retained to facilitate migrat
123123
| maxHeight | Maximum height of component, for example: 300px | string | - | undefined |
124124
| filename | Filename | string | - | undefined |
125125
| newFilename | New filename | string | - | undefined |
126+
| hideHeader | Hide header bar | boolean | - | false |
127+
| hideStat | Hide statistical part in the header bar | boolean | - | false |
126128
| theme | Add dark mode | ThemeType | light , dark | light |
129+
| ignoreMatchingLines | Give a pattern to ignore matching lines eg: '(time\|token)' | string | - | undefined |
127130

128131
## Events
129132

130133
| Name | Description | Type |
131134
| ---- | --------------------------- | ------------------------------------------------------------------------------- |
132135
| diff | triggers when diff finished | (result: {stat: { isChanged: boolean, addNum: number, delNum: number}}) => void |
133136

137+
## Slot
138+
139+
| Name | Description |
140+
| ---- | ----------------------------------------------------------- |
141+
| stat | Custom statistical content, The scope parameter is { stat } |
142+
134143
## Extend languages
135144

136145
In order to reduce the size of the packaged file, the system only supports the following commonly used languages by

src/CodeDiff.vue

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ interface Props {
2121
hideHeader?: boolean
2222
hideStat?: boolean
2323
theme?: 'light' | 'dark'
24+
// Give a pattern to ignore matching lines eg: '(time|token)'
25+
ignoreMatchingLines?: string
2426
}
2527
2628
const props = withDefaults(defineProps<Props>(), {
@@ -36,6 +38,7 @@ const props = withDefaults(defineProps<Props>(), {
3638
hideHeader: false,
3739
hideStat: false,
3840
theme: 'light',
41+
ignoreMatchingLines: undefined,
3942
})
4043
4144
const emits = defineEmits<{
@@ -67,8 +70,8 @@ const newString = computed(() => {
6770
6871
const raw = computed(() =>
6972
isUnifiedViewer.value
70-
? createUnifiedDiff(oldString.value, newString.value, props.language, props.diffStyle, props.context)
71-
: createSplitDiff(oldString.value, newString.value, props.language, props.diffStyle, props.context),
73+
? createUnifiedDiff(oldString.value, newString.value, props.language, props.diffStyle, props.context, props.ignoreMatchingLines)
74+
: createSplitDiff(oldString.value, newString.value, props.language, props.diffStyle, props.context, props.ignoreMatchingLines),
7275
)
7376
const diffChange = ref(raw.value)
7477
const isNotChanged = computed(() => diffChange.value.stat.additionsNum === 0 && diffChange.value.stat.deletionsNum === 0)

src/style.scss

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,22 +29,27 @@
2929
height: 24px;
3030

3131
.info-left {
32-
font-size: 13px;
3332
color: var(--color-fg-default);
3433
}
3534
.info-right {
3635
display: flex;
3736
justify-content: space-between;
37+
align-items: center;
3838
width: 50%;
3939
}
4040
.diff-stat {
41+
display: inline-flex;
42+
align-items: center;
43+
gap: 8px;
4144
.diff-stat-added {
4245
color: var(--color-diffstat-addition-bg);
4346
}
4447
.diff-stat-deleted {
45-
margin-left: 8px;
4648
color: var(--color-danger-emphasis);
4749
}
50+
.diff-stat-ignored {
51+
color: var(--color-fg-subtle);
52+
}
4853
}
4954
}
5055
}

src/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ export interface UnifiedLineChange {
4242
export interface DiffStat {
4343
additionsNum: number
4444
deletionsNum: number
45+
ignoreAdditionsNum: number
46+
ignoreDeletionsNum: number
4547
}
4648

4749
export interface SplitViewerChange {

src/utils.ts

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -135,19 +135,34 @@ function getHighlightCode(language: string, code: string) {
135135
.replace(new RegExp(closeEntity, 'g'), '</span>')
136136
}
137137

138-
function calcDiffStat(changes: Change[]): DiffStat {
138+
function calcDiffStat(changes: Change[], ignoreRegex?: RegExp): DiffStat {
139139
const count = (s: string, c: string) => (s.match(new RegExp(c, 'g')) || []).length
140+
const ignoreCount = (lines: string[]) => lines.filter(line => ignoreRegex?.test(line)).length
140141

141142
let additionsNum = 0
142143
let deletionsNum = 0
144+
let ignoreAdditionsNum = 0
145+
let ignoreDeletionsNum = 0
143146
for (const change of changes) {
144-
if (change.added)
145-
additionsNum += count(change.value.trim(), '\n') + 1
146-
147-
if (change.removed)
148-
deletionsNum += count(change.value.trim(), '\n') + 1
147+
if (change.added) {
148+
const ignoreNum = ignoreCount(change.value.trim().split('\n'))
149+
additionsNum += count(change.value.trim(), '\n') + 1 - ignoreNum
150+
ignoreAdditionsNum += ignoreNum
151+
continue
152+
}
153+
if (change.removed) {
154+
const ignoreNum = ignoreCount(change.value.trim().split('\n'))
155+
deletionsNum += count(change.value.trim(), '\n') + 1 - ignoreNum
156+
ignoreDeletionsNum += ignoreNum
157+
continue
158+
}
159+
}
160+
return {
161+
additionsNum,
162+
deletionsNum,
163+
ignoreAdditionsNum,
164+
ignoreDeletionsNum,
149165
}
150-
return { additionsNum, deletionsNum }
151166
}
152167

153168
export function createSplitDiff(
@@ -156,10 +171,12 @@ export function createSplitDiff(
156171
language = 'plaintext',
157172
diffStyle = 'word',
158173
context = 10,
174+
ignoreMatchingLines?: string,
159175
): SplitViewerChange {
160176
const newEmptySplitDiff = (): DiffLine => ({ type: DiffType.EMPTY })
161177
const newSplitDiff = (type: DiffType, num: number, code: string): DiffLine => ({ type, num, code })
162178
const changes = diffLines(oldString, newString)
179+
const ignoreRegex = ignoreMatchingLines ? new RegExp(ignoreMatchingLines) : undefined
163180

164181
let delNum = 0
165182
let addNum = 0
@@ -169,7 +186,7 @@ export function createSplitDiff(
169186
const result: SplitViewerChange = {
170187
changes: rawChanges,
171188
collector: [],
172-
stat: calcDiffStat(changes),
189+
stat: calcDiffStat(changes, ignoreRegex),
173190
}
174191

175192
for (let i = 0; i < changes.length; i++) {
@@ -257,13 +274,17 @@ export function createSplitDiff(
257274
const leftLine = curLines.length === nextLines.length ? renderWords(nextLine, curLine, diffStyle) : curLine
258275
const rightLine = curLines.length === nextLines.length ? renderWords(curLine, nextLine, diffStyle) : nextLine
259276

277+
// 忽略匹配的行等价于相等
278+
const leftDiffType = ignoreRegex?.test(curLine) ? DiffType.EQUAL : DiffType.DELETE
279+
const rightDiffType = ignoreRegex?.test(nextLine) ? DiffType.EQUAL : DiffType.ADD
280+
260281
const left
261282
= j < cur.count!
262-
? newSplitDiff(DiffType.DELETE, delNum, getHighlightCode(language, leftLine))
283+
? newSplitDiff(leftDiffType, delNum, getHighlightCode(language, leftLine))
263284
: newEmptySplitDiff()
264285
const right
265286
= j < next.count!
266-
? newSplitDiff(DiffType.ADD, addNum, getHighlightCode(language, rightLine))
287+
? newSplitDiff(rightDiffType, addNum, getHighlightCode(language, rightLine))
267288
: newEmptySplitDiff()
268289

269290
rawChanges.push({ left, right })
@@ -341,8 +362,10 @@ export function createUnifiedDiff(
341362
language = 'plaintext',
342363
diffStyle = 'word',
343364
context = 10,
365+
ignoreMatchingLines?: string,
344366
): UnifiedViewerChange {
345367
const changes = diffLines(oldString, newString)
368+
const ignoreRegex = ignoreMatchingLines ? new RegExp(ignoreMatchingLines) : undefined
346369

347370
let delNum = 0
348371
let addNum = 0
@@ -352,7 +375,7 @@ export function createUnifiedDiff(
352375
const result: UnifiedViewerChange = {
353376
changes: rawChanges,
354377
collector: [],
355-
stat: calcDiffStat(changes),
378+
stat: calcDiffStat(changes, ignoreRegex),
356379
}
357380

358381
for (let i = 0; i < changes.length; i++) {
@@ -414,7 +437,11 @@ export function createUnifiedDiff(
414437
delNum++
415438

416439
const code = getHighlightCode(language, renderWords(nextLine, curLine, diffStyle))
417-
rawChanges.push({ type: DiffType.DELETE, code, delNum })
440+
rawChanges.push({
441+
type: ignoreRegex?.test(curLine) ? DiffType.EQUAL : DiffType.DELETE,
442+
code,
443+
delNum,
444+
})
418445
}
419446

420447
for (let j = 0; j < nextLines.length; j++) {
@@ -423,7 +450,11 @@ export function createUnifiedDiff(
423450
addNum++
424451

425452
const code = getHighlightCode(language, renderWords(curLine, nextLine, diffStyle))
426-
rawChanges.push({ type: DiffType.ADD, code, addNum })
453+
rawChanges.push({
454+
type: ignoreRegex?.test(nextLine) ? DiffType.EQUAL : DiffType.ADD,
455+
code,
456+
addNum,
457+
})
427458
}
428459

429460
skip = true

vue2-playground/App.vue

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22
import { reactive, version } from 'vue-demi'
33
44
const form = reactive({
5-
oldString: '<script setup lang="ts">',
6-
newString: '<script lang="ts" setup>',
7-
language: 'python',
5+
oldString: '{\n "code": "200",\n "msg": "请求成功",\n "data": {\n "hitokoto": "往者不可谏,来者犹可追。",\n "from": "论语·微子篇"\n },\n "time": "2024-01-12 17:27:03"\n}',
6+
newString: '{\n "code": "200",\n "msg": "请求成功",\n "data": {\n "hitokoto": "成熟的人眼里满是前途,稚嫩的人眼里满是爱恨情仇。",\n "from": "网易云热评"\n },\n "time": "2024-01-12 17:27:06"\n}',
7+
language: 'json',
88
diffStyle: 'word',
9+
ignoreMatchingLines: 'time',
910
})
1011
</script>
1112

@@ -21,6 +22,7 @@ const form = reactive({
2122
:new-string="form.newString"
2223
:language="form.language"
2324
:diff-style="form.diffStyle"
25+
:ignore-matching-lines="form.ignoreMatchingLines"
2426
output-format="side-by-side"
2527
/>
2628
</div>

vue2.7-playground/App.vue

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ import { version } from 'vue-demi'
33
import { reactive } from 'vue'
44
55
const form = reactive({
6-
oldString: '<script setup lang="ts">',
7-
newString: '<script lang="ts" setup>',
8-
language: 'python',
6+
oldString: '{\n "code": "200",\n "msg": "请求成功",\n "data": {\n "hitokoto": "往者不可谏,来者犹可追。",\n "from": "论语·微子篇"\n },\n "time": "2024-01-12 17:27:03"\n}',
7+
newString: '{\n "code": "200",\n "msg": "请求成功",\n "data": {\n "hitokoto": "成熟的人眼里满是前途,稚嫩的人眼里满是爱恨情仇。",\n "from": "网易云热评"\n },\n "time": "2024-01-12 17:27:06"\n}',
8+
language: 'json',
99
diffStyle: 'word',
10+
ignoreMatchingLines: 'time',
1011
})
1112
</script>
1213

@@ -22,6 +23,7 @@ const form = reactive({
2223
:new-string="form.newString"
2324
:language="form.language"
2425
:diff-style="form.diffStyle"
26+
:ignore-matching-lines="form.ignoreMatchingLines"
2527
output-format="side-by-side"
2628
/>
2729
</div>

vue3-playground/App.vue

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@ import { reactive } from 'vue'
88
const form = reactive({
99
// oldString: oldLongText,
1010
// newString: newLongText,
11-
oldString: '123\n123\n123\n456\n123\n123\n123\n123\n123\n123\n123\n',
12-
newString: '123\n123\n123\n123\n123\n123\n123\n123\n123\n123\n123\n',
11+
oldString: '{\n "code": "200",\n "msg": "请求成功",\n "data": {\n "hitokoto": "往者不可谏,来者犹可追。",\n "from": "论语·微子篇"\n },\n "time": "2024-01-12 17:27:03"\n}',
12+
newString: '{\n "code": "200",\n "msg": "请求成功",\n "data": {\n "hitokoto": "成熟的人眼里满是前途,稚嫩的人眼里满是爱恨情仇。",\n "from": "网易云热评"\n },\n "time": "2024-01-12 17:27:06"\n}',
1313
filename: 'oldFile',
1414
newFilename: 'newFile',
15-
language: 'plaintext',
15+
language: 'json',
1616
diffStyle: 'word',
17-
outputFormat: 'line-by-line',
17+
outputFormat: 'site-by-site',
18+
ignoreMatchingLines: 'time',
1819
context: 3,
1920
})
2021
</script>
@@ -34,6 +35,7 @@ const form = reactive({
3435
:new-filename="form.newFilename"
3536
:language="form.language"
3637
:output-format="form.outputFormat"
38+
:ignore-matching-lines="form.ignoreMatchingLines"
3739
:diff-style="form.diffStyle"
3840
:context="form.context"
3941
/>

0 commit comments

Comments
 (0)