Changes made with multiple cursors are undone/redone in parallel

This commit is contained in:
Corey Johnson & Nathan Sobo
2012-04-04 14:21:03 -06:00
parent 6ad50b379f
commit 48b4008cab
7 changed files with 135 additions and 14 deletions

View File

@@ -127,6 +127,12 @@ class Buffer
@lines[oldRange.start.row..oldRange.end.row] = newTextLines
@trigger 'change', { oldRange, newRange, oldText, newText }
startUndoBatch: ->
@undoManager.startUndoBatch()
endUndoBatch: ->
@undoManager.endUndoBatch()
undo: ->
@undoManager.undo()

View File

@@ -77,20 +77,29 @@ class CompositeSeleciton
fn(selection) for selection in @getSelections()
@mergeIntersectingSelections(reverse: true)
mutateSelectedText: (fn) ->
selections = @getSelections()
if selections.length > 1
@editor.buffer.startUndoBatch()
fn(selection) for selection in selections
@editor.buffer.endUndoBatch()
else
fn(selections[0])
insertText: (text) ->
selection.insertText(text) for selection in @getSelections()
@mutateSelectedText (selection) -> selection.insertText(text)
backspace: ->
selection.backspace() for selection in @getSelections()
@mutateSelectedText (selection) -> selection.backspace()
backspaceToBeginningOfWord: ->
selection.backspaceToBeginningOfWord() for selection in @getSelections()
@mutateSelectedText (selection) -> selection.backspaceToBeginningOfWord()
delete: ->
selection.delete() for selection in @getSelections()
@mutateSelectedText (selection) -> selection.delete()
deleteToEndOfWord: ->
selection.deleteToEndOfWord() for selection in @getSelections()
@mutateSelectedText (selection) -> selection.deleteToEndOfWord()
selectToScreenPosition: (position) ->
@getLastSelection().selectToScreenPosition(position)

View File

@@ -2,6 +2,7 @@ module.exports =
class UndoManager
undoHistory: null
redoHistory: null
currentBatch: null
preserveHistory: false
constructor: (@buffer) ->
@@ -9,22 +10,37 @@ class UndoManager
@redoHistory = []
@buffer.on 'change', (op) =>
unless @preserveHistory
@undoHistory.push(op)
if @currentBatch
@currentBatch.push(op)
else
@undoHistory.push([op])
@redoHistory = []
undo: ->
if op = @undoHistory.pop()
if ops = @undoHistory.pop()
@preservingHistory =>
@buffer.change op.newRange, op.oldText
@redoHistory.push op
opsInReverse = new Array(ops...)
opsInReverse.reverse()
for op in opsInReverse
@buffer.change op.newRange, op.oldText
@redoHistory.push ops
redo: ->
if op = @redoHistory.pop()
if ops = @redoHistory.pop()
@preservingHistory =>
@buffer.change op.oldRange, op.newText
@undoHistory.push op
for op in ops
@buffer.change op.oldRange, op.newText
@undoHistory.push ops
startUndoBatch: ->
@currentBatch = []
endUndoBatch: ->
@undoHistory.push(@currentBatch)
@currentBatch = null
preservingHistory: (fn) ->
@preserveHistory = true
fn()
@preserveHistory = false