From 482eb6c0dea564d3ff1534267c35bd8d62be7479 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 25 Apr 2013 11:46:02 -0600 Subject: [PATCH] Give TextBuffer an object-oriented marker interface The previous API revolved around methods on TextBuffer for querying and manipulating markers based on their id. Now marker creation methods return marker objects. These are still retrievable by id so they can be dealt with across serialization boundaries in the future, but you deal with them directly as objects. --- spec/app/text-buffer-spec.coffee | 188 +++++++++++++++++-------------- src/app/buffer-marker.coffee | 6 + src/app/text-buffer.coffee | 132 ++-------------------- 3 files changed, 121 insertions(+), 205 deletions(-) diff --git a/spec/app/text-buffer-spec.coffee b/spec/app/text-buffer-spec.coffee index 7636523b0..9db25070b 100644 --- a/spec/app/text-buffer-spec.coffee +++ b/spec/app/text-buffer-spec.coffee @@ -784,21 +784,21 @@ describe 'Buffer', -> describe "marker creation", -> it "allows markers to be created with ranges and positions", -> marker1 = buffer.markRange([[4, 20], [4, 23]]) - expect(buffer.getMarkerRange(marker1)).toEqual [[4, 20], [4, 23]] - expect(buffer.getMarkerPosition(marker1)).toEqual [4, 23] - expect(buffer.getMarkerTailPosition(marker1)).toEqual [4, 20] + expect(marker1.getRange()).toEqual [[4, 20], [4, 23]] + expect(marker1.getHeadPosition()).toEqual [4, 23] + expect(marker1.getTailPosition()).toEqual [4, 20] marker2 = buffer.markPosition([4, 20]) - expect(buffer.getMarkerRange(marker2)).toEqual [[4, 20], [4, 20]] - expect(buffer.getMarkerPosition(marker2)).toEqual [4, 20] - expect(buffer.getMarkerTailPosition(marker2)).toEqual [4, 20] + expect(marker2.getRange()).toEqual [[4, 20], [4, 20]] + expect(marker2.getHeadPosition()).toEqual [4, 20] + expect(marker2.getTailPosition()).toEqual [4, 20] it "allows markers to be created in a reversed orientation", -> marker = buffer.markRange([[4, 20], [4, 23]], reverse: true) - expect(buffer.isMarkerReversed(marker)).toBeTruthy() - expect(buffer.getMarkerRange(marker)).toEqual [[4, 20], [4, 23]] - expect(buffer.getMarkerHeadPosition(marker)).toEqual [4, 20] - expect(buffer.getMarkerTailPosition(marker)).toEqual [4, 23] + expect(marker.isReversed()).toBeTruthy() + expect(marker.getRange()).toEqual [[4, 20], [4, 23]] + expect(marker.getHeadPosition()).toEqual [4, 20] + expect(marker.getTailPosition()).toEqual [4, 23] describe "marker manipulation", -> marker = null @@ -806,33 +806,33 @@ describe 'Buffer', -> marker = buffer.markRange([[4, 20], [4, 23]]) it "allows a marker's head and tail positions to be changed", -> - buffer.setMarkerHeadPosition(marker, [5, 3]) - expect(buffer.getMarkerRange(marker)).toEqual [[4, 20], [5, 3]] + marker.setHeadPosition([5, 3]) + expect(marker.getRange()).toEqual [[4, 20], [5, 3]] - buffer.setMarkerTailPosition(marker, [6, 3]) - expect(buffer.getMarkerRange(marker)).toEqual [[5, 3], [6, 3]] - expect(buffer.isMarkerReversed(marker)).toBeTruthy() + marker.setTailPosition([6, 3]) + expect(marker.getRange()).toEqual [[5, 3], [6, 3]] + expect(marker.isReversed()).toBeTruthy() it "clips head and tail positions to ensure they are in bounds", -> - buffer.setMarkerHeadPosition(marker, [-100, -5]) - expect(buffer.getMarkerRange(marker)).toEqual([[0, 0], [4, 20]]) - buffer.setMarkerTailPosition(marker, [Infinity, Infinity]) - expect(buffer.getMarkerRange(marker)).toEqual([[0, 0], [12, 2]]) + marker.setHeadPosition([-100, -5]) + expect(marker.getRange()).toEqual([[0, 0], [4, 20]]) + marker.setTailPosition([Infinity, Infinity]) + expect(marker.getRange()).toEqual([[0, 0], [12, 2]]) it "allows a marker's tail to be placed and cleared", -> - buffer.clearMarkerTail(marker) - expect(buffer.getMarkerRange(marker)).toEqual [[4, 23], [4, 23]] - buffer.placeMarkerTail(marker) - buffer.setMarkerHeadPosition(marker, [2, 0]) - expect(buffer.getMarkerRange(marker)).toEqual [[2, 0], [4, 23]] - expect(buffer.isMarkerReversed(marker)).toBeTruthy() + marker.clearTail() + expect(marker.getRange()).toEqual [[4, 23], [4, 23]] + marker.placeTail() + marker.setHeadPosition([2, 0]) + expect(marker.getRange()).toEqual [[2, 0], [4, 23]] + expect(marker.isReversed()).toBeTruthy() it "returns whether the position changed", -> - expect(buffer.setMarkerHeadPosition(marker, [5, 3])).toBeTruthy() - expect(buffer.setMarkerHeadPosition(marker, [5, 3])).toBeFalsy() + expect(marker.setHeadPosition([5, 3])).toBeTruthy() + expect(marker.setHeadPosition([5, 3])).toBeFalsy() - expect(buffer.setMarkerTailPosition(marker, [6, 3])).toBeTruthy() - expect(buffer.setMarkerTailPosition(marker, [6, 3])).toBeFalsy() + expect(marker.setTailPosition([6, 3])).toBeTruthy() + expect(marker.setTailPosition([6, 3])).toBeFalsy() describe ".observeMarker(marker, callback)", -> [observeHandler, marker, subscription] = [] @@ -840,10 +840,10 @@ describe 'Buffer', -> beforeEach -> observeHandler = jasmine.createSpy("observeHandler") marker = buffer.markRange([[4, 20], [4, 23]]) - subscription = buffer.observeMarker(marker, observeHandler) + subscription = marker.observe(observeHandler) it "calls the callback when the marker's head position changes", -> - buffer.setMarkerHeadPosition(marker, [6, 2]) + marker.setHeadPosition([6, 2]) expect(observeHandler).toHaveBeenCalled() expect(observeHandler.argsForCall[0][0]).toEqual { oldHeadPosition: [4, 23] @@ -866,7 +866,7 @@ describe 'Buffer', -> } it "calls the given callback when the marker's tail position changes", -> - buffer.setMarkerTailPosition(marker, [6, 2]) + marker.setTailPosition([6, 2]) expect(observeHandler).toHaveBeenCalled() expect(observeHandler.argsForCall[0][0]).toEqual { oldHeadPosition: [4, 23] @@ -890,7 +890,7 @@ describe 'Buffer', -> } it "calls the callback when the selection's tail is cleared", -> - buffer.clearMarkerTail(marker) + marker.clearTail() expect(observeHandler).toHaveBeenCalled() expect(observeHandler.argsForCall[0][0]).toEqual { oldHeadPosition: [4, 23] @@ -914,7 +914,7 @@ describe 'Buffer', -> } observeHandler.reset() - buffer.setMarkerRange(marker, [[0, 0], [1, 1]]) + marker.setRange([[0, 0], [1, 1]]) expect(observeHandler.callCount).toBe 1 expect(observeHandler.argsForCall[0][0]).toEqual { oldTailPosition: [4, 23] @@ -951,7 +951,7 @@ describe 'Buffer', -> it "allows the observation subscription to be cancelled", -> subscription.cancel() - buffer.setMarkerHeadPosition(marker, [6, 2]) + marker.setHeadPosition([6, 2]) expect(observeHandler).not.toHaveBeenCalled() describe ".findMarkers(attributes)", -> @@ -978,22 +978,22 @@ describe 'Buffer', -> marker = buffer.markRange([[4, 20], [4, 23]]) it "allows a marker to be destroyed", -> - buffer.destroyMarker(marker) - expect(buffer.getMarkerRange(marker)).toBeUndefined() + marker.destroy() + expect(buffer.getMarker(marker.id)).toBeUndefined() it "does not restore invalidated markers that have been destroyed", -> buffer.delete([[4, 15], [4, 25]]) - expect(buffer.getMarkerRange(marker)).toBeUndefined() - buffer.destroyMarker(marker) + expect(buffer.getMarker(marker.id)).toBeUndefined() + marker.destroy() buffer.undo() - expect(buffer.getMarkerRange(marker)).toBeUndefined() + expect(buffer.getMarker(marker.id)).toBeUndefined() # even "invalidationStrategy: never" markers get destroyed properly marker2 = buffer.markRange([[4, 20], [4, 23]], invalidationStrategy: 'never') buffer.delete([[4, 15], [4, 25]]) - buffer.destroyMarker(marker2) + marker2.destroy() buffer.undo() - expect(buffer.getMarkerRange(marker2)).toBeUndefined() + expect(buffer.getMarker(marker2.id)).toBeUndefined() describe "marker updates due to buffer changes", -> [marker1, marker2, marker3] = [] @@ -1007,149 +1007,169 @@ describe 'Buffer', -> describe "when the change precedes the marker range", -> it "moves the marker", -> buffer.insert([4, 5], '...') - expect(buffer.getMarkerRange(marker1)).toEqual [[4, 23], [4, 26]] + expect(marker1.getRange()).toEqual [[4, 23], [4, 26]] buffer.delete([[4, 5], [4, 8]]) - expect(buffer.getMarkerRange(marker1)).toEqual [[4, 20], [4, 23]] + expect(marker1.getRange()).toEqual [[4, 20], [4, 23]] buffer.insert([0, 0], '\nhi\n') - expect(buffer.getMarkerRange(marker1)).toEqual [[6, 20], [6, 23]] + expect(marker1.getRange()).toEqual [[6, 20], [6, 23]] # undo works buffer.undo() - expect(buffer.getMarkerRange(marker1)).toEqual [[4, 20], [4, 23]] + expect(marker1.getRange()).toEqual [[4, 20], [4, 23]] buffer.undo() - expect(buffer.getMarkerRange(marker1)).toEqual [[4, 23], [4, 26]] + expect(marker1.getRange()).toEqual [[4, 23], [4, 26]] describe "when the change follows the marker range", -> it "does not move the marker", -> buffer.insert([6, 5], '...') - expect(buffer.getMarkerRange(marker1)).toEqual [[4, 20], [4, 23]] + expect(marker1.getRange()).toEqual [[4, 20], [4, 23]] buffer.delete([[6, 5], [6, 8]]) - expect(buffer.getMarkerRange(marker1)).toEqual [[4, 20], [4, 23]] + expect(marker1.getRange()).toEqual [[4, 20], [4, 23]] buffer.insert([10, 0], '\nhi\n') - expect(buffer.getMarkerRange(marker1)).toEqual [[4, 20], [4, 23]] + expect(marker1.getRange()).toEqual [[4, 20], [4, 23]] describe "when the change is an insertion at the start of the marker range", -> it "does not move the start point, but does move the end point", -> buffer.insert([4, 20], '...') - expect(buffer.getMarkerRange(marker1)).toEqual [[4, 20], [4, 26]] + expect(marker1.getRange()).toEqual [[4, 20], [4, 26]] describe "when the invalidation strategy is 'between'", -> it "invalidates the marker", -> buffer.insert([4, 20], '...') - expect(buffer.getMarkerRange(marker3)).toBeUndefined() + expect(marker3.isValid()).toBeFalsy() describe "when the change is an insertion at the end of the marker range", -> it "moves the end point", -> buffer.insert([4, 23], '...') - expect(buffer.getMarkerRange(marker1)).toEqual [[4, 20], [4, 26]] + expect(marker1.getRange()).toEqual [[4, 20], [4, 26]] describe "when the invalidation strategy is 'between'", -> it "invalidates the marker", -> buffer.insert([4, 23], '...') - expect(buffer.getMarkerRange(marker3)).toBeUndefined() + expect(marker3.isValid()).toBeFalsy() describe "when the change surrounds the marker range", -> describe "when the marker's invalidation strategy is 'contains' (the default)", -> it "invalidates the marker", -> buffer.delete([[4, 15], [4, 25]]) - expect(buffer.getMarkerRange(marker1)).toBeUndefined() + expect(marker1.isValid()).toBeFalsy() buffer.undo() - expect(buffer.getMarkerRange(marker1)).toEqual [[4, 20], [4, 23]] + expect(marker1.isValid()).toBeTruthy() + expect(marker1.getRange()).toEqual [[4, 20], [4, 23]] describe "when the marker's invalidation strategy is 'between'", -> it "invalidates the marker", -> buffer.delete([[4, 15], [4, 25]]) - expect(buffer.getMarkerRange(marker3)).toBeUndefined() + expect(marker3.isValid()).toBeFalsy() buffer.undo() - expect(buffer.getMarkerRange(marker3)).toEqual [[4, 20], [4, 23]] + expect(marker3.isValid()).toBeTruthy() + expect(marker3.getRange()).toEqual [[4, 20], [4, 23]] describe "when the marker's invalidation strategy is 'never'", -> it "does not invalidate the marker, but sets it to an empty range at the end of the change", -> buffer.change([[4, 15], [4, 25]], "...") - expect(buffer.getMarkerRange(marker2)).toEqual [[4, 18], [4, 18]] + expect(marker2.isValid()).toBeTruthy() + expect(marker2.getRange()).toEqual [[4, 18], [4, 18]] buffer.undo() - expect(buffer.getMarkerRange(marker2)).toEqual [[4, 20], [4, 23]] + expect(marker2.isValid()).toBeTruthy() + expect(marker2.getRange()).toEqual [[4, 20], [4, 23]] describe "when the change straddles the start of the marker range", -> describe "when the marker's invalidation strategy is 'contains' (the default)", -> it "invalidates the marker", -> buffer.delete([[4, 15], [4, 22]]) - expect(buffer.getMarkerRange(marker1)).toBeUndefined() + expect(marker1.isValid()).toBeFalsy() buffer.undo() - expect(buffer.getMarkerRange(marker1)).toEqual [[4, 20], [4, 23]] + expect(marker1.isValid()).toBeTruthy() + expect(marker1.getRange()).toEqual [[4, 20], [4, 23]] describe "when the marker's invalidation strategy is 'between'", -> it "invalidates the marker", -> buffer.delete([[4, 15], [4, 22]]) - expect(buffer.getMarkerRange(marker3)).toBeUndefined() + expect(marker3.isValid()).toBeFalsy() buffer.undo() - expect(buffer.getMarkerRange(marker3)).toEqual [[4, 20], [4, 23]] + expect(marker3.isValid()).toBeTruthy() + expect(marker3.getRange()).toEqual [[4, 20], [4, 23]] describe "when the marker's invalidation strategy is 'never'", -> it "moves the start of the marker range to the end of the change", -> buffer.delete([[4, 15], [4, 22]]) - expect(buffer.getMarkerRange(marker2)).toEqual [[4, 15], [4, 16]] + expect(marker2.isValid()).toBeTruthy() + expect(marker2.getRange()).toEqual [[4, 15], [4, 16]] buffer.undo() - expect(buffer.getMarkerRange(marker1)).toEqual [[4, 20], [4, 23]] + expect(marker2.isValid()).toBeTruthy() + expect(marker2.getRange()).toEqual [[4, 20], [4, 23]] describe "when the change straddles the end of the marker range", -> describe "when the marker's invalidation strategy is 'contains' (the default)", -> it "invalidates the marker", -> buffer.delete([[4, 22], [4, 25]]) - expect(buffer.getMarkerRange(marker1)).toBeUndefined() + expect(marker1.isValid()).toBeFalsy() buffer.undo() - expect(buffer.getMarkerRange(marker1)).toEqual [[4, 20], [4, 23]] + expect(marker1.isValid()).toBeTruthy() + expect(marker1.getRange()).toEqual [[4, 20], [4, 23]] describe "when the marker's invalidation strategy is 'between'", -> it "invalidates the marker", -> buffer.delete([[4, 22], [4, 25]]) - expect(buffer.getMarkerRange(marker3)).toBeUndefined() + expect(marker3.isValid()).toBeFalsy() buffer.undo() - expect(buffer.getMarkerRange(marker3)).toEqual [[4, 20], [4, 23]] + expect(marker3.isValid()).toBeTruthy() + expect(marker3.getRange()).toEqual [[4, 20], [4, 23]] describe "when the marker's invalidation strategy is 'never'", -> it "moves the end of the marker range to the start of the change", -> buffer.delete([[4, 22], [4, 25]]) - expect(buffer.getMarkerRange(marker2)).toEqual [[4, 20], [4, 22]] + expect(marker2.isValid()).toBeTruthy() + expect(marker2.getRange()).toEqual [[4, 20], [4, 22]] buffer.undo() - expect(buffer.getMarkerRange(marker1)).toEqual [[4, 20], [4, 23]] + expect(marker2.isValid()).toBeTruthy() + expect(marker2.getRange()).toEqual [[4, 20], [4, 23]] describe "when the change is between the start and the end of the marker range", -> describe "when the marker's invalidation strategy is 'contains' (the default)", -> it "does not invalidate the marker", -> buffer.insert([4, 21], 'x') - expect(buffer.getMarkerRange(marker1)).toEqual [[4, 20], [4, 24]] + expect(marker1.isValid()).toBeTruthy() + expect(marker1.getRange()).toEqual [[4, 20], [4, 24]] buffer.undo() - expect(buffer.getMarkerRange(marker1)).toEqual [[4, 20], [4, 23]] + expect(marker1.isValid()).toBeTruthy() + expect(marker1.getRange()).toEqual [[4, 20], [4, 23]] describe "when the marker's invalidation strategy is 'between'", -> it "invalidates the marker", -> buffer.insert([4, 21], 'x') - expect(buffer.getMarkerRange(marker3)).toBeUndefined() + expect(marker3.isValid()).toBeFalsy() buffer.undo() - expect(buffer.getMarkerRange(marker3)).toEqual [[4, 20], [4, 23]] + expect(marker3.isValid()).toBeTruthy() + expect(marker3.getRange()).toEqual [[4, 20], [4, 23]] describe "when the marker's invalidation strategy is 'never'", -> it "moves the end of the marker range to the start of the change", -> buffer.insert([4, 21], 'x') - expect(buffer.getMarkerRange(marker2)).toEqual [[4, 20], [4, 24]] + expect(marker2.isValid()).toBeTruthy() + expect(marker2.getRange()).toEqual [[4, 20], [4, 24]] buffer.undo() - expect(buffer.getMarkerRange(marker1)).toEqual [[4, 20], [4, 23]] + expect(marker2.isValid()).toBeTruthy() + expect(marker2.getRange()).toEqual [[4, 20], [4, 23]] describe "when the buffer changes due to the undo or redo of a previous operation", -> it "restores invalidated markers when undoing/redoing in the other direction", -> buffer.change([[4, 21], [4, 24]], "foo") - expect(buffer.getMarkerRange(marker1)).toBeUndefined() + expect(marker1.isValid()).toBeFalsy() marker3 = buffer.markRange([[4, 20], [4, 23]]) buffer.undo() - expect(buffer.getMarkerRange(marker1)).toEqual [[4, 20], [4, 23]] - expect(buffer.getMarkerRange(marker3)).toBeUndefined() + expect(marker1.isValid()).toBeTruthy() + expect(marker1.getRange()).toEqual [[4, 20], [4, 23]] + expect(marker3.isValid()).toBeFalsy() marker4 = buffer.markRange([[4, 20], [4, 23]]) buffer.redo() - expect(buffer.getMarkerRange(marker3)).toEqual [[4, 20], [4, 23]] - expect(buffer.getMarkerRange(marker4)).toBeUndefined() + expect(marker3.isValid()).toBeTruthy() + expect(marker3.getRange()).toEqual [[4, 20], [4, 23]] + expect(marker4.isValid()).toBeFalsy() buffer.undo() - expect(buffer.getMarkerRange(marker4)).toEqual [[4, 20], [4, 23]] + expect(marker4.isValid()).toBeTruthy() + expect(marker4.getRange()).toEqual [[4, 20], [4, 23]] describe ".markersForPosition(position)", -> it "returns all markers that intersect the given position", -> diff --git a/src/app/buffer-marker.coffee b/src/app/buffer-marker.coffee index fdcb9f7fc..672296a5f 100644 --- a/src/app/buffer-marker.coffee +++ b/src/app/buffer-marker.coffee @@ -162,6 +162,12 @@ class BufferMarker unobserve: (callback) -> @off 'changed', callback + destroy: -> + @buffer.destroyMarker(@id) + + isValid: -> + @buffer.getMarker(@id)? + ### # Internal # ### diff --git a/src/app/text-buffer.coffee b/src/app/text-buffer.coffee index 4177ef7c4..63a6c9676 100644 --- a/src/app/text-buffer.coffee +++ b/src/app/text-buffer.coffee @@ -427,6 +427,9 @@ class Buffer getMarkers: -> _.values(@validMarkers) + getMarker: (id) -> + @validMarkers[id] + # Public: Finds the first marker satisfying the given attributes # # Returns a {String} marker-identifier @@ -440,11 +443,10 @@ class Buffer # startRow - The row at which the marker starts # endRow - The row at which the marker ends # - # Returns an {Array} of {String} marker-identifiers + # Returns an {Array} of {BufferMarker}s findMarkers: (attributes) -> markers = @getMarkers().filter (marker) -> marker.matchesAttributes(attributes) markers.sort (a, b) -> a.getRange().compare(b.getRange()) - _.pluck(markers, 'id') # Public: Retrieves the quantity of markers in a buffer. # @@ -474,7 +476,6 @@ class Buffer attributes }, options)) @validMarkers[marker.id] = marker - marker.id # Public: Constructs a new marker at a given position. # @@ -485,129 +486,14 @@ class Buffer markPosition: (position, options) -> @markRange([position, position], _.defaults({noTail: true}, options)) - # Public: Removes the marker with the given id. - # - # id - The {Number} of the ID to remove - destroyMarker: (id) -> - delete @validMarkers[id] - delete @invalidMarkers[id] - - getMarkerPosition: (args...) -> - @getMarkerHeadPosition(args...) - - setMarkerPosition: (args...) -> - @setMarkerHeadPosition(args...) - - # Public: Retrieves the position of the marker's head. - # - # id - A {Number} representing the marker to check - # - # Returns a {Point}, or `null` if the marker does not exist. - getMarkerHeadPosition: (id) -> - @validMarkers[id]?.getHeadPosition() - - # Public: Sets the position of the marker's head. - # - # id - A {Number} representing the marker to change - # position - The new {Point} to place the head - # options - A hash with the following keys: - # :clip - if `true`, the point is [clipped]{Buffer.clipPosition} - # :bufferChanged - if `true`, indicates that the {Buffer} should trigger an event that it's changed - # - # Returns a {Point} representing the new head position. - setMarkerHeadPosition: (id, position, options) -> - @validMarkers[id]?.setHeadPosition(position) - - # Public: Retrieves the position of the marker's tail. - # - # id - A {Number} representing the marker to check - # - # Returns a {Point}, or `null` if the marker does not exist. - getMarkerTailPosition: (id) -> - @validMarkers[id]?.getTailPosition() - - # Public: Sets the position of the marker's tail. - # - # id - A {Number} representing the marker to change - # position - The new {Point} to place the tail - # options - A hash with the following keys: - # :clip - if `true`, the point is [clipped]{Buffer.clipPosition} - # :bufferChanged - if `true`, indicates that the {Buffer} should trigger an event that it's changed - # - # Returns a {Point} representing the new tail position. - setMarkerTailPosition: (id, position, options) -> - @validMarkers[id]?.setTailPosition(position) - - # Public: Retrieves the {Range} between a marker's head and its tail. - # - # id - A {Number} representing the marker to check - # - # Returns a {Range}. - getMarkerRange: (id) -> - @validMarkers[id]?.getRange() - - # Public: Sets the marker's range, potentialy modifying both its head and tail. - # - # id - A {Number} representing the marker to change - # range - The new {Range} the marker should cover - # options - A hash of options with the following keys: - # :reverse - if `true`, the marker is reversed; that is, its tail is "above" the head - # :noTail - if `true`, the marker doesn't have a tail - setMarkerRange: (id, range, options) -> - @validMarkers[id]?.setRange(range, options) - - # 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) -> - @validMarkers[id]?.placeTail() - - # Public: Removes the tail from the marker. - # - # id - A {Number} representing the marker to change - clearMarkerTail: (id) -> - @validMarkers[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) -> - @validMarkers[id]?.isReversed() - - # 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) -> - @validMarkers[id]?.isRangeEmpty() - - # 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) -> - @validMarkers[id]?.observe(callback) - # Public: Given a buffer position, this finds all markers that contain the position. # # bufferPosition - A {Point} to check # # Returns an {Array} of {Numbers}, representing marker IDs containing `bufferPosition`. - markersForPosition: (bufferPosition) -> - bufferPosition = Point.fromObject(bufferPosition) - ids = [] - for id, marker of @validMarkers - ids.push(id) if marker.containsPoint(bufferPosition) - ids + markersForPosition: (position) -> + position = Point.fromObject(position) + @getMarkers().filter (marker) -> marker.containsPoint(position) # Public: Identifies if a character sequence is within a certain range. # @@ -758,6 +644,10 @@ class Buffer # Internal # ### + destroyMarker: (id) -> + delete @validMarkers[id] + delete @invalidMarkers[id] + scheduleModifiedEvents: -> clearTimeout(@stoppedChangingTimeout) if @stoppedChangingTimeout stoppedChangingCallback = =>