@@ -20,8 +20,11 @@ module.exports = SplitDiff =
20
20
activate : (state ) ->
21
21
@subscriptions = new CompositeDisposable ()
22
22
23
- @subscriptions .add atom .commands .add ' atom-workspace' ,
24
- ' split-diff:enable ' : => @ diffPanes ()
23
+ @subscriptions .add atom .commands .add ' atom-workspace, .tree-view .selected, .tab.texteditor' ,
24
+ ' split-diff:enable ' : (e ) =>
25
+ console .log (e)
26
+ @ diffPanes (e)
27
+ e .stopPropagation ()
25
28
' split-diff:next-diff ' : =>
26
29
if @isEnabled
27
30
@ nextDiff ()
@@ -48,7 +51,7 @@ module.exports = SplitDiff =
48
51
49
52
# called by "toggle" command
50
53
# toggles split diff
51
- toggle : ->
54
+ toggle : () ->
52
55
if @isEnabled
53
56
@ disable ()
54
57
else
@@ -122,65 +125,79 @@ module.exports = SplitDiff =
122
125
123
126
# called by the commands enable/toggle to do initial diff
124
127
# sets up subscriptions for auto diff and disabling when a pane is destroyed
125
- diffPanes : ->
128
+ # event is an optional argument of a file path to diff with current
129
+ diffPanes : (event ) ->
126
130
# in case enable was called again
127
131
@ disable ()
128
132
129
133
@editorSubscriptions = new CompositeDisposable ()
130
134
131
- editors = @ _getVisibleEditors ()
132
- @diffView = new DiffView (editors)
133
-
134
- # add listeners
135
- @editorSubscriptions .add editors .editor1 .onDidStopChanging =>
136
- @ updateDiff (editors)
137
- @editorSubscriptions .add editors .editor2 .onDidStopChanging =>
138
- @ updateDiff (editors)
139
- @editorSubscriptions .add editors .editor1 .onDidDestroy =>
140
- @ disable ()
141
- @editorSubscriptions .add editors .editor2 .onDidDestroy =>
142
- @ disable ()
143
- @editorSubscriptions .add atom .config .onDidChange ' split-diff' , () =>
144
- @ updateDiff (editors)
145
-
146
- # add the bottom UI panel
147
- if ! @footerView ?
148
- @footerView = new FooterView (@ _getConfig (' ignoreWhitespace' ))
149
- @footerView .createPanel ()
150
- @footerView .show ()
151
-
152
- # update diff if there is no git repo (no onchange fired)
153
- if ! @hasGitRepo
154
- @ updateDiff (editors)
155
-
156
- # add application menu items
157
- @editorSubscriptions .add atom .menu .add [
158
- {
159
- ' label' : ' Packages'
160
- ' submenu' : [
161
- ' label' : ' Split Diff'
135
+ if event ? .currentTarget .classList .contains (' tab' )
136
+ filePath = event .currentTarget .path
137
+ editorsPromise = @ _getEditorsForDiffWithActive (filePath)
138
+ else if event ? .currentTarget .classList .contains (' list-item' ) && event ? .currentTarget .classList .contains (' file' )
139
+ filePath = event .currentTarget .getPath ()
140
+ editorsPromise = @ _getEditorsForDiffWithActive (filePath)
141
+ else
142
+ editorsPromise = @ _getEditorsForQuickDiff ()
143
+
144
+ editorsPromise .then ((editors ) ->
145
+ if editors == null
146
+ return
147
+ @ _setupVisibleEditors (editors .editor1 , editors .editor2 )
148
+ @diffView = new DiffView (editors)
149
+
150
+ # add listeners
151
+ @editorSubscriptions .add editors .editor1 .onDidStopChanging =>
152
+ @ updateDiff (editors)
153
+ @editorSubscriptions .add editors .editor2 .onDidStopChanging =>
154
+ @ updateDiff (editors)
155
+ @editorSubscriptions .add editors .editor1 .onDidDestroy =>
156
+ @ disable ()
157
+ @editorSubscriptions .add editors .editor2 .onDidDestroy =>
158
+ @ disable ()
159
+ @editorSubscriptions .add atom .config .onDidChange ' split-diff' , () =>
160
+ @ updateDiff (editors)
161
+
162
+ # add the bottom UI panel
163
+ if ! @footerView ?
164
+ @footerView = new FooterView (@ _getConfig (' ignoreWhitespace' ))
165
+ @footerView .createPanel ()
166
+ @footerView .show ()
167
+
168
+ # update diff if there is no git repo (no onchange fired)
169
+ if ! @hasGitRepo
170
+ @ updateDiff (editors)
171
+
172
+ # add application menu items
173
+ @editorSubscriptions .add atom .menu .add [
174
+ {
175
+ ' label' : ' Packages'
176
+ ' submenu' : [
177
+ ' label' : ' Split Diff'
178
+ ' submenu' : [
179
+ { ' label' : ' Ignore Whitespace' , ' command' : ' split-diff:ignore-whitespace' }
180
+ { ' label' : ' Move to Next Diff' , ' command' : ' split-diff:next-diff' }
181
+ { ' label' : ' Move to Previous Diff' , ' command' : ' split-diff:prev-diff' }
182
+ { ' label' : ' Copy to Right' , ' command' : ' split-diff:copy-to-right' }
183
+ { ' label' : ' Copy to Left' , ' command' : ' split-diff:copy-to-left' }
184
+ ]
185
+ ]
186
+ }
187
+ ]
188
+ @editorSubscriptions .add atom .contextMenu .add {
189
+ ' atom-text-editor' : [{
190
+ ' label' : ' Split Diff' ,
162
191
' submenu' : [
163
192
{ ' label' : ' Ignore Whitespace' , ' command' : ' split-diff:ignore-whitespace' }
164
193
{ ' label' : ' Move to Next Diff' , ' command' : ' split-diff:next-diff' }
165
194
{ ' label' : ' Move to Previous Diff' , ' command' : ' split-diff:prev-diff' }
166
195
{ ' label' : ' Copy to Right' , ' command' : ' split-diff:copy-to-right' }
167
196
{ ' label' : ' Copy to Left' , ' command' : ' split-diff:copy-to-left' }
168
197
]
169
- ]
198
+ } ]
170
199
}
171
- ]
172
- @editorSubscriptions .add atom .contextMenu .add {
173
- ' atom-text-editor' : [{
174
- ' label' : ' Split Diff' ,
175
- ' submenu' : [
176
- { ' label' : ' Ignore Whitespace' , ' command' : ' split-diff:ignore-whitespace' }
177
- { ' label' : ' Move to Next Diff' , ' command' : ' split-diff:next-diff' }
178
- { ' label' : ' Move to Previous Diff' , ' command' : ' split-diff:prev-diff' }
179
- { ' label' : ' Copy to Right' , ' command' : ' split-diff:copy-to-right' }
180
- { ' label' : ' Copy to Left' , ' command' : ' split-diff:copy-to-left' }
181
- ]
182
- }]
183
- }
200
+ ).bind (this ) # make sure the scope is correct
184
201
185
202
# called by both diffPanes and the editor subscription to update the diff
186
203
updateDiff : (editors ) ->
@@ -248,12 +265,13 @@ module.exports = SplitDiff =
248
265
@syncScroll = new SyncScroll (editors .editor1 , editors .editor2 , false )
249
266
@syncScroll .syncPositions ()
250
267
251
- # gets two visible editors
252
- # auto opens new editors so there are two to diff with
253
- _getVisibleEditors : ->
268
+ # Gets the first two visible editors found or creates them as needed.
269
+ # Returns a Promise which yields a value of {editor1: TextEditor, editor2: TextEditor}
270
+ _getEditorsForQuickDiff : () ->
254
271
editor1 = null
255
272
editor2 = null
256
273
274
+ # try to find the first two editors
257
275
panes = atom .workspace .getPanes ()
258
276
for p in panes
259
277
activeItem = p .getActiveItem ()
@@ -268,15 +286,52 @@ module.exports = SplitDiff =
268
286
if editor1 == null
269
287
editor1 = atom .workspace .buildTextEditor ()
270
288
@wasEditor1Created = true
271
- leftPane = atom .workspace .getActivePane ()
272
- leftPane .addItem (editor1)
289
+ # add first editor to the first pane
290
+ panes[0 ].addItem (editor1)
291
+ panes[0 ].activateItem (editor1)
273
292
if editor2 == null
274
293
editor2 = atom .workspace .buildTextEditor ()
275
294
@wasEditor2Created = true
276
295
editor2 .setGrammar (editor1 .getGrammar ())
277
- rightPane = atom .workspace .getActivePane ().splitRight ()
278
- rightPane .addItem (editor2)
296
+ rightPaneIndex = panes .indexOf (atom .workspace .paneForItem (editor1)) + 1
297
+ if panes[rightPaneIndex]
298
+ # add second editor to existing pane to the right of first editor
299
+ panes[rightPaneIndex].addItem (editor2)
300
+ panes[rightPaneIndex].activateItem (editor2)
301
+ else
302
+ # no existing pane so split right
303
+ atom .workspace .paneForItem (editor1).splitRight ({items : [editor2]})
304
+
305
+ return Promise .resolve ({editor1 : editor1, editor2 : editor2})
306
+
307
+ # Gets the active editor and opens the specified file to the right of it
308
+ # Returns a Promise which yields a value of {editor1: TextEditor, editor2: TextEditor}
309
+ _getEditorsForDiffWithActive : (filePath ) ->
310
+ activeEditor = atom .workspace .getActiveTextEditor ()
311
+ if activeEditor?
312
+ editor1 = activeEditor
313
+ @wasEditor2Created = true
314
+ panes = atom .workspace .getPanes ()
315
+ # get index of pane following active editor pane
316
+ rightPaneIndex = panes .indexOf (atom .workspace .paneForItem (editor1)) + 1
317
+ # pane is created if there is not one to the right of the active editor
318
+ rightPane = panes[rightPaneIndex] || atom .workspace .paneForItem (editor1).splitRight ()
319
+ if editor1 .getPath () == filePath
320
+ # if diffing with itself, set filePath to null so an empty editor is
321
+ # opened, which will cause a git diff
322
+ filePath = null
323
+ editor2Promise = atom .workspace .openURIInPane (filePath, rightPane)
324
+
325
+ return editor2Promise .then (editor2) ->
326
+ return {editor1 : editor1, editor2 : editor2}
327
+ else
328
+ noActiveEditorMsg = ' No active file found! (Try focusing a text editor)'
329
+ atom .notifications .addWarning (' Split Diff' , {detail : noActiveEditorMsg, dismissable : false , icon : ' diff' })
330
+ return Promise .resolve (null )
331
+
332
+ return Promise .resolve (null )
279
333
334
+ _setupVisibleEditors : (editor1 , editor2 ) ->
280
335
BufferExtender = require ' ./buffer-extender'
281
336
buffer1LineEnding = (new BufferExtender (editor1 .getBuffer ())).getLineEnding ()
282
337
@@ -302,17 +357,11 @@ module.exports = SplitDiff =
302
357
atom .notifications .addWarning (' Split Diff' , {detail : softWrapMsg, dismissable : false , icon : ' diff' })
303
358
304
359
buffer2LineEnding = (new BufferExtender (editor2 .getBuffer ())).getLineEnding ()
305
- if buffer2LineEnding != ' ' && (buffer1LineEnding != buffer2LineEnding) && shouldNotify
360
+ if buffer2LineEnding != ' ' && (buffer1LineEnding != buffer2LineEnding) && editor1 . getLineCount () != 1 && editor2 . getLineCount () != 1 && shouldNotify
306
361
# pop warning if the line endings differ and we haven't done anything about it
307
362
lineEndingMsg = ' Warning: Line endings differ!'
308
363
atom .notifications .addWarning (' Split Diff' , {detail : lineEndingMsg, dismissable : false , icon : ' diff' })
309
364
310
- editors =
311
- editor1 : editor1
312
- editor2 : editor2
313
-
314
- return editors
315
-
316
365
_setupGitRepo : (editor1 , editor2 ) ->
317
366
editor1Path = editor1 .getPath ()
318
367
# only show git changes if the right editor is empty
0 commit comments