Checkpointing fold-wrap-data work. Mostly done
This commit is contained in:
parent
ff72467c10
commit
46a877e563
2 changed files with 193 additions and 67 deletions
|
|
@ -477,7 +477,7 @@ var EditSession = function(text, mode) {
|
|||
line = lines[i];
|
||||
if (foldLine) {
|
||||
var end = foldLine.range.end;
|
||||
line = this.getFoldDisplayLine(foldLine, end.row, line.length);
|
||||
line = this.getFoldDisplayLine(foldLine);
|
||||
// Continue after the foldLine.end.row. All the lines in
|
||||
// between are folded.
|
||||
i = end.row;
|
||||
|
|
@ -1003,9 +1003,30 @@ var EditSession = function(text, mode) {
|
|||
var wrapData = this.$wrapData;
|
||||
var wrapLimit = this.$wrapLimit;
|
||||
var tokens;
|
||||
var foldLine;
|
||||
|
||||
for (var row = firstRow; row <= lastRow; row++) {
|
||||
tokens = this.$getDisplayTokens(lang.stringTrimRight(lines[row]));
|
||||
foldLine = this.getFoldLine(row);
|
||||
if (!foldLine) {
|
||||
tokens = this.$getDisplayTokens(lang.stringTrimRight(lines[row]));
|
||||
} else {
|
||||
tokens = [];
|
||||
foldLine.walk(function(placeholder, row, column, lastColumn) {
|
||||
var walkTokens;
|
||||
if (placeholder) {
|
||||
walkTokens = this.$getDisplayTokens(placeholder, tokens.length);
|
||||
walkTokens[0] = PLACEHOLDER_START;
|
||||
for (var i = 1; i < walkTokens.length; i++) {
|
||||
walkTokens[i] = PLACEHOLDER_BODY;
|
||||
}
|
||||
} else {
|
||||
walkTokens = this.$getDisplayTokens(
|
||||
lines[row].substring(lastColumn, column),
|
||||
tokens.length);
|
||||
}
|
||||
tokens = tokens.concat(walkTokens);
|
||||
}.bind(this), row, lines[row].length);
|
||||
}
|
||||
wrapData[row] =
|
||||
this.$computeWrapSplits(tokens, wrapLimit, tabSize);
|
||||
}
|
||||
|
|
@ -1251,14 +1272,16 @@ var EditSession = function(text, mode) {
|
|||
};
|
||||
|
||||
this.screen2Doc = function(screenRow, screenColumn) {
|
||||
var line,
|
||||
docRow = 0,
|
||||
docColumn = 0, column,
|
||||
foldLine,
|
||||
foldLineRowLength;
|
||||
|
||||
var row = 0,
|
||||
rowLength = 0;
|
||||
var line;
|
||||
var docRow = 0;
|
||||
var docColumn = 0;
|
||||
var column;
|
||||
var foldLine;
|
||||
var foldLineRowLength;
|
||||
var row = 0;
|
||||
var rowLength = 0;
|
||||
var splits = null;
|
||||
var split = 0;
|
||||
|
||||
while (row <= screenRow) {
|
||||
rowLength = this.getRowLength(docRow);
|
||||
|
|
@ -1270,58 +1293,37 @@ var EditSession = function(text, mode) {
|
|||
}
|
||||
}
|
||||
|
||||
var splits = null;
|
||||
splits = this.$wrapData[docRow] || [];
|
||||
foldLine = this.getFoldLine(docRow);
|
||||
if (foldLine) {
|
||||
docColumn = splits[screenRow - row] || 0;
|
||||
walkScreenColumn = 0;
|
||||
line = foldLine
|
||||
? this.getFoldDisplayLine(foldLine)
|
||||
: this.getLine(docRow);
|
||||
|
||||
foldLine.walk(function(placeholder, row, column, lastColumn, isNewRow) {
|
||||
var data, str;
|
||||
if (placeholder) {
|
||||
data = this.$getStringScreenWidth(placeholder, null, walkScreenColumn);
|
||||
if (data[0] > screenColumn || data[1] == 0) {
|
||||
return true; // Stop walk.
|
||||
}
|
||||
docColumn += data[1];
|
||||
} else {
|
||||
docColumn = lastColumn;
|
||||
if (isNewRow) {
|
||||
docRow = row;
|
||||
line = this.getLine(row);
|
||||
}
|
||||
str = line.substring(lastColumn, column);
|
||||
data = this.$getStringScreenWidth(str, screenColumn, walkScreenColumn);
|
||||
docColumn += data[1];
|
||||
if (data[0] == screenColumn) {
|
||||
return true; // Stop walk.
|
||||
}
|
||||
}
|
||||
walkScreenColumn = data[0];
|
||||
}.bind(this), foldLine.end.row, this.getLine(foldLine.end.row).length);
|
||||
} else {
|
||||
line = this.getLine(docRow);
|
||||
if (this.$useWrapMode && splits) {
|
||||
docColumn = splits[screenRow - row - 1] || 0;
|
||||
line = line.substring(docColumn);
|
||||
}
|
||||
|
||||
docColumn += this.$getStringScreenWidth(line, screenColumn)[1];
|
||||
|
||||
// Need to do some clamping action here.
|
||||
if (this.$useWrapMode) {
|
||||
column = this.$wrapData[docRow][screenRow - row]
|
||||
if (docColumn >= column) {
|
||||
// We remove one character at the end such that the docColumn
|
||||
// position returned is not associated to the next row on the
|
||||
// screen.
|
||||
docColumn = column - 1;
|
||||
}
|
||||
} else {
|
||||
docColumn = Math.min(docColumn, line.length);
|
||||
}
|
||||
if (this.$useWrapMode) {
|
||||
docColumn = split = splits[screenRow - row - 1] || 0;
|
||||
line = line.substring(split);
|
||||
}
|
||||
|
||||
docColumn += this.$getStringScreenWidth(line, screenColumn)[1];
|
||||
|
||||
if (foldLine) {
|
||||
var position = foldLine.idxToPosition(docColumn);
|
||||
return [position.row, position.column];
|
||||
}
|
||||
|
||||
// Need to do some clamping action here.
|
||||
if (this.$useWrapMode) {
|
||||
column = splits[screenRow - row]
|
||||
if (docColumn >= column) {
|
||||
// We remove one character at the end such that the docColumn
|
||||
// position returned is not associated to the next row on the
|
||||
// screen.
|
||||
docColumn = column - 1;
|
||||
}
|
||||
} else {
|
||||
docColumn = Math.min(docColumn, line.length);
|
||||
}
|
||||
|
||||
return [docRow, docColumn, screenRow, row]
|
||||
}
|
||||
|
||||
|
|
@ -1388,13 +1390,14 @@ var EditSession = function(text, mode) {
|
|||
foldStartRow = docRow;
|
||||
} else {
|
||||
textLine = this.getFoldDisplayLine(foldLine, docRow, docColumn);
|
||||
foldStartRow = foldLine.start.row;
|
||||
}
|
||||
|
||||
// Clamp textLine if in wrapMode.
|
||||
if (this.$useWrapMode) {
|
||||
var wrapRow = wrapData[foldStartRow];
|
||||
var screenRowOffset = 0;
|
||||
while (docColumn >= wrapRow[screenRowOffset]) {
|
||||
while (textLine.length >= wrapRow[screenRowOffset]) {
|
||||
screenRow ++;
|
||||
screenRowOffset++;
|
||||
}
|
||||
|
|
@ -1532,6 +1535,9 @@ var EditSession = function(text, mode) {
|
|||
}
|
||||
|
||||
(function() {
|
||||
/**
|
||||
* Note: This doesn't update wrapData!
|
||||
*/
|
||||
this.shiftRow = function(shift) {
|
||||
this.start.row += shift;
|
||||
this.end.row += shift;
|
||||
|
|
@ -1602,7 +1608,7 @@ var EditSession = function(text, mode) {
|
|||
}
|
||||
|
||||
stop = callback(null, fold.start.row, fold.start.column, lastEnd, isNewRow);
|
||||
stop = stop || callback(fold.placeholder);
|
||||
stop = stop || callback(fold.placeholder, null, null, lastEnd);
|
||||
|
||||
if (stop) {
|
||||
return;
|
||||
|
|
@ -1645,8 +1651,7 @@ var EditSession = function(text, mode) {
|
|||
&& fold.start.column != column
|
||||
&& fold.start.row != row)
|
||||
{
|
||||
// TODO: Implement adding new characters inside of an
|
||||
// fold. This should extend/remove the fold etc.
|
||||
throw "Moving characters inside of a fold should never be reached";
|
||||
} else if (fold.start.row == row) {
|
||||
folds = this.folds;
|
||||
var i = folds.indexOf(fold);
|
||||
|
|
@ -1683,8 +1688,6 @@ var EditSession = function(text, mode) {
|
|||
// containing these removed folds.
|
||||
folds = folds.splice(i, folds.length - i);
|
||||
|
||||
|
||||
|
||||
var newFoldLine = new FoldLine(foldData, folds);
|
||||
foldData.splice(foldData.indexOf(this) + 1, 0, newFoldLine);
|
||||
return newFoldLine;
|
||||
|
|
@ -1710,6 +1713,35 @@ var EditSession = function(text, mode) {
|
|||
ret.push("]")
|
||||
return ret.join("\n");
|
||||
}
|
||||
|
||||
this.idxToPosition = function(idx) {
|
||||
var lastFoldEndColumn = 0;
|
||||
var fold;
|
||||
|
||||
for (var i = 0; i < this.folds.length; i++) {
|
||||
var fold = this.folds[i];
|
||||
|
||||
idx -= fold.start.column - lastFoldEndColumn;
|
||||
if (idx < 0) {
|
||||
return {
|
||||
row: fold.start.row,
|
||||
column: fold.start.column + idx
|
||||
};
|
||||
}
|
||||
|
||||
idx -= fold.placeholder.length;
|
||||
if (idx < 0) {
|
||||
return fold.start;
|
||||
}
|
||||
|
||||
lastFoldEndColumn = fold.end.column;
|
||||
}
|
||||
|
||||
return {
|
||||
row: this.end.row,
|
||||
column: this.end.column + idx
|
||||
};
|
||||
}
|
||||
}).call(FoldLine.prototype);
|
||||
|
||||
FoldLine.prototype.__defineGetter__("rangeDBG", function() {
|
||||
|
|
@ -1864,6 +1896,7 @@ var EditSession = function(text, mode) {
|
|||
this.$foldData.sort(function(a, b) {
|
||||
return a.start.row - b.start.row;
|
||||
});
|
||||
return foldLine;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1874,13 +1907,14 @@ var EditSession = function(text, mode) {
|
|||
endRow = range.end.row,
|
||||
foldData = this.$foldData,
|
||||
foldRow = null;
|
||||
var foldLine;
|
||||
|
||||
var fold = new Fold(range, placeholder);
|
||||
var added = false;
|
||||
|
||||
// For now we assume that no two folds are created for the same range!
|
||||
for (var i = 0; i < foldData.length; i++) {
|
||||
var foldLine = foldData[i];
|
||||
foldLine = foldData[i];
|
||||
if (endRow == foldLine.start.row) {
|
||||
foldLine.addFold(fold);
|
||||
added = true;
|
||||
|
|
@ -1904,10 +1938,13 @@ var EditSession = function(text, mode) {
|
|||
}
|
||||
|
||||
if (!added) {
|
||||
this.$addFoldLine(new FoldLine(this.$foldData, fold));
|
||||
foldLine = this.$addFoldLine(new FoldLine(this.$foldData, fold));
|
||||
}
|
||||
|
||||
// TODO: Recalculate wrapData
|
||||
if (this.$useWrapMode) {
|
||||
this.$updateWrapData(foldLine.start.row, foldLine.start.row);
|
||||
}
|
||||
|
||||
// Notify that fold data has changed.
|
||||
this.$modified = true;
|
||||
|
|
@ -1916,6 +1953,8 @@ var EditSession = function(text, mode) {
|
|||
|
||||
this.removeFold = function(fold) {
|
||||
var foldLine = fold.foldLine;
|
||||
var startRow = foldLine.start.row;
|
||||
var endRow = foldLine.end.row;
|
||||
|
||||
var foldLines = this.$foldData,
|
||||
folds = foldLine.folds;
|
||||
|
|
@ -1953,7 +1992,9 @@ var EditSession = function(text, mode) {
|
|||
this.$addFoldLine(newFoldLine);
|
||||
}
|
||||
|
||||
// TODO: Update wrapData.
|
||||
if (this.$useWrapMode) {
|
||||
this.$updateWrapData(startRow, endRow);
|
||||
}
|
||||
|
||||
// Notify that fold data has changed.
|
||||
this.$modified = true;
|
||||
|
|
@ -1991,6 +2032,11 @@ var EditSession = function(text, mode) {
|
|||
};
|
||||
|
||||
this.getFoldDisplayLine = function(foldLine, endRow, endColumn) {
|
||||
if (endRow == null) {
|
||||
endRow = foldLine.end.row;
|
||||
endColumn = this.getLine(endRow).length;
|
||||
}
|
||||
|
||||
// Build the textline using the FoldLine walker.
|
||||
var line = "",
|
||||
textLine = "";
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ if (typeof process !== "undefined") {
|
|||
|
||||
define(function(require, exports, module) {
|
||||
|
||||
var lang = require("pilot/lang");
|
||||
var EditSession = require("ace/edit_session").EditSession;
|
||||
var Editor = require("ace/editor").Editor;
|
||||
var UndoManager = require("ace/undomanager").UndoManager;
|
||||
|
|
@ -264,6 +265,7 @@ module.exports = {
|
|||
function computeAndAssert(line, assertEqual, wrapLimit, tabSize) {
|
||||
wrapLimit = wrapLimit || 12;
|
||||
tabSize = tabSize || 4;
|
||||
line = lang.stringTrimRight(line);
|
||||
var tokens = EditSession.prototype.$getDisplayTokens(line);
|
||||
var splits = EditSession.prototype.$computeWrapSplits(tokens, wrapLimit, tabSize);
|
||||
// console.log("String:", line, "Result:", splits, "Expected:", assertEqual);
|
||||
|
|
@ -373,6 +375,48 @@ module.exports = {
|
|||
assert.equal(session.doc.getValue(), ["", "foo"].join("\n"));
|
||||
},
|
||||
|
||||
"test fold getFoldDisplayLine": function() {
|
||||
var session = createFoldTestSession();
|
||||
function assertDisplayLine(foldLine, str) {
|
||||
var line = session.getLine(foldLine.end.row);
|
||||
var displayLine =
|
||||
session.getFoldDisplayLine(foldLine, foldLine.end.row, line.length);
|
||||
assert.equal(displayLine, str);
|
||||
}
|
||||
|
||||
assertDisplayLine(session.$foldData[0], "function foo(args...) {")
|
||||
assertDisplayLine(session.$foldData[1], " for (vfoo...ert(items[bar...\"juhu\");");
|
||||
},
|
||||
|
||||
"test foldLine idxToPosition": function() {
|
||||
var session = createFoldTestSession();
|
||||
|
||||
function assertIdx2Pos(foldLineIdx, idx, row, column) {
|
||||
var foldLine = session.$foldData[foldLineIdx];
|
||||
assert.position(foldLine.idxToPosition(idx), row, column);
|
||||
}
|
||||
|
||||
// "function foo(items) {",
|
||||
// " for (var i=0; i<items.length; i++) {",
|
||||
// " alert(items[i] + \"juhu\");",
|
||||
// " } // Real Tab.",
|
||||
// "}"
|
||||
|
||||
assertIdx2Pos(0, 12, 0, 12);
|
||||
assertIdx2Pos(0, 13, 0, 13);
|
||||
assertIdx2Pos(0, 14, 0, 13);
|
||||
assertIdx2Pos(0, 19, 0, 13);
|
||||
assertIdx2Pos(0, 20, 0, 18);
|
||||
|
||||
assertIdx2Pos(1, 10, 1, 10);
|
||||
assertIdx2Pos(1, 11, 1, 10);
|
||||
assertIdx2Pos(1, 15, 1, 10);
|
||||
assertIdx2Pos(1, 16, 2, 10);
|
||||
assertIdx2Pos(1, 26, 2, 20);
|
||||
assertIdx2Pos(1, 27, 2, 20);
|
||||
assertIdx2Pos(1, 32, 2, 25);
|
||||
},
|
||||
|
||||
"test fold documentToScreen": function() {
|
||||
var session = createFoldTestSession();
|
||||
function assertDoc2Screen(docRow, docCol, screenRow, screenCol) {
|
||||
|
|
@ -647,6 +691,42 @@ module.exports = {
|
|||
assert.range(foldLines[0].range, 0, 13, 0, 18);
|
||||
assert.range(foldLines[1].range, 1, 10, 2, 25);
|
||||
// TODO: Add test for inseration inside of folds.
|
||||
},
|
||||
|
||||
"test fold wrap data compution": function() {
|
||||
function assertArray(a, b) {
|
||||
assert.ok(a.length == b.length);
|
||||
for (var i = 0; i < a.length; i++) {
|
||||
assert.ok(a[i] == b[i]);
|
||||
}
|
||||
}
|
||||
|
||||
function assertWrap(line0, line1, line2) {
|
||||
line0 && assertArray(wrapData[0], line0);
|
||||
line1 && assertArray(wrapData[1], line1);
|
||||
line2 && assertArray(wrapData[2], line2);
|
||||
}
|
||||
|
||||
var lines = [
|
||||
"foo bar foo bar",
|
||||
"foo bar foo bar",
|
||||
"foo bar foo bar"
|
||||
];
|
||||
|
||||
var session = new EditSession(lines.join("\n"));
|
||||
var wrapData = session.$wrapData;
|
||||
session.setUseWrapMode(true);
|
||||
session.$wrapLimit = 7;
|
||||
session.$updateWrapData(0, 2);
|
||||
|
||||
assertWrap([7], [7], [7]);
|
||||
session.addFold(new Range(0, 13, 0, 18), "args...");
|
||||
|
||||
|
||||
session.addFold(new Range(1, 10, 2, 10), "foo...");
|
||||
session.addFold(new Range(2, 20, 2, 25), "bar...");
|
||||
return session;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue