@yuhufe/wtool-vdiff 0.0.1 → 0.0.2
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.
|
@@ -20,8 +20,11 @@ export declare function parseHunks(patch: string): {
|
|
|
20
20
|
/**
|
|
21
21
|
* 将 unified diff patch 转换为 [original, modified] 文件对。
|
|
22
22
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
23
|
+
* 策略:
|
|
24
|
+
* - hunk 之外的行(patch 未提供内容):两侧各补一个空行撑开行号,
|
|
25
|
+
* Monaco hideUnchangedRegions 会将这些相同的空行折叠并显示正确的行号范围
|
|
26
|
+
* - context 行(' '):两侧均写入真实内容
|
|
27
|
+
* - 连续的删除('-')/ 新增('+')块:收集后成对对齐写入,
|
|
28
|
+
* 行数较少的一侧补空行,使 Monaco 能在同一视觉行渲染替换关系
|
|
26
29
|
*/
|
|
27
30
|
export declare const patch2Pair: (patch: string) => FilePair[];
|
package/dist/wtool-vdiff.cjs.js
CHANGED
|
@@ -41,7 +41,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
41
41
|
|
|
42
42
|
For more please check the link https://github.com/suren-atoyan/monaco-loader#config
|
|
43
43
|
`},Ia=Qy(s_)(Hp),i_={config:t_},r_=function(){for(var t=arguments.length,n=new Array(t),s=0;s<t;s++)n[s]=arguments[s];return function(i){return n.reduceRight(function(r,o){return o(r)},i)}};function Bp(e,t){return Object.keys(t).forEach(function(n){t[n]instanceof Object&&e[n]&&Object.assign(t[n],Bp(e[n],t[n]))}),Va(Va({},e),t)}var o_={type:"cancelation",msg:"operation is manually canceled"};function ho(e){var t=!1,n=new Promise(function(s,i){e.then(function(r){return t?i(o_):s(r)}),e.catch(i)});return n.cancel=function(){return t=!0},n}var l_=["monaco"],c_=Xy.create({config:Zy,isInitialized:!1,resolve:null,reject:null,monaco:null}),Up=ky(c_,2),gi=Up[0],Kr=Up[1];function a_(e){var t=i_.config(e),n=t.monaco,s=Ay(t,l_);Kr(function(i){return{config:Bp(i.config,s),monaco:n}})}function f_(){var e=gi(function(t){var n=t.monaco,s=t.isInitialized,i=t.resolve;return{monaco:n,isInitialized:s,resolve:i}});if(!e.isInitialized){if(Kr({isInitialized:!0}),e.monaco)return e.resolve(e.monaco),ho(mo);if(window.monaco&&window.monaco.editor)return Kp(window.monaco),e.resolve(window.monaco),ho(mo);r_(u_,d_)(h_)}return ho(mo)}function u_(e){return document.body.appendChild(e)}function p_(e){var t=document.createElement("script");return e&&(t.src=e),t}function d_(e){var t=gi(function(s){var i=s.config,r=s.reject;return{config:i,reject:r}}),n=p_("".concat(t.config.paths.vs,"/loader.js"));return n.onload=function(){return e()},n.onerror=t.reject,n}function h_(){var e=gi(function(n){var s=n.config,i=n.resolve,r=n.reject;return{config:s,resolve:i,reject:r}}),t=window.require;t.config(e.config),t(["vs/editor/editor.main"],function(n){var s=n.m||n;Kp(s),e.resolve(s)},function(n){e.reject(n)})}function Kp(e){gi().monaco||Kr({monaco:e})}function m_(){return gi(function(e){var t=e.monaco;return t})}var mo=new Promise(function(e,t){return Kr({resolve:e,reject:t})}),Wp={config:a_,init:f_,__getMonacoInstance:m_};const Xl=function({isMaster:e=!1}={}){return{...Cy({isMaster:e,key:"diffViewer"})}},g_=Un({__name:"MonacoDiffViewer",props:{originalCode:{default:""},modifiedCode:{default:""},language:{default:"plaintext"},options:{default:()=>({})},modelOptions:{default:()=>({})}},emits:["renderComplete"],setup(e,{emit:t}){const n=e,s=t,{funcs:i}=Xl(),r=i.canUnchangeVisible,o=$e(null),l=Zn(null),c=Zn(null),u=Zn(null),f=Zn(null);let a=!1;return Kn(()=>{a=!1,(async()=>{const h=await Wp.init();if(a||!o.value)return;l.value=h,u.value=h.editor.createModel(n.originalCode,n.language),f.value=h.editor.createModel(n.modifiedCode,n.language),c.value=h.editor.createDiffEditor(o.value,{automaticLayout:!0,readOnly:!0,renderSideBySide:!0,useInlineViewWhenSpaceIsLimited:!1,scrollBeyondLastLine:!1,hideUnchangedRegions:{enabled:!0,contextLineCount:3},scrollbar:{verticalScrollbarSize:8,horizontalScrollbarSize:8},...n.options}),c.value.setModel({original:u.value,modified:f.value}),Object.keys(n.modelOptions).length>0&&(u.value.updateOptions(n.modelOptions),f.value.updateOptions(n.modelOptions));const E=c.value.onDidUpdateDiff(()=>{const v=c.value?.getLineChanges()??[],A=(m,_)=>_===0?0:_-m+1,V=v.reduce((m,_)=>m+A(_.modifiedStartLineNumber,_.modifiedEndLineNumber),0),b=v.reduce((m,_)=>m+A(_.originalStartLineNumber,_.originalEndLineNumber),0);i.updateChangedLines?.({added:V,removed:b}),s("renderComplete"),E.dispose()})})()}),fi(()=>{a=!0,c.value?.dispose(),u.value?.dispose(),f.value?.dispose(),c.value=null,u.value=null,f.value=null,l.value=null}),Et(()=>n.options,p=>{c.value&&c.value.updateOptions(p)},{deep:!0}),Et(()=>n.originalCode,p=>{u.value&&u.value.getValue()!==p&&u.value.setValue(p)}),Et(()=>n.modifiedCode,p=>{f.value&&f.value.getValue()!==p&&f.value.setValue(p)}),Et(()=>n.language,p=>{const h=l.value,E=u.value,v=f.value;!h||!E||!v||(h.editor.setModelLanguage(E,p),h.editor.setModelLanguage(v,p))}),Et(()=>n.modelOptions,p=>{!u.value||!f.value||(u.value.updateOptions(p),f.value.updateOptions(p))},{deep:!0}),(p,h)=>(Qe(),Xt("div",{ref_key:"containerEl",ref:o,class:yn(["monaco-editor-container",{"hide-unchanged-actions":!Mt(r)}])},null,2))}}),v_=Ur(g_,[["__scopeId","data-v-cfbdfd35"]]),E_={class:"top-bar-wrap"},y_={class:"title-area"},__={class:"filename"},N_={class:"diff-line-num"},b_={class:"add"},O_={class:"del"},S_={class:"toolbar"},w_=["checked"],C_={key:0},T_=["checked"],D_=Un({__name:"TopBar",props:{diffPair:{default:()=>[]}},setup(e){const{funcs:t,registerFunc:n}=Xl(),s=e,i=kt(()=>s.diffPair[0].filename),{viewed:r,rawed:o,canUnchangeVisible:l}=t,c=function(p){const h=p.target.checked;r.value=h},u=function(p){const h=p.target.checked;o.value=h};Kn(()=>{});const f=$e({added:0,removed:0});function a(p){Object.assign(f.value,p)}return n({viewed:r,rawed:o,updateChangedLines:a}),(p,h)=>(Qe(),Xt("div",E_,[Xe("div",y_,[Xe("div",__,es(i.value),1),Xe("div",N_,[Xe("div",b_,"+"+es(f.value.added),1),Xe("div",O_,"-"+es(f.value.removed),1)])]),Xe("div",S_,[Xe("label",null,[Xe("input",{type:"checkbox",checked:Mt(r),onChange:c},null,40,w_),h[0]||(h[0]=Qs(" viewed ",-1))]),Mt(l)?(Qe(),Xt("label",C_,[Xe("input",{type:"checkbox",checked:Mt(o),onChange:u},null,40,T_),h[1]||(h[1]=Qs(" raw ",-1))])):bl("",!0)])]))}}),V_=Ur(D_,[["__scopeId","data-v-4557d9f4"]]);function qp(e){const t=e.split(`
|
|
44
|
-
`);let n="",s="";const i=[];let r=null;for(const o of t){if(o.startsWith("--- ")){n=o.slice(4).trim();continue}if(o.startsWith("+++ ")){s=o.slice(4).trim();continue}const l=o.match(/^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/);if(l){r={origStart:parseInt(l[1],10),origCount:l[2]!==void 0?parseInt(l[2],10):1,modStart:parseInt(l[3],10),modCount:l[4]!==void 0?parseInt(l[4],10):1,lines:[]},i.push(r);continue}if(r){if(o.startsWith("\\"))continue;r.lines.push(o)}}return{origFilename:n,modFilename:s,hunks:i}}const x_=function(e){if(!e)return[{filename:"",content:""},{filename:"",content:""}];const{origFilename:t,modFilename:n,hunks:s}=qp(e),i=[],r=[];let o=
|
|
44
|
+
`);let n="",s="";const i=[];let r=null;for(const o of t){if(o.startsWith("--- ")){n=o.slice(4).trim();continue}if(o.startsWith("+++ ")){s=o.slice(4).trim();continue}const l=o.match(/^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/);if(l){r={origStart:parseInt(l[1],10),origCount:l[2]!==void 0?parseInt(l[2],10):1,modStart:parseInt(l[3],10),modCount:l[4]!==void 0?parseInt(l[4],10):1,lines:[]},i.push(r);continue}if(r){if(o.startsWith("\\"))continue;r.lines.push(o)}}return{origFilename:n,modFilename:s,hunks:i}}const x_=function(e){if(!e)return[{filename:"",content:""},{filename:"",content:""}];const{origFilename:t,modFilename:n,hunks:s}=qp(e),i=[],r=[],o=[],l=[],c=()=>{const a=Math.max(o.length,l.length);for(let p=0;p<a;p++)i.push(o[p]??""),r.push(l[p]??"");o.length=0,l.length=0};let u=1,f=1;for(const a of s){for(;u<a.origStart;)i.push(""),u++;for(;f<a.modStart;)r.push(""),f++;for(const p of a.lines){const h=p[0],E=p.slice(1);h===" "?(c(),i.push(E),r.push(E),u++,f++):h==="-"?(o.push(E),u++):h==="+"&&(l.push(E),f++)}c()}return[{filename:t,content:i.join(`
|
|
45
45
|
`)},{filename:n,content:r.join(`
|
|
46
46
|
`)}]},go=18;function Gp(e,t,n){let s=0,i=-1,r=-1;const o=()=>{i!==-1&&(i>1&&(s+=1),s+=r-i+1,i=-1,r=-1)};return{feed(l,c){const u=Math.max(1,l-t),f=Math.min(e,c+t);r===-1||u>r+1?(o(),i=u,r=f):r=Math.max(r,f)},flush(){return o(),s>0&&r!==e&&(s+=1),Math.min(s,n)},get visible(){return s},get maxReached(){return s>=n}}}const A_=function({patch:e,minLine:t,maxLine:n,unchangedCtxLineNum:s}){const{hunks:i}=qp(e);if(i.length===0)return t;const r=i[i.length-1],o=Math.max(r.origStart+r.origCount-1,r.modStart+r.modCount-1),l=Gp(o,s,n);for(const c of i){const u=Math.max(c.origStart+c.origCount-1,c.modStart+c.modCount-1);if(l.feed(c.origStart,u),l.maxReached)return n}return Math.max(t,l.flush())},I_=function({pair:e,minLine:t,maxLine:n,unchangedVisiable:s,unchangedCtxLineNum:i}){if(!e||e.length<2)return t;const r=e[0].content.split(`
|
|
47
47
|
`),o=e[1].content.split(`
|
package/dist/wtool-vdiff.es.js
CHANGED
|
@@ -12817,17 +12817,23 @@ const D_ = function(e) {
|
|
|
12817
12817
|
{ filename: "", content: "" },
|
|
12818
12818
|
{ filename: "", content: "" }
|
|
12819
12819
|
];
|
|
12820
|
-
const { origFilename: t, modFilename: n, hunks: s } = Kp(e), i = [], r = []
|
|
12821
|
-
|
|
12822
|
-
|
|
12823
|
-
|
|
12824
|
-
|
|
12825
|
-
|
|
12826
|
-
|
|
12827
|
-
|
|
12828
|
-
|
|
12829
|
-
|
|
12830
|
-
|
|
12820
|
+
const { origFilename: t, modFilename: n, hunks: s } = Kp(e), i = [], r = [], o = [], l = [], c = () => {
|
|
12821
|
+
const a = Math.max(o.length, l.length);
|
|
12822
|
+
for (let p = 0; p < a; p++)
|
|
12823
|
+
i.push(o[p] ?? ""), r.push(l[p] ?? "");
|
|
12824
|
+
o.length = 0, l.length = 0;
|
|
12825
|
+
};
|
|
12826
|
+
let u = 1, f = 1;
|
|
12827
|
+
for (const a of s) {
|
|
12828
|
+
for (; u < a.origStart; )
|
|
12829
|
+
i.push(""), u++;
|
|
12830
|
+
for (; f < a.modStart; )
|
|
12831
|
+
r.push(""), f++;
|
|
12832
|
+
for (const p of a.lines) {
|
|
12833
|
+
const h = p[0], E = p.slice(1);
|
|
12834
|
+
h === " " ? (c(), i.push(E), r.push(E), u++, f++) : h === "-" ? (o.push(E), u++) : h === "+" && (l.push(E), f++);
|
|
12835
|
+
}
|
|
12836
|
+
c();
|
|
12831
12837
|
}
|
|
12832
12838
|
return [
|
|
12833
12839
|
{ filename: t, content: i.join(`
|
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.2",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Monaco diff viewer as Vue 3 Web Component",
|
|
7
7
|
"keywords": [
|
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
"dev:lib": "vite build --watch --mode development",
|
|
17
17
|
"build:site": "vite build --mode production --config site/vite.config.ts",
|
|
18
18
|
"dev:site": "vite --config site/vite.config.ts",
|
|
19
|
-
"build": "vite build --mode production"
|
|
19
|
+
"build": "vite build --mode production",
|
|
20
|
+
"pub": "npm run build && npm publish"
|
|
20
21
|
},
|
|
21
22
|
"main": "./dist/wtool-vdiff.cjs.js",
|
|
22
23
|
"module": "./dist/wtool-vdiff.es.js",
|
|
@@ -56,9 +56,12 @@ export function parseHunks(patch: string): { origFilename: string; modFilename:
|
|
|
56
56
|
/**
|
|
57
57
|
* 将 unified diff patch 转换为 [original, modified] 文件对。
|
|
58
58
|
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
59
|
+
* 策略:
|
|
60
|
+
* - hunk 之外的行(patch 未提供内容):两侧各补一个空行撑开行号,
|
|
61
|
+
* Monaco hideUnchangedRegions 会将这些相同的空行折叠并显示正确的行号范围
|
|
62
|
+
* - context 行(' '):两侧均写入真实内容
|
|
63
|
+
* - 连续的删除('-')/ 新增('+')块:收集后成对对齐写入,
|
|
64
|
+
* 行数较少的一侧补空行,使 Monaco 能在同一视觉行渲染替换关系
|
|
62
65
|
*/
|
|
63
66
|
export const patch2Pair = function (patch: string): FilePair[] {
|
|
64
67
|
if (!patch) {
|
|
@@ -73,12 +76,24 @@ export const patch2Pair = function (patch: string): FilePair[] {
|
|
|
73
76
|
const origLines: string[] = []
|
|
74
77
|
const modLines: string[] = []
|
|
75
78
|
|
|
76
|
-
|
|
79
|
+
const pendingDel: string[] = []
|
|
80
|
+
const pendingAdd: string[] = []
|
|
81
|
+
|
|
82
|
+
const flushPending = () => {
|
|
83
|
+
const maxLen = Math.max(pendingDel.length, pendingAdd.length)
|
|
84
|
+
for (let i = 0; i < maxLen; i++) {
|
|
85
|
+
origLines.push(pendingDel[i] ?? '')
|
|
86
|
+
modLines.push(pendingAdd[i] ?? '')
|
|
87
|
+
}
|
|
88
|
+
pendingDel.length = 0
|
|
89
|
+
pendingAdd.length = 0
|
|
90
|
+
}
|
|
91
|
+
|
|
77
92
|
let origCursor = 1
|
|
78
93
|
let modCursor = 1
|
|
79
94
|
|
|
80
95
|
for (const hunk of hunks) {
|
|
81
|
-
// hunk
|
|
96
|
+
// hunk 之前(或两个 hunk 之间)的 gap:两侧各补空行对齐行号
|
|
82
97
|
while (origCursor < hunk.origStart) {
|
|
83
98
|
origLines.push('')
|
|
84
99
|
origCursor++
|
|
@@ -93,25 +108,21 @@ export const patch2Pair = function (patch: string): FilePair[] {
|
|
|
93
108
|
const content = line.slice(1)
|
|
94
109
|
|
|
95
110
|
if (prefix === ' ') {
|
|
96
|
-
|
|
111
|
+
flushPending()
|
|
97
112
|
origLines.push(content)
|
|
98
113
|
modLines.push(content)
|
|
99
114
|
origCursor++
|
|
100
115
|
modCursor++
|
|
101
116
|
} else if (prefix === '-') {
|
|
102
|
-
|
|
103
|
-
origLines.push(content)
|
|
104
|
-
modLines.push('')
|
|
117
|
+
pendingDel.push(content)
|
|
105
118
|
origCursor++
|
|
106
|
-
modCursor++
|
|
107
119
|
} else if (prefix === '+') {
|
|
108
|
-
|
|
109
|
-
origLines.push('')
|
|
110
|
-
modLines.push(content)
|
|
111
|
-
origCursor++
|
|
120
|
+
pendingAdd.push(content)
|
|
112
121
|
modCursor++
|
|
113
122
|
}
|
|
114
123
|
}
|
|
124
|
+
|
|
125
|
+
flushPending()
|
|
115
126
|
}
|
|
116
127
|
|
|
117
128
|
return [
|