       @preservingHistory =>
         opsInReverse = new Array(batch...)
         opsInReverse.reverse()
-        for op in opsInReverse
-          @buffer.change op.newRange, op.oldText
+        op.undo() for op in opsInReverse
         @redoHistory.push batch
       batch.oldSelectionRanges
 
   redo: ->
     if batch = @redoHistory.pop()
       @preservingHistory =>
-        for op in batch
-          @buffer.change op.oldRange, op.newText
-        @undoHistory.push batch
+        op.do() for op in batch
+        @undoHistory.push(batch)
       batch.newSelectionRanges
 
   startUndoBatch: (ranges) ->

module.exports =
class UndoManager
  undoHistory: null
  redoHistory: null

    @startBatchCallCount = 0
    @undoHistory = []
    @redoHistory = []
    @buffer.on 'change', (event) =>
      unless @preserveHistory
        op = new BufferChangeOperation(_.extend({ @buffer }, event))
        if @currentBatch
          @currentBatch.push(op)
        else
