Render 'No newline at end of file' at the end of files
For files missing a return character at the end of the file, the git warning will now be rendered instead of being stripped out of the block lines
This commit is contained in:
parent
1350740c98
commit
e8aadb0785
6 changed files with 422 additions and 18 deletions
|
|
@ -157,29 +157,35 @@ describe('Diff2Html', () => {
|
|||
"type": "delete",
|
||||
},
|
||||
{
|
||||
"content": "+ TokenRevoked, MissingToken,",
|
||||
"content": "\\ No newline at end of file",
|
||||
"newNumber": 53,
|
||||
"oldNumber": undefined,
|
||||
"type": "insert",
|
||||
"oldNumber": 55,
|
||||
"type": "context",
|
||||
},
|
||||
{
|
||||
"content": "+ IndexLock, RepositoryError, NotValidRepo, PullRequestNotMergeable, BranchError,",
|
||||
"content": "+ TokenRevoked, MissingToken,",
|
||||
"newNumber": 54,
|
||||
"oldNumber": undefined,
|
||||
"type": "insert",
|
||||
},
|
||||
{
|
||||
"content": "+ PluginError, CodeParserError, EngineError = Value",
|
||||
"content": "+ IndexLock, RepositoryError, NotValidRepo, PullRequestNotMergeable, BranchError,",
|
||||
"newNumber": 55,
|
||||
"oldNumber": undefined,
|
||||
"type": "insert",
|
||||
},
|
||||
{
|
||||
"content": "+}",
|
||||
"content": "+ PluginError, CodeParserError, EngineError = Value",
|
||||
"newNumber": 56,
|
||||
"oldNumber": undefined,
|
||||
"type": "insert",
|
||||
},
|
||||
{
|
||||
"content": "+}",
|
||||
"newNumber": 57,
|
||||
"oldNumber": undefined,
|
||||
"type": "insert",
|
||||
},
|
||||
],
|
||||
"newStartLine": 50,
|
||||
"oldStartLine": 50,
|
||||
|
|
|
|||
|
|
@ -407,6 +407,357 @@ describe('SideBySideRenderer', () => {
|
|||
`);
|
||||
});
|
||||
|
||||
it('should handle files without newlines at the end', () => {
|
||||
const exampleJson: DiffFile[] = [
|
||||
{
|
||||
blocks: [
|
||||
// Scenario 1: Old file missing newline, new file has newline
|
||||
{
|
||||
lines: [
|
||||
{
|
||||
content: '-oldLine1',
|
||||
type: LineType.DELETE,
|
||||
oldNumber: 1,
|
||||
newNumber: undefined,
|
||||
},
|
||||
{
|
||||
content: '\\ No newline at end of file',
|
||||
type: LineType.CONTEXT,
|
||||
oldNumber: 1,
|
||||
newNumber: 1,
|
||||
},
|
||||
{
|
||||
content: '+newLine1',
|
||||
type: LineType.INSERT,
|
||||
oldNumber: undefined,
|
||||
newNumber: 1,
|
||||
},
|
||||
],
|
||||
oldStartLine: 1,
|
||||
newStartLine: 1,
|
||||
header: '@@ -1 +1 @@',
|
||||
},
|
||||
// Scenario 2: Old file has newline, new file missing newline
|
||||
{
|
||||
lines: [
|
||||
{
|
||||
content: '-oldLine2',
|
||||
type: LineType.DELETE,
|
||||
oldNumber: 2,
|
||||
newNumber: undefined,
|
||||
},
|
||||
{
|
||||
content: '+newLine2',
|
||||
type: LineType.INSERT,
|
||||
oldNumber: undefined,
|
||||
newNumber: 2,
|
||||
},
|
||||
{
|
||||
content: '\\ No newline at end of file',
|
||||
type: LineType.CONTEXT,
|
||||
oldNumber: 2,
|
||||
newNumber: 2,
|
||||
},
|
||||
],
|
||||
oldStartLine: 2,
|
||||
newStartLine: 2,
|
||||
header: '@@ -2 +2 @@',
|
||||
},
|
||||
// Scenario 3: Both files missing newline
|
||||
{
|
||||
lines: [
|
||||
{
|
||||
content: '-oldLine3',
|
||||
type: LineType.DELETE,
|
||||
oldNumber: 3,
|
||||
newNumber: undefined,
|
||||
},
|
||||
{
|
||||
content: '\\ No newline at end of file',
|
||||
type: LineType.CONTEXT,
|
||||
oldNumber: 3,
|
||||
newNumber: 3,
|
||||
},
|
||||
{
|
||||
content: '+newLine3',
|
||||
type: LineType.INSERT,
|
||||
oldNumber: undefined,
|
||||
newNumber: 3,
|
||||
},
|
||||
{
|
||||
content: '\\ No newline at end of file',
|
||||
type: LineType.CONTEXT,
|
||||
oldNumber: 3,
|
||||
newNumber: 3,
|
||||
},
|
||||
],
|
||||
oldStartLine: 3,
|
||||
newStartLine: 3,
|
||||
header: '@@ -3 +3 @@',
|
||||
},
|
||||
],
|
||||
deletedLines: 3,
|
||||
addedLines: 3,
|
||||
oldName: 'sample',
|
||||
language: 'txt',
|
||||
newName: 'sample',
|
||||
isCombined: false,
|
||||
isGitDiff: true,
|
||||
},
|
||||
];
|
||||
|
||||
const hoganUtils = new HoganJsUtils({});
|
||||
const sideBySideRenderer = new SideBySideRenderer(hoganUtils, {});
|
||||
const html = sideBySideRenderer.render(exampleJson);
|
||||
expect(html).toMatchInlineSnapshot(`
|
||||
"<div class="d2h-wrapper d2h-light-color-scheme">
|
||||
<div id="d2h-675094" class="d2h-file-wrapper" data-lang="txt">
|
||||
<div class="d2h-file-header">
|
||||
<span class="d2h-file-name-wrapper">
|
||||
<svg aria-hidden="true" class="d2h-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12">
|
||||
<path d="M6 5H2v-1h4v1zM2 8h7v-1H2v1z m0 2h7v-1H2v1z m0 2h7v-1H2v1z m10-7.5v9.5c0 0.55-0.45 1-1 1H1c-0.55 0-1-0.45-1-1V2c0-0.55 0.45-1 1-1h7.5l3.5 3.5z m-1 0.5L8 2H1v12h10V5z"></path>
|
||||
</svg> <span class="d2h-file-name">sample</span>
|
||||
<span class="d2h-tag d2h-changed d2h-changed-tag">CHANGED</span></span>
|
||||
<label class="d2h-file-collapse">
|
||||
<input class="d2h-file-collapse-input" type="checkbox" name="viewed" value="viewed">
|
||||
Viewed
|
||||
</label>
|
||||
</div>
|
||||
<div class="d2h-files-diff">
|
||||
<div class="d2h-file-side-diff">
|
||||
<div class="d2h-code-wrapper">
|
||||
<table class="d2h-diff-table">
|
||||
<tbody class="d2h-diff-tbody">
|
||||
<tr>
|
||||
<td class="d2h-code-side-linenumber d2h-info"></td>
|
||||
<td class="d2h-info">
|
||||
<div class="d2h-code-side-line">@@ -1 +1 @@</div>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td class="d2h-code-side-linenumber d2h-del">
|
||||
1
|
||||
</td>
|
||||
<td class="d2h-del">
|
||||
<div class="d2h-code-side-line">
|
||||
<span class="d2h-code-line-prefix">-</span>
|
||||
<span class="d2h-code-line-ctn">oldLine1</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td class="d2h-code-side-linenumber d2h-cntx">
|
||||
1
|
||||
</td>
|
||||
<td class="d2h-cntx">
|
||||
<div class="d2h-code-side-line">
|
||||
<span class="d2h-code-line-prefix">\\</span>
|
||||
<span class="d2h-code-line-ctn"> No newline at end of file</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td class="d2h-code-side-linenumber d2h-code-side-emptyplaceholder d2h-cntx d2h-emptyplaceholder">
|
||||
|
||||
</td>
|
||||
<td class="d2h-cntx d2h-emptyplaceholder">
|
||||
<div class="d2h-code-side-line d2h-code-side-emptyplaceholder">
|
||||
<span class="d2h-code-line-prefix"> </span>
|
||||
<span class="d2h-code-line-ctn"><br></span>
|
||||
</div>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td class="d2h-code-side-linenumber d2h-info"></td>
|
||||
<td class="d2h-info">
|
||||
<div class="d2h-code-side-line">@@ -2 +2 @@</div>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td class="d2h-code-side-linenumber d2h-del d2h-change">
|
||||
2
|
||||
</td>
|
||||
<td class="d2h-del d2h-change">
|
||||
<div class="d2h-code-side-line">
|
||||
<span class="d2h-code-line-prefix">-</span>
|
||||
<span class="d2h-code-line-ctn"><del>oldLine2</del></span>
|
||||
</div>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td class="d2h-code-side-linenumber d2h-code-side-emptyplaceholder d2h-cntx d2h-emptyplaceholder">
|
||||
|
||||
</td>
|
||||
<td class="d2h-cntx d2h-emptyplaceholder">
|
||||
<div class="d2h-code-side-line d2h-code-side-emptyplaceholder">
|
||||
<span class="d2h-code-line-prefix"> </span>
|
||||
<span class="d2h-code-line-ctn"><br></span>
|
||||
</div>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td class="d2h-code-side-linenumber d2h-info"></td>
|
||||
<td class="d2h-info">
|
||||
<div class="d2h-code-side-line">@@ -3 +3 @@</div>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td class="d2h-code-side-linenumber d2h-del">
|
||||
3
|
||||
</td>
|
||||
<td class="d2h-del">
|
||||
<div class="d2h-code-side-line">
|
||||
<span class="d2h-code-line-prefix">-</span>
|
||||
<span class="d2h-code-line-ctn">oldLine3</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td class="d2h-code-side-linenumber d2h-cntx">
|
||||
3
|
||||
</td>
|
||||
<td class="d2h-cntx">
|
||||
<div class="d2h-code-side-line">
|
||||
<span class="d2h-code-line-prefix">\\</span>
|
||||
<span class="d2h-code-line-ctn"> No newline at end of file</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td class="d2h-code-side-linenumber d2h-code-side-emptyplaceholder d2h-cntx d2h-emptyplaceholder">
|
||||
|
||||
</td>
|
||||
<td class="d2h-cntx d2h-emptyplaceholder">
|
||||
<div class="d2h-code-side-line d2h-code-side-emptyplaceholder">
|
||||
<span class="d2h-code-line-prefix"> </span>
|
||||
<span class="d2h-code-line-ctn"><br></span>
|
||||
</div>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td class="d2h-code-side-linenumber d2h-code-side-emptyplaceholder d2h-cntx d2h-emptyplaceholder">
|
||||
|
||||
</td>
|
||||
<td class="d2h-cntx d2h-emptyplaceholder">
|
||||
<div class="d2h-code-side-line d2h-code-side-emptyplaceholder">
|
||||
<span class="d2h-code-line-prefix"> </span>
|
||||
<span class="d2h-code-line-ctn"><br></span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d2h-file-side-diff">
|
||||
<div class="d2h-code-wrapper">
|
||||
<table class="d2h-diff-table">
|
||||
<tbody class="d2h-diff-tbody">
|
||||
<tr>
|
||||
<td class="d2h-code-side-linenumber d2h-info"></td>
|
||||
<td class="d2h-info">
|
||||
<div class="d2h-code-side-line"> </div>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td class="d2h-code-side-linenumber d2h-code-side-emptyplaceholder d2h-cntx d2h-emptyplaceholder">
|
||||
|
||||
</td>
|
||||
<td class="d2h-cntx d2h-emptyplaceholder">
|
||||
<div class="d2h-code-side-line d2h-code-side-emptyplaceholder">
|
||||
<span class="d2h-code-line-prefix"> </span>
|
||||
<span class="d2h-code-line-ctn"><br></span>
|
||||
</div>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td class="d2h-code-side-linenumber d2h-code-side-emptyplaceholder d2h-cntx d2h-emptyplaceholder">
|
||||
|
||||
</td>
|
||||
<td class="d2h-cntx d2h-emptyplaceholder">
|
||||
<div class="d2h-code-side-line d2h-code-side-emptyplaceholder">
|
||||
<span class="d2h-code-line-prefix"> </span>
|
||||
<span class="d2h-code-line-ctn"><br></span>
|
||||
</div>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td class="d2h-code-side-linenumber d2h-ins">
|
||||
1
|
||||
</td>
|
||||
<td class="d2h-ins">
|
||||
<div class="d2h-code-side-line">
|
||||
<span class="d2h-code-line-prefix">+</span>
|
||||
<span class="d2h-code-line-ctn">newLine1</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td class="d2h-code-side-linenumber d2h-info"></td>
|
||||
<td class="d2h-info">
|
||||
<div class="d2h-code-side-line"> </div>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td class="d2h-code-side-linenumber d2h-ins d2h-change">
|
||||
2
|
||||
</td>
|
||||
<td class="d2h-ins d2h-change">
|
||||
<div class="d2h-code-side-line">
|
||||
<span class="d2h-code-line-prefix">+</span>
|
||||
<span class="d2h-code-line-ctn"><ins>newLine2</ins></span>
|
||||
</div>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td class="d2h-code-side-linenumber d2h-cntx">
|
||||
2
|
||||
</td>
|
||||
<td class="d2h-cntx">
|
||||
<div class="d2h-code-side-line">
|
||||
<span class="d2h-code-line-prefix">\\</span>
|
||||
<span class="d2h-code-line-ctn"> No newline at end of file</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td class="d2h-code-side-linenumber d2h-info"></td>
|
||||
<td class="d2h-info">
|
||||
<div class="d2h-code-side-line"> </div>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td class="d2h-code-side-linenumber d2h-code-side-emptyplaceholder d2h-cntx d2h-emptyplaceholder">
|
||||
|
||||
</td>
|
||||
<td class="d2h-cntx d2h-emptyplaceholder">
|
||||
<div class="d2h-code-side-line d2h-code-side-emptyplaceholder">
|
||||
<span class="d2h-code-line-prefix"> </span>
|
||||
<span class="d2h-code-line-ctn"><br></span>
|
||||
</div>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td class="d2h-code-side-linenumber d2h-code-side-emptyplaceholder d2h-cntx d2h-emptyplaceholder">
|
||||
|
||||
</td>
|
||||
<td class="d2h-cntx d2h-emptyplaceholder">
|
||||
<div class="d2h-code-side-line d2h-code-side-emptyplaceholder">
|
||||
<span class="d2h-code-line-prefix"> </span>
|
||||
<span class="d2h-code-line-ctn"><br></span>
|
||||
</div>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td class="d2h-code-side-linenumber d2h-ins">
|
||||
3
|
||||
</td>
|
||||
<td class="d2h-ins">
|
||||
<div class="d2h-code-side-line">
|
||||
<span class="d2h-code-line-prefix">+</span>
|
||||
<span class="d2h-code-line-ctn">newLine3</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td class="d2h-code-side-linenumber d2h-cntx">
|
||||
3
|
||||
</td>
|
||||
<td class="d2h-cntx">
|
||||
<div class="d2h-code-side-line">
|
||||
<span class="d2h-code-line-prefix">\\</span>
|
||||
<span class="d2h-code-line-ctn"> No newline at end of file</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>"
|
||||
`);
|
||||
});
|
||||
|
||||
it('should work for too big file diff', () => {
|
||||
const exampleJson = [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -87,16 +87,15 @@ export function parse(diffInput: string, config: DiffParserConfig = {}): DiffFil
|
|||
const binaryFiles = /^Binary files (.*) and (.*) differ/;
|
||||
const binaryDiff = /^GIT binary patch/;
|
||||
|
||||
const noNewlineAtEndOfFile = /^\\ No newline at end of file/;
|
||||
|
||||
/* Combined Diff */
|
||||
const combinedIndex = /^index ([\da-z]+),([\da-z]+)\.\.([\da-z]+)/;
|
||||
const combinedMode = /^mode (\d{6}),(\d{6})\.\.(\d{6})/;
|
||||
const combinedNewFile = /^new file mode (\d{6})/;
|
||||
const combinedDeletedFile = /^deleted file mode (\d{6}),(\d{6})/;
|
||||
|
||||
const diffLines = diffInput
|
||||
.replace(/\\ No newline at end of file/g, '')
|
||||
.replace(/\r\n?/g, '\n')
|
||||
.split('\n');
|
||||
const diffLines = diffInput.replace(/\r\n?/g, '\n').split('\n');
|
||||
|
||||
/* Add previous block(if exists) before start a new file */
|
||||
function saveBlock(): void {
|
||||
|
|
@ -472,6 +471,9 @@ export function parse(diffInput: string, config: DiffParserConfig = {}): DiffFil
|
|||
currentFile.deletedFileMode = values[1];
|
||||
currentFile.isDeleted = true;
|
||||
}
|
||||
if (line.match(noNewlineAtEndOfFile)) {
|
||||
createLine(line);
|
||||
}
|
||||
});
|
||||
|
||||
saveBlock();
|
||||
|
|
|
|||
|
|
@ -83,6 +83,8 @@ export function toCSSClass(lineType: LineType): CSSLineClass {
|
|||
return CSSLineClass.INSERTS;
|
||||
case LineType.DELETE:
|
||||
return CSSLineClass.DELETES;
|
||||
case LineType.NO_NEW_LINE:
|
||||
return CSSLineClass.CONTEXT;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import {
|
|||
DiffLineDeleted,
|
||||
DiffLineInserted,
|
||||
DiffLineContent,
|
||||
DiffLineNoNewline,
|
||||
} from './types';
|
||||
|
||||
export interface SideBySideRendererConfig extends renderUtils.RenderConfig {
|
||||
|
|
@ -114,20 +115,39 @@ export default class SideBySideRenderer {
|
|||
} else if (contextLines.length) {
|
||||
contextLines.forEach(line => {
|
||||
const { prefix, content } = renderUtils.deconstructLine(line.content, file.isCombined);
|
||||
const { left, right } = this.generateLineHtml(
|
||||
{
|
||||
let leftContext = undefined;
|
||||
let rightContext = undefined;
|
||||
if (line.type !== LineType.NO_NEW_LINE) {
|
||||
leftContext = {
|
||||
type: renderUtils.CSSLineClass.CONTEXT,
|
||||
prefix: prefix,
|
||||
content: content,
|
||||
number: line.oldNumber,
|
||||
},
|
||||
{
|
||||
};
|
||||
rightContext = {
|
||||
type: renderUtils.CSSLineClass.CONTEXT,
|
||||
prefix: prefix,
|
||||
content: content,
|
||||
number: line.newNumber,
|
||||
},
|
||||
);
|
||||
};
|
||||
} else if (line.type === LineType.NO_NEW_LINE) {
|
||||
if (line.isLeft) {
|
||||
leftContext = {
|
||||
type: renderUtils.CSSLineClass.CONTEXT,
|
||||
prefix: prefix,
|
||||
content: content,
|
||||
number: line.oldNumber,
|
||||
};
|
||||
} else {
|
||||
rightContext = {
|
||||
type: renderUtils.CSSLineClass.CONTEXT,
|
||||
prefix: prefix,
|
||||
content: content,
|
||||
number: line.newNumber,
|
||||
};
|
||||
}
|
||||
}
|
||||
const { left, right } = this.generateLineHtml(leftContext, rightContext);
|
||||
fileHtml.left += left;
|
||||
fileHtml.right += right;
|
||||
});
|
||||
|
|
@ -155,6 +175,7 @@ export default class SideBySideRenderer {
|
|||
|
||||
let oldLines: (DiffLineDeleted & DiffLineContent)[] = [];
|
||||
let newLines: (DiffLineInserted & DiffLineContent)[] = [];
|
||||
let lastLineType: LineType = LineType.DELETE;
|
||||
|
||||
for (let i = 0; i < block.lines.length; i++) {
|
||||
const diffLine = block.lines[i];
|
||||
|
|
@ -169,7 +190,16 @@ export default class SideBySideRenderer {
|
|||
}
|
||||
|
||||
if (diffLine.type === LineType.CONTEXT) {
|
||||
blockLinesGroups.push([[diffLine], [], []]);
|
||||
if (diffLine.content.trim() === '\\ No newline at end of file') {
|
||||
const noNewLine: DiffLineNoNewline & DiffLineContent = {
|
||||
...diffLine,
|
||||
isLeft: lastLineType === LineType.DELETE,
|
||||
type: LineType.NO_NEW_LINE,
|
||||
};
|
||||
blockLinesGroups.push([[noNewLine], [], []]);
|
||||
} else {
|
||||
blockLinesGroups.push([[diffLine], [], []]);
|
||||
}
|
||||
} else if (diffLine.type === LineType.INSERT && oldLines.length === 0) {
|
||||
blockLinesGroups.push([[], [], [diffLine]]);
|
||||
} else if (diffLine.type === LineType.INSERT && oldLines.length > 0) {
|
||||
|
|
@ -177,6 +207,11 @@ export default class SideBySideRenderer {
|
|||
} else if (diffLine.type === LineType.DELETE) {
|
||||
oldLines.push(diffLine);
|
||||
}
|
||||
|
||||
// Track the last non-context line type to determine where "No newline" belongs
|
||||
if (diffLine.type !== LineType.CONTEXT) {
|
||||
lastLineType = diffLine.type;
|
||||
}
|
||||
}
|
||||
|
||||
if (oldLines.length || newLines.length) {
|
||||
|
|
@ -296,7 +331,7 @@ export default class SideBySideRenderer {
|
|||
}
|
||||
|
||||
type DiffLineGroups = [
|
||||
(DiffLineContext & DiffLineContent)[],
|
||||
((DiffLineContext & DiffLineContent) | (DiffLineNoNewline & DiffLineContent))[],
|
||||
(DiffLineDeleted & DiffLineContent)[],
|
||||
(DiffLineInserted & DiffLineContent)[],
|
||||
][];
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ export enum LineType {
|
|||
INSERT = 'insert',
|
||||
DELETE = 'delete',
|
||||
CONTEXT = 'context',
|
||||
NO_NEW_LINE = 'noNewLine',
|
||||
}
|
||||
|
||||
export interface DiffLineDeleted {
|
||||
|
|
@ -27,6 +28,13 @@ export interface DiffLineContext {
|
|||
newNumber: number;
|
||||
}
|
||||
|
||||
export interface DiffLineNoNewline {
|
||||
type: LineType.NO_NEW_LINE;
|
||||
oldNumber: number;
|
||||
newNumber: number;
|
||||
isLeft: boolean;
|
||||
}
|
||||
|
||||
export type DiffLineContent = {
|
||||
content: string;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue