diff --git a/spec/app/display-buffer-spec.coffee b/spec/app/display-buffer-spec.coffee index 0d27113a3..b888da3b9 100644 --- a/spec/app/display-buffer-spec.coffee +++ b/spec/app/display-buffer-spec.coffee @@ -522,42 +522,40 @@ describe "DisplayBuffer", -> it "allows markers to be created in terms of both screen and buffer coordinates", -> marker1 = displayBuffer.markScreenRange([[5, 4], [5, 10]]) marker2 = displayBuffer.markBufferRange([[8, 4], [8, 10]]) - expect(displayBuffer.getMarkerBufferRange(marker1)).toEqual [[8, 4], [8, 10]] - expect(displayBuffer.getMarkerScreenRange(marker2)).toEqual [[5, 4], [5, 10]] + expect(marker1.getBufferRange()).toEqual [[8, 4], [8, 10]] + expect(marker2.getScreenRange()).toEqual [[5, 4], [5, 10]] it "allows marker head and tail positions to be manipulated in both screen and buffer coordinates", -> marker = displayBuffer.markScreenRange([[5, 4], [5, 10]]) - displayBuffer.setMarkerHeadScreenPosition(marker, [5, 4]) - displayBuffer.setMarkerTailBufferPosition(marker, [5, 4]) - expect(displayBuffer.isMarkerReversed(marker)).toBeFalsy() - expect(displayBuffer.getMarkerBufferRange(marker)).toEqual [[5, 4], [8, 4]] - - displayBuffer.setMarkerHeadBufferPosition(marker, [5, 4]) - displayBuffer.setMarkerTailScreenPosition(marker, [5, 4]) - expect(displayBuffer.isMarkerReversed(marker)).toBeTruthy() - expect(displayBuffer.getMarkerBufferRange(marker)).toEqual [[5, 4], [8, 4]] + marker.setHeadScreenPosition([5, 4]) + marker.setTailBufferPosition([5, 4]) + expect(marker.isReversed()).toBeFalsy() + expect(marker.getBufferRange()).toEqual [[5, 4], [8, 4]] + marker.setHeadBufferPosition([5, 4]) + marker.setTailScreenPosition([5, 4]) + expect(marker.isReversed()).toBeTruthy() + expect(marker.getBufferRange()).toEqual [[5, 4], [8, 4]] it "returns whether a position changed when it is assigned", -> marker = displayBuffer.markScreenRange([[0, 0], [0, 0]]) - expect(displayBuffer.setMarkerHeadScreenPosition(marker, [5, 4])).toBeTruthy() - expect(displayBuffer.setMarkerHeadScreenPosition(marker, [5, 4])).toBeFalsy() - expect(displayBuffer.setMarkerHeadBufferPosition(marker, [1, 0])).toBeTruthy() - expect(displayBuffer.setMarkerHeadBufferPosition(marker, [1, 0])).toBeFalsy() - expect(displayBuffer.setMarkerTailScreenPosition(marker, [5, 4])).toBeTruthy() - expect(displayBuffer.setMarkerTailScreenPosition(marker, [5, 4])).toBeFalsy() - expect(displayBuffer.setMarkerTailBufferPosition(marker, [1, 0])).toBeTruthy() - expect(displayBuffer.setMarkerTailBufferPosition(marker, [1, 0])).toBeFalsy() + expect(marker.setHeadScreenPosition([5, 4])).toBeTruthy() + expect(marker.setHeadScreenPosition([5, 4])).toBeFalsy() + expect(marker.setHeadBufferPosition([1, 0])).toBeTruthy() + expect(marker.setHeadBufferPosition([1, 0])).toBeFalsy() + expect(marker.setTailScreenPosition([5, 4])).toBeTruthy() + expect(marker.setTailScreenPosition([5, 4])).toBeFalsy() + expect(marker.setTailBufferPosition([1, 0])).toBeTruthy() + expect(marker.setTailBufferPosition([1, 0])).toBeFalsy() - describe ".observeMarker(marker, callback)", -> + describe "marker observation", -> [observeHandler, marker, subscription] = [] beforeEach -> - observeHandler = jasmine.createSpy("observeHandler") marker = displayBuffer.markScreenRange([[5, 4], [5, 10]]) - subscription = displayBuffer.observeMarker(marker, observeHandler) + subscription = marker.observe(observeHandler = jasmine.createSpy("observeHandler")) it "calls the callback whenever the markers head's screen position changes in the buffer or on screen", -> - displayBuffer.setMarkerHeadScreenPosition(marker, [8, 20]) + marker.setHeadScreenPosition([8, 20]) expect(observeHandler).toHaveBeenCalled() expect(observeHandler.argsForCall[0][0]).toEqual { oldHeadScreenPosition: [5, 10] @@ -621,7 +619,7 @@ describe "DisplayBuffer", -> } it "calls the callback whenever the marker tail's position changes in the buffer or on screen", -> - displayBuffer.setMarkerTailScreenPosition(marker, [8, 20]) + marker.setTailScreenPosition([8, 20]) expect(observeHandler).toHaveBeenCalled() expect(observeHandler.argsForCall[0][0]).toEqual { oldHeadScreenPosition: [5, 10] @@ -691,20 +689,18 @@ describe "DisplayBuffer", -> it "allows observation subscriptions to be cancelled", -> subscription.cancel() - displayBuffer.setMarkerHeadScreenPosition(marker, [8, 20]) + marker.setHeadScreenPosition([8, 20]) displayBuffer.destroyFoldsContainingBufferRow(4) expect(observeHandler).not.toHaveBeenCalled() it "updates the position of markers before emitting buffer change events, but does not notify their observers until the change event", -> - changeHandler = jasmine.createSpy("changeHandler").andCallFake -> + displayBuffer.on 'changed', changeHandler = jasmine.createSpy("changeHandler").andCallFake -> # calls change handler first expect(observeHandler).not.toHaveBeenCalled() # but still updates the markers - expect(displayBuffer.getMarkerScreenRange(marker)).toEqual [[5, 7], [5, 13]] - expect(displayBuffer.getMarkerHeadScreenPosition(marker)).toEqual [5, 13] - expect(displayBuffer.getMarkerTailScreenPosition(marker)).toEqual [5, 7] - - displayBuffer.on 'changed', changeHandler + expect(marker.getScreenRange()).toEqual [[5, 7], [5, 13]] + expect(marker.getHeadScreenPosition()).toEqual [5, 13] + expect(marker.getTailScreenPosition()).toEqual [5, 7] buffer.insert([8, 1], "...") @@ -712,14 +708,13 @@ describe "DisplayBuffer", -> expect(observeHandler).toHaveBeenCalled() it "updates the position of markers before emitting change events that aren't caused by a buffer change", -> - changeHandler = jasmine.createSpy("changeHandler").andCallFake -> + displayBuffer.on 'changed', changeHandler = jasmine.createSpy("changeHandler").andCallFake -> # calls change handler first expect(observeHandler).not.toHaveBeenCalled() # but still updates the markers - expect(displayBuffer.getMarkerScreenRange(marker)).toEqual [[8, 4], [8, 10]] - expect(displayBuffer.getMarkerHeadScreenPosition(marker)).toEqual [8, 10] - expect(displayBuffer.getMarkerTailScreenPosition(marker)).toEqual [8, 4] - displayBuffer.on 'changed', changeHandler + expect(marker.getScreenRange()).toEqual [[8, 4], [8, 10]] + expect(marker.getHeadScreenPosition()).toEqual [8, 10] + expect(marker.getTailScreenPosition()).toEqual [8, 4] displayBuffer.destroyFoldsContainingBufferRow(4) @@ -739,5 +734,6 @@ describe "DisplayBuffer", -> describe "marker destruction", -> it "allows markers to be destroyed", -> marker = displayBuffer.markScreenRange([[5, 4], [5, 10]]) - displayBuffer.destroyMarker(marker) - expect(displayBuffer.getMarkerBufferRange(marker)).toBeUndefined() + marker.destroy()(marker) + expect(marker.isValid()).toBeFalsy() + expect(displayBuffer.getMarker(marker.id)).toBeUndefined() diff --git a/src/app/display-buffer-marker.coffee b/src/app/display-buffer-marker.coffee index d88f67bdc..540349124 100644 --- a/src/app/display-buffer-marker.coffee +++ b/src/app/display-buffer-marker.coffee @@ -13,8 +13,8 @@ class DisplayBufferMarker # Internal # ### - constructor: ({@id, @displayBuffer}) -> - @buffer = @displayBuffer.buffer + constructor: ({@bufferMarker, @displayBuffer}) -> + @id = @bufferMarker.id ### # Public # @@ -37,14 +37,14 @@ class DisplayBufferMarker # # Returns a {Range}. getBufferRange: -> - @buffer.getMarkerRange(@id) + @bufferMarker.getRange() # Public: Modifies the buffer range of the display marker. # # screenRange - The new {Range} to use # options - A hash of options matching those found in {BufferMarker.setRange} setBufferRange: (bufferRange, options) -> - @buffer.setMarkerRange(@id, bufferRange, options) + @bufferMarker.setRange(bufferRange, options) # Public: Retrieves the screen position of the marker's head. # @@ -64,21 +64,21 @@ class DisplayBufferMarker # # Returns a {Point}. getHeadBufferPosition: -> - @buffer.getMarkerHeadPosition(@id) + @bufferMarker.getHeadPosition() # Public: Sets the buffer position of the marker's head. # # screenRange - The new {Point} to use # options - A hash of options matching those found in {DisplayBuffer.bufferPositionForScreenPosition} setHeadBufferPosition: (bufferPosition) -> - @buffer.setMarkerHeadPosition(@id, bufferPosition) + @bufferMarker.setHeadPosition(bufferPosition) # Public: Retrieves the screen position of the marker's tail. # # Returns a {Point}. getTailScreenPosition: -> @tailScreenPosition ?= @displayBuffer.screenPositionForBufferPosition(@getTailBufferPosition(), wrapAtSoftNewlines: true) - + # Public: Sets the screen position of the marker's tail. # # screenRange - The new {Point} to use @@ -91,14 +91,14 @@ class DisplayBufferMarker # # Returns a {Point}. getTailBufferPosition: -> - @buffer.getMarkerTailPosition(@id) - + @bufferMarker.getTailPosition() + # Public: Sets the buffer position of the marker's tail. # # screenRange - The new {Point} to use # options - A hash of options matching those found in {DisplayBuffer.bufferPositionForScreenPosition} setTailBufferPosition: (bufferPosition) -> - @buffer.setMarkerTailPosition(@id, bufferPosition) + @bufferMarker.setTailPosition(bufferPosition) # Public: Sets the marker's tail to the same position as the marker's head. # @@ -106,11 +106,11 @@ class DisplayBufferMarker # # Returns a {Point} representing the new tail position. placeTail: -> - @buffer.placeMarkerTail(@id) + @bufferMarker.placeTail() # Public: Removes the tail from the marker. clearTail: -> - @buffer.clearMarkerTail(@id) + @bufferMarker.clearTail() # Public: Sets a callback to be fired whenever the marker is changed. # @@ -127,6 +127,10 @@ class DisplayBufferMarker @off 'changed', callback @unobserveBufferMarkerIfNeeded() + # Returns whether the head precedes the tail in the buffer + isReversed: -> + @bufferMarker.isReversed() + ### # Internal # ### @@ -136,7 +140,7 @@ class DisplayBufferMarker @getHeadScreenPosition() # memoize current value @getTailScreenPosition() # memoize current value @bufferMarkerSubscription = - @buffer.observeMarker @id, ({oldHeadPosition, newHeadPosition, oldTailPosition, newTailPosition, bufferChanged, valid}) => + @bufferMarker.observe ({oldHeadPosition, newHeadPosition, oldTailPosition, newTailPosition, bufferChanged, valid}) => @notifyObservers oldHeadBufferPosition: oldHeadPosition newHeadBufferPosition: newHeadPosition diff --git a/src/app/display-buffer.coffee b/src/app/display-buffer.coffee index 1446b6269..5a9f54360 100644 --- a/src/app/display-buffer.coffee +++ b/src/app/display-buffer.coffee @@ -468,7 +468,9 @@ class DisplayBuffer # # Returns the {DisplayBufferMarker} (if it exists). getMarker: (id) -> - @markers[id] ? new DisplayBufferMarker({id, displayBuffer: this}) + @markers[id] ? do => + if bufferMarker = @buffer.getMarker(id) + new DisplayBufferMarker({bufferMarker, displayBuffer: this}) # Public: Retrieves the active markers in the buffer. # @@ -493,7 +495,7 @@ class DisplayBuffer # # Returns a {Number} representing the new marker's ID. markBufferRange: (args...) -> - @buffer.markRange(args...) + @getMarker(@buffer.markRange(args...).id) # Public: Constructs a new marker at the given screen position. # @@ -511,7 +513,7 @@ class DisplayBuffer # # Returns a {Number} representing the new marker's ID. markBufferPosition: (bufferPosition, options) -> - @buffer.markPosition(bufferPosition, options) + @getMarker(@buffer.markPosition(bufferPosition, options).id) # Public: Removes the marker with the given id. # @@ -520,159 +522,6 @@ class DisplayBuffer @buffer.destroyMarker(id) delete @markers[id] - # Public: Gets the screen range of the display marker. - # - # id - The {Number} of the ID to check - # - # Returns a {Range}. - getMarkerScreenRange: (id) -> - @getMarker(id).getScreenRange() - - # Public: Modifies the screen range of the display marker. - # - # id - The {Number} of the ID to change - # screenRange - The new {Range} to use - # options - A hash of options matching those found in {BufferMarker.setRange} - setMarkerScreenRange: (id, screenRange, options) -> - @getMarker(id).setScreenRange(screenRange, options) - - # Public: Gets the buffer range of the display marker. - # - # id - The {Number} of the ID to check - # - # Returns a {Range}. - getMarkerBufferRange: (id) -> - @getMarker(id).getBufferRange() - - # Public: Modifies the buffer range of the display marker. - # - # id - The {Number} of the ID to change - # screenRange - The new {Range} to use - # options - A hash of options matching those found in {BufferMarker.setRange} - setMarkerBufferRange: (id, bufferRange, options) -> - @getMarker(id).setBufferRange(bufferRange, options) - - # Public: Retrieves the screen position of the marker's head. - # - # id - The {Number} of the ID to check - # - # Returns a {Point}. - getMarkerScreenPosition: (id) -> - @getMarkerHeadScreenPosition(id) - - # Public: Retrieves the buffer position of the marker's head. - # - # id - The {Number} of the ID to check - # - # Returns a {Point}. - getMarkerBufferPosition: (id) -> - @getMarkerHeadBufferPosition(id) - - # Public: Retrieves the screen position of the marker's head. - # - # id - The {Number} of the ID to check - # - # Returns a {Point}. - getMarkerHeadScreenPosition: (id) -> - @getMarker(id).getHeadScreenPosition() - - # Public: Sets the screen position of the marker's head. - # - # id - The {Number} of the ID to change - # screenRange - The new {Point} to use - # options - A hash of options matching those found in {DisplayBuffer.bufferPositionForScreenPosition} - setMarkerHeadScreenPosition: (id, screenPosition, options) -> - @getMarker(id).setHeadScreenPosition(screenPosition, options) - - # Public: Retrieves the buffer position of the marker's head. - # - # id - The {Number} of the ID to check - # - # Returns a {Point}. - getMarkerHeadBufferPosition: (id) -> - @getMarker(id).getHeadBufferPosition() - - # Public: Sets the buffer position of the marker's head. - # - # id - The {Number} of the ID to check - # screenRange - The new {Point} to use - # options - A hash of options matching those found in {DisplayBuffer.bufferPositionForScreenPosition} - setMarkerHeadBufferPosition: (id, bufferPosition) -> - @getMarker(id).setHeadBufferPosition(bufferPosition) - - # Public: Retrieves the screen position of the marker's tail. - # - # id - The {Number} of the ID to check - # - # Returns a {Point}. - getMarkerTailScreenPosition: (id) -> - @getMarker(id).getTailScreenPosition() - - # Public: Sets the screen position of the marker's tail. - # - # id - The {Number} of the ID to change - # screenRange - The new {Point} to use - # options - A hash of options matching those found in {DisplayBuffer.bufferPositionForScreenPosition} - setMarkerTailScreenPosition: (id, screenPosition, options) -> - @getMarker(id).setTailScreenPosition(screenPosition, options) - - # Public: Retrieves the buffer position of the marker's tail. - # - # id - The {Number} of the ID to check - # - # Returns a {Point}. - getMarkerTailBufferPosition: (id) -> - @getMarker(id).getTailBufferPosition() - - # Public: Sets the buffer position of the marker's tail. - # - # id - The {Number} of the ID to check - # screenRange - The new {Point} to use - # options - A hash of options matching those found in {DisplayBuffer.bufferPositionForScreenPosition} - setMarkerTailBufferPosition: (id, bufferPosition) -> - @getMarker(id).setTailBufferPosition(bufferPosition) - - # Public: Sets the marker's tail to the same position as the marker's head. - # - # This only works if there isn't already a tail position. - # - # id - A {Number} representing the marker to change - # - # Returns a {Point} representing the new tail position. - placeMarkerTail: (id) -> - @getMarker(id).placeTail() - - # Public: Removes the tail from the marker. - # - # id - A {Number} representing the marker to change - clearMarkerTail: (id) -> - @getMarker(id).clearTail() - - # Public: Identifies if the ending position of a marker is greater than the starting position. - # - # This can happen when, for example, you highlight text "up" in a {Buffer}. - # - # id - A {Number} representing the marker to check - # - # Returns a {Boolean}. - isMarkerReversed: (id) -> - @buffer.isMarkerReversed(id) - - # Public: Identifies if the marker's head position is equal to its tail. - # - # id - A {Number} representing the marker to check - # - # Returns a {Boolean}. - isMarkerRangeEmpty: (id) -> - @buffer.isMarkerRangeEmpty(id) - - # Public: Sets a callback to be fired whenever a marker is changed. - # - # id - A {Number} representing the marker to watch - # callback - A {Function} to execute - observeMarker: (id, callback) -> - @getMarker(id).observe(callback) - findMarker: (attributes) -> @findMarkers(attributes)[0]