make foldAll faster

This commit is contained in:
nightwing 2013-02-25 23:33:40 +04:00
commit 1b21841dba
4 changed files with 98 additions and 83 deletions

View file

@ -31,9 +31,9 @@
define(function(require, exports, module) {
"use strict";
var config = require("./config");
var oop = require("./lib/oop");
var lang = require("./lib/lang");
var config = require("./config");
var EventEmitter = require("./lib/event_emitter").EventEmitter;
var Selection = require("./selection").Selection;
var TextMode = require("./mode/text").Mode;
@ -41,7 +41,6 @@ var Range = require("./range").Range;
var Document = require("./document").Document;
var BackgroundTokenizer = require("./background_tokenizer").BackgroundTokenizer;
var SearchHighlight = require("./search_highlight").SearchHighlight;
var config = require("./config");
/**
* Stores all the data about [[Editor `Editor`]] state providing easy way to change editors state.
@ -1377,8 +1376,8 @@ var EditSession = function(text, mode) {
};
this.$moveLines = function(firstRow, lastRow, dir) {
var firstRow = this.getRowFoldStart(firstRow);
var lastRow = this.getRowFoldEnd(lastRow);
firstRow = this.getRowFoldStart(firstRow);
lastRow = this.getRowFoldEnd(lastRow);
if (dir < 0) {
var row = this.getRowFoldStart(firstRow + dir);
if (row < 0) return 0;

View file

@ -260,9 +260,10 @@ function Folding() {
if (placeholder instanceof Fold)
fold = placeholder;
else
else {
fold = new Fold(range, placeholder);
fold.collapseChildren = range.collapseChildren;
}
this.$clipRangeToDocument(fold.range);
var startRow = fold.start.row;
@ -303,8 +304,7 @@ 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) {
@ -317,8 +317,7 @@ function Folding() {
}
}
break;
}
else if (endRow <= foldLine.start.row) {
} else if (endRow <= foldLine.start.row) {
break;
}
}
@ -411,11 +410,14 @@ function Folding() {
};
this.expandFold = function(fold) {
this.removeFold(fold);
this.removeFold(fold);
fold.subFolds.forEach(function(subFold) {
fold.restoreRange(subFold);
this.addFold(subFold);
}, this);
if (fold.collapseChildren > 0) {
this.foldAll(fold.start.row+1, fold.end.row, fold.collapseChildren-1);
}
fold.subFolds = [];
};
@ -427,9 +429,10 @@ function Folding() {
this.unfold = function(location, expandInner) {
var range, folds;
if (location == null)
if (location == null) {
range = new Range(0, 0, this.getLength(), 0);
else if (typeof location == "number")
expandInner = true;
} else if (typeof location == "number")
range = new Range(location, 0, location, this.getLine(location).length);
else if ("row" in location)
range = Range.fromPoints(location, location);
@ -483,20 +486,20 @@ function Folding() {
var textLine = "";
foldLine.walk(function(placeholder, row, column, lastColumn) {
if (row < startRow) {
if (row < startRow)
return;
} else if (row == startRow) {
if (column < startColumn) {
if (row == startRow) {
if (column < startColumn)
return;
}
lastColumn = Math.max(startColumn, lastColumn);
}
if (placeholder != null) {
textLine += placeholder;
} else {
textLine += doc.getLine(row).substring(lastColumn, column);
}
}.bind(this), endRow, endColumn);
}, endRow, endColumn);
return textLine;
};
@ -538,26 +541,22 @@ function Folding() {
if (fold) {
this.expandFold(fold);
return;
}
else if (bracketPos = this.findMatchingBracket(cursor)) {
} else if (bracketPos = this.findMatchingBracket(cursor)) {
if (range.comparePoint(bracketPos) == 1) {
range.end = bracketPos;
}
else {
} else {
range.start = bracketPos;
range.start.column++;
range.end.column--;
}
}
else if (bracketPos = this.findMatchingBracket({row: cursor.row, column: cursor.column + 1})) {
} else if (bracketPos = this.findMatchingBracket({row: cursor.row, column: cursor.column + 1})) {
if (range.comparePoint(bracketPos) == 1)
range.end = bracketPos;
else
range.start = bracketPos;
range.start.column++;
}
else {
} else {
range = this.getCommentFoldRange(cursor.row, cursor.column) || range;
}
} else {
@ -565,8 +564,7 @@ function Folding() {
if (tryToUnfold && folds.length) {
this.expandFolds(folds);
return;
}
else if (folds.length == 1 ) {
} else if (folds.length == 1 ) {
fold = folds[0];
}
}
@ -622,7 +620,9 @@ function Folding() {
}
};
this.foldAll = function(startRow, endRow) {
this.foldAll = function(startRow, endRow, depth) {
if (depth == undefined)
depth = 100000; // JSON.stringify doesn't hanle Infinity
var foldWidgets = this.foldWidgets;
endRow = endRow || this.getLength();
for (var row = startRow || 0; row < endRow; row++) {
@ -633,13 +633,16 @@ function Folding() {
var range = this.getFoldWidgetRange(row);
// sometimes range can be incompatible with existing fold
// wouldn't it be better for addFold to return null istead of throwing?
// TODO change addFold to return null istead of throwing
if (range && range.end.row <= endRow) try {
this.addFold("...", range);
var fold = this.addFold("...", range);
fold.collapseChildren = depth;
} catch(e) {}
row = range.end.row;
}
};
// structured folding
this.$foldStyles = {
"manual": 1,
"markbegin": 1,
@ -664,7 +667,6 @@ function Folding() {
this.$setFolding(mode);
};
// structured folding
this.$setFolding = function(foldMode) {
if (this.$foldMode == foldMode)
return;
@ -688,21 +690,46 @@ function Folding() {
};
this.getParentFoldRangeData = function (row, ignoreCurrent) {
var fw = this.foldWidgets;
if (!fw || (ignoreCurrent && fw[row]))
return {};
var i = row - 1, firstRange;
while (i >= 0) {
var c = fw[i];
if (c == null)
c = fw[i] = this.getFoldWidget(i);
if (c == "start") {
var range = this.getFoldWidgetRange(i);
if (!firstRange)
firstRange = range;
if (range && range.end.row >= row)
break;
}
i--;
}
return {
range: i !== -1 && range,
firstRange: firstRange
};
}
this.onFoldWidgetClick = function(row, e) {
e = e.domEvent;
var type = this.getFoldWidget(row);
var line = this.getLine(row);
var onlySubfolds = e.shiftKey;
var addSubfolds = onlySubfolds || e.ctrlKey || e.altKey || e.metaKey;
var fold;
e = e.domEvent;
var children = e.shiftKey;
var all = e.ctrlKey || e.metaKey;
var siblings = e.altKey;
if (type == "end")
fold = this.getFoldAt(row, 0, -1);
else
fold = this.getFoldAt(row, line.length, 1);
var dir = type === "end" ? -1 : 1;
var fold = this.getFoldAt(row, dir === -1 ? 0 : line.length, dir);
if (fold) {
if (addSubfolds)
if (children || all)
this.removeFold(fold);
else
this.expandFold(fold);
@ -710,28 +737,35 @@ function Folding() {
}
var range = this.getFoldWidgetRange(row);
if (range) {
// sometimes singleline folds can be missed by the code above
if (!range.isMultiLine()) {
fold = this.getFoldAt(range.start.row, range.start.column, 1);
if (fold && range.isEqual(fold.range)) {
this.removeFold(fold);
return;
}
// sometimes singleline folds can be missed by the code above
if (range && !range.isMultiLine()) {
fold = this.getFoldAt(range.start.row, range.start.column, 1);
if (fold && range.isEqual(fold.range)) {
this.removeFold(fold);
return;
}
if (!onlySubfolds)
this.addFold("...", range);
if (addSubfolds)
this.foldAll(range.start.row + 1, range.end.row);
} else {
if (addSubfolds)
this.foldAll(row + 1, this.getLength());
(e.target || e.srcElement).className += " ace_invalid"
}
if (siblings) {
var data = this.getParentFoldRangeData(row);
if (data.range) {
var startRow = data.range.start.row + 1;
var endRow = data.range.end.row;
}
this.foldAll(startRow, endRow, all ? 10000 : 0);
} else if (children) {
var endRow = range ? range.end.row : this.getLength();
this.foldAll(row + 1, range.end.row, all ? 10000 : 0);
} else if (range) {
if (all)
range.collapseChildren = 10000;
this.addFold("...", range);
}
if (!range)
(e.target || e.srcElement).className += " ace_invalid"
};
this.updateFoldWidgets = function(e) {
var delta = e.data;
var range = delta.range;

View file

@ -69,27 +69,8 @@ function FoldHandler(editor) {
if (gutterRegion == "foldWidgets") {
var row = e.getDocumentPosition().row;
var session = editor.session;
var fw = session.foldWidgets;
if (!fw || fw[row])
return;
var i = row - 1, firstRange;
while (i >= 0) {
var c = fw[i];
if (c == null)
c = fw[i] = session.getFoldWidget(i);
if (c == "start") {
var range = session.getFoldWidgetRange(i);
if (!firstRange)
firstRange = range;
if (range && range.end.row >= row)
break;
}
i--;
}
if (i == -1)
range = firstRange;
var data = session.getParentFoldRangeData(row, true);
var range = data.range || data.firstRange;
if (range) {
var row = range.start.row;

View file

@ -85,11 +85,12 @@ var TokenIterator = function(session, initialRow, initialColumn) {
* @returns {String}
**/
this.stepForward = function() {
var rowCount = this.$session.getLength();
this.$tokenIndex += 1;
var rowCount;
while (this.$tokenIndex >= this.$rowTokens.length) {
this.$row += 1;
if (!rowCount)
rowCount = this.$session.getLength();
if (this.$row >= rowCount) {
this.$row = rowCount - 1;
return null;