Merge pull request #3446 from atom/bo-move-var

Add columnCount variables to cursor::moveLeft and moveRight and related methods
This commit is contained in:
Ben Ogle
2014-09-03 17:36:31 -07:00
4 changed files with 146 additions and 21 deletions

View File

@@ -321,6 +321,21 @@ describe "Editor", ->
editor.moveLeft()
expect(editor.getCursorScreenPosition()).toEqual [1, 7]
it "moves the cursor by n columns to the left", ->
editor.setCursorScreenPosition([1, 8])
editor.moveLeft(4)
expect(editor.getCursorScreenPosition()).toEqual [1, 4]
it "moves the cursor by two rows up when the columnCount is longer than an entire line", ->
editor.setCursorScreenPosition([2, 2])
editor.moveLeft(34)
expect(editor.getCursorScreenPosition()).toEqual [0, 29]
it "moves the cursor to the beginning columnCount is longer than the position in the buffer", ->
editor.setCursorScreenPosition([1, 0])
editor.moveLeft(100)
expect(editor.getCursorScreenPosition()).toEqual [0, 0]
describe "when the cursor is in the first column", ->
describe "when there is a previous line", ->
it "wraps to the end of the previous line", ->
@@ -328,12 +343,28 @@ describe "Editor", ->
editor.moveLeft()
expect(editor.getCursorScreenPosition()).toEqual(row: 0, column: buffer.lineForRow(0).length)
it "moves the cursor by one row up and n columns to the left", ->
editor.setCursorScreenPosition([1, 0])
editor.moveLeft(4)
expect(editor.getCursorScreenPosition()).toEqual [0, 26]
describe "when the next line is empty", ->
it "wraps to the beginning of the previous line", ->
editor.setCursorScreenPosition([11, 0])
editor.moveLeft()
expect(editor.getCursorScreenPosition()).toEqual [10, 0]
describe "when the cursor is on the first line", ->
it "remains in the same position (0,0)", ->
editor.setCursorScreenPosition(row: 0, column: 0)
editor.moveLeft()
expect(editor.getCursorScreenPosition()).toEqual(row: 0, column: 0)
it "remains in the same position (0,0) when columnCount is specified", ->
editor.setCursorScreenPosition([0, 0])
editor.moveLeft(4)
expect(editor.getCursorScreenPosition()).toEqual [0, 0]
describe "when softTabs is enabled and the cursor is preceded by leading whitespace", ->
it "skips tabLength worth of whitespace at a time", ->
editor.setCursorBufferPosition([5, 6])
@@ -368,6 +399,21 @@ describe "Editor", ->
editor.moveRight()
expect(editor.getCursorScreenPosition()).toEqual [3, 4]
it "moves the cursor by n columns to the right", ->
editor.setCursorScreenPosition([3, 7])
editor.moveRight(4)
expect(editor.getCursorScreenPosition()).toEqual [3, 11]
it "moves the cursor by two rows down when the columnCount is longer than an entire line", ->
editor.setCursorScreenPosition([0, 29])
editor.moveRight(34)
expect(editor.getCursorScreenPosition()).toEqual [2, 2]
it "moves the cursor to the end of the buffer when columnCount is longer than the number of characters following the cursor position", ->
editor.setCursorScreenPosition([11, 5])
editor.moveRight(100)
expect(editor.getCursorScreenPosition()).toEqual [12, 2]
describe "when the cursor is on the last column of a line", ->
describe "when there is a subsequent line", ->
it "wraps to the beginning of the next line", ->
@@ -375,6 +421,17 @@ describe "Editor", ->
editor.moveRight()
expect(editor.getCursorScreenPosition()).toEqual [1, 0]
it "moves the cursor by one row down and n columns to the right", ->
editor.setCursorScreenPosition([0, buffer.lineForRow(0).length])
editor.moveRight(4)
expect(editor.getCursorScreenPosition()).toEqual [1, 3]
describe "when the next line is empty", ->
it "wraps to the beginning of the next line", ->
editor.setCursorScreenPosition([9, 4])
editor.moveRight()
expect(editor.getCursorScreenPosition()).toEqual [10, 0]
describe "when the cursor is on the last line", ->
it "remains in the same position", ->
lastLineIndex = buffer.getLines().length - 1
@@ -924,6 +981,27 @@ describe "Editor", ->
expect(selection1.getScreenRange()).toEqual([[0, 9], [1, 21]])
expect(selection1.isReversed()).toBeFalsy()
describe "when counts are passed into the selection functions", ->
it "expands each selection to its cursor's new location", ->
editor.setSelectedBufferRanges([[[0,9], [0,13]], [[3,16], [3,21]]])
[selection1, selection2] = editor.getSelections()
editor.selectRight(2)
expect(selection1.getBufferRange()).toEqual [[0,9], [0,15]]
expect(selection2.getBufferRange()).toEqual [[3,16], [3,23]]
editor.selectLeft(3)
expect(selection1.getBufferRange()).toEqual [[0,9], [0,12]]
expect(selection2.getBufferRange()).toEqual [[3,16], [3,20]]
editor.selectDown(3)
expect(selection1.getBufferRange()).toEqual [[0,9], [3,12]]
expect(selection2.getBufferRange()).toEqual [[3,16], [6,20]]
editor.selectUp(2)
expect(selection1.getBufferRange()).toEqual [[0,9], [1,12]]
expect(selection2.getBufferRange()).toEqual [[3,16], [4,20]]
describe ".selectToBufferPosition(bufferPosition)", ->
it "expands the last selection to the given position", ->
editor.setSelectedBufferRange([[3, 0], [4, 5]])

View File

@@ -225,6 +225,11 @@ class Cursor extends Model
@editor.lineTextForBufferRow(@getBufferRow())
# Public: Moves the cursor up one screen row.
#
# * `rowCount` (optional) {Number} number of rows to move (default: 1)
# * `options` (optional) {Object} with the following keys:
# * `moveToEndOfSelection` if true, move to the left of the selection if a
# selection exists.
moveUp: (rowCount=1, {moveToEndOfSelection}={}) ->
range = @marker.getScreenRange()
if moveToEndOfSelection and not range.isEmpty()
@@ -237,7 +242,12 @@ class Cursor extends Model
@goalColumn = column
# Public: Moves the cursor down one screen row.
moveDown: (rowCount = 1, {moveToEndOfSelection}={}) ->
#
# * `rowCount` (optional) {Number} number of rows to move (default: 1)
# * `options` (optional) {Object} with the following keys:
# * `moveToEndOfSelection` if true, move to the left of the selection if a
# selection exists.
moveDown: (rowCount=1, {moveToEndOfSelection}={}) ->
range = @marker.getScreenRange()
if moveToEndOfSelection and not range.isEmpty()
{ row, column } = range.end
@@ -250,30 +260,51 @@ class Cursor extends Model
# Public: Moves the cursor left one screen column.
#
# * `columnCount` (optional) {Number} number of columns to move (default: 1)
# * `options` (optional) {Object} with the following keys:
# * `moveToEndOfSelection` if true, move to the left of the selection if a
# selection exists.
moveLeft: ({moveToEndOfSelection}={}) ->
moveLeft: (columnCount=1, {moveToEndOfSelection}={}) ->
range = @marker.getScreenRange()
if moveToEndOfSelection and not range.isEmpty()
@setScreenPosition(range.start)
else
{row, column} = @getScreenPosition()
[row, column] = if column > 0 then [row, column - 1] else [row - 1, Infinity]
while columnCount > column and row > 0
columnCount -= column
column = @editor.lineTextForScreenRow(--row).length
columnCount-- # subtract 1 for the row move
column = column - columnCount
@setScreenPosition({row, column})
# Public: Moves the cursor right one screen column.
#
# * `columnCount` (optional) {Number} number of columns to move (default: 1)
# * `options` (optional) {Object} with the following keys:
# * `moveToEndOfSelection` if true, move to the right of the selection if a
# selection exists.
moveRight: ({moveToEndOfSelection}={}) ->
moveRight: (columnCount=1, {moveToEndOfSelection}={}) ->
range = @marker.getScreenRange()
if moveToEndOfSelection and not range.isEmpty()
@setScreenPosition(range.end)
else
{ row, column } = @getScreenPosition()
@setScreenPosition([row, column + 1], skipAtomicTokens: true, wrapBeyondNewlines: true, wrapAtSoftNewlines: true)
maxLines = @editor.getScreenLineCount()
rowLength = @editor.lineTextForScreenRow(row).length
columnsRemainingInLine = rowLength - column
while columnCount > columnsRemainingInLine and row < maxLines - 1
columnCount -= columnsRemainingInLine
columnCount-- # subtract 1 for the row move
column = 0
rowLength = @editor.lineTextForScreenRow(++row).length
columnsRemainingInLine = rowLength
column = column + columnCount
@setScreenPosition({row, column}, skipAtomicTokens: true, wrapBeyondNewlines: true, wrapAtSoftNewlines: true)
# Public: Moves the cursor to the top of the buffer.
moveToTop: ->

View File

@@ -1619,7 +1619,7 @@ class Editor extends Model
# Essential: Move every cursor up one row in screen coordinates.
#
# * `lineCount` {Number} number of lines to move
# * `lineCount` (optional) {Number} number of lines to move
moveUp: (lineCount) ->
@moveCursors (cursor) -> cursor.moveUp(lineCount, moveToEndOfSelection: true)
moveCursorUp: (lineCount) ->
@@ -1628,7 +1628,7 @@ class Editor extends Model
# Essential: Move every cursor down one row in screen coordinates.
#
# * `lineCount` {Number} number of lines to move
# * `lineCount` (optional) {Number} number of lines to move
moveDown: (lineCount) ->
@moveCursors (cursor) -> cursor.moveDown(lineCount, moveToEndOfSelection: true)
moveCursorDown: (lineCount) ->
@@ -1636,15 +1636,19 @@ class Editor extends Model
@moveDown(lineCount)
# Essential: Move every cursor left one column.
moveLeft: ->
@moveCursors (cursor) -> cursor.moveLeft(moveToEndOfSelection: true)
#
# * `columnCount` (optional) {Number} number of columns to move (default: 1)
moveLeft: (columnCount) ->
@moveCursors (cursor) -> cursor.moveLeft(columnCount, moveToEndOfSelection: true)
moveCursorLeft: ->
deprecate("Use Editor::moveLeft() instead")
@moveLeft()
# Essential: Move every cursor right one column.
moveRight: ->
@moveCursors (cursor) -> cursor.moveRight(moveToEndOfSelection: true)
#
# * `columnCount` (optional) {Number} number of columns to move (default: 1)
moveRight: (columnCount) ->
@moveCursors (cursor) -> cursor.moveRight(columnCount, moveToEndOfSelection: true)
moveCursorRight: ->
deprecate("Use Editor::moveRight() instead")
@moveRight()
@@ -1978,7 +1982,7 @@ class Editor extends Model
# Essential: Move the cursor of each selection one character upward while
# preserving the selection's tail position.
#
# * `rowCount` {Number} of rows to select up
# * `rowCount` (optional) {Number} number of rows to select (default: 1)
#
# This method may merge selections that end up intesecting.
selectUp: (rowCount) ->
@@ -1987,7 +1991,7 @@ class Editor extends Model
# Essential: Move the cursor of each selection one character downward while
# preserving the selection's tail position.
#
# * `rowCount` {Number} of rows to select down
# * `rowCount` (optional) {Number} number of rows to select (default: 1)
#
# This method may merge selections that end up intesecting.
selectDown: (rowCount) ->
@@ -1996,16 +2000,20 @@ class Editor extends Model
# Essential: Move the cursor of each selection one character leftward while
# preserving the selection's tail position.
#
# * `columnCount` (optional) {Number} number of columns to select (default: 1)
#
# This method may merge selections that end up intesecting.
selectLeft: ->
@expandSelectionsBackward (selection) -> selection.selectLeft()
selectLeft: (columnCount) ->
@expandSelectionsBackward (selection) -> selection.selectLeft(columnCount)
# Essential: Move the cursor of each selection one character rightward while
# preserving the selection's tail position.
#
# * `columnCount` (optional) {Number} number of columns to select (default: 1)
#
# This method may merge selections that end up intesecting.
selectRight: ->
@expandSelectionsForward (selection) -> selection.selectRight()
selectRight: (columnCount) ->
@expandSelectionsForward (selection) -> selection.selectRight(columnCount)
# Essential: Select from the top of the buffer to the end of the last selection
# in the buffer.

View File

@@ -198,18 +198,26 @@ class Selection extends Model
@modifySelection => @cursor.setBufferPosition(position)
# Public: Selects the text one position right of the cursor.
selectRight: ->
@modifySelection => @cursor.moveRight()
#
# * `columnCount` (optional) {Number} number of columns to select (default: 1)
selectRight: (columnCount) ->
@modifySelection => @cursor.moveRight(columnCount)
# Public: Selects the text one position left of the cursor.
selectLeft: ->
@modifySelection => @cursor.moveLeft()
#
# * `columnCount` (optional) {Number} number of columns to select (default: 1)
selectLeft: (columnCount) ->
@modifySelection => @cursor.moveLeft(columnCount)
# Public: Selects all the text one position above the cursor.
#
# * `rowCount` (optional) {Number} number of rows to select (default: 1)
selectUp: (rowCount) ->
@modifySelection => @cursor.moveUp(rowCount)
# Public: Selects all the text one position below the cursor.
#
# * `rowCount` (optional) {Number} number of rows to select (default: 1)
selectDown: (rowCount) ->
@modifySelection => @cursor.moveDown(rowCount)