@yuhufe/wtool-vdiff 0.0.9 → 0.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/DiffFiles/FileExplore/FileExplore.vue.d.ts +3 -5
- package/dist/DiffViewer/DiffViewer.vue.d.ts +1 -1
- package/dist/DiffViewer/TopBar.vue.d.ts +0 -2
- package/dist/DiffViewer/utils/patch2Pair.d.ts +3 -3
- package/dist/utils/index.d.ts +1 -0
- package/dist/wtool-vdiff.cjs.js +39 -39
- package/dist/wtool-vdiff.es.js +5782 -5581
- package/package.json +13 -13
- package/src/DiffViewer/DiffViewer.vue +4 -3
- package/src/DiffViewer/TopBar.vue +2 -21
- package/src/DiffViewer/utils/patch2Pair.ts +18 -11
- package/src/utils/index.ts +5 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yuhufe/wtool-vdiff",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.11",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Monaco diff viewer as Vue 3 Web Component",
|
|
7
7
|
"keywords": [
|
|
@@ -11,6 +11,14 @@
|
|
|
11
11
|
"vue3",
|
|
12
12
|
"web-component"
|
|
13
13
|
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"vite": "pnpm run dev:site",
|
|
16
|
+
"dev:lib": "vite build --watch --mode development",
|
|
17
|
+
"build:site": "vite build --mode production --config site/vite.config.ts",
|
|
18
|
+
"dev:site": "vite --config site/vite.config.ts",
|
|
19
|
+
"build": "vite build --mode production",
|
|
20
|
+
"pub": "pnpm run build && pnpm publish"
|
|
21
|
+
},
|
|
14
22
|
"main": "./dist/wtool-vdiff.cjs.js",
|
|
15
23
|
"module": "./dist/wtool-vdiff.es.js",
|
|
16
24
|
"files": [
|
|
@@ -31,26 +39,18 @@
|
|
|
31
39
|
"@wsfe/vue-tree": "^4.1.1"
|
|
32
40
|
},
|
|
33
41
|
"devDependencies": {
|
|
42
|
+
"@yuhufe/web-common": "workspace:*",
|
|
43
|
+
"@yuhufe/web-ui": "workspace:*",
|
|
34
44
|
"@vitejs/plugin-vue": "^5.2.0",
|
|
35
45
|
"less": "4.6.4",
|
|
36
46
|
"typescript": "^6.0.3",
|
|
37
47
|
"vite": "^7.3.1",
|
|
38
48
|
"vite-plugin-css-injected-by-js": "5.0.1",
|
|
39
49
|
"vite-plugin-dts": "^4.5.3",
|
|
40
|
-
"vue": "^3.5.
|
|
41
|
-
"@yuhufe/web-ui": "0.1.1",
|
|
42
|
-
"@yuhufe/web-common": "0.1.1"
|
|
50
|
+
"vue": "^3.5.40"
|
|
43
51
|
},
|
|
44
52
|
"repository": {
|
|
45
53
|
"type": "git",
|
|
46
54
|
"url": "https://github.com/defghy/web-toolkits.git"
|
|
47
|
-
},
|
|
48
|
-
"scripts": {
|
|
49
|
-
"vite": "pnpm run dev:site",
|
|
50
|
-
"dev:lib": "vite build --watch --mode development",
|
|
51
|
-
"build:site": "vite build --mode production --config site/vite.config.ts",
|
|
52
|
-
"dev:site": "vite --config site/vite.config.ts",
|
|
53
|
-
"build": "vite build --mode production",
|
|
54
|
-
"pub": "pnpm run build && pnpm publish"
|
|
55
55
|
}
|
|
56
|
-
}
|
|
56
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="diff-viewer-wrap" :style="viewerStyle" @viewStateChange="">
|
|
3
|
-
<TopBar class="top-bar" :diffPair="diffPair"
|
|
3
|
+
<TopBar class="top-bar" :diffPair="diffPair" />
|
|
4
4
|
<div class="content-wrap" v-show="!viewed" v-loading="loading">
|
|
5
5
|
<MonacoDiffViewer
|
|
6
6
|
class="monaco-container"
|
|
@@ -28,6 +28,7 @@ import { useDiffViewer } from './useDiffView'
|
|
|
28
28
|
import { patch2Pair } from './utils/patch2Pair'
|
|
29
29
|
import { autoHeight } from './utils/autoHeight'
|
|
30
30
|
import { HEIGHT_TOP_BAR } from './const'
|
|
31
|
+
import { debugLog } from '../utils'
|
|
31
32
|
|
|
32
33
|
const emit = defineEmits<{
|
|
33
34
|
viewStateChange: [data: { viewed: boolean; rawed: boolean }]
|
|
@@ -39,7 +40,7 @@ const loading = ref(true)
|
|
|
39
40
|
const _renderStart = performance.now()
|
|
40
41
|
const onMonacoRenderComplete = async () => {
|
|
41
42
|
const cost = performance.now() - _renderStart
|
|
42
|
-
|
|
43
|
+
debugLog(`[DiffViewer] 渲染耗时: ${cost.toFixed(2)} ms`)
|
|
43
44
|
loading.value = false
|
|
44
45
|
}
|
|
45
46
|
|
|
@@ -62,7 +63,7 @@ const initDiff = function () {
|
|
|
62
63
|
diffPair.value = patch2Pair(props.diffPatch)
|
|
63
64
|
}
|
|
64
65
|
initDiff()
|
|
65
|
-
|
|
66
|
+
debugLog(`[DiffViewer] patch耗时: ${(performance.now() - _renderStart).toFixed(2)} ms`)
|
|
66
67
|
|
|
67
68
|
const originalCode = computed(() => diffPair.value[0]?.content ?? '')
|
|
68
69
|
const modifiedCode = computed(() => diffPair.value[1]?.content ?? '')
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
<div class="filename">{{ filenameDisplay }}</div>
|
|
5
5
|
<span :class="['diff-type-tag', diffType]">{{ diffTypeLabel }}</span>
|
|
6
6
|
<div class="diff-line-num">
|
|
7
|
-
<div class="add" v-if="diffType !== 'del'">+{{
|
|
8
|
-
<div class="del" v-if="diffType !== 'add'">-{{
|
|
7
|
+
<div class="add" v-if="diffType !== 'del'">+{{ changed.added }}</div>
|
|
8
|
+
<div class="del" v-if="diffType !== 'add'">-{{ changed.removed }}</div>
|
|
9
9
|
</div>
|
|
10
10
|
</div>
|
|
11
11
|
<div class="toolbar">
|
|
@@ -25,18 +25,15 @@
|
|
|
25
25
|
import { computed, ref, onMounted } from 'vue'
|
|
26
26
|
import { useDiffViewer } from './useDiffView'
|
|
27
27
|
import { HEIGHT_TOP_BAR } from './const'
|
|
28
|
-
import { parsePatchHunks } from '@/utils/patch'
|
|
29
28
|
|
|
30
29
|
const { funcs, registerFunc } = useDiffViewer()
|
|
31
30
|
|
|
32
31
|
const props = withDefaults(
|
|
33
32
|
defineProps<{
|
|
34
33
|
diffPair?: { filename: string; content: string | null }[]
|
|
35
|
-
diffPatch?: string
|
|
36
34
|
}>(),
|
|
37
35
|
{
|
|
38
36
|
diffPair: () => [],
|
|
39
|
-
diffPatch: '',
|
|
40
37
|
}
|
|
41
38
|
)
|
|
42
39
|
|
|
@@ -90,22 +87,6 @@ onMounted(() => {
|
|
|
90
87
|
|
|
91
88
|
// 变更行数
|
|
92
89
|
const changed = ref({ added: 0, removed: 0 })
|
|
93
|
-
const patchChanged = computed(() => {
|
|
94
|
-
const result = { added: 0, removed: 0 }
|
|
95
|
-
|
|
96
|
-
for (const hunk of parsePatchHunks(props.diffPatch)) {
|
|
97
|
-
for (const line of hunk.lines) {
|
|
98
|
-
if (line.startsWith('+')) {
|
|
99
|
-
result.added++
|
|
100
|
-
} else if (line.startsWith('-')) {
|
|
101
|
-
result.removed++
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
return result
|
|
107
|
-
})
|
|
108
|
-
const displayedChanged = computed(() => (props.diffPatch ? patchChanged.value : changed.value))
|
|
109
90
|
function updateChangedLines(newVal) {
|
|
110
91
|
Object.assign(changed.value, newVal)
|
|
111
92
|
}
|
|
@@ -2,7 +2,7 @@ import { parsePatchFilenames, parsePatchHunks } from '@/utils/patch'
|
|
|
2
2
|
|
|
3
3
|
export interface FilePair {
|
|
4
4
|
filename: string
|
|
5
|
-
content: string
|
|
5
|
+
content: string | null
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
export interface PatchChangedLineBlock {
|
|
@@ -23,8 +23,8 @@ export interface PatchPairLayout {
|
|
|
23
23
|
* - hunk 之外的行(patch 未提供内容):两侧各补一个空行撑开行号,
|
|
24
24
|
* Monaco hideUnchangedRegions 会将这些相同的空行折叠并显示正确的行号范围
|
|
25
25
|
* - context 行(' '):两侧均写入真实内容
|
|
26
|
-
* - 连续的删除('-')/ 新增('+'
|
|
27
|
-
*
|
|
26
|
+
* - 连续的删除('-')/ 新增('+')块:分别写入对应侧,
|
|
27
|
+
* 由 Monaco 自己为纯新增、纯删除和不等长替换生成视觉占位
|
|
28
28
|
*/
|
|
29
29
|
export const patch2PairWithLayout = function (patch: string): PatchPairLayout {
|
|
30
30
|
if (!patch) {
|
|
@@ -47,17 +47,17 @@ export const patch2PairWithLayout = function (patch: string): PatchPairLayout {
|
|
|
47
47
|
|
|
48
48
|
const pendingDel: string[] = []
|
|
49
49
|
const pendingAdd: string[] = []
|
|
50
|
+
let layoutLineCount = 0
|
|
50
51
|
|
|
51
52
|
const flushPending = () => {
|
|
52
53
|
const maxLen = Math.max(pendingDel.length, pendingAdd.length)
|
|
53
54
|
if (maxLen > 0) {
|
|
54
|
-
const start =
|
|
55
|
+
const start = layoutLineCount + 1
|
|
55
56
|
changedLineBlocks.push({ start, end: start + maxLen - 1 })
|
|
57
|
+
layoutLineCount += maxLen
|
|
56
58
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
modLines.push(pendingAdd[i] ?? '')
|
|
60
|
-
}
|
|
59
|
+
origLines.push(...pendingDel)
|
|
60
|
+
modLines.push(...pendingAdd)
|
|
61
61
|
pendingDel.length = 0
|
|
62
62
|
pendingAdd.length = 0
|
|
63
63
|
}
|
|
@@ -67,6 +67,8 @@ export const patch2PairWithLayout = function (patch: string): PatchPairLayout {
|
|
|
67
67
|
|
|
68
68
|
for (const hunk of hunks) {
|
|
69
69
|
// hunk 之前(或两个 hunk 之间)的 gap:两侧各补空行对齐行号
|
|
70
|
+
const origGap = hunk.origStart - origCursor
|
|
71
|
+
const modGap = hunk.modStart - modCursor
|
|
70
72
|
while (origCursor < hunk.origStart) {
|
|
71
73
|
origLines.push('')
|
|
72
74
|
origCursor++
|
|
@@ -75,6 +77,7 @@ export const patch2PairWithLayout = function (patch: string): PatchPairLayout {
|
|
|
75
77
|
modLines.push('')
|
|
76
78
|
modCursor++
|
|
77
79
|
}
|
|
80
|
+
layoutLineCount += Math.max(0, origGap, modGap)
|
|
78
81
|
|
|
79
82
|
for (const line of hunk.lines) {
|
|
80
83
|
const prefix = line[0]
|
|
@@ -86,6 +89,7 @@ export const patch2PairWithLayout = function (patch: string): PatchPairLayout {
|
|
|
86
89
|
modLines.push(content)
|
|
87
90
|
origCursor++
|
|
88
91
|
modCursor++
|
|
92
|
+
layoutLineCount++
|
|
89
93
|
} else if (prefix === '-') {
|
|
90
94
|
pendingDel.push(content)
|
|
91
95
|
origCursor++
|
|
@@ -98,13 +102,16 @@ export const patch2PairWithLayout = function (patch: string): PatchPairLayout {
|
|
|
98
102
|
flushPending()
|
|
99
103
|
}
|
|
100
104
|
|
|
105
|
+
const originalContent = origLines.length === 0 && modLines.length > 0 ? null : origLines.join('\n')
|
|
106
|
+
const modifiedContent = modLines.length === 0 && origLines.length > 0 ? null : modLines.join('\n')
|
|
107
|
+
|
|
101
108
|
return {
|
|
102
109
|
pair: [
|
|
103
|
-
{ filename: origFilename, content:
|
|
104
|
-
{ filename: modFilename, content:
|
|
110
|
+
{ filename: origFilename, content: originalContent },
|
|
111
|
+
{ filename: modFilename, content: modifiedContent },
|
|
105
112
|
],
|
|
106
113
|
changedLineBlocks,
|
|
107
|
-
totalLines:
|
|
114
|
+
totalLines: layoutLineCount,
|
|
108
115
|
}
|
|
109
116
|
}
|
|
110
117
|
|