Skip to content
This repository was archived by the owner on Apr 6, 2018. It is now read-only.

Atom undo for insert #849

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 17 additions & 14 deletions lib/operators/input.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,9 @@ class InsertAtBeginningOfLine extends Insert
class InsertAboveWithNewline extends Insert
execute: (count=1) ->
@vimState.setInsertionCheckpoint() unless @typingCompleted
@editor.insertNewlineAbove()
@editor.getLastCursor().skipLeadingWhitespace()
@editor.transact Infinity, =>
@editor.insertNewlineAbove()
@editor.getLastCursor().skipLeadingWhitespace()

if @typingCompleted
# We'll have captured the inserted newline, but we want to do that
Expand All @@ -83,8 +84,9 @@ class InsertAboveWithNewline extends Insert
class InsertBelowWithNewline extends Insert
execute: (count=1) ->
@vimState.setInsertionCheckpoint() unless @typingCompleted
@editor.insertNewlineBelow()
@editor.getLastCursor().skipLeadingWhitespace()
@editor.transact Infinity, =>
@editor.insertNewlineBelow()
@editor.getLastCursor().skipLeadingWhitespace()

if @typingCompleted
# We'll have captured the inserted newline, but we want to do that
Expand Down Expand Up @@ -116,17 +118,18 @@ class Change extends Insert
# undo transactions are already handled.
@vimState.setInsertionCheckpoint() unless @typingCompleted

@setTextRegister(@register, @editor.getSelectedText())
if @motion.isLinewise?() and not @typingCompleted
for selection in @editor.getSelections()
if selection.getBufferRange().end.row is 0
@editor.transact Infinity, =>
@setTextRegister(@register, @editor.getSelectedText())
if @motion.isLinewise?() and not @typingCompleted
for selection in @editor.getSelections()
if selection.getBufferRange().end.row is 0
selection.deleteSelectedText()
else
selection.insertText("\n", autoIndent: true)
selection.cursor.moveLeft()
else
for selection in @editor.getSelections()
selection.deleteSelectedText()
else
selection.insertText("\n", autoIndent: true)
selection.cursor.moveLeft()
else
for selection in @editor.getSelections()
selection.deleteSelectedText()

return super if @typingCompleted

Expand Down
5 changes: 4 additions & 1 deletion lib/vim-state.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,10 @@ class VimState
return unless @mode in [null, 'insert']
@editorElement.component.setInputEnabled(false)
@editorElement.classList.remove('replace-mode')
@editor.groupChangesSinceCheckpoint(@insertionCheckpoint)

# this empty transaction with 0 grouping interval makes sure undo doesn't group changes across here
@editor.transact 0, ->

changes = getChangesSinceCheckpoint(@editor.buffer, @insertionCheckpoint)
item = @inputOperator(@history[0])
@insertionCheckpoint = null
Expand Down
55 changes: 40 additions & 15 deletions spec/operators-spec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ describe "Operators", ->
editor.setCursorScreenPosition([0, 0])
keydown('3')
keydown('s')
editor.insertText("ab")
editor.insertText("ab", groupUndo: true)
keydown('escape')
expect(editor.getText()).toBe 'ab345'
keydown('u')
Expand Down Expand Up @@ -292,7 +292,7 @@ describe "Operators", ->

it "is undoable", ->
keydown('S', shift: true)
editor.insertText("abc")
editor.insertText("abc", groupUndo: true)
keydown 'escape'
expect(editor.getText()).toBe "12345\nabc\nABCDE"
keydown 'u'
Expand Down Expand Up @@ -620,13 +620,38 @@ describe "Operators", ->
it "is undoable", ->
keydown('c')
keydown('c')
editor.insertText("abc")
editor.insertText("def", groupUndo: true)
keydown 'escape'
expect(editor.getText()).toBe "12345\n abc\nABCDE"
expect(editor.getText()).toBe "12345\n def\nABCDE"
keydown 'u'
expect(editor.getText()).toBe "12345\n abcde\nABCDE"
expect(editor.getSelectedText()).toBe ''

describe "with simulated slow typing", ->
beforeEach ->
spyOn(Date, "now").andCallFake -> window.now
atom.config.set('editor.undoGroupingInterval', 300)

it "uses Atom undo grouping", ->
keydown('c')
keydown('c')
advanceClock 1000
editor.insertText("d", groupUndo: true)
advanceClock 100
editor.insertText("e", groupUndo: true)
advanceClock 500
editor.insertText("f", groupUndo: true)
keydown 'escape'
expect(editor.getText()).toBe "12345\n def\nABCDE"
keydown 'u'
expect(editor.getText()).toBe "12345\n de\nABCDE"
# FIXME: if TextBuffer allows Infinity for special case groupingInterval,
# the following undo will undo both changes, so the immediate two lines below will go
keydown 'u'
expect(editor.getText()).toBe "12345\n \nABCDE"
keydown 'u'
expect(editor.getText()).toBe "12345\n abcde\nABCDE"

describe "when the cursor is on the last line", ->
it "deletes the line's content and enters insert mode on the last line", ->
editor.setCursorScreenPosition([2, 1])
Expand Down Expand Up @@ -663,8 +688,7 @@ describe "Operators", ->
expect(editor.getCursorScreenPosition()).toEqual [1, 0]
expect(editorElement.classList.contains('insert-mode')).toBe(true)

# Just cannot get "typing" to work correctly in test.
editor.setText("12345\nfg\nABCDE")
editor.insertText("fg", groupUndo: true)
keydown('escape')
expect(editorElement.classList.contains('normal-mode')).toBe(true)
expect(editor.getText()).toBe "12345\nfg\nABCDE"
Expand Down Expand Up @@ -717,7 +741,7 @@ describe "Operators", ->
editor.addCursorAtScreenPosition([2, 1])
keydown('c')
keydown('%')
editor.insertText('x')
editor.insertText('x', groupUndo: true)

it "replaces inclusively until matching bracket", ->
expect(editor.getText()).toBe("1x8\naxe\nAxBCDE")
Expand Down Expand Up @@ -1395,7 +1419,7 @@ describe "Operators", ->

it "is undoable", ->
keydown('O', shift: true)
editor.insertText "def"
editor.insertText "def", groupUndo: true
keydown 'escape'
expect(editor.getText()).toBe " abc\n def\n 012\n"
keydown 'u'
Expand Down Expand Up @@ -1434,7 +1458,7 @@ describe "Operators", ->

it "is undoable", ->
keydown('o')
editor.insertText "def"
editor.insertText "def", groupUndo: true
keydown 'escape'
expect(editor.getText()).toBe "abc\n 012\n def\n"
keydown 'u'
Expand Down Expand Up @@ -1912,16 +1936,17 @@ describe "Operators", ->

it "allows undoing an entire batch of typing", ->
keydown 'i'
editor.insertText("abcXX")
editor.backspace()
editor.backspace()
editor.insertText("abcXX", groupUndo: true)
# transact to enable grouping of changes, as is done in TextEditorElement
editor.transact 300, -> editor.backspace()
editor.transact 300, -> editor.backspace()
keydown 'escape'
expect(editor.getText()).toBe "abc123\nabc4567"

keydown 'i'
editor.insertText "d"
editor.insertText "e"
editor.insertText "f"
editor.insertText "d", groupUndo: true
editor.insertText "e", groupUndo: true
editor.insertText "f", groupUndo: true
keydown 'escape'
expect(editor.getText()).toBe "abdefc123\nabdefc4567"

Expand Down