make foldAll faster
This commit is contained in:
parent
4e82a96353
commit
1b21841dba
4 changed files with 98 additions and 83 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue