From 1d2fa089e5cc8e4b054cf1a41cc0f8b90e8af14b Mon Sep 17 00:00:00 2001 From: Corey Johnson & Kevin Sawicki Date: Mon, 28 Jan 2013 12:00:12 -0800 Subject: [PATCH 01/13] editor.wordRegex is now a config option. --- src/app/cursor.coffee | 5 ++--- src/app/editor.coffee | 1 + 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app/cursor.coffee b/src/app/cursor.coffee index 4599705f3..efc80fbf4 100644 --- a/src/app/cursor.coffee +++ b/src/app/cursor.coffee @@ -9,7 +9,6 @@ class Cursor screenPosition: null bufferPosition: null goalColumn: null - wordRegex: /(\w+)|([^\w\n]+)/g visible: true needsAutoscroll: false @@ -150,7 +149,7 @@ class Cursor previousLinesRange = [[previousNonBlankRow, 0], currentBufferPosition] beginningOfWordPosition = currentBufferPosition - @editSession.backwardsScanInRange (options.wordRegex || @wordRegex), previousLinesRange, (match, matchRange, { stop }) => + @editSession.backwardsScanInRange (options.wordRegex ? config.get("editor.wordRegex")), previousLinesRange, (match, matchRange, { stop }) => if matchRange.end.isGreaterThanOrEqual(currentBufferPosition) or allowPrevious beginningOfWordPosition = matchRange.start stop() @@ -162,7 +161,7 @@ class Cursor range = [currentBufferPosition, @editSession.getEofBufferPosition()] endOfWordPosition = null - @editSession.scanInRange (options.wordRegex || @wordRegex), range, (match, matchRange, { stop }) => + @editSession.scanInRange (options.wordRegex ? config.get("editor.wordRegex")), range, (match, matchRange, { stop }) => endOfWordPosition = matchRange.end if not allowNext and matchRange.start.isGreaterThan(currentBufferPosition) endOfWordPosition = currentBufferPosition diff --git a/src/app/editor.coffee b/src/app/editor.coffee index 0fb628d4d..55600c0fa 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -19,6 +19,7 @@ class Editor extends View autosave: false autoIndent: true autoIndentOnPaste: false + wordRegex: /(\w+)|([^\w\n]+)/g @content: (params) -> @div class: @classes(params), tabindex: -1, => From b66efbe3e7137d18d29460ff41735c77c04e9a2c Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Tue, 29 Jan 2013 11:08:17 -0800 Subject: [PATCH 02/13] cursor.getBeginningOfCurrentWordBufferPosition behaves like vim --- spec/app/edit-session-spec.coffee | 10 +++++----- src/app/cursor.coffee | 6 +++++- src/app/editor.coffee | 1 + 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/spec/app/edit-session-spec.coffee b/spec/app/edit-session-spec.coffee index 6f72cd8bc..a16554f84 100644 --- a/spec/app/edit-session-spec.coffee +++ b/spec/app/edit-session-spec.coffee @@ -16,7 +16,7 @@ describe "EditSession", -> afterEach -> fixturesProject.destroy() - describe "cursor", -> + fdescribe "cursor", -> describe ".getCursor()", -> it "returns the most recently created cursor", -> editSession.addCursorAtScreenPosition([1, 0]) @@ -276,17 +276,17 @@ describe "EditSession", -> editSession.moveCursorToBeginningOfWord() expect(cursor1.getBufferPosition()).toEqual [0, 4] - expect(cursor2.getBufferPosition()).toEqual [1, 10] + expect(cursor2.getBufferPosition()).toEqual [1, 11] expect(cursor3.getBufferPosition()).toEqual [2, 39] it "does not fail at position [0, 0]", -> editSession.setCursorBufferPosition([0, 0]) editSession.moveCursorToBeginningOfWord() - it "works when the preceding line is blank", -> - editSession.setCursorBufferPosition([10, 0]) + it "works when the previous line is blank", -> + editSession.setCursorBufferPosition([11, 0]) editSession.moveCursorToBeginningOfWord() - expect(editSession.getCursorBufferPosition()).toEqual [9, 0] + expect(editSession.getCursorBufferPosition()).toEqual [10, 0] describe ".moveCursorToEndOfWord()", -> it "moves the cursor to the end of the word", -> diff --git a/src/app/cursor.coffee b/src/app/cursor.coffee index efc80fbf4..cc4c13c30 100644 --- a/src/app/cursor.coffee +++ b/src/app/cursor.coffee @@ -149,10 +149,14 @@ class Cursor previousLinesRange = [[previousNonBlankRow, 0], currentBufferPosition] beginningOfWordPosition = currentBufferPosition - @editSession.backwardsScanInRange (options.wordRegex ? config.get("editor.wordRegex")), previousLinesRange, (match, matchRange, { stop }) => + + wordSeparators = config.get("editor.wordSeparators") + wordSeparatorsRegex = new RegExp("^[\t ]*\n|[^\\s#{_.escapeRegExp(wordSeparators)}]+|[#{_.escapeRegExp(wordSeparators)}]+", "m") + @editSession.backwardsScanInRange (options.wordRegex ? wordSeparatorsRegex), previousLinesRange, (match, matchRange, { stop }) => if matchRange.end.isGreaterThanOrEqual(currentBufferPosition) or allowPrevious beginningOfWordPosition = matchRange.start stop() + beginningOfWordPosition getEndOfCurrentWordBufferPosition: (options = {}) -> diff --git a/src/app/editor.coffee b/src/app/editor.coffee index 55600c0fa..affeefc68 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -20,6 +20,7 @@ class Editor extends View autoIndent: true autoIndentOnPaste: false wordRegex: /(\w+)|([^\w\n]+)/g + wordSeparators: "./\()\"’-:,.;<>~!@#$%^&*|+=[]{}`~?" @content: (params) -> @div class: @classes(params), tabindex: -1, => From dac92ca6e748cec3d8bcddf361c16fa3a6fca852 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Tue, 29 Jan 2013 12:15:43 -0800 Subject: [PATCH 03/13] Make cursor.moveCursorToBeginningOfWord behave like vim --- spec/app/edit-session-spec.coffee | 28 ++++++++++++++++++++++------ src/app/cursor.coffee | 15 ++++++++++----- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/spec/app/edit-session-spec.coffee b/spec/app/edit-session-spec.coffee index a16554f84..a6c67536f 100644 --- a/spec/app/edit-session-spec.coffee +++ b/spec/app/edit-session-spec.coffee @@ -16,7 +16,7 @@ describe "EditSession", -> afterEach -> fixturesProject.destroy() - fdescribe "cursor", -> + describe "cursor", -> describe ".getCursor()", -> it "returns the most recently created cursor", -> editSession.addCursorAtScreenPosition([1, 0]) @@ -266,7 +266,7 @@ describe "EditSession", -> editSession.moveCursorToFirstCharacterOfLine() expect(editSession.getCursorBufferPosition()).toEqual [10, 0] - describe ".moveCursorToBeginningOfWord()", -> + fdescribe ".moveCursorToBeginningOfWord()", -> it "moves the cursor to the beginning of the word", -> editSession.setCursorBufferPosition [0, 8] editSession.addCursorAtBufferPosition [1, 12] @@ -283,12 +283,17 @@ describe "EditSession", -> editSession.setCursorBufferPosition([0, 0]) editSession.moveCursorToBeginningOfWord() - it "works when the previous line is blank", -> + it "treats lines with only whitespace as a word", -> editSession.setCursorBufferPosition([11, 0]) editSession.moveCursorToBeginningOfWord() expect(editSession.getCursorBufferPosition()).toEqual [10, 0] - describe ".moveCursorToEndOfWord()", -> + it "works when the current line is blank", -> + editSession.setCursorBufferPosition([10, 0]) + editSession.moveCursorToBeginningOfWord() + expect(editSession.getCursorBufferPosition()).toEqual [9, 2] + + fdescribe ".moveCursorToEndOfWord()", -> it "moves the cursor to the end of the word", -> editSession.setCursorBufferPosition [0, 6] editSession.addCursorAtBufferPosition [1, 10] @@ -298,8 +303,8 @@ describe "EditSession", -> editSession.moveCursorToEndOfWord() expect(cursor1.getBufferPosition()).toEqual [0, 13] - expect(cursor2.getBufferPosition()).toEqual [1, 13] - expect(cursor3.getBufferPosition()).toEqual [3, 4] + expect(cursor2.getBufferPosition()).toEqual [1, 12] + expect(cursor3.getBufferPosition()).toEqual [3, 7] it "does not blow up when there is no next word", -> editSession.setCursorBufferPosition [Infinity, Infinity] @@ -307,6 +312,17 @@ describe "EditSession", -> editSession.moveCursorToEndOfWord() expect(editSession.getCursorBufferPosition()).toEqual endPosition + it "treats lines with only whitespace as a word", -> + editSession.setCursorBufferPosition([9, 4]) + editSession.moveCursorToEndOfWord() + expect(editSession.getCursorBufferPosition()).toEqual [10, 0] + + it "works when the current line is blank", -> + editSession.setCursorBufferPosition([10, 0]) + editSession.moveCursorToEndOfWord() + expect(editSession.getCursorBufferPosition()).toEqual [11, 8] + + describe ".getCurrentParagraphBufferRange()", -> it "returns the buffer range of the current paragraph, delimited by blank lines or the beginning / end of the file", -> buffer.setText """ diff --git a/src/app/cursor.coffee b/src/app/cursor.coffee index cc4c13c30..46ff27d5b 100644 --- a/src/app/cursor.coffee +++ b/src/app/cursor.coffee @@ -142,6 +142,10 @@ class Cursor if position = @getEndOfCurrentWordBufferPosition() @setBufferPosition(position) + wordSeparatorsRegExp: -> + wordSeparators = config.get("editor.wordSeparators") + new RegExp("^[\t ]*$|[^\\s#{_.escapeRegExp(wordSeparators)}]+|[#{_.escapeRegExp(wordSeparators)}]+", "mg") + getBeginningOfCurrentWordBufferPosition: (options = {}) -> allowPrevious = options.allowPrevious ? true currentBufferPosition = @getBufferPosition() @@ -150,12 +154,10 @@ class Cursor beginningOfWordPosition = currentBufferPosition - wordSeparators = config.get("editor.wordSeparators") - wordSeparatorsRegex = new RegExp("^[\t ]*\n|[^\\s#{_.escapeRegExp(wordSeparators)}]+|[#{_.escapeRegExp(wordSeparators)}]+", "m") - @editSession.backwardsScanInRange (options.wordRegex ? wordSeparatorsRegex), previousLinesRange, (match, matchRange, { stop }) => + @editSession.backwardsScanInRange (options.wordRegex ? @wordSeparatorsRegExp()), previousLinesRange, (match, matchRange, { stop }) => if matchRange.end.isGreaterThanOrEqual(currentBufferPosition) or allowPrevious beginningOfWordPosition = matchRange.start - stop() + stop() unless beginningOfWordPosition.isEqual(currentBufferPosition) beginningOfWordPosition @@ -165,8 +167,11 @@ class Cursor range = [currentBufferPosition, @editSession.getEofBufferPosition()] endOfWordPosition = null - @editSession.scanInRange (options.wordRegex ? config.get("editor.wordRegex")), range, (match, matchRange, { stop }) => + @editSession.scanInRange (options.wordRegex ? @wordSeparatorsRegExp()), + range, (match, matchRange, { stop }) => endOfWordPosition = matchRange.end + return if endOfWordPosition.isEqual(currentBufferPosition) + if not allowNext and matchRange.start.isGreaterThan(currentBufferPosition) endOfWordPosition = currentBufferPosition stop() From 8973a66cfe6d34cf6407c7a353464be499d6e523 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Tue, 29 Jan 2013 16:33:06 -0800 Subject: [PATCH 04/13] selection.selectWord will consider whitespace a word --- src/app/cursor.coffee | 5 +++++ src/app/selection.coffee | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/app/cursor.coffee b/src/app/cursor.coffee index 46ff27d5b..3f39bb572 100644 --- a/src/app/cursor.coffee +++ b/src/app/cursor.coffee @@ -58,6 +58,11 @@ class Cursor isLastCursor: -> this == @editSession.getCursor() + isSurroundedByWhitespace: -> + {row, column} = @getBufferPosition() + range = [[row, column + 1], [row, Math.max(0, column - 1)]] + /^\s+$/.test @editSession.getTextInBufferRange(range) + autoscrolled: -> @needsAutoscroll = false diff --git a/src/app/selection.coffee b/src/app/selection.coffee index 8123d1157..abc702103 100644 --- a/src/app/selection.coffee +++ b/src/app/selection.coffee @@ -96,7 +96,10 @@ class Selection @screenRangeChanged() selectWord: -> - @setBufferRange(@cursor.getCurrentWordBufferRange()) + options = {} + options.wordRegex = /[\t ]*/ if @cursor.isSurroundedByWhitespace() + + @setBufferRange(@cursor.getCurrentWordBufferRange(options)) @wordwise = true @initialScreenRange = @getScreenRange() From 46aefc75abf6205051519e02e0ee78695e763d27 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Tue, 29 Jan 2013 16:45:24 -0800 Subject: [PATCH 05/13] Make EditSession specs match vim style word behavior --- spec/app/edit-session-spec.coffee | 75 ++++++++++++++++--------------- 1 file changed, 40 insertions(+), 35 deletions(-) diff --git a/spec/app/edit-session-spec.coffee b/spec/app/edit-session-spec.coffee index a6c67536f..327f6ab76 100644 --- a/spec/app/edit-session-spec.coffee +++ b/spec/app/edit-session-spec.coffee @@ -266,7 +266,7 @@ describe "EditSession", -> editSession.moveCursorToFirstCharacterOfLine() expect(editSession.getCursorBufferPosition()).toEqual [10, 0] - fdescribe ".moveCursorToBeginningOfWord()", -> + describe ".moveCursorToBeginningOfWord()", -> it "moves the cursor to the beginning of the word", -> editSession.setCursorBufferPosition [0, 8] editSession.addCursorAtBufferPosition [1, 12] @@ -293,7 +293,7 @@ describe "EditSession", -> editSession.moveCursorToBeginningOfWord() expect(editSession.getCursorBufferPosition()).toEqual [9, 2] - fdescribe ".moveCursorToEndOfWord()", -> + describe ".moveCursorToEndOfWord()", -> it "moves the cursor to the end of the word", -> editSession.setCursorBufferPosition [0, 6] editSession.addCursorAtBufferPosition [1, 10] @@ -534,13 +534,13 @@ describe "EditSession", -> expect(editSession.getCursors().length).toBe 2 [cursor1, cursor2] = editSession.getCursors() expect(cursor1.getBufferPosition()).toEqual [0,4] - expect(cursor2.getBufferPosition()).toEqual [3,44] + expect(cursor2.getBufferPosition()).toEqual [3,47] expect(editSession.getSelections().length).toBe 2 [selection1, selection2] = editSession.getSelections() expect(selection1.getBufferRange()).toEqual [[0,4], [0,13]] expect(selection1.isReversed()).toBeTruthy() - expect(selection2.getBufferRange()).toEqual [[3,44], [3,49]] + expect(selection2.getBufferRange()).toEqual [[3,47], [3,49]] expect(selection2.isReversed()).toBeTruthy() describe ".selectToEndOfWord()", -> @@ -553,40 +553,44 @@ describe "EditSession", -> expect(editSession.getCursors().length).toBe 2 [cursor1, cursor2] = editSession.getCursors() expect(cursor1.getBufferPosition()).toEqual [0,13] - expect(cursor2.getBufferPosition()).toEqual [3,51] + expect(cursor2.getBufferPosition()).toEqual [3,50] expect(editSession.getSelections().length).toBe 2 [selection1, selection2] = editSession.getSelections() expect(selection1.getBufferRange()).toEqual [[0,4], [0,13]] expect(selection1.isReversed()).toBeFalsy() - expect(selection2.getBufferRange()).toEqual [[3,48], [3,51]] + expect(selection2.getBufferRange()).toEqual [[3,48], [3,50]] expect(selection2.isReversed()).toBeFalsy() describe ".selectWord()", -> - describe "when the cursor is inside a word", -> - it "selects the entire word", -> - editSession.setCursorScreenPosition([0, 8]) - editSession.selectWord() - expect(editSession.getSelectedText()).toBe 'quicksort' + describe "when the cursor is inside a word", -> + it "selects the entire word", -> + editSession.setCursorScreenPosition([0, 8]) + editSession.selectWord() + expect(editSession.getSelectedText()).toBe 'quicksort' - describe "when the cursor is between two words", -> - it "selects both words", -> - editSession.setCursorScreenPosition([0, 4]) - editSession.selectWord() - expect(editSession.getSelectedText()).toBe ' quicksort' + describe "when the cursor is between two words", -> + it "selects the nearest word", -> + editSession.setCursorScreenPosition([0, 4]) + editSession.selectWord() + expect(editSession.getSelectedText()).toBe 'quicksort' - describe "when the cursor is inside a region of whitespace", -> - it "selects the whitespace region", -> - editSession.setCursorScreenPosition([5, 2]) - editSession.selectWord() - expect(editSession.getSelectedBufferRange()).toEqual [[5, 0], [5, 6]] + describe "when the cursor is inside a region of whitespace", -> + it "selects the whitespace region", -> + editSession.setCursorScreenPosition([5, 2]) + editSession.selectWord() + expect(editSession.getSelectedBufferRange()).toEqual [[5, 0], [5, 6]] - describe "when the cursor is at the end of the text", -> - it "select the previous word", -> - editSession.buffer.append 'word' - editSession.moveCursorToBottom() - editSession.selectWord() - expect(editSession.getSelectedBufferRange()).toEqual [[12, 2], [12, 6]] + editSession.setCursorScreenPosition([5, 0]) + editSession.selectWord() + expect(editSession.getSelectedBufferRange()).toEqual [[5, 0], [5, 6]] + + describe "when the cursor is at the end of the text", -> + it "select the previous word", -> + editSession.buffer.append 'word' + editSession.moveCursorToBottom() + editSession.selectWord() + expect(editSession.getSelectedBufferRange()).toEqual [[12, 2], [12, 6]] describe ".setSelectedBufferRanges(ranges)", -> it "clears existing selections and creates selections for each of the given ranges", -> @@ -1126,25 +1130,26 @@ describe "EditSession", -> describe "when no text is selected", -> it "deletes all text between the cursor and the beginning of the word", -> editSession.setCursorBufferPosition([1, 24]) - editSession.addCursorAtBufferPosition([2, 5]) + editSession.addCursorAtBufferPosition([3, 5]) [cursor1, cursor2] = editSession.getCursors() editSession.backspaceToBeginningOfWord() expect(buffer.lineForRow(1)).toBe ' var sort = function(ems) {' - expect(buffer.lineForRow(2)).toBe ' f (items.length <= 1) return items;' + expect(buffer.lineForRow(3)).toBe ' ar pivot = items.shift(), current, left = [], right = [];' expect(cursor1.getBufferPosition()).toEqual [1, 22] - expect(cursor2.getBufferPosition()).toEqual [2, 4] + expect(cursor2.getBufferPosition()).toEqual [3, 4] editSession.backspaceToBeginningOfWord() expect(buffer.lineForRow(1)).toBe ' var sort = functionems) {' - expect(buffer.lineForRow(2)).toBe 'f (items.length <= 1) return items;' + expect(buffer.lineForRow(2)).toBe ' if (items.length <= 1) return itemsar pivot = items.shift(), current, left = [], right = [];' expect(cursor1.getBufferPosition()).toEqual [1, 21] - expect(cursor2.getBufferPosition()).toEqual [2, 0] + expect(cursor2.getBufferPosition()).toEqual [2, 39] editSession.backspaceToBeginningOfWord() - expect(buffer.lineForRow(1)).toBe ' var sort = emsf (items.length <= 1) return items;' + expect(buffer.lineForRow(1)).toBe ' var sort = ems) {' + expect(buffer.lineForRow(2)).toBe ' if (items.length <= 1) return ar pivot = items.shift(), current, left = [], right = [];' expect(cursor1.getBufferPosition()).toEqual [1, 13] - expect(cursor2.getBufferPosition()).toEqual [1, 16] + expect(cursor2.getBufferPosition()).toEqual [2, 34] describe "when text is selected", -> it "deletes only selected text", -> @@ -1312,7 +1317,7 @@ describe "EditSession", -> expect(cursor2.getBufferPosition()).toEqual [2, 5] editSession.deleteToEndOfWord() - expect(buffer.lineForRow(1)).toBe ' var sort = function(it' + expect(buffer.lineForRow(1)).toBe ' var sort = function(it {' expect(buffer.lineForRow(2)).toBe ' iitems.length <= 1) return items;' expect(cursor1.getBufferPosition()).toEqual [1, 24] expect(cursor2.getBufferPosition()).toEqual [2, 5] From 167b9c28fa7355c715dc19fdd360e64787e9b369 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Tue, 29 Jan 2013 17:06:39 -0800 Subject: [PATCH 06/13] Rename wordSeparators to nonWordCharacters --- src/app/cursor.coffee | 10 +++++----- src/app/editor.coffee | 3 +-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/app/cursor.coffee b/src/app/cursor.coffee index 3f39bb572..aaffe22d6 100644 --- a/src/app/cursor.coffee +++ b/src/app/cursor.coffee @@ -147,9 +147,9 @@ class Cursor if position = @getEndOfCurrentWordBufferPosition() @setBufferPosition(position) - wordSeparatorsRegExp: -> - wordSeparators = config.get("editor.wordSeparators") - new RegExp("^[\t ]*$|[^\\s#{_.escapeRegExp(wordSeparators)}]+|[#{_.escapeRegExp(wordSeparators)}]+", "mg") + wordRegExp: -> + nonWordCharacters = config.get("editor.nonWordCharacters") + new RegExp("^[\t ]*$|[^\\s#{_.escapeRegExp(nonWordCharacters)}]+|[#{_.escapeRegExp(nonWordCharacters)}]+", "mg") getBeginningOfCurrentWordBufferPosition: (options = {}) -> allowPrevious = options.allowPrevious ? true @@ -159,7 +159,7 @@ class Cursor beginningOfWordPosition = currentBufferPosition - @editSession.backwardsScanInRange (options.wordRegex ? @wordSeparatorsRegExp()), previousLinesRange, (match, matchRange, { stop }) => + @editSession.backwardsScanInRange (options.wordRegex ? @wordRegExp()), previousLinesRange, (match, matchRange, { stop }) => if matchRange.end.isGreaterThanOrEqual(currentBufferPosition) or allowPrevious beginningOfWordPosition = matchRange.start stop() unless beginningOfWordPosition.isEqual(currentBufferPosition) @@ -172,7 +172,7 @@ class Cursor range = [currentBufferPosition, @editSession.getEofBufferPosition()] endOfWordPosition = null - @editSession.scanInRange (options.wordRegex ? @wordSeparatorsRegExp()), + @editSession.scanInRange (options.wordRegex ? @wordRegExp()), range, (match, matchRange, { stop }) => endOfWordPosition = matchRange.end return if endOfWordPosition.isEqual(currentBufferPosition) diff --git a/src/app/editor.coffee b/src/app/editor.coffee index affeefc68..bdd25ba67 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -19,8 +19,7 @@ class Editor extends View autosave: false autoIndent: true autoIndentOnPaste: false - wordRegex: /(\w+)|([^\w\n]+)/g - wordSeparators: "./\()\"’-:,.;<>~!@#$%^&*|+=[]{}`~?" + nonWordCharacters: "./\()\"’-:,.;<>~!@#$%^&*|+=[]{}`~?" @content: (params) -> @div class: @classes(params), tabindex: -1, => From c71f58a65231c3622ee7e5a1ea8529e35901efb2 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Tue, 29 Jan 2013 17:08:07 -0800 Subject: [PATCH 07/13] :lipstick: --- src/app/cursor.coffee | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/app/cursor.coffee b/src/app/cursor.coffee index aaffe22d6..c3e0a0591 100644 --- a/src/app/cursor.coffee +++ b/src/app/cursor.coffee @@ -55,6 +55,10 @@ class Cursor isVisible: -> @visible + wordRegExp: -> + nonWordCharacters = config.get("editor.nonWordCharacters") + new RegExp("^[\t ]*$|[^\\s#{_.escapeRegExp(nonWordCharacters)}]+|[#{_.escapeRegExp(nonWordCharacters)}]+", "mg") + isLastCursor: -> this == @editSession.getCursor() @@ -147,10 +151,6 @@ class Cursor if position = @getEndOfCurrentWordBufferPosition() @setBufferPosition(position) - wordRegExp: -> - nonWordCharacters = config.get("editor.nonWordCharacters") - new RegExp("^[\t ]*$|[^\\s#{_.escapeRegExp(nonWordCharacters)}]+|[#{_.escapeRegExp(nonWordCharacters)}]+", "mg") - getBeginningOfCurrentWordBufferPosition: (options = {}) -> allowPrevious = options.allowPrevious ? true currentBufferPosition = @getBufferPosition() From c32836ad2c1b9e4e3e7b8f318aaa15d535de28e4 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Tue, 29 Jan 2013 17:10:27 -0800 Subject: [PATCH 08/13] _ and - both considered non word characters. Fixes #82 Maybe @defunkt wanted the reverse though (consider _ and - word characters)? Either way, it's a config option you can change now. --- src/app/editor.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/editor.coffee b/src/app/editor.coffee index bdd25ba67..9a6710d8e 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -19,7 +19,7 @@ class Editor extends View autosave: false autoIndent: true autoIndentOnPaste: false - nonWordCharacters: "./\()\"’-:,.;<>~!@#$%^&*|+=[]{}`~?" + nonWordCharacters: "./\()\"’-_:,.;<>~!@#$%^&*|+=[]{}`~?" @content: (params) -> @div class: @classes(params), tabindex: -1, => From a34b9296e9c38da457f95245fea450caa6eb1444 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Tue, 29 Jan 2013 17:14:10 -0800 Subject: [PATCH 09/13] Escape \ in editor.nonWordCharachters --- src/app/editor.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/editor.coffee b/src/app/editor.coffee index 9a6710d8e..7d4ee0382 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -19,7 +19,7 @@ class Editor extends View autosave: false autoIndent: true autoIndentOnPaste: false - nonWordCharacters: "./\()\"’-_:,.;<>~!@#$%^&*|+=[]{}`~?" + nonWordCharacters: "./\\()\"’-_:,.;<>~!@#$%^&*|+=[]{}`~?" @content: (params) -> @div class: @classes(params), tabindex: -1, => From 1a8986aae2f5d0035252e4761879ee76b6bd1913 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Wed, 30 Jan 2013 08:02:19 -0800 Subject: [PATCH 10/13] Fix start/end for range --- src/app/cursor.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/cursor.coffee b/src/app/cursor.coffee index c3e0a0591..bf6e058ae 100644 --- a/src/app/cursor.coffee +++ b/src/app/cursor.coffee @@ -64,7 +64,7 @@ class Cursor isSurroundedByWhitespace: -> {row, column} = @getBufferPosition() - range = [[row, column + 1], [row, Math.max(0, column - 1)]] + range = [[row, Math.min(0, column - 1)], [row, Math.max(0, column + 1)]] /^\s+$/.test @editSession.getTextInBufferRange(range) autoscrolled: -> From 086c7ef98712ae824f3296a5192edf95d1ac7ace Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Wed, 30 Jan 2013 08:15:28 -0800 Subject: [PATCH 11/13] multiline regex not needed --- src/app/cursor.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/cursor.coffee b/src/app/cursor.coffee index bf6e058ae..04d13ee37 100644 --- a/src/app/cursor.coffee +++ b/src/app/cursor.coffee @@ -57,7 +57,7 @@ class Cursor wordRegExp: -> nonWordCharacters = config.get("editor.nonWordCharacters") - new RegExp("^[\t ]*$|[^\\s#{_.escapeRegExp(nonWordCharacters)}]+|[#{_.escapeRegExp(nonWordCharacters)}]+", "mg") + new RegExp("^[\t ]*$|[^\\s#{_.escapeRegExp(nonWordCharacters)}]+|[#{_.escapeRegExp(nonWordCharacters)}]+", "g") isLastCursor: -> this == @editSession.getCursor() From f698d7e9dcff5c9aebef3064d7d9236ccdcd3c17 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Wed, 30 Jan 2013 08:20:11 -0800 Subject: [PATCH 12/13] :lipstick: --- src/app/cursor.coffee | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/app/cursor.coffee b/src/app/cursor.coffee index 04d13ee37..659e91e43 100644 --- a/src/app/cursor.coffee +++ b/src/app/cursor.coffee @@ -155,16 +155,16 @@ class Cursor allowPrevious = options.allowPrevious ? true currentBufferPosition = @getBufferPosition() previousNonBlankRow = @editSession.buffer.previousNonBlankRow(currentBufferPosition.row) - previousLinesRange = [[previousNonBlankRow, 0], currentBufferPosition] + range = [[previousNonBlankRow, 0], currentBufferPosition] - beginningOfWordPosition = currentBufferPosition - - @editSession.backwardsScanInRange (options.wordRegex ? @wordRegExp()), previousLinesRange, (match, matchRange, { stop }) => + beginningOfWordPosition = null + @editSession.backwardsScanInRange (options.wordRegex ? @wordRegExp()), range, (match, matchRange, { stop }) => if matchRange.end.isGreaterThanOrEqual(currentBufferPosition) or allowPrevious beginningOfWordPosition = matchRange.start - stop() unless beginningOfWordPosition.isEqual(currentBufferPosition) + if not beginningOfWordPosition?.isEqual(currentBufferPosition) + stop() - beginningOfWordPosition + beginningOfWordPosition or currentBufferPosition getEndOfCurrentWordBufferPosition: (options = {}) -> allowNext = options.allowNext ? true @@ -172,14 +172,13 @@ class Cursor range = [currentBufferPosition, @editSession.getEofBufferPosition()] endOfWordPosition = null - @editSession.scanInRange (options.wordRegex ? @wordRegExp()), - range, (match, matchRange, { stop }) => + @editSession.scanInRange (options.wordRegex ? @wordRegExp()), range, (match, matchRange, { stop }) => endOfWordPosition = matchRange.end - return if endOfWordPosition.isEqual(currentBufferPosition) - - if not allowNext and matchRange.start.isGreaterThan(currentBufferPosition) + if matchRange.start.isGreaterThan(currentBufferPosition) and not allowNext endOfWordPosition = currentBufferPosition - stop() + if not endOfWordPosition.isEqual(currentBufferPosition) + stop() + endOfWordPosition or currentBufferPosition getCurrentWordBufferRange: (options={}) -> From 97fa9d522a05b00aa3299196015859af10ec9626 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Wed, 30 Jan 2013 08:39:32 -0800 Subject: [PATCH 13/13] end/beginning word implementations are now more similar --- spec/app/edit-session-spec.coffee | 7 ++++++- src/app/cursor.coffee | 7 +++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/spec/app/edit-session-spec.coffee b/spec/app/edit-session-spec.coffee index 327f6ab76..c77ddd15c 100644 --- a/spec/app/edit-session-spec.coffee +++ b/spec/app/edit-session-spec.coffee @@ -570,11 +570,16 @@ describe "EditSession", -> expect(editSession.getSelectedText()).toBe 'quicksort' describe "when the cursor is between two words", -> - it "selects the nearest word", -> + it "selects the word the cursor is on", -> editSession.setCursorScreenPosition([0, 4]) editSession.selectWord() expect(editSession.getSelectedText()).toBe 'quicksort' + editSession.setCursorScreenPosition([0, 3]) + editSession.selectWord() + expect(editSession.getSelectedText()).toBe 'var' + + describe "when the cursor is inside a region of whitespace", -> it "selects the whitespace region", -> editSession.setCursorScreenPosition([5, 2]) diff --git a/src/app/cursor.coffee b/src/app/cursor.coffee index 659e91e43..8ac44739e 100644 --- a/src/app/cursor.coffee +++ b/src/app/cursor.coffee @@ -173,10 +173,9 @@ class Cursor endOfWordPosition = null @editSession.scanInRange (options.wordRegex ? @wordRegExp()), range, (match, matchRange, { stop }) => - endOfWordPosition = matchRange.end - if matchRange.start.isGreaterThan(currentBufferPosition) and not allowNext - endOfWordPosition = currentBufferPosition - if not endOfWordPosition.isEqual(currentBufferPosition) + if matchRange.start.isLessThanOrEqual(currentBufferPosition) or allowNext + endOfWordPosition = matchRange.end + if not endOfWordPosition?.isEqual(currentBufferPosition) stop() endOfWordPosition or currentBufferPosition