difit 3.1.1 → 3.1.3
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/README.ja.md +12 -12
- package/README.ko.md +12 -12
- package/README.md +12 -12
- package/README.zh.md +12 -12
- package/dist/cli/index.js +2 -1
- package/dist/cli/index.test.js +46 -35
- package/dist/client/assets/index-CJFEXHVo.css +1 -0
- package/dist/client/assets/index-DkSWqPfG.js +67 -0
- package/dist/client/assets/{prism-csharp-IeaHKRXr.js → prism-csharp-B0flB6m_.js} +1 -1
- package/dist/client/assets/{prism-hcl-D1Ufo4Op.js → prism-hcl-Dw-ceyEl.js} +1 -1
- package/dist/client/assets/{prism-java-BDxiL45l.js → prism-java-NEfmWs-a.js} +1 -1
- package/dist/client/assets/{prism-perl-CLSwNCtq.js → prism-perl-BBlpkdoq.js} +1 -1
- package/dist/client/assets/{prism-php-C8Ln7ncE.js → prism-php-C05TZp5_.js} +1 -1
- package/dist/client/assets/{prism-ruby-tXtdOUSG.js → prism-ruby-C_UU6C7J.js} +1 -1
- package/dist/client/assets/{prism-solidity-B1IyUWlb.js → prism-solidity-Dy4Vtzco.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/server/server.js +72 -3
- package/dist/server/server.test.js +4 -4
- package/dist/tui/App.js +7 -6
- package/dist/tui/components/StatusBar.d.ts +1 -1
- package/dist/tui/components/StatusBar.js +3 -3
- package/dist/types/diff.d.ts +3 -2
- package/dist/utils/diffMode.d.ts +3 -0
- package/dist/utils/diffMode.js +13 -0
- package/dist/utils/editorOptions.d.ts +26 -0
- package/dist/utils/editorOptions.js +33 -0
- package/package.json +2 -2
- package/dist/client/assets/index-Dth7XxZm.js +0 -59
- package/dist/client/assets/index-fq3A-zVZ.css +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{g as U}from"./index-
|
|
1
|
+
import{g as U}from"./index-DkSWqPfG.js";function W(r,t){for(var e=0;e<t.length;e++){const a=t[e];if(typeof a!="string"&&!Array.isArray(a)){for(const s in a)if(s!=="default"&&!(s in r)){const u=Object.getOwnPropertyDescriptor(a,s);u&&Object.defineProperty(r,s,u.get?u:{enumerable:!0,get:()=>a[s]})}}}return Object.freeze(Object.defineProperty(r,Symbol.toStringTag,{value:"Module"}))}var I={},O;function Z(){return O||(O=1,(function(r){function t(n,l){return n.replace(/<<(\d+)>>/g,function(f,M){return"(?:"+l[+M]+")"})}function e(n,l,f){return RegExp(t(n,l),"")}function a(n,l){for(var f=0;f<l;f++)n=n.replace(/<<self>>/g,function(){return"(?:"+n+")"});return n.replace(/<<self>>/g,"[^\\s\\S]")}var s={type:"bool byte char decimal double dynamic float int long object sbyte short string uint ulong ushort var void",typeDeclaration:"class enum interface record struct",contextual:"add alias and ascending async await by descending from(?=\\s*(?:\\w|$)) get global group into init(?=\\s*;) join let nameof not notnull on or orderby partial remove select set unmanaged value when where with(?=\\s*{)",other:"abstract as base break case catch checked const continue default delegate do else event explicit extern finally fixed for foreach goto if implicit in internal is lock namespace new null operator out override params private protected public readonly ref return sealed sizeof stackalloc static switch this throw try typeof unchecked unsafe using virtual volatile while yield"};function u(n){return"\\b(?:"+n.trim().replace(/ /g,"|")+")\\b"}var v=u(s.typeDeclaration),d=RegExp(u(s.type+" "+s.typeDeclaration+" "+s.contextual+" "+s.other)),T=u(s.typeDeclaration+" "+s.contextual+" "+s.other),z=u(s.type+" "+s.typeDeclaration+" "+s.other),g=a(/<(?:[^<>;=+\-*/%&|^]|<<self>>)*>/.source,2),h=a(/\((?:[^()]|<<self>>)*\)/.source,2),i=/@?\b[A-Za-z_]\w*\b/.source,b=t(/<<0>>(?:\s*<<1>>)?/.source,[i,g]),c=t(/(?!<<0>>)<<1>>(?:\s*\.\s*<<1>>)*/.source,[T,b]),y=/\[\s*(?:,\s*)*\]/.source,A=t(/<<0>>(?:\s*(?:\?\s*)?<<1>>)*(?:\s*\?)?/.source,[c,y]),K=t(/[^,()<>[\];=+\-*/%&|^]|<<0>>|<<1>>|<<2>>/.source,[g,h,y]),q=t(/\(<<0>>+(?:,<<0>>+)+\)/.source,[K]),p=t(/(?:<<0>>|<<1>>)(?:\s*(?:\?\s*)?<<2>>)*(?:\s*\?)?/.source,[q,c,y]),o={keyword:d,punctuation:/[<>()?,.:[\]]/},k=/'(?:[^\r\n'\\]|\\.|\\[Uux][\da-fA-F]{1,8})'/.source,w=/"(?:\\.|[^\\"\r\n])*"/.source,F=/@"(?:""|\\[\s\S]|[^\\"])*"(?!")/.source;r.languages.csharp=r.languages.extend("clike",{string:[{pattern:e(/(^|[^$\\])<<0>>/.source,[F]),lookbehind:!0,greedy:!0},{pattern:e(/(^|[^@$\\])<<0>>/.source,[w]),lookbehind:!0,greedy:!0}],"class-name":[{pattern:e(/(\busing\s+static\s+)<<0>>(?=\s*;)/.source,[c]),lookbehind:!0,inside:o},{pattern:e(/(\busing\s+<<0>>\s*=\s*)<<1>>(?=\s*;)/.source,[i,p]),lookbehind:!0,inside:o},{pattern:e(/(\busing\s+)<<0>>(?=\s*=)/.source,[i]),lookbehind:!0},{pattern:e(/(\b<<0>>\s+)<<1>>/.source,[v,b]),lookbehind:!0,inside:o},{pattern:e(/(\bcatch\s*\(\s*)<<0>>/.source,[c]),lookbehind:!0,inside:o},{pattern:e(/(\bwhere\s+)<<0>>/.source,[i]),lookbehind:!0},{pattern:e(/(\b(?:is(?:\s+not)?|as)\s+)<<0>>/.source,[A]),lookbehind:!0,inside:o},{pattern:e(/\b<<0>>(?=\s+(?!<<1>>|with\s*\{)<<2>>(?:\s*[=,;:{)\]]|\s+(?:in|when)\b))/.source,[p,z,i]),inside:o}],keyword:d,number:/(?:\b0(?:x[\da-f_]*[\da-f]|b[01_]*[01])|(?:\B\.\d+(?:_+\d+)*|\b\d+(?:_+\d+)*(?:\.\d+(?:_+\d+)*)?)(?:e[-+]?\d+(?:_+\d+)*)?)(?:[dflmu]|lu|ul)?\b/i,operator:/>>=?|<<=?|[-=]>|([-+&|])\1|~|\?\?=?|[-+*/%&|^!=<>]=?/,punctuation:/\?\.?|::|[{}[\];(),.:]/}),r.languages.insertBefore("csharp","number",{range:{pattern:/\.\./,alias:"operator"}}),r.languages.insertBefore("csharp","punctuation",{"named-parameter":{pattern:e(/([(,]\s*)<<0>>(?=\s*:)/.source,[i]),lookbehind:!0,alias:"punctuation"}}),r.languages.insertBefore("csharp","class-name",{namespace:{pattern:e(/(\b(?:namespace|using)\s+)<<0>>(?:\s*\.\s*<<0>>)*(?=\s*[;{])/.source,[i]),lookbehind:!0,inside:{punctuation:/\./}},"type-expression":{pattern:e(/(\b(?:default|sizeof|typeof)\s*\(\s*(?!\s))(?:[^()\s]|\s(?!\s)|<<0>>)*(?=\s*\))/.source,[h]),lookbehind:!0,alias:"class-name",inside:o},"return-type":{pattern:e(/<<0>>(?=\s+(?:<<1>>\s*(?:=>|[({]|\.\s*this\s*\[)|this\s*\[))/.source,[p,c]),inside:o,alias:"class-name"},"constructor-invocation":{pattern:e(/(\bnew\s+)<<0>>(?=\s*[[({])/.source,[p]),lookbehind:!0,inside:o,alias:"class-name"},"generic-method":{pattern:e(/<<0>>\s*<<1>>(?=\s*\()/.source,[i,g]),inside:{function:e(/^<<0>>/.source,[i]),generic:{pattern:RegExp(g),alias:"class-name",inside:o}}},"type-list":{pattern:e(/\b((?:<<0>>\s+<<1>>|record\s+<<1>>\s*<<5>>|where\s+<<2>>)\s*:\s*)(?:<<3>>|<<4>>|<<1>>\s*<<5>>|<<6>>)(?:\s*,\s*(?:<<3>>|<<4>>|<<6>>))*(?=\s*(?:where|[{;]|=>|$))/.source,[v,b,i,p,d.source,h,/\bnew\s*\(\s*\)/.source]),lookbehind:!0,inside:{"record-arguments":{pattern:e(/(^(?!new\s*\()<<0>>\s*)<<1>>/.source,[b,h]),lookbehind:!0,greedy:!0,inside:r.languages.csharp},keyword:d,"class-name":{pattern:RegExp(p),greedy:!0,inside:o},punctuation:/[,()]/}},preprocessor:{pattern:/(^[\t ]*)#.*/m,lookbehind:!0,alias:"property",inside:{directive:{pattern:/(#)\b(?:define|elif|else|endif|endregion|error|if|line|nullable|pragma|region|undef|warning)\b/,lookbehind:!0,alias:"keyword"}}}});var x=w+"|"+k,E=t(/\/(?![*/])|\/\/[^\r\n]*[\r\n]|\/\*(?:[^*]|\*(?!\/))*\*\/|<<0>>/.source,[x]),S=a(t(/[^"'/()]|<<0>>|\(<<self>>*\)/.source,[E]),2),_=/\b(?:assembly|event|field|method|module|param|property|return|type)\b/.source,N=t(/<<0>>(?:\s*\(<<1>>*\))?/.source,[c,S]);r.languages.insertBefore("csharp","class-name",{attribute:{pattern:e(/((?:^|[^\s\w>)?])\s*\[\s*)(?:<<0>>\s*:\s*)?<<1>>(?:\s*,\s*<<1>>)*(?=\s*\])/.source,[_,N]),lookbehind:!0,greedy:!0,inside:{target:{pattern:e(/^<<0>>(?=\s*:)/.source,[_]),alias:"keyword"},"attribute-arguments":{pattern:e(/\(<<0>>*\)/.source,[S]),inside:r.languages.csharp},"class-name":{pattern:RegExp(c),inside:{punctuation:/\./}},punctuation:/[:,]/}}});var m=/:[^}\r\n]+/.source,C=a(t(/[^"'/()]|<<0>>|\(<<self>>*\)/.source,[E]),2),$=t(/\{(?!\{)(?:(?![}:])<<0>>)*<<1>>?\}/.source,[C,m]),R=a(t(/[^"'/()]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|<<0>>|\(<<self>>*\)/.source,[x]),2),D=t(/\{(?!\{)(?:(?![}:])<<0>>)*<<1>>?\}/.source,[R,m]);function j(n,l){return{interpolation:{pattern:e(/((?:^|[^{])(?:\{\{)*)<<0>>/.source,[n]),lookbehind:!0,inside:{"format-string":{pattern:e(/(^\{(?:(?![}:])<<0>>)*)<<1>>(?=\}$)/.source,[l,m]),lookbehind:!0,inside:{punctuation:/^:/}},punctuation:/^\{|\}$/,expression:{pattern:/[\s\S]+/,alias:"language-csharp",inside:r.languages.csharp}}},string:/[\s\S]+/}}r.languages.insertBefore("csharp","string",{"interpolation-string":[{pattern:e(/(^|[^\\])(?:\$@|@\$)"(?:""|\\[\s\S]|\{\{|<<0>>|[^\\{"])*"/.source,[$]),lookbehind:!0,greedy:!0,inside:j($,C)},{pattern:e(/(^|[^@\\])\$"(?:\\.|\{\{|<<0>>|[^\\"{])*"/.source,[D]),lookbehind:!0,greedy:!0,inside:j(D,R)}],char:{pattern:RegExp(k),greedy:!0}}),r.languages.dotnet=r.languages.cs=r.languages.csharp})(Prism)),I}var B=Z();const G=U(B),J=W({__proto__:null,default:G},[B]);export{J as p};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{g as u}from"./index-
|
|
1
|
+
import{g as u}from"./index-DkSWqPfG.js";function d(t,o){for(var a=0;a<o.length;a++){const e=o[a];if(typeof e!="string"&&!Array.isArray(e)){for(const r in e)if(r!=="default"&&!(r in t)){const i=Object.getOwnPropertyDescriptor(e,r);i&&Object.defineProperty(t,r,i.get?i:{enumerable:!0,get:()=>e[r]})}}}return Object.freeze(Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}))}var s={},n;function p(){return n||(n=1,Prism.languages.hcl={comment:/(?:\/\/|#).*|\/\*[\s\S]*?(?:\*\/|$)/,heredoc:{pattern:/<<-?(\w+\b)[\s\S]*?^[ \t]*\1/m,greedy:!0,alias:"string"},keyword:[{pattern:/(?:data|resource)\s+(?:"(?:\\[\s\S]|[^\\"])*")(?=\s+"[\w-]+"\s+\{)/i,inside:{type:{pattern:/(resource|data|\s+)(?:"(?:\\[\s\S]|[^\\"])*")/i,lookbehind:!0,alias:"variable"}}},{pattern:/(?:backend|module|output|provider|provisioner|variable)\s+(?:[\w-]+|"(?:\\[\s\S]|[^\\"])*")\s+(?=\{)/i,inside:{type:{pattern:/(backend|module|output|provider|provisioner|variable)\s+(?:[\w-]+|"(?:\\[\s\S]|[^\\"])*")\s+/i,lookbehind:!0,alias:"variable"}}},/[\w-]+(?=\s+\{)/],property:[/[-\w\.]+(?=\s*=(?!=))/,/"(?:\\[\s\S]|[^\\"])+"(?=\s*[:=])/],string:{pattern:/"(?:[^\\$"]|\\[\s\S]|\$(?:(?=")|\$+(?!\$)|[^"${])|\$\{(?:[^{}"]|"(?:[^\\"]|\\[\s\S])*")*\})*"/,greedy:!0,inside:{interpolation:{pattern:/(^|[^$])\$\{(?:[^{}"]|"(?:[^\\"]|\\[\s\S])*")*\}/,lookbehind:!0,inside:{type:{pattern:/(\b(?:count|data|local|module|path|self|terraform|var)\b\.)[\w\*]+/i,lookbehind:!0,alias:"variable"},keyword:/\b(?:count|data|local|module|path|self|terraform|var)\b/i,function:/\w+(?=\()/,string:{pattern:/"(?:\\[\s\S]|[^\\"])*"/,greedy:!0},number:/\b0x[\da-f]+\b|\b\d+(?:\.\d*)?(?:e[+-]?\d+)?/i,punctuation:/[!\$#%&'()*+,.\/;<=>@\[\\\]^`{|}~?:]/}}}},number:/\b0x[\da-f]+\b|\b\d+(?:\.\d*)?(?:e[+-]?\d+)?/i,boolean:/\b(?:false|true)\b/i,punctuation:/[=\[\]{}]/}),s}var l=p();const b=u(l),f=d({__proto__:null,default:b},[l]);export{f as p};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{g as u}from"./index-
|
|
1
|
+
import{g as u}from"./index-DkSWqPfG.js";function p(t,a){for(var r=0;r<a.length;r++){const e=a[r];if(typeof e!="string"&&!Array.isArray(e)){for(const s in e)if(s!=="default"&&!(s in t)){const n=Object.getOwnPropertyDescriptor(e,s);n&&Object.defineProperty(t,s,n.get?n:{enumerable:!0,get:()=>e[s]})}}}return Object.freeze(Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}))}var o={},i;function d(){return i||(i=1,(function(t){var a=/\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|non-sealed|null|open|opens|package|permits|private|protected|provides|public|record(?!\s*[(){}[\]<>=%~.:,;?+\-*/&|^])|requires|return|sealed|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\b/,r=/(?:[a-z]\w*\s*\.\s*)*(?:[A-Z]\w*\s*\.\s*)*/.source,e={pattern:RegExp(/(^|[^\w.])/.source+r+/[A-Z](?:[\d_A-Z]*[a-z]\w*)?\b/.source),lookbehind:!0,inside:{namespace:{pattern:/^[a-z]\w*(?:\s*\.\s*[a-z]\w*)*(?:\s*\.)?/,inside:{punctuation:/\./}},punctuation:/\./}};t.languages.java=t.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"/,lookbehind:!0,greedy:!0},"class-name":[e,{pattern:RegExp(/(^|[^\w.])/.source+r+/[A-Z]\w*(?=\s+\w+\s*[;,=()]|\s*(?:\[[\s,]*\]\s*)?::\s*new\b)/.source),lookbehind:!0,inside:e.inside},{pattern:RegExp(/(\b(?:class|enum|extends|implements|instanceof|interface|new|record|throws)\s+)/.source+r+/[A-Z]\w*\b/.source),lookbehind:!0,inside:e.inside}],keyword:a,function:[t.languages.clike.function,{pattern:/(::\s*)[a-z_]\w*/,lookbehind:!0}],number:/\b0b[01][01_]*L?\b|\b0x(?:\.[\da-f_p+-]+|[\da-f_]+(?:\.[\da-f_p+-]+)?)\b|(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?[dfl]?/i,operator:{pattern:/(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m,lookbehind:!0},constant:/\b[A-Z][A-Z_\d]+\b/}),t.languages.insertBefore("java","string",{"triple-quoted-string":{pattern:/"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/,greedy:!0,alias:"string"},char:{pattern:/'(?:\\.|[^'\\\r\n]){1,6}'/,greedy:!0}}),t.languages.insertBefore("java","class-name",{annotation:{pattern:/(^|[^.])@\w+(?:\s*\.\s*\w+)*/,lookbehind:!0,alias:"punctuation"},generics:{pattern:/<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&))*>)*>)*>)*>/,inside:{"class-name":e,keyword:a,punctuation:/[<>(),.:]/,operator:/[?&|]/}},import:[{pattern:RegExp(/(\bimport\s+)/.source+r+/(?:[A-Z]\w*|\*)(?=\s*;)/.source),lookbehind:!0,inside:{namespace:e.inside.namespace,punctuation:/\./,operator:/\*/,"class-name":/\w+/}},{pattern:RegExp(/(\bimport\s+static\s+)/.source+r+/(?:\w+|\*)(?=\s*;)/.source),lookbehind:!0,alias:"static",inside:{namespace:e.inside.namespace,static:/\b\w+$/,punctuation:/\./,operator:/\*/,"class-name":/\w+/}}],namespace:{pattern:RegExp(/(\b(?:exports|import(?:\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\s+)(?!<keyword>)[a-z]\w*(?:\.[a-z]\w*)*\.?/.source.replace(/<keyword>/g,function(){return a.source})),lookbehind:!0,inside:{punctuation:/\./}}})})(Prism)),o}var c=d();const l=u(c),w=p({__proto__:null,default:l},[c]);export{w as p};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{g as l}from"./index-
|
|
1
|
+
import{g as l}from"./index-DkSWqPfG.js";function d(r,e){for(var o=0;o<e.length;o++){const t=e[o];if(typeof t!="string"&&!Array.isArray(t)){for(const s in t)if(s!=="default"&&!(s in r)){const n=Object.getOwnPropertyDescriptor(t,s);n&&Object.defineProperty(r,s,n.get?n:{enumerable:!0,get:()=>t[s]})}}}return Object.freeze(Object.defineProperty(r,Symbol.toStringTag,{value:"Module"}))}var a={},u;function c(){return u||(u=1,(function(r){var e=/(?:\((?:[^()\\]|\\[\s\S])*\)|\{(?:[^{}\\]|\\[\s\S])*\}|\[(?:[^[\]\\]|\\[\s\S])*\]|<(?:[^<>\\]|\\[\s\S])*>)/.source;r.languages.perl={comment:[{pattern:/(^\s*)=\w[\s\S]*?=cut.*/m,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\$])#.*/,lookbehind:!0,greedy:!0}],string:[{pattern:RegExp(/\b(?:q|qq|qw|qx)(?![a-zA-Z0-9])\s*/.source+"(?:"+[/([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1/.source,/([a-zA-Z0-9])(?:(?!\2)[^\\]|\\[\s\S])*\2/.source,e].join("|")+")"),greedy:!0},{pattern:/("|`)(?:(?!\1)[^\\]|\\[\s\S])*\1/,greedy:!0},{pattern:/'(?:[^'\\\r\n]|\\.)*'/,greedy:!0}],regex:[{pattern:RegExp(/\b(?:m|qr)(?![a-zA-Z0-9])\s*/.source+"(?:"+[/([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1/.source,/([a-zA-Z0-9])(?:(?!\2)[^\\]|\\[\s\S])*\2/.source,e].join("|")+")"+/[msixpodualngc]*/.source),greedy:!0},{pattern:RegExp(/(^|[^-])\b(?:s|tr|y)(?![a-zA-Z0-9])\s*/.source+"(?:"+[/([^a-zA-Z0-9\s{(\[<])(?:(?!\2)[^\\]|\\[\s\S])*\2(?:(?!\2)[^\\]|\\[\s\S])*\2/.source,/([a-zA-Z0-9])(?:(?!\3)[^\\]|\\[\s\S])*\3(?:(?!\3)[^\\]|\\[\s\S])*\3/.source,e+/\s*/.source+e].join("|")+")"+/[msixpodualngcer]*/.source),lookbehind:!0,greedy:!0},{pattern:/\/(?:[^\/\\\r\n]|\\.)*\/[msixpodualngc]*(?=\s*(?:$|[\r\n,.;})&|\-+*~<>!?^]|(?:and|cmp|eq|ge|gt|le|lt|ne|not|or|x|xor)\b))/,greedy:!0}],variable:[/[&*$@%]\{\^[A-Z]+\}/,/[&*$@%]\^[A-Z_]/,/[&*$@%]#?(?=\{)/,/[&*$@%]#?(?:(?:::)*'?(?!\d)[\w$]+(?![\w$]))+(?:::)*/,/[&*$@%]\d+/,/(?!%=)[$@%][!"#$%&'()*+,\-.\/:;<=>?@[\\\]^_`{|}~]/],filehandle:{pattern:/<(?![<=])\S*?>|\b_\b/,alias:"symbol"},"v-string":{pattern:/v\d+(?:\.\d+)*|\d+(?:\.\d+){2,}/,alias:"string"},function:{pattern:/(\bsub[ \t]+)\w+/,lookbehind:!0},keyword:/\b(?:any|break|continue|default|delete|die|do|else|elsif|eval|for|foreach|given|goto|if|last|local|my|next|our|package|print|redo|require|return|say|state|sub|switch|undef|unless|until|use|when|while)\b/,number:/\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0b[01](?:_?[01])*|(?:(?:\d(?:_?\d)*)?\.)?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)\b/,operator:/-[rwxoRWXOezsfdlpSbctugkTBMAC]\b|\+[+=]?|-[-=>]?|\*\*?=?|\/\/?=?|=[=~>]?|~[~=]?|\|\|?=?|&&?=?|<(?:=>?|<=?)?|>>?=?|![~=]?|[%^]=?|\.(?:=|\.\.?)?|[\\?]|\bx(?:=|\b)|\b(?:and|cmp|eq|ge|gt|le|lt|ne|not|or|xor)\b/,punctuation:/[{}[\];(),:]/}})(Prism)),a}var i=c();const p=l(i),b=d({__proto__:null,default:p},[i]);export{b as p};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{g as c}from"./index-
|
|
1
|
+
import{g as c}from"./index-DkSWqPfG.js";function f(e,r){for(var n=0;n<r.length;n++){const t=r[n];if(typeof t!="string"&&!Array.isArray(t)){for(const a in t)if(a!=="default"&&!(a in e)){const i=Object.getOwnPropertyDescriptor(t,a);i&&Object.defineProperty(e,a,i.get?i:{enumerable:!0,get:()=>t[a]})}}}return Object.freeze(Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}))}var u={},d;function g(){return d||(d=1,(function(e){var r=/\/\*[\s\S]*?\*\/|\/\/.*|#(?!\[).*/,n=[{pattern:/\b(?:false|true)\b/i,alias:"boolean"},{pattern:/(::\s*)\b[a-z_]\w*\b(?!\s*\()/i,greedy:!0,lookbehind:!0},{pattern:/(\b(?:case|const)\s+)\b[a-z_]\w*(?=\s*[;=])/i,greedy:!0,lookbehind:!0},/\b(?:null)\b/i,/\b[A-Z_][A-Z0-9_]*\b(?!\s*\()/],t=/\b0b[01]+(?:_[01]+)*\b|\b0o[0-7]+(?:_[0-7]+)*\b|\b0x[\da-f]+(?:_[\da-f]+)*\b|(?:\b\d+(?:_\d+)*\.?(?:\d+(?:_\d+)*)?|\B\.\d+)(?:e[+-]?\d+)?/i,a=/<?=>|\?\?=?|\.{3}|\??->|[!=]=?=?|::|\*\*=?|--|\+\+|&&|\|\||<<|>>|[?~]|[/^|%*&<>.+-]=?/,i=/[{}\[\](),:;]/;e.languages.php={delimiter:{pattern:/\?>$|^<\?(?:php(?=\s)|=)?/i,alias:"important"},comment:r,variable:/\$+(?:\w+\b|(?=\{))/,package:{pattern:/(namespace\s+|use\s+(?:function\s+)?)(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,lookbehind:!0,inside:{punctuation:/\\/}},"class-name-definition":{pattern:/(\b(?:class|enum|interface|trait)\s+)\b[a-z_]\w*(?!\\)\b/i,lookbehind:!0,alias:"class-name"},"function-definition":{pattern:/(\bfunction\s+)[a-z_]\w*(?=\s*\()/i,lookbehind:!0,alias:"function"},keyword:[{pattern:/(\(\s*)\b(?:array|bool|boolean|float|int|integer|object|string)\b(?=\s*\))/i,alias:"type-casting",greedy:!0,lookbehind:!0},{pattern:/([(,?]\s*)\b(?:array(?!\s*\()|bool|callable|(?:false|null)(?=\s*\|)|float|int|iterable|mixed|object|self|static|string)\b(?=\s*\$)/i,alias:"type-hint",greedy:!0,lookbehind:!0},{pattern:/(\)\s*:\s*(?:\?\s*)?)\b(?:array(?!\s*\()|bool|callable|(?:false|null)(?=\s*\|)|float|int|iterable|mixed|never|object|self|static|string|void)\b/i,alias:"return-type",greedy:!0,lookbehind:!0},{pattern:/\b(?:array(?!\s*\()|bool|float|int|iterable|mixed|object|string|void)\b/i,alias:"type-declaration",greedy:!0},{pattern:/(\|\s*)(?:false|null)\b|\b(?:false|null)(?=\s*\|)/i,alias:"type-declaration",greedy:!0,lookbehind:!0},{pattern:/\b(?:parent|self|static)(?=\s*::)/i,alias:"static-context",greedy:!0},{pattern:/(\byield\s+)from\b/i,lookbehind:!0},/\bclass\b/i,{pattern:/((?:^|[^\s>:]|(?:^|[^-])>|(?:^|[^:]):)\s*)\b(?:abstract|and|array|as|break|callable|case|catch|clone|const|continue|declare|default|die|do|echo|else|elseif|empty|enddeclare|endfor|endforeach|endif|endswitch|endwhile|enum|eval|exit|extends|final|finally|fn|for|foreach|function|global|goto|if|implements|include|include_once|instanceof|insteadof|interface|isset|list|match|namespace|never|new|or|parent|print|private|protected|public|readonly|require|require_once|return|self|static|switch|throw|trait|try|unset|use|var|while|xor|yield|__halt_compiler)\b/i,lookbehind:!0}],"argument-name":{pattern:/([(,]\s*)\b[a-z_]\w*(?=\s*:(?!:))/i,lookbehind:!0},"class-name":[{pattern:/(\b(?:extends|implements|instanceof|new(?!\s+self|\s+static))\s+|\bcatch\s*\()\b[a-z_]\w*(?!\\)\b/i,greedy:!0,lookbehind:!0},{pattern:/(\|\s*)\b[a-z_]\w*(?!\\)\b/i,greedy:!0,lookbehind:!0},{pattern:/\b[a-z_]\w*(?!\\)\b(?=\s*\|)/i,greedy:!0},{pattern:/(\|\s*)(?:\\?\b[a-z_]\w*)+\b/i,alias:"class-name-fully-qualified",greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/(?:\\?\b[a-z_]\w*)+\b(?=\s*\|)/i,alias:"class-name-fully-qualified",greedy:!0,inside:{punctuation:/\\/}},{pattern:/(\b(?:extends|implements|instanceof|new(?!\s+self\b|\s+static\b))\s+|\bcatch\s*\()(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,alias:"class-name-fully-qualified",greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/\b[a-z_]\w*(?=\s*\$)/i,alias:"type-declaration",greedy:!0},{pattern:/(?:\\?\b[a-z_]\w*)+(?=\s*\$)/i,alias:["class-name-fully-qualified","type-declaration"],greedy:!0,inside:{punctuation:/\\/}},{pattern:/\b[a-z_]\w*(?=\s*::)/i,alias:"static-context",greedy:!0},{pattern:/(?:\\?\b[a-z_]\w*)+(?=\s*::)/i,alias:["class-name-fully-qualified","static-context"],greedy:!0,inside:{punctuation:/\\/}},{pattern:/([(,?]\s*)[a-z_]\w*(?=\s*\$)/i,alias:"type-hint",greedy:!0,lookbehind:!0},{pattern:/([(,?]\s*)(?:\\?\b[a-z_]\w*)+(?=\s*\$)/i,alias:["class-name-fully-qualified","type-hint"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/(\)\s*:\s*(?:\?\s*)?)\b[a-z_]\w*(?!\\)\b/i,alias:"return-type",greedy:!0,lookbehind:!0},{pattern:/(\)\s*:\s*(?:\?\s*)?)(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,alias:["class-name-fully-qualified","return-type"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}}],constant:n,function:{pattern:/(^|[^\\\w])\\?[a-z_](?:[\w\\]*\w)?(?=\s*\()/i,lookbehind:!0,inside:{punctuation:/\\/}},property:{pattern:/(->\s*)\w+/,lookbehind:!0},number:t,operator:a,punctuation:i};var l={pattern:/\{\$(?:\{(?:\{[^{}]+\}|[^{}]+)\}|[^{}])+\}|(^|[^\\{])\$+(?:\w+(?:\[[^\r\n\[\]]+\]|->\w+)?)/,lookbehind:!0,inside:e.languages.php},o=[{pattern:/<<<'([^']+)'[\r\n](?:.*[\r\n])*?\1;/,alias:"nowdoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<<'[^']+'|[a-z_]\w*;$/i,alias:"symbol",inside:{punctuation:/^<<<'?|[';]$/}}}},{pattern:/<<<(?:"([^"]+)"[\r\n](?:.*[\r\n])*?\1;|([a-z_]\w*)[\r\n](?:.*[\r\n])*?\2;)/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<<(?:"[^"]+"|[a-z_]\w*)|[a-z_]\w*;$/i,alias:"symbol",inside:{punctuation:/^<<<"?|[";]$/}},interpolation:l}},{pattern:/`(?:\\[\s\S]|[^\\`])*`/,alias:"backtick-quoted-string",greedy:!0},{pattern:/'(?:\\[\s\S]|[^\\'])*'/,alias:"single-quoted-string",greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,alias:"double-quoted-string",greedy:!0,inside:{interpolation:l}}];e.languages.insertBefore("php","variable",{string:o,attribute:{pattern:/#\[(?:[^"'\/#]|\/(?![*/])|\/\/.*$|#(?!\[).*$|\/\*(?:[^*]|\*(?!\/))*\*\/|"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*')+\](?=\s*[a-z$#])/im,greedy:!0,inside:{"attribute-content":{pattern:/^(#\[)[\s\S]+(?=\]$)/,lookbehind:!0,inside:{comment:r,string:o,"attribute-class-name":[{pattern:/([^:]|^)\b[a-z_]\w*(?!\\)\b/i,alias:"class-name",greedy:!0,lookbehind:!0},{pattern:/([^:]|^)(?:\\?\b[a-z_]\w*)+/i,alias:["class-name","class-name-fully-qualified"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}}],constant:n,number:t,operator:a,punctuation:i}},delimiter:{pattern:/^#\[|\]$/,alias:"punctuation"}}}}),e.hooks.add("before-tokenize",function(s){if(/<\?/.test(s.code)){var p=/<\?(?:[^"'/#]|\/(?![*/])|("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|(?:\/\/|#(?!\[))(?:[^?\n\r]|\?(?!>))*(?=$|\?>|[\r\n])|#\[|\/\*(?:[^*]|\*(?!\/))*(?:\*\/|$))*?(?:\?>|$)/g;e.languages["markup-templating"].buildPlaceholders(s,"php",p)}}),e.hooks.add("after-tokenize",function(s){e.languages["markup-templating"].tokenizePlaceholders(s,"php")})})(Prism)),u}var b=g();const y=c(b),m=f({__proto__:null,default:y},[b]);export{m as p};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{g as l}from"./index-
|
|
1
|
+
import{g as l}from"./index-DkSWqPfG.js";function d(e,r){for(var n=0;n<r.length;n++){const t=r[n];if(typeof t!="string"&&!Array.isArray(t)){for(const i in t)if(i!=="default"&&!(i in e)){const s=Object.getOwnPropertyDescriptor(t,i);s&&Object.defineProperty(e,i,s.get?s:{enumerable:!0,get:()=>t[i]})}}}return Object.freeze(Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}))}var a={},o;function g(){return o||(o=1,(function(e){e.languages.ruby=e.languages.extend("clike",{comment:{pattern:/#.*|^=begin\s[\s\S]*?^=end/m,greedy:!0},"class-name":{pattern:/(\b(?:class|module)\s+|\bcatch\s+\()[\w.\\]+|\b[A-Z_]\w*(?=\s*\.\s*new\b)/,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:BEGIN|END|alias|and|begin|break|case|class|def|define_method|defined|do|each|else|elsif|end|ensure|extend|for|if|in|include|module|new|next|nil|not|or|prepend|private|protected|public|raise|redo|require|rescue|retry|return|self|super|then|throw|undef|unless|until|when|while|yield)\b/,operator:/\.{2,3}|&\.|===|<?=>|[!=]?~|(?:&&|\|\||<<|>>|\*\*|[+\-*/%<>!^&|=])=?|[?:]/,punctuation:/[(){}[\].,;]/}),e.languages.insertBefore("ruby","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}});var r={pattern:/((?:^|[^\\])(?:\\{2})*)#\{(?:[^{}]|\{[^{}]*\})*\}/,lookbehind:!0,inside:{content:{pattern:/^(#\{)[\s\S]+(?=\}$)/,lookbehind:!0,inside:e.languages.ruby},delimiter:{pattern:/^#\{|\}$/,alias:"punctuation"}}};delete e.languages.ruby.function;var n="(?:"+[/([^a-zA-Z0-9\s{(\[<=])(?:(?!\1)[^\\]|\\[\s\S])*\1/.source,/\((?:[^()\\]|\\[\s\S]|\((?:[^()\\]|\\[\s\S])*\))*\)/.source,/\{(?:[^{}\\]|\\[\s\S]|\{(?:[^{}\\]|\\[\s\S])*\})*\}/.source,/\[(?:[^\[\]\\]|\\[\s\S]|\[(?:[^\[\]\\]|\\[\s\S])*\])*\]/.source,/<(?:[^<>\\]|\\[\s\S]|<(?:[^<>\\]|\\[\s\S])*>)*>/.source].join("|")+")",t=/(?:"(?:\\.|[^"\\\r\n])*"|(?:\b[a-zA-Z_]\w*|[^\s\0-\x7F]+)[?!]?|\$.)/.source;e.languages.insertBefore("ruby","keyword",{"regex-literal":[{pattern:RegExp(/%r/.source+n+/[egimnosux]{0,6}/.source),greedy:!0,inside:{interpolation:r,regex:/[\s\S]+/}},{pattern:/(^|[^/])\/(?!\/)(?:\[[^\r\n\]]+\]|\\.|[^[/\\\r\n])+\/[egimnosux]{0,6}(?=\s*(?:$|[\r\n,.;})#]))/,lookbehind:!0,greedy:!0,inside:{interpolation:r,regex:/[\s\S]+/}}],variable:/[@$]+[a-zA-Z_]\w*(?:[?!]|\b)/,symbol:[{pattern:RegExp(/(^|[^:]):/.source+t),lookbehind:!0,greedy:!0},{pattern:RegExp(/([\r\n{(,][ \t]*)/.source+t+/(?=:(?!:))/.source),lookbehind:!0,greedy:!0}],"method-definition":{pattern:/(\bdef\s+)\w+(?:\s*\.\s*\w+)?/,lookbehind:!0,inside:{function:/\b\w+$/,keyword:/^self\b/,"class-name":/^\w+/,punctuation:/\./}}}),e.languages.insertBefore("ruby","string",{"string-literal":[{pattern:RegExp(/%[qQiIwWs]?/.source+n),greedy:!0,inside:{interpolation:r,string:/[\s\S]+/}},{pattern:/("|')(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|(?!\1)[^\\#\r\n])*\1/,greedy:!0,inside:{interpolation:r,string:/[\s\S]+/}},{pattern:/<<[-~]?([a-z_]\w*)[\r\n](?:.*[\r\n])*?[\t ]*\1/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<[-~]?[a-z_]\w*|\b[a-z_]\w*$/i,inside:{symbol:/\b\w+/,punctuation:/^<<[-~]?/}},interpolation:r,string:/[\s\S]+/}},{pattern:/<<[-~]?'([a-z_]\w*)'[\r\n](?:.*[\r\n])*?[\t ]*\1/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<[-~]?'[a-z_]\w*'|\b[a-z_]\w*$/i,inside:{symbol:/\b\w+/,punctuation:/^<<[-~]?'|'$/}},string:/[\s\S]+/}}],"command-literal":[{pattern:RegExp(/%x/.source+n),greedy:!0,inside:{interpolation:r,command:{pattern:/[\s\S]+/,alias:"string"}}},{pattern:/`(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|[^\\`#\r\n])*`/,greedy:!0,inside:{interpolation:r,command:{pattern:/[\s\S]+/,alias:"string"}}}]}),delete e.languages.ruby.string,e.languages.insertBefore("ruby","number",{builtin:/\b(?:Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Fixnum|Float|Hash|IO|Integer|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|Stat|String|Struct|Symbol|TMS|Thread|ThreadGroup|Time|TrueClass)\b/,constant:/\b[A-Z][A-Z0-9_]*(?:[?!]|\b)/}),e.languages.rb=e.languages.ruby})(Prism)),a}var u=g();const p=l(u),b=d({__proto__:null,default:p},[u]);export{b as p};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{g as u}from"./index-
|
|
1
|
+
import{g as u}from"./index-DkSWqPfG.js";function d(t,n){for(var i=0;i<n.length;i++){const e=n[i];if(typeof e!="string"&&!Array.isArray(e)){for(const r in e)if(r!=="default"&&!(r in t)){const s=Object.getOwnPropertyDescriptor(e,r);s&&Object.defineProperty(t,r,s.get?s:{enumerable:!0,get:()=>e[r]})}}}return Object.freeze(Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}))}var o={},a;function c(){return a||(a=1,Prism.languages.solidity=Prism.languages.extend("clike",{"class-name":{pattern:/(\b(?:contract|enum|interface|library|new|struct|using)\s+)(?!\d)[\w$]+/,lookbehind:!0},keyword:/\b(?:_|anonymous|as|assembly|assert|break|calldata|case|constant|constructor|continue|contract|default|delete|do|else|emit|enum|event|external|for|from|function|if|import|indexed|inherited|interface|internal|is|let|library|mapping|memory|modifier|new|payable|pragma|private|public|pure|require|returns?|revert|selfdestruct|solidity|storage|struct|suicide|switch|this|throw|using|var|view|while)\b/,operator:/=>|->|:=|=:|\*\*|\+\+|--|\|\||&&|<<=?|>>=?|[-+*/%^&|<>!=]=?|[~?]/}),Prism.languages.insertBefore("solidity","keyword",{builtin:/\b(?:address|bool|byte|u?int(?:8|16|24|32|40|48|56|64|72|80|88|96|104|112|120|128|136|144|152|160|168|176|184|192|200|208|216|224|232|240|248|256)?|string|bytes(?:[1-9]|[12]\d|3[0-2])?)\b/}),Prism.languages.insertBefore("solidity","number",{version:{pattern:/([<>]=?|\^)\d+\.\d+\.\d+\b/,lookbehind:!0,alias:"number"}}),Prism.languages.sol=Prism.languages.solidity),o}var l=c();const m=u(l),y=d({__proto__:null,default:m},[l]);export{y as p};
|
package/dist/client/index.html
CHANGED
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
<link rel="icon" href="/favicon-white.svg" media="(prefers-color-scheme: dark)" />
|
|
8
8
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
9
9
|
<title>difit - Git Diff Viewer</title>
|
|
10
|
-
<script type="module" crossorigin src="/assets/index-
|
|
11
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
10
|
+
<script type="module" crossorigin src="/assets/index-DkSWqPfG.js"></script>
|
|
11
|
+
<link rel="stylesheet" crossorigin href="/assets/index-CJFEXHVo.css">
|
|
12
12
|
</head>
|
|
13
13
|
<body>
|
|
14
14
|
<div id="root"></div>
|
package/dist/server/server.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { spawn } from 'child_process';
|
|
2
|
+
import { join, dirname, resolve, sep } from 'path';
|
|
2
3
|
import { fileURLToPath } from 'url';
|
|
3
4
|
import express from 'express';
|
|
4
5
|
import open from 'open';
|
|
5
6
|
const __filename = fileURLToPath(import.meta.url);
|
|
6
7
|
const __dirname = dirname(__filename);
|
|
7
8
|
import { formatCommentsOutput } from '../utils/commentFormatting.js';
|
|
9
|
+
import { normalizeDiffViewMode } from '../utils/diffMode.js';
|
|
10
|
+
import { resolveEditorOption } from '../utils/editorOptions.js';
|
|
8
11
|
import { getFileExtension } from '../utils/fileUtils.js';
|
|
9
12
|
import { FileWatcherService } from './file-watcher.js';
|
|
10
13
|
import { GitDiffParser } from './git-diff.js';
|
|
@@ -14,8 +17,7 @@ export async function startServer(options) {
|
|
|
14
17
|
const fileWatcher = new FileWatcherService();
|
|
15
18
|
let diffDataCache = null;
|
|
16
19
|
let currentIgnoreWhitespace = options.ignoreWhitespace || false;
|
|
17
|
-
const
|
|
18
|
-
const diffMode = normalizeDiffMode(options.mode);
|
|
20
|
+
const diffMode = normalizeDiffViewMode(options.mode);
|
|
19
21
|
app.use(express.json());
|
|
20
22
|
app.use(express.text()); // For sendBeacon text/plain requests
|
|
21
23
|
app.use((_req, res, next) => {
|
|
@@ -235,6 +237,73 @@ export async function startServer(options) {
|
|
|
235
237
|
res.send('');
|
|
236
238
|
}
|
|
237
239
|
});
|
|
240
|
+
app.post('/api/open-in-editor', async (req, res) => {
|
|
241
|
+
if (options.stdinDiff) {
|
|
242
|
+
res.status(400).json({ error: 'Open in editor is not available for stdin diff' });
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
const { filePath, line, editor } = (req.body ?? {});
|
|
246
|
+
if (typeof filePath !== 'string') {
|
|
247
|
+
res.status(400).json({ error: 'Invalid request payload' });
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
const repoRoot = resolve(options.repoPath ?? process.cwd());
|
|
251
|
+
const resolvedPath = resolve(repoRoot, filePath);
|
|
252
|
+
if (resolvedPath !== repoRoot && !resolvedPath.startsWith(`${repoRoot}${sep}`)) {
|
|
253
|
+
res.status(400).json({ error: 'File path outside repository' });
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
const editorInput = typeof editor === 'string' ? editor : (process.env.DIFIT_EDITOR ?? process.env.EDITOR);
|
|
257
|
+
const resolvedEditor = resolveEditorOption(editorInput);
|
|
258
|
+
if (resolvedEditor.protocol === null) {
|
|
259
|
+
res.status(400).json({ error: 'Open in editor is disabled' });
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
const lineNumber = (() => {
|
|
263
|
+
const parsed = Number.parseInt(String(line ?? ''), 10);
|
|
264
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
|
|
265
|
+
})();
|
|
266
|
+
const tryOpenWithCli = async () => {
|
|
267
|
+
if (!resolvedEditor.cliCommand)
|
|
268
|
+
return false;
|
|
269
|
+
const args = [...resolvedEditor.cliArgs];
|
|
270
|
+
if (lineNumber !== null) {
|
|
271
|
+
args.push('-g', `${resolvedPath}:${lineNumber}`);
|
|
272
|
+
}
|
|
273
|
+
else {
|
|
274
|
+
args.push(resolvedPath);
|
|
275
|
+
}
|
|
276
|
+
args.push(repoRoot);
|
|
277
|
+
return await new Promise((resolvePromise) => {
|
|
278
|
+
const child = spawn(resolvedEditor.cliCommand, args, { stdio: 'ignore', detached: true });
|
|
279
|
+
child.once('error', (error) => {
|
|
280
|
+
const code = error.code;
|
|
281
|
+
if (code && code !== 'ENOENT') {
|
|
282
|
+
console.error('Failed to launch editor CLI:', error);
|
|
283
|
+
}
|
|
284
|
+
resolvePromise(false);
|
|
285
|
+
});
|
|
286
|
+
child.once('spawn', () => {
|
|
287
|
+
child.unref();
|
|
288
|
+
resolvePromise(true);
|
|
289
|
+
});
|
|
290
|
+
});
|
|
291
|
+
};
|
|
292
|
+
if (await tryOpenWithCli()) {
|
|
293
|
+
res.json({ success: true });
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
const lineSuffix = lineNumber !== null ? `:${lineNumber}` : '';
|
|
297
|
+
const fileUri = `${resolvedEditor.protocol}://file${encodeURI(resolvedPath)}${lineSuffix}`;
|
|
298
|
+
try {
|
|
299
|
+
await open(fileUri);
|
|
300
|
+
res.json({ success: true });
|
|
301
|
+
}
|
|
302
|
+
catch (error) {
|
|
303
|
+
console.error('Failed to open file in editor:', error);
|
|
304
|
+
res.status(500).json({ error: 'Failed to open file in editor' });
|
|
305
|
+
}
|
|
306
|
+
});
|
|
238
307
|
// Function to output comments when server shuts down
|
|
239
308
|
function outputFinalComments() {
|
|
240
309
|
if (finalComments.length > 0) {
|
|
@@ -367,7 +367,7 @@ describe('Server Integration Tests', () => {
|
|
|
367
367
|
const result = await startServer({
|
|
368
368
|
targetCommitish: 'HEAD',
|
|
369
369
|
baseCommitish: 'HEAD^',
|
|
370
|
-
mode: '
|
|
370
|
+
mode: 'unified',
|
|
371
371
|
});
|
|
372
372
|
servers.push(result.server);
|
|
373
373
|
expect(result.port).toBeGreaterThanOrEqual(4966);
|
|
@@ -377,13 +377,13 @@ describe('Server Integration Tests', () => {
|
|
|
377
377
|
const inlineResult = await startServer({
|
|
378
378
|
targetCommitish: 'HEAD',
|
|
379
379
|
baseCommitish: 'HEAD^',
|
|
380
|
-
mode: '
|
|
380
|
+
mode: 'unified',
|
|
381
381
|
});
|
|
382
382
|
servers.push(inlineResult.server);
|
|
383
383
|
const sideBySideResult = await startServer({
|
|
384
384
|
targetCommitish: 'HEAD',
|
|
385
385
|
baseCommitish: 'HEAD^',
|
|
386
|
-
mode: '
|
|
386
|
+
mode: 'split',
|
|
387
387
|
});
|
|
388
388
|
servers.push(sideBySideResult.server);
|
|
389
389
|
expect(inlineResult.port).toBeGreaterThanOrEqual(4966);
|
|
@@ -399,7 +399,7 @@ describe('Server Integration Tests', () => {
|
|
|
399
399
|
const response = await fetch(`http://localhost:${result.port}/api/diff`);
|
|
400
400
|
const data = await response.json();
|
|
401
401
|
// The mode should be included in the response
|
|
402
|
-
expect(data).toHaveProperty('mode', '
|
|
402
|
+
expect(data).toHaveProperty('mode', 'unified');
|
|
403
403
|
});
|
|
404
404
|
});
|
|
405
405
|
describe('Revision options API', () => {
|
package/dist/tui/App.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Box, Text, useApp, useInput } from 'ink';
|
|
2
2
|
import React, { useState, useEffect } from 'react';
|
|
3
3
|
import { loadGitDiff } from '../server/git-diff-tui.js';
|
|
4
|
+
import { normalizeDiffViewMode } from '../utils/diffMode.js';
|
|
4
5
|
import DiffViewer from './components/DiffViewer.js';
|
|
5
6
|
import FileList from './components/FileList.js';
|
|
6
7
|
import SideBySideDiffViewer from './components/SideBySideDiffViewer.js';
|
|
@@ -10,7 +11,7 @@ const App = ({ targetCommitish, baseCommitish, mode, repoPath }) => {
|
|
|
10
11
|
const [selectedFileIndex, setSelectedFileIndex] = useState(0);
|
|
11
12
|
const [loading, setLoading] = useState(true);
|
|
12
13
|
const [error, setError] = useState(null);
|
|
13
|
-
const [viewMode, setViewMode] = useState(mode
|
|
14
|
+
const [viewMode, setViewMode] = useState(normalizeDiffViewMode(mode));
|
|
14
15
|
const { exit } = useApp();
|
|
15
16
|
const loadDiff = async () => {
|
|
16
17
|
setLoading(true);
|
|
@@ -46,10 +47,10 @@ const App = ({ targetCommitish, baseCommitish, mode, repoPath }) => {
|
|
|
46
47
|
setSelectedFileIndex((prev) => Math.min(files.length - 1, prev + 1));
|
|
47
48
|
}
|
|
48
49
|
if (key.return || input === ' ') {
|
|
49
|
-
setViewMode('
|
|
50
|
+
setViewMode('split');
|
|
50
51
|
}
|
|
51
52
|
if (input === 'd') {
|
|
52
|
-
setViewMode('
|
|
53
|
+
setViewMode('unified');
|
|
53
54
|
}
|
|
54
55
|
}
|
|
55
56
|
else if (key.escape || input === 'b') {
|
|
@@ -81,13 +82,13 @@ const App = ({ targetCommitish, baseCommitish, mode, repoPath }) => {
|
|
|
81
82
|
React.createElement(StatusBar, { commitish: targetCommitish, totalFiles: files.length, currentMode: viewMode }),
|
|
82
83
|
React.createElement(Box, { flexGrow: 1, flexDirection: "column" }, viewMode === 'list' ?
|
|
83
84
|
React.createElement(FileList, { files: files, selectedIndex: selectedFileIndex })
|
|
84
|
-
: viewMode === '
|
|
85
|
+
: viewMode === 'split' ?
|
|
85
86
|
React.createElement(SideBySideDiffViewer, { files: files, initialFileIndex: selectedFileIndex, onBack: () => setViewMode('list') })
|
|
86
87
|
: React.createElement(DiffViewer, { files: files, initialFileIndex: selectedFileIndex })),
|
|
87
88
|
React.createElement(Box, { borderStyle: "single", paddingX: 1 },
|
|
88
89
|
React.createElement(Text, { dimColor: true }, viewMode === 'list' ?
|
|
89
|
-
'↑/↓ or j/k: navigate | Enter/Space:
|
|
90
|
-
: viewMode === '
|
|
90
|
+
'↑/↓ or j/k: navigate | Enter/Space: split | d: unified diff | r: reload | q: quit'
|
|
91
|
+
: viewMode === 'split' ?
|
|
91
92
|
'Tab: next file | Shift+Tab: prev | ↑/↓ or j/k: scroll | ESC/b: list | r: reload | q: quit'
|
|
92
93
|
: 'Tab: next | Shift+Tab: prev | ↑/↓ or j/k: scroll | ESC/b: list | r: reload | q: quit'))));
|
|
93
94
|
};
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
interface StatusBarProps {
|
|
3
3
|
commitish: string;
|
|
4
4
|
totalFiles: number;
|
|
5
|
-
currentMode: 'list' | '
|
|
5
|
+
currentMode: 'list' | 'split' | 'unified';
|
|
6
6
|
}
|
|
7
7
|
declare const StatusBar: React.FC<StatusBarProps>;
|
|
8
8
|
export default StatusBar;
|
|
@@ -15,9 +15,9 @@ const StatusBar = ({ commitish, totalFiles, currentMode }) => {
|
|
|
15
15
|
"[",
|
|
16
16
|
currentMode === 'list' ?
|
|
17
17
|
'File List'
|
|
18
|
-
: currentMode === '
|
|
19
|
-
'
|
|
20
|
-
: '
|
|
18
|
+
: currentMode === 'split' ?
|
|
19
|
+
'Split'
|
|
20
|
+
: 'Unified',
|
|
21
21
|
"]"))));
|
|
22
22
|
};
|
|
23
23
|
export default StatusBar;
|
package/dist/types/diff.d.ts
CHANGED
|
@@ -31,14 +31,15 @@ export interface DiffLine {
|
|
|
31
31
|
export interface ParsedDiff {
|
|
32
32
|
chunks: DiffChunk[];
|
|
33
33
|
}
|
|
34
|
-
export type DiffViewMode = '
|
|
34
|
+
export type DiffViewMode = 'split' | 'unified';
|
|
35
|
+
export type LegacyDiffViewMode = 'side-by-side' | 'inline';
|
|
35
36
|
export type DiffSide = 'old' | 'new';
|
|
36
37
|
export interface DiffResponse {
|
|
37
38
|
commit: string;
|
|
38
39
|
files: DiffFile[];
|
|
39
40
|
ignoreWhitespace?: boolean;
|
|
40
41
|
isEmpty?: boolean;
|
|
41
|
-
mode?: DiffViewMode;
|
|
42
|
+
mode?: DiffViewMode | LegacyDiffViewMode;
|
|
42
43
|
baseCommitish?: string;
|
|
43
44
|
targetCommitish?: string;
|
|
44
45
|
requestedBaseCommitish?: string;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export const DEFAULT_DIFF_VIEW_MODE = 'split';
|
|
2
|
+
export function normalizeDiffViewMode(mode) {
|
|
3
|
+
switch (mode) {
|
|
4
|
+
case 'split':
|
|
5
|
+
case 'side-by-side':
|
|
6
|
+
return 'split';
|
|
7
|
+
case 'unified':
|
|
8
|
+
case 'inline':
|
|
9
|
+
return 'unified';
|
|
10
|
+
default:
|
|
11
|
+
return DEFAULT_DIFF_VIEW_MODE;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export declare const EDITOR_OPTIONS: readonly [{
|
|
2
|
+
readonly id: "vscode";
|
|
3
|
+
readonly label: "VS Code";
|
|
4
|
+
readonly protocol: "vscode";
|
|
5
|
+
readonly cliCommand: "code";
|
|
6
|
+
readonly cliArgs: readonly [];
|
|
7
|
+
readonly aliases: readonly ["vscode", "code"];
|
|
8
|
+
}, {
|
|
9
|
+
readonly id: "cursor";
|
|
10
|
+
readonly label: "Cursor";
|
|
11
|
+
readonly protocol: "cursor";
|
|
12
|
+
readonly cliCommand: "cursor";
|
|
13
|
+
readonly cliArgs: readonly [];
|
|
14
|
+
readonly aliases: readonly ["cursor"];
|
|
15
|
+
}, {
|
|
16
|
+
readonly id: "none";
|
|
17
|
+
readonly label: "Hide “Open in editor” button";
|
|
18
|
+
readonly protocol: null;
|
|
19
|
+
readonly cliCommand: null;
|
|
20
|
+
readonly cliArgs: readonly [];
|
|
21
|
+
readonly aliases: readonly ["none", "disabled", "off"];
|
|
22
|
+
}];
|
|
23
|
+
export type EditorOption = (typeof EDITOR_OPTIONS)[number];
|
|
24
|
+
export type EditorOptionId = EditorOption['id'];
|
|
25
|
+
export declare const DEFAULT_EDITOR_ID: EditorOptionId;
|
|
26
|
+
export declare const resolveEditorOption: (input?: string) => EditorOption;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export const EDITOR_OPTIONS = [
|
|
2
|
+
{
|
|
3
|
+
id: 'vscode',
|
|
4
|
+
label: 'VS Code',
|
|
5
|
+
protocol: 'vscode',
|
|
6
|
+
cliCommand: 'code',
|
|
7
|
+
cliArgs: [],
|
|
8
|
+
aliases: ['vscode', 'code'],
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
id: 'cursor',
|
|
12
|
+
label: 'Cursor',
|
|
13
|
+
protocol: 'cursor',
|
|
14
|
+
cliCommand: 'cursor',
|
|
15
|
+
cliArgs: [],
|
|
16
|
+
aliases: ['cursor'],
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
id: 'none',
|
|
20
|
+
label: 'Hide “Open in editor” button',
|
|
21
|
+
protocol: null,
|
|
22
|
+
cliCommand: null,
|
|
23
|
+
cliArgs: [],
|
|
24
|
+
aliases: ['none', 'disabled', 'off'],
|
|
25
|
+
},
|
|
26
|
+
];
|
|
27
|
+
export const DEFAULT_EDITOR_ID = 'vscode';
|
|
28
|
+
export const resolveEditorOption = (input) => {
|
|
29
|
+
const normalized = (input ?? DEFAULT_EDITOR_ID).toLowerCase();
|
|
30
|
+
const matched = EDITOR_OPTIONS.find((option) => option.id === normalized || option.aliases.some((alias) => alias === normalized));
|
|
31
|
+
const fallback = EDITOR_OPTIONS.find((option) => option.id === DEFAULT_EDITOR_ID);
|
|
32
|
+
return matched ?? fallback ?? EDITOR_OPTIONS[0];
|
|
33
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "difit",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.3",
|
|
4
4
|
"description": "A lightweight command-line tool that spins up a local web server to display Git commit diffs in a GitHub-like Files changed view",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -116,5 +116,5 @@
|
|
|
116
116
|
"publishConfig": {
|
|
117
117
|
"access": "public"
|
|
118
118
|
},
|
|
119
|
-
"packageManager": "pnpm@10.28.
|
|
119
|
+
"packageManager": "pnpm@10.28.1"
|
|
120
120
|
}
|