From bd96db781ed4ab45b25734b891d8b060b0120300 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Sat, 2 Feb 2013 18:00:35 -0700 Subject: [PATCH] Pass old/new buffer and screen positions to marker position observers This is needed by the snippets package, which needs to know where the cursor was previously when it moves to decide whether to cancel the current snippet. --- spec/app/buffer-spec.coffee | 4 +-- spec/app/display-buffer-spec.coffee | 56 +++++++++++++++++++++++++---- src/app/buffer-marker.coffee | 5 ++- src/app/cursor.coffee | 8 ++--- src/app/display-buffer.coffee | 16 +++++++-- 5 files changed, 72 insertions(+), 17 deletions(-) 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()