Skip to content
This repository was archived by the owner on Mar 3, 2023. It is now read-only.
Merged
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
55 changes: 54 additions & 1 deletion spec/text-editor-spec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -762,11 +762,24 @@ describe "TextEditor", ->
editor.moveToBeginningOfWord()
expect(editor.getCursorBufferPosition()).toEqual [10, 0]

it "treats lines with only whitespace as a word (CRLF line ending)", ->
editor.buffer.setText(buffer.getText().replace(/\n/g, "\r\n"))
editor.setCursorBufferPosition([11, 0])
editor.moveToBeginningOfWord()
expect(editor.getCursorBufferPosition()).toEqual [10, 0]

it "works when the current line is blank", ->
editor.setCursorBufferPosition([10, 0])
editor.moveToBeginningOfWord()
expect(editor.getCursorBufferPosition()).toEqual [9, 2]

it "works when the current line is blank (CRLF line ending)", ->
editor.buffer.setText(buffer.getText().replace(/\n/g, "\r\n"))
editor.setCursorBufferPosition([10, 0])
editor.moveToBeginningOfWord()
expect(editor.getCursorBufferPosition()).toEqual [9, 2]
editor.buffer.setText(buffer.getText().replace(/\r\n/g, "\n"))

describe ".moveToPreviousWordBoundary()", ->
it "moves the cursor to the previous word boundary", ->
editor.setCursorBufferPosition [0, 8]
Expand Down Expand Up @@ -821,11 +834,23 @@ describe "TextEditor", ->
editor.moveToEndOfWord()
expect(editor.getCursorBufferPosition()).toEqual [10, 0]

it "treats lines with only whitespace as a word (CRLF line ending)", ->
editor.buffer.setText(buffer.getText().replace(/\n/g, "\r\n"))
editor.setCursorBufferPosition([9, 4])
editor.moveToEndOfWord()
expect(editor.getCursorBufferPosition()).toEqual [10, 0]

it "works when the current line is blank", ->
editor.setCursorBufferPosition([10, 0])
editor.moveToEndOfWord()
expect(editor.getCursorBufferPosition()).toEqual [11, 8]

it "works when the current line is blank (CRLF line ending)", ->
editor.buffer.setText(buffer.getText().replace(/\n/g, "\r\n"))
editor.setCursorBufferPosition([10, 0])
editor.moveToEndOfWord()
expect(editor.getCursorBufferPosition()).toEqual [11, 8]

describe ".moveToBeginningOfNextWord()", ->
it "moves the cursor before the first character of the next word", ->
editor.setCursorBufferPosition [0, 6]
Expand Down Expand Up @@ -1055,8 +1080,36 @@ describe "TextEditor", ->
editor.moveToBeginningOfNextParagraph()
expect(editor.getCursorBufferPosition()).toEqual [0, 0]

it "moves the cursor before the first line of the next paragraph (CRLF line endings)", ->
editor.setText(editor.getText().replace(/\n/g, '\r\n'))

editor.setCursorBufferPosition [0, 6]
editor.foldBufferRow(4)

editor.moveToBeginningOfNextParagraph()
expect(editor.getCursorBufferPosition()).toEqual [10, 0]

editor.setText("")
editor.setCursorBufferPosition [0, 0]
editor.moveToBeginningOfNextParagraph()
expect(editor.getCursorBufferPosition()).toEqual [0, 0]

describe ".moveToBeginningOfPreviousParagraph()", ->
it "moves the cursor before the first line of the pevious paragraph", ->
it "moves the cursor before the first line of the previous paragraph", ->
editor.setCursorBufferPosition [10, 0]
editor.foldBufferRow(4)

editor.moveToBeginningOfPreviousParagraph()
expect(editor.getCursorBufferPosition()).toEqual [0, 0]

editor.setText("")
editor.setCursorBufferPosition [0, 0]
editor.moveToBeginningOfPreviousParagraph()
expect(editor.getCursorBufferPosition()).toEqual [0, 0]

it "moves the cursor before the first line of the previous paragraph (CRLF line endings)", ->
editor.setText(editor.getText().replace(/\n/g, '\r\n'))

editor.setCursorBufferPosition [10, 0]
editor.foldBufferRow(4)

Expand Down
56 changes: 29 additions & 27 deletions src/cursor.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
_ = require 'underscore-plus'
Model = require './model'

EmptyLineRegExp = /(\r\n[\t ]*\r\n)|(\n[\t ]*\n)/g

# Extended: The `Cursor` class represents the little blinking line identifying
# where text can be inserted.
#
Expand Down Expand Up @@ -467,10 +469,13 @@ class Cursor extends Model
scanRange = [[previousNonBlankRow, 0], currentBufferPosition]

beginningOfWordPosition = null
@editor.backwardsScanInBufferRange (options.wordRegex ? @wordRegExp(options)), scanRange, ({range, stop}) ->
if range.end.isGreaterThanOrEqual(currentBufferPosition) or allowPrevious
beginningOfWordPosition = range.start
if not beginningOfWordPosition?.isEqual(currentBufferPosition)
@editor.backwardsScanInBufferRange (options.wordRegex ? @wordRegExp(options)), scanRange, ({range, matchText, stop}) ->
# Ignore 'empty line' matches between '\r' and '\n'
return if matchText is '' and range.start.column isnt 0

if range.start.isLessThan(currentBufferPosition)
if range.end.isGreaterThanOrEqual(currentBufferPosition) or allowPrevious
beginningOfWordPosition = range.start
stop()

if beginningOfWordPosition?
Expand All @@ -496,13 +501,12 @@ class Cursor extends Model
scanRange = [currentBufferPosition, @editor.getEofBufferPosition()]

endOfWordPosition = null
@editor.scanInBufferRange (options.wordRegex ? @wordRegExp(options)), scanRange, ({range, stop}) ->
if allowNext
if range.end.isGreaterThan(currentBufferPosition)
endOfWordPosition = range.end
stop()
else
if range.start.isLessThanOrEqual(currentBufferPosition)
@editor.scanInBufferRange (options.wordRegex ? @wordRegExp(options)), scanRange, ({range, matchText, stop}) ->
# Ignore 'empty line' matches between '\r' and '\n'
return if matchText is '' and range.start.column isnt 0

if range.end.isGreaterThan(currentBufferPosition)
if allowNext or range.start.isLessThanOrEqual(currentBufferPosition)
endOfWordPosition = range.end
stop()

Expand Down Expand Up @@ -603,14 +607,14 @@ class Cursor extends Model
# non-word characters in the regex. (default: true)
#
# Returns a {RegExp}.
wordRegExp: ({includeNonWordCharacters}={}) ->
includeNonWordCharacters ?= true
nonWordCharacters = @config.get('editor.nonWordCharacters', scope: @getScopeDescriptor())
segments = ["^[\t ]*$"]
segments.push("[^\\s#{_.escapeRegExp(nonWordCharacters)}]+")
if includeNonWordCharacters
segments.push("[#{_.escapeRegExp(nonWordCharacters)}]+")
new RegExp(segments.join("|"), "g")
wordRegExp: (options) ->
scope = @getScopeDescriptor()
nonWordCharacters = _.escapeRegExp(@config.get('editor.nonWordCharacters', {scope}))

source = "^[\t ]*$|[^\\s#{nonWordCharacters}]+"
if options?.includeNonWordCharacters ? true
source += "|" + "[#{nonWordCharacters}]+"
new RegExp(source, "g")

# Public: Get the RegExp used by the cursor to determine what a "subword" is.
#
Expand Down Expand Up @@ -666,10 +670,9 @@ class Cursor extends Model
{row, column} = eof
position = new Point(row, column - 1)

@editor.scanInBufferRange /^\n*$/g, scanRange, ({range, stop}) ->
unless range.start.isEqual(start)
position = range.start
stop()
@editor.scanInBufferRange EmptyLineRegExp, scanRange, ({range, stop}) ->
position = range.start.traverse(Point(1, 0))
stop() unless position.isEqual(start)
position

getBeginningOfPreviousParagraphBufferPosition: ->
Expand All @@ -679,8 +682,7 @@ class Cursor extends Model
scanRange = [[row-1, column], [0, 0]]
position = new Point(0, 0)
zero = new Point(0, 0)
@editor.backwardsScanInBufferRange /^\n*$/g, scanRange, ({range, stop}) ->
unless range.start.isEqual(zero)
position = range.start
stop()
@editor.backwardsScanInBufferRange EmptyLineRegExp, scanRange, ({range, stop}) ->
position = range.start.traverse(Point(1, 0))
stop() unless position.isEqual(start)
position