change how diffing works

[ci skip]
This commit is contained in:
Phil Hughes 2017-11-22 09:08:30 +00:00
parent eb8a609519
commit caa2f10e71
No known key found for this signature in database
GPG key ID: 32245528C52E0F9F
5 changed files with 55 additions and 100 deletions

View file

@ -1,24 +1,25 @@
/* global monaco */
import Disposable from '../common/disposable';
import DirtyDiffWorker from './worker';
import Disposable from '../common/disposable';
import decorationsController from '../decorations/controller';
export const getDiffChangeType = (change) => {
if (change.originalEndLineNumber === 0) {
if (change.modified) {
return 'modified';
} else if (change.added) {
return 'added';
} else if (change.modifiedEndLineNumber === 0) {
} else if (change.removed) {
return 'removed';
}
return 'modified';
return '';
};
export const getDecorator = change => ({
range: new monaco.Range(
change.modifiedStartLineNumber,
change.lineNumber,
1,
!change.modifiedEndLineNumber ?
change.modifiedStartLineNumber : change.modifiedEndLineNumber,
change.endLineNumber,
1,
),
options: {
@ -37,22 +38,15 @@ export default class DirtyDiffController {
this.disposable = new Disposable();
this.editorSimpleWorker = null;
this.modelManager = modelManager;
this.disposable.add(this.worker = new DirtyDiffWorker());
this.dirtyDiffWorker = new DirtyDiffWorker();
}
attachModel(model) {
if (model.attachedToWorker) return;
[model.getModel(), model.getOriginalModel()].forEach(() => {
this.worker.attachModel(model);
});
model.onChange((_, e) => this.computeDiff(model, e));
model.onChange(() => this.computeDiff(model));
}
computeDiff(model, e) {
this.worker.modelChanged(model, e);
this.worker.compute(model, changes => decorate(model, changes));
computeDiff(model) {
decorate(model, this.dirtyDiffWorker.compute(model));
}
// eslint-disable-next-line class-methods-use-this

View file

@ -1,77 +1,34 @@
/* global monaco */
import Disposable from '../common/disposable';
import { diffLines } from 'diff';
export default class DirtyDiffWorker {
constructor() {
this.editorSimpleWorker = null;
this.disposable = new Disposable();
this.actions = new Set();
// eslint-disable-next-line class-methods-use-this
compute(model) {
const originalContent = model.getOriginalModel().getValue();
const newContent = model.getModel().getValue();
const changes = diffLines(originalContent, newContent);
// eslint-disable-next-line promise/catch-or-return
monaco.editor.createWebWorker({
moduleId: 'vs/editor/common/services/editorSimpleWorker',
}).getProxy().then((editorSimpleWorker) => {
this.disposable.add(this.editorSimpleWorker = editorSimpleWorker);
this.ready();
});
}
let lineNumber = 1;
return changes.reduce((acc, change) => {
const findOnLine = acc.find(c => c.lineNumber === lineNumber);
// loop through all the previous cached actions
// this way we don't block the user from editing the file
ready() {
this.actions.forEach((action) => {
const methodName = Object.keys(action)[0];
this[methodName](...action[methodName]);
});
if (findOnLine) {
Object.assign(findOnLine, change, {
modified: true,
endLineNumber: change.count > 1 ? lineNumber + change.count : lineNumber,
});
} else if ('added' in change || 'removed' in change) {
acc.push(Object.assign({}, change, {
lineNumber,
modified: undefined,
endLineNumber: change.count > 1 ? lineNumber + change.count : lineNumber,
}));
}
this.actions.clear();
}
if (!change.removed) {
lineNumber += change.count;
}
attachModel(model) {
if (this.editorSimpleWorker && !model.attachedToWorker) {
this.editorSimpleWorker.acceptNewModel(model.diffModel);
this.editorSimpleWorker.acceptNewModel(model.originalDiffModel);
model.setAttachedToWorker(true);
} else if (!this.editorSimpleWorker) {
this.actions.add({
attachModel: [model],
});
}
}
modelChanged(model, e) {
if (this.editorSimpleWorker) {
this.editorSimpleWorker.acceptModelChanged(
model.url,
e,
);
} else {
this.actions.add({
modelChanged: [model, e],
});
}
}
compute(model, cb) {
if (this.editorSimpleWorker) {
return this.editorSimpleWorker.computeDiff(
model.originalUrl,
model.url,
).then(cb);
}
this.actions.add({
compute: [model, cb],
});
return null;
}
dispose() {
this.actions.clear();
this.disposable.dispose();
this.editorSimpleWorker = null;
return acc;
}, []);
}
}

View file

@ -11,28 +11,27 @@ export default class Editor {
}
constructor() {
this.diffComputers = new Map();
this.currentModel = null;
this.instance = null;
this.dirtyDiffController = null;
this.modelManager = new ModelManager();
this.disposable = new Disposable();
this.disposable.add(this.modelManager);
this.disposable.add(
this.modelManager = new ModelManager(),
);
}
createInstance(domElement) {
if (!this.instance) {
this.instance = monaco.editor.create(domElement, {
model: null,
readOnly: false,
contextmenu: true,
scrollBeyondLastLine: false,
});
this.dirtyDiffController = new DirtyDiffController(this.modelManager);
this.disposable.add(this.dirtyDiffController, this.instance);
this.disposable.add(
this.instance = monaco.editor.create(domElement, {
model: null,
readOnly: false,
contextmenu: true,
scrollBeyondLastLine: false,
}),
this.dirtyDiffController = new DirtyDiffController(this.modelManager),
);
}
}

View file

@ -33,6 +33,7 @@
"css-loader": "^0.28.0",
"d3": "^3.5.11",
"deckar01-task_list": "^2.0.0",
"diff": "^3.4.0",
"document-register-element": "1.3.0",
"dropzone": "^4.2.0",
"emoji-unicode-version": "^0.2.1",

View file

@ -1895,6 +1895,10 @@ di@^0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c"
diff@^3.4.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/diff/-/diff-3.4.0.tgz#b1d85507daf3964828de54b37d0d73ba67dda56c"
diffie-hellman@^5.0.0:
version "5.0.2"
resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.2.tgz#b5835739270cfe26acf632099fded2a07f209e5e"