From 8c63cd7ff50c5df6fc3c445bfc433120e0b9e3de Mon Sep 17 00:00:00 2001 From: Julian Viereck Date: Sun, 24 Apr 2011 23:59:59 +0200 Subject: [PATCH] Get move(Word)Right/left working with folds --- lib/ace/edit_session.js | 84 +++++++++++++++++++++++++++++++++++++++++ lib/ace/selection.js | 47 ++++++++++++++++++----- 2 files changed, 121 insertions(+), 10 deletions(-) diff --git a/lib/ace/edit_session.js b/lib/ace/edit_session.js index 92faf946..984e0163 100644 --- a/lib/ace/edit_session.js +++ b/lib/ace/edit_session.js @@ -1502,8 +1502,92 @@ var EditSession = function(text, mode) { } callback(null, endRow, endColumn, lastEnd, isNewRow); } + + this.getStringAt = function(session, row, column, trim) { + var fold, lastFold, cmp, str; + lastFold = { + end: { column: 0 } + }; + for (var i = 0; i < this.folds.length; i++) { + fold = this.folds[i]; + cmp = fold.compare(row, column); + if (cmp == -1) { + str = session.getLine(fold.start.row). + substring(lastFold.end.column, fold.start.column); + break; + } else if (cmp == 0) { + return null; + } + lastFold = fold; + } + if (!str) { + str = session.getLine(fold.start.row). + substring(lastFold.end.column); + } + if (trim == -1) { + return str.substring(0, column - lastFold.end.column); + } else if (trim == 1) { + return str.substring(column - lastFold.end.column) + } else { + return str; + } + } }).call(FoldLine.prototype); + this.getFoldAt = function(row, column, side) { + var foldLine = this.getFoldLine(row); + if (foldLine) { + var folds = foldLine.folds, + fold; + + for (var i = 0; i < folds.length; i++) { + fold = folds[i]; + if (fold.range.contains(row, column)) { + if (side == -1) { + if (fold.start.row != row || fold.start.column != column) { + return fold; + } + } else if (side == 1) { + if (fold.end.row != row || fold.end.column != column) { + return fold; + } + } else if (side == 0) { + return fold; + } + return null; + } + } + } else { + return null; + } + } + + /** + * Returns the string between folds at the given position. + * E.g. + * foob|arwolrd -> "bar" + * foobarwol|rd -> "world" + * foobarwolrd -> + * + * where | means the position of row/column + * + * The trim option determs if the return string should be trimed according + * to the "side" passed with the trim value: + * + * E.g. + * foob|arwolrd -trim=-1> "b" + * foobarwol|rd -trim=+1> "rld" + * fo|obarwolrd -trim=00> "foo" + */ + this.getFoldStringAt = function(row, column, trim) { + var foldLine = this.getFoldLine(row); + if (!foldLine) { + return null; + } else { + return foldLine.getStringAt(this, row, column, trim); + } + } + this.getFoldLine = function(docRow, startFoldLine) { var foldData = this.$foldData; var i = Math.max(foldData.indexOf(startFoldLine), 0); diff --git a/lib/ace/selection.js b/lib/ace/selection.js index 1be40c41..6a5bd7b8 100644 --- a/lib/ace/selection.js +++ b/lib/ace/selection.js @@ -262,8 +262,12 @@ var Selection = function(session) { }; this.moveCursorLeft = function() { - var cursor = this.selectionLead.getPosition(); - if (cursor.column == 0) { + var cursor = this.selectionLead.getPosition(), + fold; + + if (fold = this.session.getFoldAt(cursor.row, cursor.column, -1)) { + this.moveCursorTo(fold.start.row, fold.start.column); + } else if (cursor.column == 0) { // cursor is a line (start if (cursor.row > 0) { this.moveCursorTo(cursor.row - 1, this.doc.getLine(cursor.row - 1).length); @@ -279,7 +283,11 @@ var Selection = function(session) { }; this.moveCursorRight = function() { - if (this.selectionLead.column == this.doc.getLine(this.selectionLead.row).length) { + var cursor = this.selectionLead.getPosition(), + fold; + if (fold = this.session.getFoldAt(cursor.row, cursor.column, 1)) { + this.moveCursorTo(fold.end.row, fold.end.column); + } else if (this.selectionLead.column == this.doc.getLine(this.selectionLead.row).length) { if (this.selectionLead.row < this.doc.getLength() - 1) { this.moveCursorTo(this.selectionLead.row + 1, 0); } @@ -339,7 +347,11 @@ var Selection = function(session) { this.session.nonTokenRe.lastIndex = 0; this.session.tokenRe.lastIndex = 0; - if (column == line.length) { + var fold; + if (fold = this.session.getFoldAt(row, column, 1)) { + this.moveCursorTo(fold.end.row, fold.end.column); + return; + } else if (column == line.length) { this.moveCursorRight(); return; } @@ -358,18 +370,33 @@ var Selection = function(session) { this.moveCursorWordLeft = function() { var row = this.selectionLead.row; var column = this.selectionLead.column; - var line = this.doc.getLine(row); - var leftOfCursor = lang.stringReverse(line.substring(0, column)); - var match; - this.session.nonTokenRe.lastIndex = 0; - this.session.tokenRe.lastIndex = 0; + 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; } - else if (match = this.session.nonTokenRe.exec(leftOfCursor)) { + + var str = null; + var foldLine = this.session.getFoldLine(row); + if (foldLine) { + str = foldLine.getStringAt(this.session, 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; + + if (match = this.session.nonTokenRe.exec(leftOfCursor)) { column -= this.session.nonTokenRe.lastIndex; this.session.nonTokenRe.lastIndex = 0; }