Skip to content
This repository has been archived by the owner on Nov 8, 2017. It is now read-only.

Commit

Permalink
Merge pull request #108 from smashwilson/model
Browse files Browse the repository at this point in the history
Use Editor instead of EditorView.
  • Loading branch information
smashwilson committed Jan 18, 2015
2 parents 9c63c9e + fbb6c41 commit e9a9a90
Show file tree
Hide file tree
Showing 10 changed files with 68 additions and 76 deletions.
48 changes: 20 additions & 28 deletions lib/conflict-marker.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,23 @@ ResolverView = require './resolver-view'
module.exports =
class ConflictMarker

constructor: (@state, @editorView) ->
constructor: (@state, @editor) ->
@subs = new CompositeDisposable

@conflicts = Conflict.all(@state, @editorView.getModel())
@adapter = EditorAdapter.adapt(@editorView)

$(@editorView).addClass 'conflicted' if @conflicts
@conflicts = Conflict.all(@state, @editor)

@coveringViews = []
for c in @conflicts
@coveringViews.push new SideView(c.ours, @editorView)
@coveringViews.push new NavigationView(c.navigator, @editorView)
@coveringViews.push new SideView(c.theirs, @editorView)
@coveringViews.push new SideView(c.ours, @editor)
@coveringViews.push new NavigationView(c.navigator, @editor)
@coveringViews.push new SideView(c.theirs, @editor)

@subs.add c.onDidResolveConflict =>
unresolved = (v for v in @coveringViews when not v.conflict().isResolved())
v.reposition() for v in unresolved
resolvedCount = @conflicts.length - Math.floor(unresolved.length / 3)
atom.emitter.emit 'merge-conflicts:resolved',
file: @editor().getPath(),
file: @editor.getPath(),
total: @conflicts.length, resolved: resolvedCount,
source: this

Expand All @@ -39,15 +36,15 @@ class ConflictMarker
@installEvents()
@focusConflict @conflicts[0]
else
atom.emit 'merge-conflicts:resolved',
file: @editor().getPath(),
atom.emitter.emit 'merge-conflicts:resolved',
file: @editor.getPath(),
total: 1, resolved: 1,
source: this
@conflictsResolved()

installEvents: ->
@subs.add @editor().onDidStopChanging => @detectDirty()
@subs.add @editor().onDidDestroy => @cleanup()
@subs.add @editor.onDidStopChanging => @detectDirty()
@subs.add @editor.onDidDestroy => @cleanup()

@subs.add atom.commands.add 'atom-text-editor', 'merge-conflicts:accept-current', => @acceptCurrent()
@subs.add atom.commands.add 'atom-text-editor', 'merge-conflicts:accept-ours', => @acceptOurs()
Expand All @@ -59,22 +56,21 @@ class ConflictMarker
@subs.add atom.commands.add 'atom-text-editor', 'merge-conflicts:revert-current', => @revertCurrent()

@subs.add atom.emitter.on 'merge-conflicts:resolved', ({total, resolved, file}) =>
if file is @editor().getPath() and total is resolved
if file is @editor.getPath() and total is resolved
@conflictsResolved()

cleanup: ->
@subs.dispose()
v.remove() for v in @coveringViews
$(@editorView).removeClass 'conflicted'

conflictsResolved: ->
@cleanup()
atom.workspace.addTopPanel item: new ResolverView(@editor())
atom.workspace.addTopPanel item: new ResolverView(@editor)

detectDirty: ->
# Only detect dirty regions within CoveringViews that have a cursor within them.
potentials = []
for c in @editor().getCursors()
for c in @editor.getCursors()
for v in @coveringViews
potentials.push(v) if v.includesCursor(c)

Expand Down Expand Up @@ -113,7 +109,7 @@ class ConflictMarker
n = final.conflict.navigator.nextUnresolved()
@focusConflict(n) if n?
else
orderedCursors = _.sortBy @editor().getCursors(), (c) ->
orderedCursors = _.sortBy @editor.getCursors(), (c) ->
c.getBufferPosition().row
lastCursor = _.last orderedCursors
return unless lastCursor?
Expand All @@ -138,7 +134,7 @@ class ConflictMarker
p = initial.conflict.navigator.previousUnresolved()
@focusConflict(p) if p?
else
orderedCursors = _.sortBy @editor().getCursors(), (c) ->
orderedCursors = _.sortBy @editor.getCursors(), (c) ->
c.getBufferPosition().row
firstCursor = _.first orderedCursors
return unless firstCursor?
Expand All @@ -163,7 +159,7 @@ class ConflictMarker
view.revert() if view.isDirty()

active: ->
positions = (c.getBufferPosition() for c in @editor().getCursors())
positions = (c.getBufferPosition() for c in @editor.getCursors())
matching = []
for c in @conflicts
for p in positions
Expand All @@ -173,19 +169,15 @@ class ConflictMarker
matching.push c.theirs
matching

editor: -> @editorView.getModel()

linesForMarker: (marker) -> @adapter.linesForMarker(marker)

combineSides: (first, second) ->
text = @editor().getTextInBufferRange second.marker.getBufferRange()
text = @editor.getTextInBufferRange second.marker.getBufferRange()
e = first.marker.getBufferRange().end
insertPoint = @editor().setTextInBufferRange([e, e], text).end
insertPoint = @editor.setTextInBufferRange([e, e], text).end
first.marker.setHeadBufferPosition insertPoint
first.followingMarker.setTailBufferPosition insertPoint
first.resolve()

focusConflict: (conflict) ->
st = conflict.ours.marker.getBufferRange().start
@editor().scrollToBufferPosition st, center: true
@editor().setCursorBufferPosition st, autoscroll: false
@editor.scrollToBufferPosition st, center: true
@editor.setCursorBufferPosition st, autoscroll: false
19 changes: 7 additions & 12 deletions lib/covering-view.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ _ = require 'underscore-plus'

class CoveringView extends View

initialize: (@editorView) ->
initialize: (@editor) ->
@editorView = atom.views.getView @editor
@adapter = EditorAdapter.adapt(@editorView)

@adapter.append(this)
Expand All @@ -30,34 +31,28 @@ class CoveringView extends View
getModel: -> null

reposition: ->
# FIXME this is a workaround for a TextEditorView bug.
# https://github.com/atom/atom/pull/3517
@editorView.component.checkForVisibilityChange()

marker = @cover()
anchor = $(@editorView).offset()
ref = @offsetForMarker marker
scrollTop = @editor().getScrollTop()
scrollTop = @editor.getScrollTop()

@offset top: ref.top + anchor.top - scrollTop
@height @editor().getLineHeightInPixels()

editor: -> @editorView.getModel()
@height @editor.getLineHeightInPixels()

buffer: -> @editor().getBuffer()
buffer: -> @editor.getBuffer()

includesCursor: (cursor) -> false

offsetForMarker: (marker) ->
position = marker.getTailBufferPosition()
@editor().pixelPositionForBufferPosition position
@editor.pixelPositionForBufferPosition position

deleteMarker: (marker) ->
@buffer().delete marker.getBufferRange()
marker.destroy()

scrollTo: (positionOrNull) ->
@editor().setCursorBufferPosition positionOrNull if positionOrNull?
@editor.setCursorBufferPosition positionOrNull if positionOrNull?

prependKeystroke: (eventName, element) ->
bindings = atom.keymap.findKeyBindings
Expand Down
11 changes: 5 additions & 6 deletions lib/merge-conflicts-view.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,14 @@ class MergeConflictsView extends View
# Any files that were present, but aren't there any more, have been
# resolved.
for item in @pathList.find('li')
p = $(item).find('.path').text()
p = $(item).data('path')
icon = $(item).find('.staged')
icon.removeClass 'icon-dash icon-check text-success'
if _.contains @state.conflictPaths(), p
icon.addClass 'icon-dash'
else
icon.addClass 'icon-check text-success'
@pathList.find("li:contains('#{p}') .stage-ready").eq(0).hide()
@pathList.find("li[data-path='#{p}'] .stage-ready").hide()

if @state.isEmpty()
atom.emitter.emit 'merge-conflicts:done'
Expand All @@ -110,7 +110,7 @@ class MergeConflictsView extends View

sideResolver: (side) ->
(event) ->
p = $(event.target).closest('li').find('.path').text()
p = $(event.target).closest('li').data('path')
GitBridge.checkoutSide side, p, (err) ->
return if handleErr(err)

Expand All @@ -119,7 +119,7 @@ class MergeConflictsView extends View
atom.workspace.open p

stageFile: (event, element) ->
repoPath = element.closest('li').find('.path').text()
repoPath = element.closest('li').data('path')
filePath = path.join atom.project.getRepositories()[0].getWorkingDirectory(), repoPath

for e in atom.workspace.getTextEditors()
Expand Down Expand Up @@ -155,5 +155,4 @@ class MergeConflictsView extends View
repoPath = atom.project.getRepositories()[0].relativize fullPath
return unless _.contains state.conflictPaths(), repoPath

editorView = atom.views.getView editor
new ConflictMarker(state, editorView)
new ConflictMarker(state, editor)
3 changes: 0 additions & 3 deletions lib/merge-conflicts.coffee
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
{CompositeDisposable} = require 'atom'
MergeConflictsView = require './merge-conflicts-view'
SideView = require './side-view'
NavigationView = require './navigation-view'
Conflict = require './conflict'
{GitBridge} = require './git-bridge'
handleErr = require './error-view'

Expand Down
6 changes: 3 additions & 3 deletions lib/navigation-view.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
module.exports =
class NavigationView extends CoveringView

@content: (navigator, editorView) ->
@content: (navigator, editor) ->
@div class: 'controls navigation', =>
@text ' '
@span class: 'pull-right', =>
@button class: 'btn btn-xs', click: 'up', outlet: 'prevBtn', 'prev'
@button class: 'btn btn-xs', click: 'down', outlet: 'nextBtn', 'next'

initialize: (@navigator, editorView) ->
super editorView
initialize: (@navigator, editor) ->
super editor
@subs = new CompositeDisposable

@prependKeystroke 'merge-conflicts:previous-unresolved', @prevBtn
Expand Down
2 changes: 1 addition & 1 deletion lib/resolver-view.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class ResolverView extends View
@subs = new CompositeDisposable()

@refresh()
@editor.onDidSave => @refresh()
@subs.add @editor.onDidSave => @refresh()

@subs.add atom.commands.add @element, 'merge-conflicts:quit', => @dismiss()

Expand Down
13 changes: 6 additions & 7 deletions lib/side-view.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
module.exports =
class SideView extends CoveringView

@content: (side, editorView) ->
@content: (side, editor) ->
@div class: "side #{side.klass()} #{side.position} ui-site-#{side.site()}", =>
@div class: 'controls', =>
@label class: 'text-highlight', side.ref
Expand All @@ -13,8 +13,8 @@ class SideView extends CoveringView
@button class: 'btn btn-xs inline-block-tight revert', click: 'revert', outlet: 'revertBtn', 'Revert'
@button class: 'btn btn-xs inline-block-tight', click: 'useMe', outlet: 'useMeBtn', 'Use Me'

initialize: (@side, editorView) ->
super editorView
initialize: (@side, editor) ->
super editor
@subs = new CompositeDisposable

@decoration = null
Expand All @@ -37,7 +37,7 @@ class SideView extends CoveringView
type: 'line'
class: @side.lineClass()
@decoration.destroy() if @decoration?
@decoration = @editor().decorateMarker(@side.marker, args)
@decoration = @editor.decorateMarker(@side.marker, args)

conflict: -> @side.conflict

Expand All @@ -54,12 +54,11 @@ class SideView extends CoveringView
@decorate()

revert: ->
@editor().setTextInBufferRange @side.marker.getBufferRange(),
@side.originalText
@editor.setTextInBufferRange @side.marker.getBufferRange(), @side.originalText
@decorate()

detectDirty: ->
currentText = @editor().getTextInBufferRange @side.marker.getBufferRange()
currentText = @editor.getTextInBufferRange @side.marker.getBufferRange()
@side.isDirty = currentText isnt @side.originalText

@decorate()
Expand Down
35 changes: 22 additions & 13 deletions spec/conflict-marker-spec.coffee
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{$} = require 'space-pen'
_ = require 'underscore-plus'

ConflictMarker = require '../lib/conflict-marker'
{GitBridge} = require '../lib/git-bridge'
util = require './util'
Expand All @@ -12,6 +14,17 @@ describe 'ConflictMarker', ->
for sv in m.coveringViews
sv.detectDirty() if 'detectDirty' of sv

linesForMarker = (marker) ->
fromBuffer = marker.getTailBufferPosition()
fromScreen = editor.screenPositionForBufferPosition fromBuffer
toBuffer = marker.getHeadBufferPosition()
toScreen = editor.screenPositionForBufferPosition toBuffer

result = $()
for row in _.range(fromScreen.row, toScreen.row)
result = result.add editorView.component.lineNodeForScreenRow(row)
result

beforeEach ->
done = false

Expand All @@ -33,34 +46,30 @@ describe 'ConflictMarker', ->
state =
isRebase: false

m = new ConflictMarker(state, editorView)
m = new ConflictMarker(state, editor)

it 'attaches two SideViews and a NavigationView for each conflict', ->
expect($(editorView).find('.side').length).toBe(6)
expect($(editorView).find('.navigation').length).toBe(3)

it 'adds the conflicted class', ->
expect($(editorView).hasClass 'conflicted').toBe(true)

it 'locates the correct lines', ->
lines = m.linesForMarker m.conflicts[1].ours.marker
lines = linesForMarker m.conflicts[1].ours.marker
expect(lines.text()).toBe("My middle changes")

it 'applies the "ours" class to our sides of conflicts', ->
lines = m.linesForMarker m.conflicts[0].ours.marker
lines = linesForMarker m.conflicts[0].ours.marker
expect(lines.hasClass 'conflict-ours').toBe(true)

it 'applies the "theirs" class to their sides of conflicts', ->
lines = m.linesForMarker m.conflicts[0].theirs.marker
lines = linesForMarker m.conflicts[0].theirs.marker
expect(lines.hasClass 'conflict-theirs').toBe(true)

it 'applies the "dirty" class to modified sides', ->
editor = editorView.getModel()
editor.setCursorBufferPosition [14, 0]
editor.insertText "Make conflict 1 dirty"
detectDirty()

lines = m.linesForMarker m.conflicts[1].ours.marker
lines = linesForMarker m.conflicts[1].ours.marker
expect(lines.hasClass 'conflict-dirty').toBe(true)
expect(lines.hasClass 'conflict-ours').toBe(false)

Expand All @@ -69,15 +78,15 @@ describe 'ConflictMarker', ->
atom.emitter.on 'merge-conflicts:resolved', (e) -> event = e
m.conflicts[2].theirs.resolve()

expect(event.file).toBe(editorView.getModel().getPath())
expect(event.file).toBe(editor.getPath())
expect(event.total).toBe(3)
expect(event.resolved).toBe(1)
expect(event.source).toBe(m)

it 'tracks the active conflict side', ->
editorView.getModel().setCursorBufferPosition [11, 0]
editor.setCursorBufferPosition [11, 0]
expect(m.active()).toEqual([])
editorView.getModel().setCursorBufferPosition [14, 5]
editor.setCursorBufferPosition [14, 5]
expect(m.active()).toEqual([m.conflicts[1].ours])

describe 'with an active merge conflict', ->
Expand Down Expand Up @@ -182,7 +191,7 @@ describe 'ConflictMarker', ->
state =
isRebase: true

m = new ConflictMarker(state, editorView)
m = new ConflictMarker(state, editor)

editor.setCursorBufferPosition [3, 14]
active = m.conflicts[0]
Expand Down
Loading

0 comments on commit e9a9a90

Please sign in to comment.