From a67bb98f027185d9c58f511550306dc7a3aa24d8 Mon Sep 17 00:00:00 2001 From: Corey Johnson & Nathan Sobo Date: Fri, 23 Mar 2012 16:02:34 -0600 Subject: [PATCH] Multiple newlines can be inserted on the same line Redesign Cursor.handleBufferChange. The basic intuition is that each cursor should have the same spatial relationship with the end of the new range as it previously had with the end of the old range. --- spec/atom/editor-spec.coffee | 68 +++++++++++++++++++++++------------- src/atom/cursor.coffee | 15 +++++--- 2 files changed, 54 insertions(+), 29 deletions(-) diff --git a/spec/atom/editor-spec.coffee b/spec/atom/editor-spec.coffee index b7aa8390f..a55d88fb3 100644 --- a/spec/atom/editor-spec.coffee +++ b/spec/atom/editor-spec.coffee @@ -770,36 +770,54 @@ describe "Editor", -> expect(cursor2.getBufferPosition()).toEqual [6, 0] describe "inserting text", -> - describe "when inserting characters other than newlines", -> - it "inserts text for all cursors", -> - editor.setCursorScreenPosition([3, 0]) - editor.addCursorAtScreenPosition([6, 0]) + describe "when cursors are on the same line", -> + describe "when inserting newlines", -> + it "breaks the line into three lines at the cursor locations", -> + editor.setCursorScreenPosition([3, 13]) + editor.addCursorAtScreenPosition([3, 38]) - editor.insertText("abc") - expect(editor.lineForBufferRow(3)).toBe "abc var pivot = items.shift(), current, left = [], right = [];" - expect(editor.lineForBufferRow(6)).toBe "abc current < pivot ? left.push(current) : right.push(current);" + editor.insertText('\n') - [cursor1, cursor2] = editor.compositeCursor.getCursors() - expect(cursor1.getBufferPosition()).toEqual [3,3] - expect(cursor2.getBufferPosition()).toEqual [6,3] + expect(editor.lineForBufferRow(3)).toBe " var pivot" + expect(editor.lineForBufferRow(4)).toBe " = items.shift(), current" + expect(editor.lineForBufferRow(5)).toBe ", left = [], right = [];" + expect(editor.lineForBufferRow(6)).toBe " while(items.length > 0) {" - describe "when inserting newlines", -> - it "inserts newlines for all cursors", -> - editor.setCursorScreenPosition([3, 0]) - editor.addCursorAtScreenPosition([6, 0]) + [cursor1, cursor2] = editor.compositeCursor.getCursors() + expect(cursor1.getBufferPosition()).toEqual [4, 0] + expect(cursor2.getBufferPosition()).toEqual [5, 0] - editor.insertText("\n") - expect(editor.lineForBufferRow(3)).toBe "" - expect(editor.lineForBufferRow(4)).toBe " var pivot = items.shift(), current, left = [], right = [];" - expect(editor.lineForBufferRow(5)).toBe " while(items.length > 0) {" - expect(editor.lineForBufferRow(6)).toBe " current = items.shift();" - expect(editor.lineForBufferRow(7)).toBe "" - expect(editor.lineForBufferRow(8)).toBe " current < pivot ? left.push(current) : right.push(current);" - expect(editor.lineForBufferRow(9)).toBe " }" + describe "when cursors are on different lines", -> + describe "when inserting characters other than newlines", -> + it "inserts text for all cursors", -> + editor.setCursorScreenPosition([3, 0]) + editor.addCursorAtScreenPosition([6, 0]) - [cursor1, cursor2] = editor.compositeCursor.getCursors() - expect(cursor1.getBufferPosition()).toEqual [4,0] - expect(cursor2.getBufferPosition()).toEqual [8,0] + editor.insertText("abc") + expect(editor.lineForBufferRow(3)).toBe "abc var pivot = items.shift(), current, left = [], right = [];" + expect(editor.lineForBufferRow(6)).toBe "abc current < pivot ? left.push(current) : right.push(current);" + + [cursor1, cursor2] = editor.compositeCursor.getCursors() + expect(cursor1.getBufferPosition()).toEqual [3,3] + expect(cursor2.getBufferPosition()).toEqual [6,3] + + describe "when inserting newlines", -> + it "inserts newlines for all cursors", -> + editor.setCursorScreenPosition([3, 0]) + editor.addCursorAtScreenPosition([6, 0]) + + editor.insertText("\n") + expect(editor.lineForBufferRow(3)).toBe "" + expect(editor.lineForBufferRow(4)).toBe " var pivot = items.shift(), current, left = [], right = [];" + expect(editor.lineForBufferRow(5)).toBe " while(items.length > 0) {" + expect(editor.lineForBufferRow(6)).toBe " current = items.shift();" + expect(editor.lineForBufferRow(7)).toBe "" + expect(editor.lineForBufferRow(8)).toBe " current < pivot ? left.push(current) : right.push(current);" + expect(editor.lineForBufferRow(9)).toBe " }" + + [cursor1, cursor2] = editor.compositeCursor.getCursors() + expect(cursor1.getBufferPosition()).toEqual [4,0] + expect(cursor2.getBufferPosition()).toEqual [8,0] describe "backspace", -> describe "when cursors are on the same line", -> diff --git a/src/atom/cursor.coffee b/src/atom/cursor.coffee index 5432a0623..ec3026735 100644 --- a/src/atom/cursor.coffee +++ b/src/atom/cursor.coffee @@ -17,11 +17,18 @@ class Cursor extends View handleBufferChange: (e) -> { newRange, oldRange } = e - delta = newRange.end.subtract(oldRange.end) + position = @getBufferPosition() + return if position.isLessThan(oldRange.end) - delta.column = 0 if newRange.end.row != @getBufferPosition().row - return if @getBufferPosition().isLessThan(oldRange.end) - @setBufferPosition(@getBufferPosition().add(delta)) + newRow = newRange.end.row + newColumn = newRange.end.column + if position.row == oldRange.end.row + newColumn += position.column - oldRange.end.column + else + newColumn = position.column + newRow += position.row - oldRange.end.row + + @setBufferPosition([newRow, newColumn]) setScreenPosition: (position, options={}) -> position = Point.fromObject(position)