From 44b8d656f2235e67c66b950f2981ca747e74ef54 Mon Sep 17 00:00:00 2001 From: Fabian Jakobs Date: Mon, 25 Jul 2011 12:00:19 +0200 Subject: [PATCH] make addFold arguments less flexible and do some cleanups in the folding code --- demo/demo.js | 8 +- lib/ace/edit_session/folding.js | 207 ++++++++++++++------------------ lib/ace/edit_session_test.js | 54 ++++----- 3 files changed, 118 insertions(+), 151 deletions(-) diff --git a/demo/demo.js b/demo/demo.js index a268f446..991140ea 100644 --- a/demo/demo.js +++ b/demo/demo.js @@ -657,11 +657,11 @@ exports.launch = function(env) { var fold = session.getFoldAt(range.start.row, range.start.column); var column; - if(fold) { + if (fold) { session.expandFold(fold); selection.setSelectionRange(fold.range) - } else if(br) { - if(range.compare(br.row,br.column) == 1) + } else if (br) { + if (range.compare(br.row, br.column) == 1) range.end = br; else range.start = br; @@ -686,7 +686,7 @@ exports.launch = function(env) { } else { addFold = true; } - if(addFold) { + if (addFold) { var placeHolder = session.getTextRange(range); if(placeHolder.length < 3) return; diff --git a/lib/ace/edit_session/folding.js b/lib/ace/edit_session/folding.js index b36d0d6e..48659958 100644 --- a/lib/ace/edit_session/folding.js +++ b/lib/ace/edit_session/folding.js @@ -50,25 +50,22 @@ function Folding() { */ 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 && fold.range.isEnd(row, column)) { - continue; - } else if (side == -1 && fold.range.isStart(row, column)) { - continue; - } - return fold; - } - } - } else { + if (!foldLine) return null; + + var folds = foldLine.folds; + for (var i = 0; i < folds.length; i++) { + var fold = folds[i]; + if (fold.range.contains(row, column)) { + if (side == 1 && fold.range.isEnd(row, column)) { + continue; + } else if (side == -1 && fold.range.isStart(row, column)) { + continue; + } + return fold; + } } - } + }; /** * Returns all folds in the given range. Note, that this will return folds @@ -76,33 +73,30 @@ function Folding() { */ this.getFoldsInRange = function(range) { range = range.clone(); - var start = range.start, - end = range.end; - var foldLines = this.$foldData, - folds, - fold; - var cmp, - foundFolds = []; + var start = range.start; + var end = range.end; + var foldLines = this.$foldData; + var foundFolds = []; start.column += 1; end.column -= 1; for (var i = 0; i < foldLines.length; i++) { - cmp = foldLines[i].range.compareRange(range); - // Range is before foldLine. No intersection. This means, - // there might be other foldLines that intersect. + var cmp = foldLines[i].range.compareRange(range); if (cmp == 2) { + // Range is before foldLine. No intersection. This means, + // there might be other foldLines that intersect. continue; - } else - // Range is after foldLine. There can't be any other foldLines then, - // so let's give up. - if (cmp == -2) { + } + else if (cmp == -2) { + // Range is after foldLine. There can't be any other foldLines then, + // so let's give up. break; } - folds = foldLines[i].folds; + var folds = foldLines[i].folds; for (var j = 0; j < folds.length; j++) { - fold = folds[j]; + var fold = folds[j]; cmp = fold.range.compareRange(range); if (cmp == -2) { break; @@ -138,46 +132,44 @@ function Folding() { */ this.getFoldStringAt = function(row, column, trim, foldLine) { var foldLine = foldLine || this.getFoldLine(row); - if (!foldLine) { + if (!foldLine) return null; - } else { - var fold, lastFold, cmp, str; - lastFold = { - end: { column: 0 } - }; - // TODO: Refactor to use getNextFoldTo function. - for (var i = 0; i < foldLine.folds.length; i++) { - fold = foldLine.folds[i]; - cmp = fold.range.compareEnd(row, column); - if (cmp == -1) { - str = this.getLine(fold.start.row). - substring(lastFold.end.column, fold.start.column); - break; - } else if (cmp == 0) { - return null; - } - lastFold = fold; + + var lastFold = { + end: { column: 0 } + }; + // TODO: Refactor to use getNextFoldTo function. + for (var i = 0; i < foldLine.folds.length; i++) { + var fold = foldLine.folds[i]; + var cmp = fold.range.compareEnd(row, column); + if (cmp == -1) { + var str = this + .getLine(fold.start.row) + .substring(lastFold.end.column, fold.start.column); + break; } - if (!str) { - str = this.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; + else if (cmp == 0) { + return null; } + lastFold = fold; } + if (!str) + str = this.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; } this.getFoldLine = function(docRow, startFoldLine) { var foldData = this.$foldData; var i = 0; - if(startFoldLine) + if (startFoldLine) i = foldData.indexOf(startFoldLine); - if(i == -1) + if (i == -1) i = 0; for (i; i < foldData.length; i++) { var foldLine = foldData[i]; @@ -194,9 +186,9 @@ function Folding() { this.getNextFold = function(docRow, startFoldLine) { var foldData = this.$foldData, ans; var i = 0; - if(startFoldLine) + if (startFoldLine) i = foldData.indexOf(startFoldLine); - if(i == -1) + if (i == -1) i = 0; for (i; i < foldData.length; i++) { var foldLine = foldData[i]; @@ -213,7 +205,7 @@ function Folding() { var foldLine = foldData[i], end = foldLine.end.row, start = foldLine.start.row; - if(end >= last) { + if (end >= last) { if(start < last) { if(start >= first) rowCount -= last-start; @@ -246,76 +238,55 @@ function Folding() { * The new created Fold object or an existing fold object in case the * passed in range fits an existing fold exactly. */ - this.addFold = function(placeholder, startRow, startColumn, endRow, endColumn) { - var range; + this.addFold = function(placeholder, range) { var foldData = this.$foldData; var foldRow = null; var foldLine; - var fold; - var argsFold; var folds; var added = false; - if (placeholder instanceof Fold) { - argsFold = placeholder; - startRow = argsFold.range; - placeholder = argsFold.placeholder; - } - - // Normalize parameters. - if (!(startRow instanceof Range)) { - range = new Range(startRow, startColumn, endRow, endColumn); - } else { - range = startRow; - startRow = range.start.row; - startColumn = range.start.column; - endRow = range.end.row; - endColumn = range.end.column; - } + if (placeholder instanceof Fold) + var fold = placeholder; + else + fold = new Fold(range, placeholder); + var startRow = fold.start.row; + var startColumn = fold.start.column; + var endRow = fold.end.row; + var endColumn = fold.end.column; + // --- Some checking --- - if (placeholder.length < 2) { + if (fold.placeholder.length < 2) throw "Placeholder has to be at least 2 characters"; - } - if (startRow == endRow && endColumn - startColumn < 2) { + if (startRow == endRow && endColumn - startColumn < 2) throw "The range has to be at least 2 characters width"; - } - fold = this.getFoldAt(startRow, startColumn, 1); - if (fold - && fold.range.isEnd(endRow, endColumn) - && fold.range.isStart(startRow, startColumn)) - { + var existingFold = this.getFoldAt(startRow, startColumn, 1); + if ( + existingFold + && existingFold.range.isEnd(endRow, endColumn) + && existingFold.range.isStart(startRow, startColumn) + ) { return fold; } - fold = this.getFoldAt(startRow, startColumn, 1); - if (fold && !fold.range.isStart(startRow, startColumn)) { + existingFold = this.getFoldAt(startRow, startColumn, 1); + if (existingFold && !existingFold.range.isStart(startRow, startColumn)) throw "A fold can't start inside of an already existing fold"; - } - fold = this.getFoldAt(endRow, endColumn, -1); - if (fold && !fold.range.isEnd(endRow, endColumn)) { + existingFold = this.getFoldAt(endRow, endColumn, -1); + if (existingFold && !existingFold.range.isEnd(endRow, endColumn)) throw "A fold can't end inside of an already existing fold"; - } - if (endRow >= this.doc.getLength()) { + if (endRow >= this.doc.getLength()) throw "End of fold is outside of the document."; - } - if (endColumn > this.getLine(endRow).length - || startColumn > this.getLine(startRow).length) - { + if (endColumn > this.getLine(endRow).length || startColumn > this.getLine(startRow).length) throw "End of fold is outside of the document."; - } - - // --- Start adding the fold --- - // Use the passed in fold or create a new one. - fold = argsFold || new Fold(range, placeholder); // Check if there are folds in the range we create the new fold for. - folds = this.getFoldsInRange(range); + folds = this.getFoldsInRange(fold.range); if (folds.length > 0) { // Remove the folds from fold data. this.removeFolds(folds); @@ -329,7 +300,8 @@ function Folding() { foldLine.addFold(fold); added = true; break; - } else if (startRow == foldLine.end.row) { + } + else if (startRow == foldLine.end.row) { foldLine.addFold(fold); added = true; if (!fold.sameRow) { @@ -342,18 +314,17 @@ function Folding() { } } break; - } else if (endRow <= foldLine.start.row) { + } + else if (endRow <= foldLine.start.row) { break; } } - if (!added) { + if (!added) foldLine = this.$addFoldLine(new FoldLine(this.$foldData, fold)); - } - if (this.$useWrapMode) { + if (this.$useWrapMode) this.$updateWrapData(foldLine.start.row, foldLine.start.row); - } // Notify that fold data has changed. this.$modified = true; diff --git a/lib/ace/edit_session_test.js b/lib/ace/edit_session_test.js index 808dad39..445dc746 100644 --- a/lib/ace/edit_session_test.js +++ b/lib/ace/edit_session_test.js @@ -768,45 +768,45 @@ module.exports = { // Adding a fold. The split position is inside of the fold. As placeholder // are not splitable, the split should be before the split. - session.addFold("woot", 0, 4, 0, 15); + session.addFold("woot", new Range(0, 4, 0, 15)); assertWrap([4], [8], [8]); // Remove the fold again which should reset the wrapData. removeFoldAssertWrap(0, 4, [8], [8], [8]); - session.addFold("woot", 0, 6, 0, 9); + session.addFold("woot", new Range(0, 6, 0, 9)); assertWrap([6, 13], [8], [8]); removeFoldAssertWrap(0, 6, [8], [8], [8]); // The fold fits into the wrap limit - no split expected. - session.addFold("woot", 0, 3, 0, 15); + session.addFold("woot", new Range(0, 3, 0, 15)); assertWrap([], [8], [8]); removeFoldAssertWrap(0, 4, [8], [8], [8]); // Fold after split position should be all fine. - session.addFold("woot", 0, 8, 0, 15); + session.addFold("woot", new Range(0, 8, 0, 15)); assertWrap([8], [8], [8]); removeFoldAssertWrap(0, 8, [8], [8], [8]); // Fold's placeholder is far too long for wrapSplit. - session.addFold("woot0123456789", 0, 8, 0, 15); + session.addFold("woot0123456789", new Range(0, 8, 0, 15)); assertWrap([8], [8], [8]); removeFoldAssertWrap(0, 8, [8], [8], [8]); // Fold's placeholder is far too long for wrapSplit // + content at the end of the line - session.addFold("woot0123456789", 0, 6, 0, 8); + session.addFold("woot0123456789", new Range(0, 6, 0, 8)); assertWrap([6, 20], [8], [8]); removeFoldAssertWrap(0, 8, [8], [8], [8]); - session.addFold("woot0123456789", 0, 6, 0, 8); - session.addFold("woot0123456789", 0, 8, 0, 10); + session.addFold("woot0123456789", new Range(0, 6, 0, 8)); + session.addFold("woot0123456789", new Range(0, 8, 0, 10)); assertWrap([6, 20, 34], [8], [8]); session.removeFold(session.getFoldAt(0, 7)); removeFoldAssertWrap(0, 8, [8], [8], [8]); - session.addFold("woot0123456789", 0, 7, 0, 9); - session.addFold("woot0123456789", 0, 13, 0, 15); + session.addFold("woot0123456789", new Range(0, 7, 0, 9)); + session.addFold("woot0123456789", new Range(0, 13, 0, 15)); assertWrap([7, 21, 25], [8], [8]); session.removeFold(session.getFoldAt(0, 7)); removeFoldAssertWrap(0, 14, [8], [8], [8]); @@ -815,15 +815,15 @@ module.exports = { // Add a fold over two lines. Note, that the wrapData[1] stays the // same. This is an implementation detail and expected behavior. - session.addFold("woot", 0, 8, 1, 15); + session.addFold("woot", new Range(0, 8, 1, 15)); assertWrap([8], [8 /* See comments */], [8]); removeFoldAssertWrap(0, 8, [8], [8], [8]); - session.addFold("woot", 0, 9, 1, 11); + session.addFold("woot", new Range(0, 9, 1, 11)); assertWrap([8, 14], [8 /* See comments */], [8]); removeFoldAssertWrap(0, 9, [8], [8], [8]); - session.addFold("woot", 0, 9, 1, 15); + session.addFold("woot", new Range(0, 9, 1, 15)); assertWrap([8], [8 /* See comments */], [8]); removeFoldAssertWrap(0, 9, [8], [8], [8]); @@ -834,14 +834,10 @@ module.exports = { var session = createFoldTestSession(); var fold; - function tryAddFold( - placeholder, - startRow, startColumn, endRow, endColumn, shouldFail) - { + function tryAddFold(placeholder, range, shouldFail) { var fail = false; try { - fold = session.addFold(placeholder, - startRow, startColumn, endRow, endColumn); + fold = session.addFold(placeholder, range); } catch (e) { fail = true; } @@ -850,19 +846,19 @@ module.exports = { } } - tryAddFold("foo", 0, 13, 0, 17, true); - tryAddFold("foo", 0, 14, 0, 18, true); - tryAddFold("foo", 0, 13, 0, 18, false); + tryAddFold("foo", new Range(0, 13, 0, 17), true); + tryAddFold("foo", new Range(0, 14, 0, 18), true); + tryAddFold("foo", new Range(0, 13, 0, 18), false); assert.equal(session.$foldData[0].folds.length, 1); - tryAddFold("f", 0, 13, 0, 18, true); - tryAddFold("foo", 0, 18, 0, 21, false); + tryAddFold("f", new Range(0, 13, 0, 18), true); + tryAddFold("foo", new Range(0, 18, 0, 21), false); assert.equal(session.$foldData[0].folds.length, 2); session.removeFold(fold); - tryAddFold("foo", 0, 18, 0, 22, true); - tryAddFold("foo", 0, 18, 0, 19, true); - tryAddFold("foo", 0, 22, 1, 10, true); + tryAddFold("foo", new Range(0, 18, 0, 22), true); + tryAddFold("foo", new Range(0, 18, 0, 19), true); + tryAddFold("foo", new Range(0, 22, 1, 10), true); }, "test add subfolds": function() { @@ -872,7 +868,7 @@ module.exports = { oldFold = foldData[0].folds[0]; - fold = session.addFold("fold0", 0, 10, 0, 21); + fold = session.addFold("fold0", new Range(0, 10, 0, 21)); assert.equal(foldData[0].folds.length, 1); assert.equal(fold.subFolds.length, 1); assert.equal(fold.subFolds[0], oldFold); @@ -882,7 +878,7 @@ module.exports = { assert.equal(foldData[0].folds[0], oldFold); assert.equal(fold.subFolds.length, 0); - fold = session.addFold("fold0", 0, 13, 2, 10); + fold = session.addFold("fold0", new Range(0, 13, 2, 10)); assert.equal(foldData.length, 1); assert.equal(fold.subFolds.length, 2); assert.equal(fold.subFolds[0], oldFold);