diff --git a/spec/app/buffer-spec.coffee b/spec/app/buffer-spec.coffee index 8efa354a8..4a42d0b52 100644 --- a/spec/app/buffer-spec.coffee +++ b/spec/app/buffer-spec.coffee @@ -726,11 +726,11 @@ describe 'Buffer', -> buffer.setMarkerHeadPosition(marker, [6, 2]) expect(observeHandler).toHaveBeenCalled() - expect(observeHandler.argsForCall[0]).toEqual [[6, 2], false] + expect(observeHandler.argsForCall[0][0]).toEqual { oldPosition: [4, 23], newPosition: [6, 2], bufferChanged: false } observeHandler.reset() buffer.insert([6, 0], '...') - expect(observeHandler.argsForCall[0]).toEqual [[6, 5], true] + expect(observeHandler.argsForCall[0][0]).toEqual { oldPosition: [6, 2], newPosition: [6, 5], bufferChanged: true } it "allows the observation subscription to be cancelled", -> marker = buffer.markRange([[4, 20], [4, 23]]) diff --git a/spec/app/display-buffer-spec.coffee b/spec/app/display-buffer-spec.coffee index 158034b8f..94c96b70e 100644 --- a/spec/app/display-buffer-spec.coffee +++ b/spec/app/display-buffer-spec.coffee @@ -625,22 +625,46 @@ describe "DisplayBuffer", -> displayBuffer.observeMarkerHeadScreenPosition(marker, observeHandler) displayBuffer.setMarkerHeadScreenPosition(marker, [8, 20]) expect(observeHandler).toHaveBeenCalled() - expect(observeHandler.argsForCall[0]).toEqual [[8, 20], false] + expect(observeHandler.argsForCall[0][0]).toEqual { + oldScreenPosition: [5, 10] + newScreenPosition: [8, 20] + oldBufferPosition: [8, 10] + newBufferPosition: [11, 20] + bufferChanged: false + } observeHandler.reset() buffer.insert([11, 0], '...') expect(observeHandler).toHaveBeenCalled() - expect(observeHandler.argsForCall[0]).toEqual [[8, 23], true] + expect(observeHandler.argsForCall[0][0]).toEqual { + oldScreenPosition: [8, 20] + newScreenPosition: [8, 23] + oldBufferPosition: [11, 20] + newBufferPosition: [11, 23] + bufferChanged: true + } observeHandler.reset() displayBuffer.unfoldBufferRow(4) expect(observeHandler).toHaveBeenCalled() - expect(observeHandler.argsForCall[0]).toEqual [[11, 23], false] + expect(observeHandler.argsForCall[0][0]).toEqual { + oldScreenPosition: [8, 23] + newScreenPosition: [11, 23] + oldBufferPosition: [11, 23] + newBufferPosition: [11, 23] + bufferChanged: false + } observeHandler.reset() displayBuffer.foldBufferRow(4) expect(observeHandler).toHaveBeenCalled() - expect(observeHandler.argsForCall[0]).toEqual [[8, 23], false] + expect(observeHandler.argsForCall[0][0]).toEqual { + oldScreenPosition: [11, 23] + newScreenPosition: [8, 23] + oldBufferPosition: [11, 23] + newBufferPosition: [11, 23] + bufferChanged: false + } it "does not call the callback for screen changes that don't change the position of the marker", -> marker = displayBuffer.markScreenPosition([3, 4]) @@ -648,7 +672,13 @@ describe "DisplayBuffer", -> buffer.insert([3, 0], '...') expect(observeHandler).toHaveBeenCalled() - expect(observeHandler.argsForCall[0][0]).toEqual [3, 7] + expect(observeHandler.argsForCall[0][0]).toEqual { + oldScreenPosition: [3, 4] + newScreenPosition: [3, 7] + oldBufferPosition: [3, 4] + newBufferPosition: [3, 7] + bufferChanged: true + } observeHandler.reset() displayBuffer.unfoldBufferRow(4) @@ -656,12 +686,24 @@ describe "DisplayBuffer", -> fold = displayBuffer.createFold(0, 2) expect(observeHandler).toHaveBeenCalled() - expect(observeHandler.argsForCall[0][0]).toEqual [1, 7] + expect(observeHandler.argsForCall[0][0]).toEqual { + oldScreenPosition: [3, 7] + newScreenPosition: [1, 7] + oldBufferPosition: [3, 7] + newBufferPosition: [3, 7] + bufferChanged: false + } observeHandler.reset() fold.destroy() expect(observeHandler).toHaveBeenCalled() - expect(observeHandler.argsForCall[0][0]).toEqual [3, 7] + expect(observeHandler.argsForCall[0][0]).toEqual { + oldScreenPosition: [1, 7] + newScreenPosition: [3, 7] + oldBufferPosition: [3, 7] + newBufferPosition: [3, 7] + bufferChanged: false + } it "allows observation subscriptions to be cancelled", -> marker = displayBuffer.markScreenRange([[5, 4], [5, 10]]) diff --git a/src/app/buffer-marker.coffee b/src/app/buffer-marker.coffee index 803595593..341a9ae2a 100644 --- a/src/app/buffer-marker.coffee +++ b/src/app/buffer-marker.coffee @@ -36,9 +36,12 @@ class BufferMarker getTailPosition: -> @tailPosition setHeadPosition: (headPosition, options={}) -> + oldPosition = @headPosition @headPosition = Point.fromObject(headPosition) @headPosition = @buffer.clipPosition(@headPosition) if options.clip ? true - observer(@headPosition, !!options.bufferChanged) for observer in @headPositionObservers + newPosition = @headPosition + bufferChanged = !!options.bufferChanged + observer({oldPosition, newPosition, bufferChanged}) for observer in @headPositionObservers @headPosition setTailPosition: (tailPosition, options={}) -> diff --git a/src/app/cursor.coffee b/src/app/cursor.coffee index 0218c5fe7..92c59ed32 100644 --- a/src/app/cursor.coffee +++ b/src/app/cursor.coffee @@ -12,10 +12,10 @@ class Cursor needsAutoscroll: null constructor: ({@editSession, @marker}) -> - @editSession.observeMarkerHeadScreenPosition @marker, (screenPosition, bufferChanged) => - @needsAutoscroll ?= @isLastCursor() and !bufferChanged - @trigger 'moved', screenPosition - @editSession.trigger 'cursor-moved', screenPosition + @editSession.observeMarkerHeadScreenPosition @marker, (e) => + @needsAutoscroll ?= @isLastCursor() and !e.bufferChanged + @trigger 'moved', e + @editSession.trigger 'cursor-moved', e @needsAutoscroll = true destroy: -> diff --git a/src/app/display-buffer.coffee b/src/app/display-buffer.coffee index 45f62c6a1..ab86c06ee 100644 --- a/src/app/display-buffer.coffee +++ b/src/app/display-buffer.coffee @@ -372,9 +372,14 @@ class DisplayBuffer @markerScreenPositionObservers[id] ?= { head: [], tail: [] } @cacheMarkerScreenPositions(id) unless @markerScreenPositions[id] @markerScreenPositionObservers[id].head.push(callback) - subscription = @buffer.observeMarkerHeadPosition id, (bufferPosition, bufferChanged) => + subscription = @buffer.observeMarkerHeadPosition id, (e) => + bufferChanged = e.bufferChanged + oldBufferPosition = e.oldPosition + newBufferPosition = e.newPosition + oldScreenPosition = @markerScreenPositions[id].head @cacheMarkerScreenPositions(id) - callback(@getMarkerHeadScreenPosition(id), bufferChanged) + newScreenPosition = @getMarkerHeadScreenPosition(id) + callback({ oldBufferPosition, newBufferPosition, oldScreenPosition, newScreenPosition, bufferChanged }) cancel: => subscription.cancel() @@ -391,8 +396,13 @@ class DisplayBuffer for id, { head } of @markerScreenPositions currentHeadPosition = @getMarkerHeadScreenPosition(id) unless currentHeadPosition.isEqual(head) + bufferChanged = false + oldBufferPosition = newBufferPosition = @buffer.getMarkerHeadPosition(id) + oldScreenPosition = @markerScreenPositions[id].head @cacheMarkerScreenPositions(id) - observer(currentHeadPosition, false) for observer in @markerScreenPositionObservers[id].head + newScreenPosition = @getMarkerHeadScreenPosition(id) + for observer in @markerScreenPositionObservers[id].head + observer({oldScreenPosition, newScreenPosition, oldBufferPosition, newBufferPosition, bufferChanged}) destroy: -> @tokenizedBuffer.destroy()