Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/notebook/common/notebookDiff.ts
3296 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { IDiffChange } from '../../../../base/common/diff/diff.js';
7
import { CellKind, INotebookDiffResult } from './notebookCommon.js';
8
9
export type CellDiffInfo = {
10
originalCellIndex: number;
11
modifiedCellIndex: number;
12
type: 'unchanged' | 'modified';
13
} |
14
{
15
originalCellIndex: number;
16
type: 'delete';
17
} |
18
{
19
modifiedCellIndex: number;
20
type: 'insert';
21
};
22
23
interface ICell {
24
cellKind: CellKind;
25
getHashValue(): number;
26
equal(cell: ICell): boolean;
27
}
28
// interface INotebookDiffResult {
29
// cellsDiff: IDiffResult;
30
// metadataChanged: boolean;
31
// }
32
33
export function computeDiff(originalModel: { readonly cells: readonly ICell[] }, modifiedModel: { readonly cells: readonly ICell[] }, diffResult: INotebookDiffResult) {
34
const cellChanges = diffResult.cellsDiff.changes;
35
const cellDiffInfo: CellDiffInfo[] = [];
36
let originalCellIndex = 0;
37
let modifiedCellIndex = 0;
38
39
let firstChangeIndex = -1;
40
41
for (let i = 0; i < cellChanges.length; i++) {
42
const change = cellChanges[i];
43
// common cells
44
45
for (let j = 0; j < change.originalStart - originalCellIndex; j++) {
46
const originalCell = originalModel.cells[originalCellIndex + j];
47
const modifiedCell = modifiedModel.cells[modifiedCellIndex + j];
48
if (originalCell.getHashValue() === modifiedCell.getHashValue()) {
49
cellDiffInfo.push({
50
originalCellIndex: originalCellIndex + j,
51
modifiedCellIndex: modifiedCellIndex + j,
52
type: 'unchanged'
53
});
54
} else {
55
if (firstChangeIndex === -1) {
56
firstChangeIndex = cellDiffInfo.length;
57
}
58
cellDiffInfo.push({
59
originalCellIndex: originalCellIndex + j,
60
modifiedCellIndex: modifiedCellIndex + j,
61
type: 'modified'
62
});
63
}
64
}
65
66
const modifiedLCS = computeModifiedLCS(change, originalModel, modifiedModel);
67
if (modifiedLCS.length && firstChangeIndex === -1) {
68
firstChangeIndex = cellDiffInfo.length;
69
}
70
71
cellDiffInfo.push(...modifiedLCS);
72
originalCellIndex = change.originalStart + change.originalLength;
73
modifiedCellIndex = change.modifiedStart + change.modifiedLength;
74
}
75
76
for (let i = originalCellIndex; i < originalModel.cells.length; i++) {
77
cellDiffInfo.push({
78
originalCellIndex: i,
79
modifiedCellIndex: i - originalCellIndex + modifiedCellIndex,
80
type: 'unchanged'
81
});
82
}
83
84
return {
85
cellDiffInfo,
86
firstChangeIndex
87
};
88
}
89
90
function computeModifiedLCS(change: IDiffChange, originalModel: { readonly cells: readonly ICell[] }, modifiedModel: { readonly cells: readonly ICell[] }) {
91
const result: CellDiffInfo[] = [];
92
// modified cells
93
const modifiedLen = Math.min(change.originalLength, change.modifiedLength);
94
95
for (let j = 0; j < modifiedLen; j++) {
96
const originalCell = originalModel.cells[change.originalStart + j];
97
const modifiedCell = modifiedModel.cells[change.modifiedStart + j];
98
if (originalCell.cellKind !== modifiedCell.cellKind) {
99
result.push({
100
originalCellIndex: change.originalStart + j,
101
type: 'delete'
102
});
103
result.push({
104
modifiedCellIndex: change.modifiedStart + j,
105
type: 'insert'
106
});
107
} else {
108
const isTheSame = originalCell.equal(modifiedCell);
109
result.push({
110
originalCellIndex: change.originalStart + j,
111
modifiedCellIndex: change.modifiedStart + j,
112
type: isTheSame ? 'unchanged' : 'modified'
113
});
114
}
115
}
116
117
for (let j = modifiedLen; j < change.originalLength; j++) {
118
// deletion
119
result.push({
120
originalCellIndex: change.originalStart + j,
121
type: 'delete'
122
});
123
}
124
125
for (let j = modifiedLen; j < change.modifiedLength; j++) {
126
result.push({
127
modifiedCellIndex: change.modifiedStart + j,
128
type: 'insert'
129
});
130
}
131
132
return result;
133
}
134
135