1
1
'use babel'
2
2
3
3
import EditorDiffExtender from './editor-diff-extender' ;
4
+ import ComputeWordDiff from './compute-word-diff' ;
5
+
4
6
5
7
module . exports = class DiffView {
6
8
/*
7
9
* @param editors Array of editors being diffed.
8
10
* @param diff ex: {
9
- * addedLines: [startIndex, endIndex],
10
- * removedLines: [startIndex, endIndex],
11
11
* oldLineOffsets: [lineNumber: numOffsetLines, ...],
12
12
* newLineOffsets: [lineNumber: numOffsetLines, ...],
13
13
* chunks: [{
@@ -33,19 +33,47 @@ module.exports = class DiffView {
33
33
* @param chunks The diff chunks to highlight.
34
34
* @param leftHighlightType The type of highlight (ex: 'added').
35
35
* @param rightHighlightType The type of highlight (ex: 'removed').
36
+ * @param isWordDiffEnabled Whether differences between words per line should be highlighted.
37
+ * @param isWhitespaceIgnored Whether whitespace should be ignored.
36
38
*/
37
- displayDiff ( diff , leftHighlightType , rightHighlightType ) {
39
+ displayDiff ( diff , leftHighlightType , rightHighlightType , isWordDiffEnabled , isWhitespaceIgnored ) {
38
40
this . _chunks = diff . chunks ;
39
41
42
+ // make the last chunk equal size on both screens so the editors retain sync scroll #58
43
+ if ( this . _chunks . length > 0 ) {
44
+ var lastChunk = this . _chunks [ this . _chunks . length - 1 ] ;
45
+ var oldChunkRange = lastChunk . oldLineEnd - lastChunk . oldLineStart ;
46
+ var newChunkRange = lastChunk . newLineEnd - lastChunk . newLineStart ;
47
+ if ( oldChunkRange > newChunkRange ) {
48
+ // make the offset as large as needed to make the chunk the same size in both editors
49
+ diff . newLineOffsets [ lastChunk . newLineStart + newChunkRange ] = oldChunkRange - newChunkRange ;
50
+ } else if ( newChunkRange > oldChunkRange ) {
51
+ // make the offset as large as needed to make the chunk the same size in both editors
52
+ diff . oldLineOffsets [ lastChunk . oldLineStart + oldChunkRange ] = newChunkRange - oldChunkRange ;
53
+ }
54
+ }
55
+
40
56
for ( chunk of this . _chunks ) {
41
57
this . _editorDiffExtender1 . highlightLines ( chunk . oldLineStart , chunk . oldLineEnd , leftHighlightType ) ;
42
58
this . _editorDiffExtender2 . highlightLines ( chunk . newLineStart , chunk . newLineEnd , rightHighlightType ) ;
59
+
60
+ if ( isWordDiffEnabled ) {
61
+ this . _highlightWordsInChunk ( chunk , leftHighlightType , rightHighlightType , isWhitespaceIgnored ) ;
62
+ }
43
63
}
44
64
45
65
this . _editorDiffExtender1 . setLineOffsets ( diff . oldLineOffsets ) ;
46
66
this . _editorDiffExtender2 . setLineOffsets ( diff . newLineOffsets ) ;
47
67
}
48
68
69
+ /**
70
+ * Clears the diff highlighting and offsets from the editors.
71
+ */
72
+ clearDiff ( ) {
73
+ this . _editorDiffExtender1 . destroyMarkers ( ) ;
74
+ this . _editorDiffExtender2 . destroyMarkers ( ) ;
75
+ }
76
+
49
77
/**
50
78
* Called to move the current selection highlight to the next diff chunk.
51
79
*/
@@ -80,27 +108,6 @@ module.exports = class DiffView {
80
108
return this . _selectedChunkIndex ;
81
109
}
82
110
83
- /**
84
- * Selects and highlights the diff chunk in both editors according to the
85
- * given index.
86
- *
87
- * @param index The index of the diff chunk to highlight in both editors.
88
- */
89
- _selectChunk ( index ) {
90
- var diffChunk = this . _chunks [ index ] ;
91
- if ( diffChunk != null ) {
92
- // deselect previous next/prev highlights
93
- this . _editorDiffExtender1 . deselectAllLines ( ) ;
94
- this . _editorDiffExtender2 . deselectAllLines ( ) ;
95
- // highlight and scroll editor 1
96
- this . _editorDiffExtender1 . selectLines ( diffChunk . oldLineStart , diffChunk . oldLineEnd ) ;
97
- this . _editorDiffExtender1 . getEditor ( ) . setCursorBufferPosition ( [ diffChunk . oldLineStart , 0 ] , { autoscroll : true } ) ;
98
- // highlight and scroll editor 2
99
- this . _editorDiffExtender2 . selectLines ( diffChunk . newLineStart , diffChunk . newLineEnd ) ;
100
- this . _editorDiffExtender2 . getEditor ( ) . setCursorBufferPosition ( [ diffChunk . newLineStart , 0 ] , { autoscroll : true } ) ;
101
- }
102
- }
103
-
104
111
/**
105
112
* Copies the currently selected diff chunk from the left editor to the right
106
113
* editor.
@@ -175,11 +182,110 @@ module.exports = class DiffView {
175
182
}
176
183
177
184
/**
178
- * Gets the editor diff abstractions.
185
+ * Cleans up the editor indicated by index. A clean up will remove the editor
186
+ * or the pane if necessary. Typically left editor == 1 and right editor == 2.
179
187
*
180
- * @return EditorDiffExtender Array containing the editors being diffed .
188
+ * @param editorIndex The index of the editor to clean up .
181
189
*/
182
- getEditorDiffExtenders ( ) {
183
- return [ this . _editorDiffExtender1 , this . _editorDiffExtender2 ] ;
190
+ cleanUpEditor ( editorIndex ) {
191
+ if ( editorIndex === 1 ) {
192
+ this . _editorDiffExtender1 . cleanUp ( ) ;
193
+ } else if ( editorIndex === 2 ) {
194
+ this . _editorDiffExtender2 . cleanUp ( ) ;
195
+ }
196
+ }
197
+
198
+ /**
199
+ * Destroys the editor diff extenders.
200
+ */
201
+ destroy ( ) {
202
+ this . _editorDiffExtender1 . destroy ( ) ;
203
+ this . _editorDiffExtender2 . destroy ( ) ;
204
+ }
205
+
206
+ /**
207
+ * Gets the number of differences between the editors.
208
+ *
209
+ * @return int The number of differences between the editors.
210
+ */
211
+ getNumDifferences ( ) {
212
+ return this . _chunks . length ;
213
+ }
214
+
215
+ // ----------------------------------------------------------------------- //
216
+ // --------------------------- PRIVATE METHODS --------------------------- //
217
+ // ----------------------------------------------------------------------- //
218
+
219
+ /**
220
+ * Selects and highlights the diff chunk in both editors according to the
221
+ * given index.
222
+ *
223
+ * @param index The index of the diff chunk to highlight in both editors.
224
+ */
225
+ _selectChunk ( index ) {
226
+ var diffChunk = this . _chunks [ index ] ;
227
+ if ( diffChunk != null ) {
228
+ // deselect previous next/prev highlights
229
+ this . _editorDiffExtender1 . deselectAllLines ( ) ;
230
+ this . _editorDiffExtender2 . deselectAllLines ( ) ;
231
+ // highlight and scroll editor 1
232
+ this . _editorDiffExtender1 . selectLines ( diffChunk . oldLineStart , diffChunk . oldLineEnd ) ;
233
+ this . _editorDiffExtender1 . getEditor ( ) . setCursorBufferPosition ( [ diffChunk . oldLineStart , 0 ] , { autoscroll : true } ) ;
234
+ // highlight and scroll editor 2
235
+ this . _editorDiffExtender2 . selectLines ( diffChunk . newLineStart , diffChunk . newLineEnd ) ;
236
+ this . _editorDiffExtender2 . getEditor ( ) . setCursorBufferPosition ( [ diffChunk . newLineStart , 0 ] , { autoscroll : true } ) ;
237
+ }
238
+ }
239
+
240
+ /**
241
+ * Highlights the word diff of the chunk passed in.
242
+ *
243
+ * @param chunk The chunk that should have its words highlighted.
244
+ */
245
+ _highlightWordsInChunk ( chunk , leftHighlightType , rightHighlightType , isWhitespaceIgnored ) {
246
+ var leftLineNumber = chunk . oldLineStart ;
247
+ var rightLineNumber = chunk . newLineStart ;
248
+ // for each line that has a corresponding line
249
+ while ( leftLineNumber < chunk . oldLineEnd && rightLineNumber < chunk . newLineEnd ) {
250
+ // do word diff
251
+ var wordDiff = ComputeWordDiff . computeWordDiff (
252
+ this . _editorDiffExtender1 . getEditor ( ) . lineTextForBufferRow ( leftLineNumber ) ,
253
+ this . _editorDiffExtender2 . getEditor ( ) . lineTextForBufferRow ( rightLineNumber )
254
+ ) ;
255
+ this . _editorDiffExtender1 . setWordHighlights ( leftLineNumber , wordDiff . removedWords , leftHighlightType , isWhitespaceIgnored ) ;
256
+ this . _editorDiffExtender2 . setWordHighlights ( rightLineNumber , wordDiff . addedWords , rightHighlightType , isWhitespaceIgnored ) ;
257
+
258
+ leftLineNumber ++ ;
259
+ rightLineNumber ++ ;
260
+ }
261
+
262
+ // highlight remaining lines in left editor
263
+ while ( leftLineNumber < chunk . oldLineEnd ) {
264
+ this . _editorDiffExtender1 . setWordHighlights (
265
+ leftLineNumber ,
266
+ [ {
267
+ changed : true ,
268
+ value : this . _editorDiffExtender1 . getEditor ( ) . lineTextForBufferRow ( leftLineNumber )
269
+ } ] ,
270
+ leftHighlightType ,
271
+ isWhitespaceIgnored
272
+ ) ;
273
+
274
+ leftLineNumber ++ ;
275
+ }
276
+ // highlight remaining lines in the right editor
277
+ while ( rightLineNumber < chunk . newLineEnd ) {
278
+ this . _editorDiffExtender2 . setWordHighlights (
279
+ rightLineNumber ,
280
+ [ {
281
+ changed : true ,
282
+ value : this . _editorDiffExtender2 . getEditor ( ) . lineTextForBufferRow ( rightLineNumber )
283
+ } ] ,
284
+ rightHighlightType ,
285
+ isWhitespaceIgnored
286
+ ) ;
287
+
288
+ rightLineNumber ++ ;
289
+ }
184
290
}
185
291
} ;
0 commit comments