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

View file

@ -1,77 +1,34 @@
/* global monaco */ import { diffLines } from 'diff';
import Disposable from '../common/disposable';
export default class DirtyDiffWorker { export default class DirtyDiffWorker {
constructor() { // eslint-disable-next-line class-methods-use-this
this.editorSimpleWorker = null; compute(model) {
this.disposable = new Disposable(); const originalContent = model.getOriginalModel().getValue();
this.actions = new Set(); const newContent = model.getModel().getValue();
const changes = diffLines(originalContent, newContent);
// eslint-disable-next-line promise/catch-or-return let lineNumber = 1;
monaco.editor.createWebWorker({ return changes.reduce((acc, change) => {
moduleId: 'vs/editor/common/services/editorSimpleWorker', const findOnLine = acc.find(c => c.lineNumber === lineNumber);
}).getProxy().then((editorSimpleWorker) => {
this.disposable.add(this.editorSimpleWorker = editorSimpleWorker); if (findOnLine) {
this.ready(); 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,
}));
} }
// loop through all the previous cached actions if (!change.removed) {
// this way we don't block the user from editing the file lineNumber += change.count;
ready() {
this.actions.forEach((action) => {
const methodName = Object.keys(action)[0];
this[methodName](...action[methodName]);
});
this.actions.clear();
} }
attachModel(model) { return acc;
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;
} }
} }

View file

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

View file

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

View file

@ -1895,6 +1895,10 @@ di@^0.0.1:
version "0.0.1" version "0.0.1"
resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" 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: diffie-hellman@^5.0.0:
version "5.0.2" version "5.0.2"
resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.2.tgz#b5835739270cfe26acf632099fded2a07f209e5e" resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.2.tgz#b5835739270cfe26acf632099fded2a07f209e5e"