summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhil Hughes <me@iamphill.com>2017-11-16 12:55:01 +0000
committerPhil Hughes <me@iamphill.com>2017-11-16 12:55:01 +0000
commit655dca954ea3e3e4556d97cf905e482f975999fe (patch)
treee1596ef7357bfff4c3f3cf364e7d6b3c44866942
parent58bd04ab75d99fa9be0d9568c442704d400e8b1d (diff)
downloadgitlab-ce-655dca954ea3e3e4556d97cf905e482f975999fe.tar.gz
Multi-file editor dirty diff indicator
[ci skip]
-rw-r--r--app/assets/javascripts/repo/components/repo_editor.vue50
-rw-r--r--app/assets/stylesheets/pages/repo.scss20
2 files changed, 64 insertions, 6 deletions
diff --git a/app/assets/javascripts/repo/components/repo_editor.vue b/app/assets/javascripts/repo/components/repo_editor.vue
index 1c864b176b1..3c06e75a472 100644
--- a/app/assets/javascripts/repo/components/repo_editor.vue
+++ b/app/assets/javascripts/repo/components/repo_editor.vue
@@ -14,8 +14,9 @@ export default {
if (this.monaco) {
this.initMonaco();
} else {
- monacoLoader(['vs/editor/editor.main'], () => {
+ monacoLoader(['vs/editor/editor.main', 'vs/editor/common/diff/diffComputer'], (_, { DiffComputer }) => {
this.monaco = monaco;
+ this.DiffComputer = DiffComputer;
this.initMonaco();
});
@@ -44,8 +45,6 @@ export default {
});
this.languages = this.monaco.languages.getLanguages();
-
- this.addMonacoEvents();
}
this.setupEditor();
@@ -62,11 +61,50 @@ export default {
const newModel = this.monaco.editor.createModel(
content, foundLang ? foundLang.id : 'plaintext',
);
+ const originalLines = this.monaco.editor.createModel(
+ this.activeFile.raw, foundLang ? foundLang.id : 'plaintext',
+ ).getLinesContent();
this.monacoInstance.setModel(newModel);
- },
- addMonacoEvents() {
- this.monacoInstance.onKeyUp(() => {
+ this.decorations = [];
+
+ const modifiedType = (change) => {
+ if (change.originalEndLineNumber === 0) {
+ return 'added';
+ } else if (change.modifiedEndLineNumber === 0) {
+ return 'removed';
+ }
+
+ return 'modified';
+ };
+
+ this.monacoModelChangeContents = newModel.onDidChangeContent(() => {
+ const diffComputer = new this.DiffComputer(
+ originalLines,
+ newModel.getLinesContent(),
+ {
+ shouldPostProcessCharChanges: true,
+ shouldIgnoreTrimWhitespace: true,
+ shouldMakePrettyDiff: true,
+ },
+ );
+
+ this.decorations = this.monacoInstance.deltaDecorations(this.decorations,
+ diffComputer.computeDiff().map(change => ({
+ range: new monaco.Range(
+ change.modifiedStartLineNumber,
+ 1,
+ !change.modifiedEndLineNumber ?
+ change.modifiedStartLineNumber : change.modifiedEndLineNumber,
+ 1,
+ ),
+ options: {
+ isWholeLine: true,
+ linesDecorationsClassName: `dirty-diff dirty-diff-${modifiedType(change)}`,
+ },
+ })),
+ );
+
this.changeFileContent({
file: this.activeFile,
content: this.monacoInstance.getValue(),
diff --git a/app/assets/stylesheets/pages/repo.scss b/app/assets/stylesheets/pages/repo.scss
index d93c51d5448..35b5862374b 100644
--- a/app/assets/stylesheets/pages/repo.scss
+++ b/app/assets/stylesheets/pages/repo.scss
@@ -302,3 +302,23 @@
.multi-file-table-col-name {
width: 350px;
}
+
+.dirty-diff {
+ // !important need to override monaco inline style
+ width: 4px !important;
+ left: 0 !important;
+
+ &-modified {
+ background-color: rgb(19, 117, 150);
+ }
+
+ &-added {
+ background-color: rgb(89, 119, 11);
+ }
+
+ &-removed {
+ height: 4px!important;
+ bottom: -2px;
+ background-color: red;
+ }
+}