mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-11-10 18:24:09 +03:00
Convert display buffer markers to object-oriented API
This commit is contained in:
parent
482eb6c0de
commit
5403bc647a
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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]
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user