@yuhufe/wtool-vdiff 0.0.5 → 0.0.6

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@yuhufe/wtool-vdiff",
3
3
  "private": false,
4
- "version": "0.0.5",
4
+ "version": "0.0.6",
5
5
  "type": "module",
6
6
  "description": "Monaco diff viewer as Vue 3 Web Component",
7
7
  "keywords": [
@@ -2,29 +2,33 @@ import type { WtoolDiffViewerProps } from '@/types'
2
2
  import { parseHunks } from './patch2Pair'
3
3
 
4
4
  const LINE_HEIGHT = 18
5
+ const GAP_HEIGHT = 24
5
6
 
6
7
  interface CommonParams {
7
- minLine: number
8
- maxLine: number
8
+ minPx: number
9
+ maxPx: number
9
10
  unchangedVisiable: boolean
10
11
  unchangedCtxLineNum: number
11
12
  }
12
13
 
13
14
  /**
14
15
  * 在线可见行计数器,按顺序逐个喂入变更区间(1-based inclusive),流式累计可见行数。
15
- * 区间必须按 start 升序喂入,每次 feed 后可读取 visible 判断是否达到 maxLine。
16
+ * 区间必须按 start 升序喂入,每次 feed 后可读取 maxReached 判断是否达到像素上限。
16
17
  * @param totalLines 文件总行数,用于 clamp context 窗口上界及判断尾部是否有折叠 widget
17
18
  * @param ctx 每个变更块上下保留的 context 行数,对应 Monaco contextLineCount
18
- * @param maxLine 可见行上限,达到后 maxReached 为 true,调用方应立即停止 feed
19
+ * @param maxPx 像素上限,达到后 maxReached 为 true,调用方应立即停止 feed
19
20
  */
20
- function makeVisibleLineCounter(totalLines: number, ctx: number, maxLine: number) {
21
+ function makeVisibleLineCounter(totalLines: number, ctx: number, maxPx: number) {
21
22
  let visible = 0 // 已 commit 的确定可见行数(不含当前 pending 块)
23
+ let gaps = 0 // gap widget 数量(每个折叠区域占 GAP_HEIGHT,非 LINE_HEIGHT)
22
24
  let pendingStart = -1 // 当前待合并窗口的起始行(-1 表示无 pending)
23
25
  let pendingEnd = -1 // 当前待合并窗口的结束行
24
26
 
27
+ const usedPx = () => visible * LINE_HEIGHT + gaps * GAP_HEIGHT
28
+
25
29
  const commitPending = () => {
26
30
  if (pendingStart === -1) return
27
- if (pendingStart > 1) visible += 1
31
+ if (pendingStart > 1) gaps += 1
28
32
  visible += pendingEnd - pendingStart + 1
29
33
  pendingStart = -1
30
34
  pendingEnd = -1
@@ -43,79 +47,82 @@ function makeVisibleLineCounter(totalLines: number, ctx: number, maxLine: number
43
47
  }
44
48
  },
45
49
  flush() {
50
+ const lastEnd = pendingEnd
46
51
  commitPending()
47
- if (visible > 0 && pendingEnd !== totalLines) visible += 1
48
- return Math.min(visible, maxLine)
52
+ if (visible > 0 && lastEnd !== totalLines) gaps += 1
53
+ return usedPx()
54
+ },
55
+ get usedPx() {
56
+ return usedPx()
49
57
  },
50
- get visible() {
51
- return visible
58
+ get gaps() {
59
+ return gaps
52
60
  },
53
61
  get maxReached() {
54
- return visible >= maxLine
62
+ return usedPx() >= maxPx
55
63
  },
56
64
  }
57
65
  }
58
66
 
59
67
  const autoHeightPatch = function ({
60
68
  patch,
61
- minLine,
62
- maxLine,
69
+ minPx,
70
+ maxPx,
63
71
  unchangedCtxLineNum,
64
72
  }: {
65
73
  patch: string
66
74
  } & CommonParams): number {
67
75
  const { hunks } = parseHunks(patch)
68
- if (hunks.length === 0) return minLine
76
+ if (hunks.length === 0) return minPx
69
77
 
70
78
  const lastHunk = hunks[hunks.length - 1]
71
79
  const totalLines = Math.max(
72
80
  lastHunk.origStart + lastHunk.origCount - 1,
73
81
  lastHunk.modStart + lastHunk.modCount - 1,
74
82
  )
75
- const counter = makeVisibleLineCounter(totalLines, unchangedCtxLineNum, maxLine)
83
+ const counter = makeVisibleLineCounter(totalLines, unchangedCtxLineNum, maxPx)
76
84
 
77
85
  for (const h of hunks) {
78
86
  const hunkEnd = Math.max(h.origStart + h.origCount - 1, h.modStart + h.modCount - 1)
79
87
  counter.feed(h.origStart, hunkEnd)
80
- if (counter.maxReached) return maxLine
88
+ if (counter.maxReached) return maxPx
81
89
  }
82
90
 
83
- return Math.max(minLine, counter.flush())
91
+ return Math.max(minPx, counter.flush())
84
92
  }
85
93
 
86
94
  const autoHeightPair = function ({
87
95
  pair,
88
- minLine,
89
- maxLine,
96
+ minPx,
97
+ maxPx,
90
98
  unchangedVisiable,
91
99
  unchangedCtxLineNum,
92
100
  }: {
93
101
  pair: WtoolDiffViewerProps['diffPair']
94
102
  } & CommonParams): number {
95
- if (!pair || pair.length < 2) return minLine
103
+ if (!pair || pair.length < 2) return minPx
96
104
 
97
105
  const origLines = pair[0].content?.split('\n') ?? []
98
106
  const modLines = pair[1].content?.split('\n') ?? []
99
107
  const totalLines = Math.max(origLines.length, modLines.length)
100
108
 
101
109
  if (unchangedVisiable) {
102
- return Math.max(minLine, Math.min(totalLines, maxLine))
110
+ return Math.max(minPx, Math.min(totalLines * LINE_HEIGHT, maxPx))
103
111
  }
104
112
 
105
- const counter = makeVisibleLineCounter(totalLines, unchangedCtxLineNum, maxLine)
106
- let i = 0
107
- while (i < totalLines) {
108
- if ((origLines[i] ?? '') !== (modLines[i] ?? '')) {
109
- const start = i + 1
110
- while (i < totalLines && (origLines[i] ?? '') !== (modLines[i] ?? '')) i++
111
- counter.feed(start, i)
112
- if (counter.maxReached) return maxLine
113
- } else {
114
- i++
115
- }
116
- }
113
+ // 剥前缀相同行
114
+ let lo = 0
115
+ while (lo < origLines.length && lo < modLines.length && origLines[lo] === modLines[lo]) lo++
116
+
117
+ // 剥后缀相同行
118
+ let origHi = origLines.length, modHi = modLines.length
119
+ while (origHi > lo && modHi > lo && origLines[origHi - 1] === modLines[modHi - 1]) { origHi--; modHi-- }
120
+
121
+ if (origHi <= lo && modHi <= lo) return minPx
117
122
 
118
- return Math.max(minLine, counter.flush())
123
+ const counter = makeVisibleLineCounter(totalLines, unchangedCtxLineNum, maxPx)
124
+ counter.feed(lo + 1, Math.max(origHi, modHi))
125
+ return Math.max(minPx, counter.flush())
119
126
  }
120
127
 
121
128
  const height2Num = (heightStr: string): number => {
@@ -141,9 +148,9 @@ export const autoHeight = function ({
141
148
  unchangedVisiable: boolean
142
149
  unchangedCtxLineNum: number
143
150
  }): number {
144
- const [minLine, maxLine] = [minHeight, maxHeight].map(str => Math.floor(height2Num(str) / LINE_HEIGHT))
145
- const commonParams: CommonParams = { minLine, maxLine, unchangedVisiable, unchangedCtxLineNum }
151
+ const [minPx, maxPx] = [minHeight, maxHeight].map(height2Num)
152
+ const commonParams: CommonParams = { minPx, maxPx, unchangedVisiable, unchangedCtxLineNum }
146
153
 
147
- if (patch) return autoHeightPatch({ patch, ...commonParams }) * LINE_HEIGHT
148
- return autoHeightPair({ pair, ...commonParams }) * LINE_HEIGHT
154
+ if (patch) return autoHeightPatch({ patch, ...commonParams })
155
+ return autoHeightPair({ pair, ...commonParams })
149
156
  }