diff --git a/lib/ace/selection.js b/lib/ace/selection.js index 4f0474d9..88ba70ef 100644 --- a/lib/ace/selection.js +++ b/lib/ace/selection.js @@ -385,19 +385,31 @@ var Selection = function(session) { this.session.nonTokenRe.lastIndex = 0; this.session.tokenRe.lastIndex = 0; - var fold; - if (fold = this.session.getFoldAt(row, column, 1)) { + // skip folds + var fold = this.session.getFoldAt(row, column, 1); + if (fold) { this.moveCursorTo(fold.end.row, fold.end.column); return; - } else if (column == line.length) { - this.moveCursorRight(); - return; } - else if (match = this.session.nonTokenRe.exec(rightOfCursor)) { + + // first skip space + if (match = this.session.nonTokenRe.exec(rightOfCursor)) { column += this.session.nonTokenRe.lastIndex; this.session.nonTokenRe.lastIndex = 0; + rightOfCursor = line.substring(column); } - else if (match = this.session.tokenRe.exec(rightOfCursor)) { + + // if at line end proceed with next line + if (column >= line.length) { + this.moveCursorTo(row, line.length); + this.moveCursorRight(); + if (row < this.doc.getLength() - 1) + this.moveCursorWordRight(); + return; + } + + // advance to the end of the next token + if (match = this.session.tokenRe.exec(rightOfCursor)) { column += this.session.tokenRe.lastIndex; this.session.tokenRe.lastIndex = 0; } @@ -409,32 +421,41 @@ var Selection = function(session) { var row = this.selectionLead.row; var column = this.selectionLead.column; + // skip folds var fold; if (fold = this.session.getFoldAt(row, column, -1)) { this.moveCursorTo(fold.start.row, fold.start.column); return; } - if (column == 0) { - this.moveCursorLeft(); - return; - } - var str = this.session.getFoldStringAt(row, column, -1); if (str == null) { str = this.doc.getLine(row).substring(0, column) } + var leftOfCursor = lang.stringReverse(str); - var match; this.session.nonTokenRe.lastIndex = 0; this.session.tokenRe.lastIndex = 0; - + + // skip whitespace if (match = this.session.nonTokenRe.exec(leftOfCursor)) { column -= this.session.nonTokenRe.lastIndex; + leftOfCursor = leftOfCursor.slice(this.session.nonTokenRe.lastIndex); this.session.nonTokenRe.lastIndex = 0; } - else if (match = this.session.tokenRe.exec(leftOfCursor)) { + + // if at begin of the line proceed in line above + if (column <= 0) { + this.moveCursorTo(row, 0); + this.moveCursorLeft(); + if (row > 0) + this.moveCursorWordLeft(); + return; + } + + // move to the begin of the word + if (match = this.session.tokenRe.exec(leftOfCursor)) { column -= this.session.tokenRe.lastIndex; this.session.tokenRe.lastIndex = 0; } diff --git a/lib/ace/selection_test.js b/lib/ace/selection_test.js index f7d036b3..1fe6b086 100644 --- a/lib/ace/selection_test.js +++ b/lib/ace/selection_test.js @@ -120,6 +120,9 @@ module.exports = { // wrap line selection.moveCursorWordRight(); assert.position(selection.getCursor(), 2, 4); + + selection.moveCursorWordRight(); + assert.position(selection.getCursor(), 2, 4); }, "test: select word right if cursor in word" : function() { @@ -145,36 +148,24 @@ module.exports = { selection.moveCursorLineEnd(); assert.position(selection.getCursor(), 1, 23); - selection.moveCursorWordLeft(); - assert.position(selection.getCursor(), 1, 22); - selection.moveCursorWordLeft(); assert.position(selection.getCursor(), 1, 20); - selection.moveCursorWordLeft(); - assert.position(selection.getCursor(), 1, 18); - selection.moveCursorWordLeft(); assert.position(selection.getCursor(), 1, 15); - selection.moveCursorWordLeft(); - assert.position(selection.getCursor(), 1, 13); - selection.moveCursorWordLeft(); assert.position(selection.getCursor(), 1, 6); - selection.moveCursorWordLeft(); - assert.position(selection.getCursor(), 1, 5); - selection.moveCursorWordLeft(); assert.position(selection.getCursor(), 1, 1); - selection.moveCursorWordLeft(); - assert.position(selection.getCursor(), 1, 0); - // wrap line selection.moveCursorWordLeft(); - assert.position(selection.getCursor(), 0, 2); + assert.position(selection.getCursor(), 0, 0); + + selection.moveCursorWordLeft(); + assert.position(selection.getCursor(), 0, 0); }, "test: moveCursor word left" : function() { @@ -186,7 +177,7 @@ module.exports = { assert.position(selection.getCursor(), 0, 5); selection.moveCursorWordLeft(); - assert.position(selection.getCursor(), 0, 4); + assert.position(selection.getCursor(), 0, 1); }, "test: select word left if cursor in word" : function() { @@ -310,15 +301,11 @@ module.exports = { assert.notOk(called); }, - "test: moveWordLeft should move past || and [": function() { + "test: moveWordright should move past || and [": function() { var session = new EditSession("||foo["); var selection = session.getSelection(); - // Move behind || - selection.moveCursorWordRight(); - assert.position(selection.getCursor(), 0, 2); - - // Move beind foo + // Move behind ||foo selection.moveCursorWordRight(); assert.position(selection.getCursor(), 0, 5); @@ -327,17 +314,13 @@ module.exports = { assert.position(selection.getCursor(), 0, 6); }, - "test: moveWordRight should move past || and [": function() { + "test: moveWordLeft should move past || and [": function() { var session = new EditSession("||foo["); var selection = session.getSelection(); selection.moveCursorTo(0, 6); - // Move behind [ - selection.moveCursorWordLeft(); - assert.position(selection.getCursor(), 0, 5); - - // Move beind foo + // Move behind [foo selection.moveCursorWordLeft(); assert.position(selection.getCursor(), 0, 2);