Merge pull request #645 from github/bo-move-word-behavior

Add new commands for moving between words
This commit is contained in:
Ben Ogle 2013-07-23 15:38:37 -07:00
commit 18370bb663
5 changed files with 159 additions and 0 deletions

View File

@ -313,6 +313,36 @@ describe "EditSession", ->
editSession.moveCursorToBeginningOfWord()
expect(editSession.getCursorBufferPosition()).toEqual [9, 2]
describe ".moveCursorToPreviousWordBoundary()", ->
it "moves the cursor to the previous word boundary", ->
editSession.setCursorBufferPosition [0, 8]
editSession.addCursorAtBufferPosition [2, 0]
editSession.addCursorAtBufferPosition [2, 4]
editSession.addCursorAtBufferPosition [3, 14]
[cursor1, cursor2, cursor3, cursor4] = editSession.getCursors()
editSession.moveCursorToPreviousWordBoundary()
expect(cursor1.getBufferPosition()).toEqual [0, 4]
expect(cursor2.getBufferPosition()).toEqual [1, 30]
expect(cursor3.getBufferPosition()).toEqual [2, 0]
expect(cursor4.getBufferPosition()).toEqual [3, 13]
describe ".moveCursorToNextWordBoundary()", ->
it "moves the cursor to the previous word boundary", ->
editSession.setCursorBufferPosition [0, 8]
editSession.addCursorAtBufferPosition [2, 40]
editSession.addCursorAtBufferPosition [3, 0]
editSession.addCursorAtBufferPosition [3, 30]
[cursor1, cursor2, cursor3, cursor4] = editSession.getCursors()
editSession.moveCursorToNextWordBoundary()
expect(cursor1.getBufferPosition()).toEqual [0, 13]
expect(cursor2.getBufferPosition()).toEqual [3, 0]
expect(cursor3.getBufferPosition()).toEqual [3, 4]
expect(cursor4.getBufferPosition()).toEqual [3, 31]
describe ".moveCursorToEndOfWord()", ->
it "moves the cursor to the end of the word", ->
editSession.setCursorBufferPosition [0, 6]
@ -668,6 +698,46 @@ describe "EditSession", ->
expect(selection2.getBufferRange()).toEqual [[3,48], [3,51]]
expect(selection2.isReversed()).toBeFalsy()
describe ".selectToPreviousWordBoundary()", ->
it "select to the previous word boundary", ->
editSession.setCursorBufferPosition [0, 8]
editSession.addCursorAtBufferPosition [2, 0]
editSession.addCursorAtBufferPosition [3, 4]
editSession.addCursorAtBufferPosition [3, 14]
editSession.selectToPreviousWordBoundary()
expect(editSession.getSelections().length).toBe 4
[selection1, selection2, selection3, selection4] = editSession.getSelections()
expect(selection1.getBufferRange()).toEqual [[0,8], [0,4]]
expect(selection1.isReversed()).toBeTruthy()
expect(selection2.getBufferRange()).toEqual [[2,0], [1,30]]
expect(selection2.isReversed()).toBeTruthy()
expect(selection3.getBufferRange()).toEqual [[3,4], [3,0]]
expect(selection3.isReversed()).toBeTruthy()
expect(selection4.getBufferRange()).toEqual [[3,14], [3,13]]
expect(selection4.isReversed()).toBeTruthy()
describe ".selectToNextWordBoundary()", ->
it "select to the next word boundary", ->
editSession.setCursorBufferPosition [0, 8]
editSession.addCursorAtBufferPosition [2, 40]
editSession.addCursorAtBufferPosition [4, 0]
editSession.addCursorAtBufferPosition [3, 30]
editSession.selectToNextWordBoundary()
expect(editSession.getSelections().length).toBe 4
[selection1, selection2, selection3, selection4] = editSession.getSelections()
expect(selection1.getBufferRange()).toEqual [[0,8], [0,13]]
expect(selection1.isReversed()).toBeFalsy()
expect(selection2.getBufferRange()).toEqual [[2,40], [3,0]]
expect(selection2.isReversed()).toBeFalsy()
expect(selection3.getBufferRange()).toEqual [[4,0], [4,4]]
expect(selection3.isReversed()).toBeFalsy()
expect(selection4.getBufferRange()).toEqual [[3,30], [3,31]]
expect(selection4.isReversed()).toBeFalsy()
describe ".selectWord()", ->
describe "when the cursor is inside a word", ->
it "selects the entire word", ->

View File

@ -244,6 +244,16 @@ class Cursor
if position = @getBeginningOfNextWordBufferPosition()
@setBufferPosition(position)
# Moves the cursor to the previous word boundary.
moveToPreviousWordBoundary: ->
if position = @getMovePreviousWordBoundaryBufferPosition()
@setBufferPosition(position)
# Moves the cursor to the next word boundary.
moveToNextWordBoundary: ->
if position = @getMoveNextWordBoundaryBufferPosition()
@setBufferPosition(position)
# Retrieves the buffer position of where the current word starts.
#
# options - A hash with one option:
@ -265,6 +275,49 @@ class Cursor
beginningOfWordPosition or currentBufferPosition
# Retrieves buffer position of previous word boiundry. It might be on the
# current word, or the previous word.
getMovePreviousWordBoundaryBufferPosition: (options = {}) ->
currentBufferPosition = @getBufferPosition()
previousNonBlankRow = @editSession.buffer.previousNonBlankRow(currentBufferPosition.row)
scanRange = [[previousNonBlankRow, 0], currentBufferPosition]
beginningOfWordPosition = null
@editSession.backwardsScanInBufferRange (options.wordRegex ? @wordRegExp()), scanRange, ({range, stop}) =>
if range.start.row < currentBufferPosition.row and currentBufferPosition.column > 0
# force it to stop at the beginning of each line
beginningOfWordPosition = new Point(currentBufferPosition.row, 0)
else if range.end.isLessThan(currentBufferPosition)
beginningOfWordPosition = range.end
else
beginningOfWordPosition = range.start
if not beginningOfWordPosition?.isEqual(currentBufferPosition)
stop()
beginningOfWordPosition or currentBufferPosition
# Retrieves buffer position of previous word boiundry. It might be on the
# current word, or the previous word.
getMoveNextWordBoundaryBufferPosition: (options = {}) ->
currentBufferPosition = @getBufferPosition()
scanRange = [currentBufferPosition, @editSession.getEofBufferPosition()]
endOfWordPosition = null
@editSession.scanInBufferRange (options.wordRegex ? @wordRegExp()), scanRange, ({range, stop}) =>
if range.start.row > currentBufferPosition.row
# force it to stop at the beginning of each line
endOfWordPosition = new Point(range.start.row, 0)
else if range.start.isGreaterThan(currentBufferPosition)
endOfWordPosition = range.start
else
endOfWordPosition = range.end
if not endOfWordPosition?.isEqual(currentBufferPosition)
stop()
endOfWordPosition or currentBufferPosition
# Retrieves the buffer position of where the current word ends.
#
# options - A hash with one option:

View File

@ -1101,6 +1101,12 @@ class EditSession
moveCursorToBeginningOfNextWord: ->
@moveCursors (cursor) -> cursor.moveToBeginningOfNextWord()
moveCursorToPreviousWordBoundary: ->
@moveCursors (cursor) -> cursor.moveToPreviousWordBoundary()
moveCursorToNextWordBoundary: ->
@moveCursors (cursor) -> cursor.moveToNextWordBoundary()
# Internal:
moveCursors: (fn) ->
fn(cursor) for cursor in @getCursors()
@ -1154,6 +1160,12 @@ class EditSession
selectToEndOfLine: ->
@expandSelectionsForward (selection) => selection.selectToEndOfLine()
selectToPreviousWordBoundary: ->
@expandSelectionsBackward (selection) => selection.selectToPreviousWordBoundary()
selectToNextWordBoundary: ->
@expandSelectionsForward (selection) => selection.selectToNextWordBoundary()
# Selects the current line.
selectLine: ->
@expandSelectionsForward (selection) => selection.selectLine()

View File

@ -141,11 +141,15 @@ class Editor extends View
'editor:move-to-beginning-of-word': @moveCursorToBeginningOfWord
'editor:move-to-end-of-word': @moveCursorToEndOfWord
'editor:move-to-beginning-of-next-word': @moveCursorToBeginningOfNextWord
'editor:move-to-previous-word-boundary': @moveCursorToPreviousWordBoundary
'editor:move-to-next-word-boundary': @moveCursorToNextWordBoundary
'editor:select-to-end-of-line': @selectToEndOfLine
'editor:select-to-beginning-of-line': @selectToBeginningOfLine
'editor:select-to-end-of-word': @selectToEndOfWord
'editor:select-to-beginning-of-word': @selectToBeginningOfWord
'editor:select-to-beginning-of-next-word': @selectToBeginningOfNextWord
'editor:select-to-next-word-boundary': @selectToNextWordBoundary
'editor:select-to-previous-word-boundary': @selectToPreviousWordBoundary
'editor:select-to-first-character-of-line': @selectToFirstCharacterOfLine
'editor:add-selection-below': @addSelectionBelow
'editor:add-selection-above': @addSelectionAbove
@ -238,6 +242,12 @@ class Editor extends View
# {Delegates to: EditSession.moveCursorToFirstCharacterOfLine}
moveCursorToFirstCharacterOfLine: -> @activeEditSession.moveCursorToFirstCharacterOfLine()
# {Delegates to: EditSession.moveCursorToPreviousWordBoundary}
moveCursorToPreviousWordBoundary: -> @activeEditSession.moveCursorToPreviousWordBoundary()
# {Delegates to: EditSession.moveCursorToNextWordBoundary}
moveCursorToNextWordBoundary: -> @activeEditSession.moveCursorToNextWordBoundary()
# {Delegates to: EditSession.moveCursorToEndOfLine}
moveCursorToEndOfLine: -> @activeEditSession.moveCursorToEndOfLine()
@ -334,6 +344,12 @@ class Editor extends View
# {Delegates to: EditSession.selectToEndOfLine}
selectToEndOfLine: -> @activeEditSession.selectToEndOfLine()
# {Delegates to: EditSession.selectToPreviousWordBoundary}
selectToPreviousWordBoundary: -> @activeEditSession.selectToPreviousWordBoundary()
# {Delegates to: EditSession.selectToNextWordBoundary}
selectToNextWordBoundary: -> @activeEditSession.selectToNextWordBoundary()
# {Delegates to: EditSession.addSelectionBelow}
addSelectionBelow: -> @activeEditSession.addSelectionBelow()

View File

@ -218,6 +218,14 @@ class Selection
selectToBeginningOfNextWord: ->
@modifySelection => @cursor.moveToBeginningOfNextWord()
# Selects text to the previous word boundary.
selectToPreviousWordBoundary: ->
@modifySelection => @cursor.moveToPreviousWordBoundary()
# Selects text to the next word boundary.
selectToNextWordBoundary: ->
@modifySelection => @cursor.moveToNextWordBoundary()
# Moves the selection down one row.
addSelectionBelow: ->
range = (@goalBufferRange ? @getBufferRange()).copy()