CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
sagemathinc

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/frontend/codemirror/extensions/diff-apply.ts
Views: 687
1
/*
2
* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
3
* License: MS-RSL – see LICENSE.md for details
4
*/
5
6
import * as CodeMirror from "codemirror";
7
8
// We define the diffApply extension separately so it can be applied to CodeMirror's
9
// in iframes, e.g., Jupyter's.
10
11
export function cm_define_diffApply_extension(cm) {
12
// applies a diff and returns last pos modified
13
cm.defineExtension("diffApply", function (diff) {
14
// @ts-ignore
15
const editor = this;
16
const next_pos = function (
17
val: string,
18
pos: CodeMirror.Position
19
): CodeMirror.Position {
20
// This functions answers the question:
21
// If you were to insert the string val at the CodeMirror position pos
22
// in a codemirror document, at what position (in codemirror) would
23
// the inserted string end at?
24
const number_of_newlines = (val.match(/\n/g) || []).length;
25
if (number_of_newlines === 0) {
26
return { line: pos.line, ch: pos.ch + val.length };
27
} else {
28
return {
29
line: pos.line + number_of_newlines,
30
ch: val.length - val.lastIndexOf("\n") - 1,
31
};
32
}
33
};
34
35
let pos: CodeMirror.Position = { line: 0, ch: 0 }; // start at the beginning
36
let last_pos: CodeMirror.Position | undefined = undefined;
37
for (let chunk of diff) {
38
const op = chunk[0]; // 0 = stay same; -1 = delete; +1 = add
39
const val = chunk[1]; // the actual text to leave same, delete, or add
40
const pos1 = next_pos(val, pos);
41
42
switch (op) {
43
case 0: // stay the same
44
// Move our pos pointer to the next position
45
pos = pos1;
46
break;
47
//console.log("skipping to ", pos1)
48
case -1: // delete
49
// Delete until where val ends; don't change pos pointer.
50
editor.replaceRange("", pos, pos1);
51
last_pos = pos;
52
break;
53
//console.log("deleting from ", pos, " to ", pos1)
54
case +1: // insert
55
// Insert the new text right here.
56
editor.replaceRange(val, pos);
57
//console.log("inserted new text at ", pos)
58
// Move our pointer to just beyond the text we just inserted.
59
pos = pos1;
60
last_pos = pos1;
61
break;
62
}
63
}
64
return last_pos;
65
});
66
}
67
68
cm_define_diffApply_extension(CodeMirror);
69
70