Skip to content

Commit

Permalink
feat: add ignoreMatchingLines prop support
Browse files Browse the repository at this point in the history
resolved #120
  • Loading branch information
Lruihao committed Jan 13, 2024
1 parent 538b3aa commit d8a735b
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 12 deletions.
9 changes: 8 additions & 1 deletion src/CodeDiff.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ interface Props {
hideHeader?: boolean
hideStat?: boolean
theme?: 'light' | 'dark'
// Give a pattern to ignore matching lines eg: '(time|token)' (**Only support side-by-side**)
ignoreMatchingLines?: string
}
const props = withDefaults(defineProps<Props>(), {
Expand All @@ -36,6 +38,7 @@ const props = withDefaults(defineProps<Props>(), {
hideHeader: false,
hideStat: false,
theme: 'light',
ignoreMatchingLines: undefined,
})
const emits = defineEmits<{
Expand Down Expand Up @@ -68,7 +71,7 @@ const newString = computed(() => {
const raw = computed(() =>
isUnifiedViewer.value
? createUnifiedDiff(oldString.value, newString.value, props.language, props.diffStyle, props.context)
: createSplitDiff(oldString.value, newString.value, props.language, props.diffStyle, props.context),
: createSplitDiff(oldString.value, newString.value, props.language, props.diffStyle, props.context, props.ignoreMatchingLines),
)
const diffChange = ref(raw.value)
const isNotChanged = computed(() => diffChange.value.stat.additionsNum === 0 && diffChange.value.stat.deletionsNum === 0)
Expand Down Expand Up @@ -110,6 +113,10 @@ watch(() => props, () => {
<slot name="stat" :stat="diffChange.stat">
<span class="diff-stat-added">+{{ diffChange.stat.additionsNum }} additions</span>
<span class="diff-stat-deleted">-{{ diffChange.stat.deletionsNum }} deletions</span>
<span
v-if="diffChange.stat.ignoreNum.additions + diffChange.stat.ignoreNum.deletions > 0"
class="diff-stat-ignored"
>±{{ diffChange.stat.ignoreNum.additions + diffChange.stat.ignoreNum.deletions }} lines</span>
</slot>
</span>
</span>
Expand Down
7 changes: 6 additions & 1 deletion src/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,18 @@
width: 50%;
}
.diff-stat {
display: inline-flex;
align-items: center;
gap: 8px;
.diff-stat-added {
color: var(--color-diffstat-addition-bg);
}
.diff-stat-deleted {
margin-left: 8px;
color: var(--color-danger-emphasis);
}
.diff-stat-ignored {
color: var(--color-fg-subtle);
}
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export interface UnifiedLineChange {
export interface DiffStat {
additionsNum: number
deletionsNum: number
ignoreNum: object
}

export interface SplitViewerChange {
Expand Down
34 changes: 24 additions & 10 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,19 +135,28 @@ function getHighlightCode(language: string, code: string) {
.replace(new RegExp(closeEntity, 'g'), '</span>')
}

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

let additionsNum = 0
let deletionsNum = 0
const ignoreNum = { additions: 0, deletions: 0 }
for (const change of changes) {
if (change.added)
additionsNum += count(change.value.trim(), '\n') + 1

if (change.removed)
deletionsNum += count(change.value.trim(), '\n') + 1
if (change.added) {
const ignoreLines = ignoreCount(change.value.trim().split('\n'))
additionsNum += count(change.value.trim(), '\n') + 1 - ignoreLines
ignoreNum.additions += ignoreLines
continue
}
if (change.removed) {
const ignoreLines = ignoreCount(change.value.trim().split('\n'))
deletionsNum += count(change.value.trim(), '\n') + 1 - ignoreLines
ignoreNum.deletions += ignoreLines
continue
}
}
return { additionsNum, deletionsNum }
return { additionsNum, deletionsNum, ignoreNum }
}

export function createSplitDiff(
Expand All @@ -156,10 +165,12 @@ export function createSplitDiff(
language = 'plaintext',
diffStyle = 'word',
context = 10,
ignoreMatchingLines?: string,
): SplitViewerChange {
const newEmptySplitDiff = (): DiffLine => ({ type: DiffType.EMPTY })
const newSplitDiff = (type: DiffType, num: number, code: string): DiffLine => ({ type, num, code })
const changes = diffLines(oldString, newString)
const ignoreRegex = ignoreMatchingLines ? new RegExp(ignoreMatchingLines) : undefined

let delNum = 0
let addNum = 0
Expand All @@ -169,7 +180,7 @@ export function createSplitDiff(
const result: SplitViewerChange = {
changes: rawChanges,
collector: [],
stat: calcDiffStat(changes),
stat: calcDiffStat(changes, ignoreRegex),
}

for (let i = 0; i < changes.length; i++) {
Expand Down Expand Up @@ -256,14 +267,17 @@ export function createSplitDiff(

const leftLine = curLines.length === nextLines.length ? renderWords(nextLine, curLine, diffStyle) : curLine
const rightLine = curLines.length === nextLines.length ? renderWords(curLine, nextLine, diffStyle) : nextLine
// 忽略匹配的行等价于相等
const leftDiffType = ignoreRegex?.test(leftLine) ? DiffType.EQUAL : DiffType.DELETE
const rightDiffType = ignoreRegex?.test(rightLine) ? DiffType.EQUAL : DiffType.ADD

const left
= j < cur.count!
? newSplitDiff(DiffType.DELETE, delNum, getHighlightCode(language, leftLine))
? newSplitDiff(leftDiffType, delNum, getHighlightCode(language, leftLine))
: newEmptySplitDiff()
const right
= j < next.count!
? newSplitDiff(DiffType.ADD, addNum, getHighlightCode(language, rightLine))
? newSplitDiff(rightDiffType, addNum, getHighlightCode(language, rightLine))
: newEmptySplitDiff()

rawChanges.push({ left, right })
Expand Down

0 comments on commit d8a735b

Please sign in to comment.