From 6177b46cf9c233bba1a47579008a12c64d904043 Mon Sep 17 00:00:00 2001 From: Corey Johnson & Nathan Sobo Date: Fri, 6 Jul 2012 11:42:07 -0600 Subject: [PATCH] Restore selection on active edit session when undoing/redoing The `do`, `undo`, and `redo` methods on operations take an optional editSession argument, which can be used to determine the context in which they are being run. We restore selections on that edit session instead of the session where the operations originally occurred. --- spec/app/edit-session-spec.coffee | 24 ++++++++++++++++-------- src/app/buffer.coffee | 8 ++++---- src/app/edit-session.coffee | 14 ++++++++++---- src/app/project.coffee | 22 +++++++++++++--------- src/app/undo-manager.coffee | 12 ++++++------ 5 files changed, 49 insertions(+), 31 deletions(-) diff --git a/spec/app/edit-session-spec.coffee b/spec/app/edit-session-spec.coffee index 34e24d637..d8ae398c3 100644 --- a/spec/app/edit-session-spec.coffee +++ b/spec/app/edit-session-spec.coffee @@ -6,18 +6,16 @@ describe "EditSession", -> [buffer, editSession, lineLengths] = [] beforeEach -> - buffer = new Buffer(require.resolve('fixtures/sample.js')) - editSession = new EditSession - buffer: buffer - tabText: ' ' - autoIndent: false - softWrap: false - project: new Project() + buffer = new Buffer() + editSession = fixturesProject.open('sample.js', autoIndent: false) + console.log editSession.tabText + + buffer = editSession.buffer lineLengths = buffer.getLines().map (line) -> line.length afterEach -> - buffer.destroy() + fixturesProject.destroy() describe "cursor movement", -> describe ".setCursorScreenPosition(screenPosition)", -> @@ -1263,6 +1261,16 @@ describe "EditSession", -> expect(selections[0].getBufferRange()).toEqual [[1, 6], [1, 6]] expect(selections[1].getBufferRange()).toEqual [[1, 18], [1, 18]] + it "restores selected ranges even when the change occurred in another edit session", -> + otherEditSession = fixturesProject.open(editSession.getPath()) + otherEditSession.setSelectedBufferRange([[2, 2], [3, 3]]) + otherEditSession.delete() + + editSession.undo() + + expect(editSession.getSelectedBufferRange()).toEqual [[2, 2], [3, 3]] + expect(otherEditSession.getSelectedBufferRange()).toEqual [[3, 3], [3, 3]] + describe "when the buffer is changed (via its direct api, rather than via than edit session)", -> it "moves the cursor so it is in the same relative position of the buffer", -> expect(editSession.getCursorScreenPosition()).toEqual [0, 0] diff --git a/src/app/buffer.coffee b/src/app/buffer.coffee index 972ef5c34..d84692e93 100644 --- a/src/app/buffer.coffee +++ b/src/app/buffer.coffee @@ -151,11 +151,11 @@ class Buffer transact: (fn) -> @undoManager.transact(fn) - undo: -> - @undoManager.undo() + undo: (editSession) -> + @undoManager.undo(editSession) - redo: -> - @undoManager.redo() + redo: (editSession) -> + @undoManager.redo(editSession) save: -> @saveAs(@getPath()) diff --git a/src/app/edit-session.coffee b/src/app/edit-session.coffee index 8428bd24f..4300855b9 100644 --- a/src/app/edit-session.coffee +++ b/src/app/edit-session.coffee @@ -95,6 +95,7 @@ class EditSession new Point(row, column) getFileExtension: -> @buffer.getExtension() + getPath: -> @buffer.getPath() getEofBufferPosition: -> @buffer.getEofPosition() bufferRangeForBufferRow: (row) -> @buffer.rangeForRow(row) lineForBufferRow: (row) -> @buffer.lineForRow(row) @@ -177,10 +178,10 @@ class EditSession @insertText($native.readFromPasteboard()) undo: -> - @buffer.undo() + @buffer.undo(this) redo: -> - @buffer.redo() + @buffer.redo(this) foldSelection: -> selection.fold() for selection in @getSelections() @@ -237,10 +238,15 @@ class EditSession transact: (fn) -> @buffer.transact => oldSelectedRanges = @getSelectedBufferRanges() - @buffer.pushOperation(undo: => @setSelectedBufferRanges(oldSelectedRanges)) + @buffer.pushOperation + undo: (editSession) -> + editSession?.setSelectedBufferRanges(oldSelectedRanges) + fn() newSelectedRanges = @getSelectedBufferRanges() - @buffer.pushOperation(redo: => @setSelectedBufferRanges(newSelectedRanges)) + @buffer.pushOperation + redo: (editSession) -> + editSession?.setSelectedBufferRanges(newSelectedRanges) getAnchors: -> new Array(@anchors...) diff --git a/src/app/project.coffee b/src/app/project.coffee index 11a05c820..40ddfc523 100644 --- a/src/app/project.coffee +++ b/src/app/project.coffee @@ -75,26 +75,30 @@ class Project getSoftWrap: -> @softWrap setSoftWrap: (@softWrap) -> - open: (filePath) -> + open: (filePath, editSessionOptions={}) -> if filePath? filePath = @resolve(filePath) buffer = @bufferWithPath(filePath) ? @buildBuffer(filePath) else buffer = @buildBuffer() - editSession = new EditSession - project: this - buffer: buffer - tabText: @getTabText() - autoIndent: @getAutoIndent() - softTabs: @getSoftTabs() - softWrap: @getSoftWrap() - + @buildEditSession(buffer, editSessionOptions) + buildEditSession: (buffer, editSessionOptions) -> + options = _.extend(@defaultEditSessionOptions(), editSessionOptions) + options.project = this + options.buffer = buffer + editSession = new EditSession(options) @editSessions.push editSession @trigger 'new-edit-session', editSession editSession + defaultEditSessionOptions: -> + tabText: @getTabText() + autoIndent: @getAutoIndent() + softTabs: @getSoftTabs() + softWrap: @getSoftWrap() + destroy: -> for editSession in _.clone(@editSessions) @removeEditSession(editSession) diff --git a/src/app/undo-manager.coffee b/src/app/undo-manager.coffee index abfe16072..c3bcaa0df 100644 --- a/src/app/undo-manager.coffee +++ b/src/app/undo-manager.coffee @@ -7,7 +7,7 @@ class UndoManager redoHistory: null currentTransaction: null - constructor: (@buffer) -> + constructor: -> @startBatchCallCount = 0 @undoHistory = [] @redoHistory = [] @@ -29,18 +29,18 @@ class UndoManager @undoHistory.push(@currentTransaction) if @currentTransaction.length @currentTransaction = null - undo: -> + undo: (editSession) -> if batch = @undoHistory.pop() opsInReverse = new Array(batch...) opsInReverse.reverse() - op.undo?() for op in opsInReverse + op.undo?(editSession) for op in opsInReverse @redoHistory.push batch batch.oldSelectionRanges - redo: -> + redo: (editSession) -> if batch = @redoHistory.pop() for op in batch - op.do?() - op.redo?() + op.do?(editSession) + op.redo?(editSession) @undoHistory.push(batch) batch.newSelectionRanges