mirror of
https://github.com/atom/atom.git
synced 2026-01-23 13:58:08 -05:00
WIP: Destroy nested tab stops when engulfed by a buffer change
Has 2 failing specs... There are still some issue with this code's interaction with the undo system. The tab stops will need to be or destroyed when certain changes are undone or redone.
This commit is contained in:
@@ -35,6 +35,10 @@
|
||||
"Point array":
|
||||
prefix: "pt"
|
||||
body: "[$1, $2]"
|
||||
|
||||
"Key-value pair":
|
||||
prefix: ":"
|
||||
body: '${1:"${2:key}"}: ${3:value}'
|
||||
"Create Jasmine spy":
|
||||
prefix: "pt"
|
||||
body: 'jasmine.createSpy("${1:description}")$2'
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
Range = require 'range'
|
||||
EventEmitter = require 'event-emitter'
|
||||
Subscriber = require 'subscriber'
|
||||
_ = require 'underscore'
|
||||
|
||||
module.exports =
|
||||
class AnchorRange
|
||||
@@ -6,11 +9,14 @@ class AnchorRange
|
||||
end: null
|
||||
buffer: null
|
||||
editSession: null # optional
|
||||
destroyed: false
|
||||
|
||||
constructor: (bufferRange, @buffer, @editSession) ->
|
||||
bufferRange = Range.fromObject(bufferRange)
|
||||
@startAnchor = @buffer.addAnchorAtPosition(bufferRange.start, ignoreChangesStartingOnAnchor: true)
|
||||
@endAnchor = @buffer.addAnchorAtPosition(bufferRange.end)
|
||||
@subscribe @startAnchor, 'destroyed', => @destroy()
|
||||
@subscribe @endAnchor, 'destroyed', => @destroy()
|
||||
|
||||
getBufferRange: ->
|
||||
new Range(@startAnchor.getBufferPosition(), @endAnchor.getBufferPosition())
|
||||
@@ -22,7 +28,14 @@ class AnchorRange
|
||||
@getBufferRange().containsPoint(bufferPosition)
|
||||
|
||||
destroy: ->
|
||||
return if @destroyed
|
||||
@unsubscribe()
|
||||
@startAnchor.destroy()
|
||||
@endAnchor.destroy()
|
||||
@buffer.removeAnchorRange(this)
|
||||
@editSession?.removeAnchorRange(this)
|
||||
@destroyed = true
|
||||
@trigger 'destroyed'
|
||||
|
||||
_.extend(AnchorRange.prototype, EventEmitter)
|
||||
_.extend(AnchorRange.prototype, Subscriber)
|
||||
|
||||
@@ -10,6 +10,7 @@ class Anchor
|
||||
screenPosition: null
|
||||
ignoreChangesStartingOnAnchor: false
|
||||
strong: false
|
||||
destroyed: false
|
||||
|
||||
constructor: (@buffer, options = {}) ->
|
||||
{ @editSession, @ignoreChangesStartingOnAnchor, @strong } = options
|
||||
@@ -81,8 +82,10 @@ class Anchor
|
||||
@setScreenPosition(screenPosition, bufferChange: options.bufferChange, clip: false, assignBufferPosition: false, autoscroll: options.autoscroll)
|
||||
|
||||
destroy: ->
|
||||
return if @destroyed
|
||||
@buffer.removeAnchor(this)
|
||||
@editSession?.removeAnchor(this)
|
||||
@destroyed = true
|
||||
@trigger 'destroyed'
|
||||
|
||||
_.extend(Anchor.prototype, EventEmitter)
|
||||
|
||||
@@ -52,12 +52,9 @@ describe "Snippets extension", ->
|
||||
|
||||
"""
|
||||
|
||||
"multi-line placeholders":
|
||||
"nested tab stops":
|
||||
prefix: "t5"
|
||||
body: """
|
||||
behold ${1:my multi-
|
||||
line placeholder}. amazing.
|
||||
"""
|
||||
body: '${1:"${2:key}"}: ${3:value}'
|
||||
|
||||
"caused problems with undo":
|
||||
prefix: "t6"
|
||||
@@ -122,6 +119,17 @@ describe "Snippets extension", ->
|
||||
editor.trigger keydownEvent('tab', target: editor[0])
|
||||
expect(editor.getSelectedBufferRange()).toEqual [[1, 29], [1, 35]]
|
||||
|
||||
describe "when tab stops are nested", ->
|
||||
it "destroys the inner tab stop if the outer tab stop is modified", ->
|
||||
buffer.setText('')
|
||||
editor.insertText 't5'
|
||||
editor.trigger 'snippets:expand'
|
||||
expect(buffer.lineForRow(0)).toBe '"key": value'
|
||||
expect(editor.getSelectedBufferRange()).toEqual [[0, 0], [0, 5]]
|
||||
editor.insertText("foo")
|
||||
editor.trigger keydownEvent('tab', target: editor[0])
|
||||
expect(editor.getSelectedBufferRange()).toEqual [[0, 5], [0, 10]]
|
||||
|
||||
describe "when the cursor is moved beyond the bounds of a tab stop", ->
|
||||
it "terminates the snippet", ->
|
||||
editor.setCursorScreenPosition([2, 0])
|
||||
@@ -182,7 +190,7 @@ describe "Snippets extension", ->
|
||||
editor.trigger keydownEvent('tab', target: editor[0])
|
||||
expect(buffer.lineForRow(0)).toBe "first line"
|
||||
|
||||
describe "when a snippet expansion is undone and redone", ->
|
||||
ffdescribe "when a snippet expansion is undone and redone", ->
|
||||
it "recreates the snippet's tab stops", ->
|
||||
editor.insertText ' t6\n'
|
||||
editor.setCursorBufferPosition [0, 6]
|
||||
|
||||
@@ -25,7 +25,9 @@ class SnippetExpansion
|
||||
|
||||
placeTabStopAnchorRanges: (startPosition, tabStopRanges) ->
|
||||
@tabStopAnchorRanges = tabStopRanges.map ({start, end}) =>
|
||||
@editSession.addAnchorRange([startPosition.add(start), startPosition.add(end)])
|
||||
anchorRange = @editSession.addAnchorRange([startPosition.add(start), startPosition.add(end)])
|
||||
anchorRange.on 'destroyed', => _.remove(@tabStopAnchorRanges, anchorRange)
|
||||
anchorRange
|
||||
@setTabStopIndex(0)
|
||||
|
||||
indentSubsequentLines: (startRow, snippet) ->
|
||||
@@ -68,7 +70,7 @@ class SnippetExpansion
|
||||
_.intersection(@tabStopAnchorRanges, @editSession.anchorRangesForBufferPosition(bufferPosition))
|
||||
|
||||
destroy: ->
|
||||
anchorRange.destroy() for anchorRange in @tabStopAnchorRanges
|
||||
anchorRange.destroy() for anchorRange in new Array(@tabStopAnchorRanges...)
|
||||
@editSession.off '.snippet-expansion'
|
||||
@editSession.snippetExpansion = null
|
||||
|
||||
|
||||
Reference in New Issue
Block a user