Skip to content

Commit f03a769

Browse files
committed
Adds #9 - diff with active file. Fixes issues with getting editors before diff.
1 parent 2400b15 commit f03a769

File tree

4 files changed

+128
-74
lines changed

4 files changed

+128
-74
lines changed

CHANGELOG.md

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
## 1.0.7 - XXXX-XX-XX
1+
## 1.1.0 - XXXX-XX-XX
2+
* Added ability to diff active file with right click in tree view or tab header #9
23
* Fixed issue where toggling ignore whitespace from command wouldn't update footer bar
3-
* Huge code refactor!
4+
* Fixed issue where one line editor would always pop notification about differing line endings
5+
* Fixed poor user experience when auto opening text editors in new panes (Now tries to reuse panes more often instead of greedily creating new ones)
6+
* Large code refactor
47

58
## 1.0.6 - 2016-10-24
69
* Fixed next/prev diff highlight skipping a selection after copying to right/left

lib/editor-diff-extender.js

-1
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,6 @@ module.exports = class EditorDiffExtender {
200200
if (typeof editorPane !== 'undefined' && editorPane != null && editorPane.getItems().length == 1) {
201201
editorPane.destroy();
202202
} else {
203-
this._editor.setText('');
204203
this._editor.destroy();
205204
}
206205
}

lib/split-diff.coffee

+112-63
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,11 @@ module.exports = SplitDiff =
2020
activate: (state) ->
2121
@subscriptions = new CompositeDisposable()
2222

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()
2528
'split-diff:next-diff': =>
2629
if @isEnabled
2730
@nextDiff()
@@ -48,7 +51,7 @@ module.exports = SplitDiff =
4851

4952
# called by "toggle" command
5053
# toggles split diff
51-
toggle: ->
54+
toggle: () ->
5255
if @isEnabled
5356
@disable()
5457
else
@@ -122,65 +125,79 @@ module.exports = SplitDiff =
122125

123126
# called by the commands enable/toggle to do initial diff
124127
# 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) ->
126130
# in case enable was called again
127131
@disable()
128132

129133
@editorSubscriptions = new CompositeDisposable()
130134

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',
162191
'submenu': [
163192
{ 'label': 'Ignore Whitespace', 'command': 'split-diff:ignore-whitespace' }
164193
{ 'label': 'Move to Next Diff', 'command': 'split-diff:next-diff' }
165194
{ 'label': 'Move to Previous Diff', 'command': 'split-diff:prev-diff' }
166195
{ 'label': 'Copy to Right', 'command': 'split-diff:copy-to-right'}
167196
{ 'label': 'Copy to Left', 'command': 'split-diff:copy-to-left'}
168197
]
169-
]
198+
}]
170199
}
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
184201

185202
# called by both diffPanes and the editor subscription to update the diff
186203
updateDiff: (editors) ->
@@ -248,12 +265,13 @@ module.exports = SplitDiff =
248265
@syncScroll = new SyncScroll(editors.editor1, editors.editor2, false)
249266
@syncScroll.syncPositions()
250267

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: () ->
254271
editor1 = null
255272
editor2 = null
256273

274+
# try to find the first two editors
257275
panes = atom.workspace.getPanes()
258276
for p in panes
259277
activeItem = p.getActiveItem()
@@ -268,15 +286,52 @@ module.exports = SplitDiff =
268286
if editor1 == null
269287
editor1 = atom.workspace.buildTextEditor()
270288
@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)
273292
if editor2 == null
274293
editor2 = atom.workspace.buildTextEditor()
275294
@wasEditor2Created = true
276295
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)
279333

334+
_setupVisibleEditors: (editor1, editor2) ->
280335
BufferExtender = require './buffer-extender'
281336
buffer1LineEnding = (new BufferExtender(editor1.getBuffer())).getLineEnding()
282337

@@ -302,17 +357,11 @@ module.exports = SplitDiff =
302357
atom.notifications.addWarning('Split Diff', {detail: softWrapMsg, dismissable: false, icon: 'diff'})
303358

304359
buffer2LineEnding = (new BufferExtender(editor2.getBuffer())).getLineEnding()
305-
if buffer2LineEnding != '' && (buffer1LineEnding != buffer2LineEnding) && shouldNotify
360+
if buffer2LineEnding != '' && (buffer1LineEnding != buffer2LineEnding) && editor1.getLineCount() != 1 && editor2.getLineCount() != 1 && shouldNotify
306361
# pop warning if the line endings differ and we haven't done anything about it
307362
lineEndingMsg = 'Warning: Line endings differ!'
308363
atom.notifications.addWarning('Split Diff', {detail: lineEndingMsg, dismissable: false, icon: 'diff'})
309364

310-
editors =
311-
editor1: editor1
312-
editor2: editor2
313-
314-
return editors
315-
316365
_setupGitRepo: (editor1, editor2) ->
317366
editor1Path = editor1.getPath()
318367
# only show git changes if the right editor is empty

menus/split-diff.cson

+11-8
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
11
'context-menu':
22
'atom-text-editor': [
3-
'label': 'Split Diff'
4-
'submenu':[
5-
{ 'label': 'Toggle', 'command': 'split-diff:toggle' }
3+
label: 'Split Diff'
4+
submenu:[
5+
{ label: 'Toggle', command: 'split-diff:toggle' }
66
]
77
]
8+
'.tree-view .file, .tab.texteditor': [
9+
{ label: 'Diff with Active File', command: 'split-diff:enable' }
10+
]
811

912
'menu': [
1013
{
11-
'label': 'Packages'
12-
'submenu': [
13-
'label': 'Split Diff'
14-
'submenu': [
15-
{ 'label': 'Toggle', 'command': 'split-diff:toggle' }
14+
label: 'Packages'
15+
submenu: [
16+
label: 'Split Diff'
17+
submenu: [
18+
{ label: 'Toggle', command: 'split-diff:toggle' }
1619
]
1720
]
1821
}

0 commit comments

Comments
 (0)