Files
atom/src/app/undo-manager.coffee
2012-04-19 11:19:24 -06:00

57 lines
1.4 KiB
CoffeeScript

module.exports =
class UndoManager
undoHistory: null
redoHistory: null
currentBatch: null
preserveHistory: false
startBatchCallCount: null
constructor: (@buffer) ->
@startBatchCallCount = 0
@undoHistory = []
@redoHistory = []
@buffer.on 'change', (op) =>
unless @preserveHistory
if @currentBatch
@currentBatch.push(op)
else
@undoHistory.push([op])
@redoHistory = []
undo: ->
if batch = @undoHistory.pop()
@preservingHistory =>
opsInReverse = new Array(batch...)
opsInReverse.reverse()
for op in opsInReverse
@buffer.change op.newRange, op.oldText
@redoHistory.push batch
batch.oldSelectionRanges
redo: ->
if batch = @redoHistory.pop()
@preservingHistory =>
for op in batch
@buffer.change op.oldRange, op.newText
@undoHistory.push batch
batch.newSelectionRanges
startUndoBatch: (ranges) ->
@startBatchCallCount++
return if @startBatchCallCount > 1
@currentBatch = []
@currentBatch.oldSelectionRanges = ranges
endUndoBatch: (ranges) ->
@startBatchCallCount--
return if @startBatchCallCount > 0
@currentBatch.newSelectionRanges = ranges
@undoHistory.push(@currentBatch) if @currentBatch.length > 0
@currentBatch = null
preservingHistory: (fn) ->
@preserveHistory = true
fn()
@preserveHistory = false