fix some key navigation issues

This commit is contained in:
Fabian Jakobs 2011-07-19 20:11:44 +02:00
commit b6223bc801
4 changed files with 61 additions and 22 deletions

View file

@ -56,7 +56,6 @@ var EditSession = function(text, mode) {
this.$backMarkers = {};
this.$markerId = 1;
this.$rowCache = [];
this.$rowCacheSize = 1000;
this.$wrapData = [];
this.$foldData = [];
this.$foldData.toString = function() {
@ -1352,6 +1351,9 @@ var EditSession = function(text, mode) {
return [screenColumn, column];
}
/**
* Returns the number of rows required to render this row on the screen
*/
this.getRowLength = function(row) {
if (!this.$useWrapMode || !this.$wrapData[row]) {
return 1;
@ -1360,14 +1362,14 @@ var EditSession = function(text, mode) {
}
}
/**
* Returns the height in pixels required to render this row on the screen
**/
this.getRowHeight = function(config, row) {
return this.getRowLength(row) * config.lineHeight;
}
this.getScreenLastRowColumn = function(screenRow) {
// Note: This won't work if someone has more then
// 1.7976931348623158e+307 characters in one row. But I think we can
// live with this limitation ;)
return this.screenToDocumentColumn(screenRow, Number.MAX_VALUE / 10)
};
@ -1405,6 +1407,13 @@ var EditSession = function(text, mode) {
};
this.screenToDocumentPosition = function(screenRow, screenColumn) {
if (screenRow < 0) {
return {
row: 0,
column: 0
}
}
var line;
var docRow = 0;
var docColumn = 0;
@ -1412,7 +1421,6 @@ var EditSession = function(text, mode) {
var foldLineRowLength;
var row = 0;
var rowLength = 0;
var splits = null;
var rowCache = this.$rowCache;
var doCache = !rowCache.length;
@ -1423,21 +1431,18 @@ var EditSession = function(text, mode) {
doCache = i == rowCache.length - 1;
}
}
var docRowCacheLast = docRow;
// clamp row before clamping column, for selection on last line
var maxRow = this.getLength() - 1;
var foldLine = this.getNextFold(docRow);
var foldStart = foldLine ?foldLine.start.row :Infinity;
var foldStart = foldLine ? foldLine.start.row : Infinity;
while (row <= screenRow) {
if (doCache
&& docRow - docRowCacheLast > this.$rowCacheSize) {
if (doCache) {
rowCache.push({
docRow: docRow,
screenRow: row
});
docRowCacheLast = docRow;
}
rowLength = this.getRowLength(docRow);
if (row + rowLength - 1 >= screenRow || docRow >= maxRow) {
@ -1445,10 +1450,10 @@ var EditSession = function(text, mode) {
} else {
row += rowLength;
docRow++;
if(docRow > foldStart) {
if (docRow > foldStart) {
docRow = foldLine.end.row+1;
foldLine = this.getNextFold(docRow);
foldStart = foldLine ?foldLine.start.row :Infinity;
foldStart = foldLine ? foldLine.start.row : Infinity;
}
}
}
@ -1460,6 +1465,7 @@ var EditSession = function(text, mode) {
foldLine = null;
}
var splits = [];
if (this.$useWrapMode) {
splits = this.$wrapData[docRow];
if (splits) {
@ -1473,6 +1479,10 @@ var EditSession = function(text, mode) {
docColumn += this.$getStringScreenWidth(line, screenColumn)[1];
// clip row at the end of the documen
if (row + splits.length < screenRow)
docColumn = Number.MAX_VALUE;
// Need to do some clamping action here.
if (this.$useWrapMode) {
if (docColumn >= column) {
@ -1539,7 +1549,6 @@ var EditSession = function(text, mode) {
doCache = i == rowCache.length - 1;
}
}
var docRowCacheLast = row;
var foldLine = this.getNextFold(row);
var foldStart = foldLine ?foldLine.start.row :Infinity;
@ -1554,13 +1563,11 @@ var EditSession = function(text, mode) {
} else {
rowEnd = row + 1;
}
if (doCache
&& row - docRowCacheLast > this.$rowCacheSize) {
if (doCache) {
rowCache.push({
docRow: row,
screenRow: screenRow
});
docRowCacheLast = row;
}
screenRow += this.getRowLength(row);
@ -1586,7 +1593,8 @@ var EditSession = function(text, mode) {
screenRowOffset++;
}
textLine = textLine.substring(
wrapRow[screenRowOffset - 1] || 0, textLine.length);
wrapRow[screenRowOffset - 1] || 0, textLine.length
);
}
return {

View file

@ -233,9 +233,7 @@ module.exports = {
assert.equal(session.screenToDocumentColumn(0, 14), 13);
},
"test: screenToDocument with soft wrap and multi byte characters": function() {
var tabSize = 4;
var wrapLimit = 12;
"test: screenToDocument with soft wrap": function() {
var session = new EditSession(["foo bar foo bar"]);
session.setUseWrapMode(true);
session.setWrapLimitRange(12, 12);
@ -246,7 +244,9 @@ module.exports = {
// Check if the position is clamped the right way.
assert.position(session.screenToDocumentPosition(0, 12), 0, 11);
assert.position(session.screenToDocumentPosition(0, 20), 0, 11);
},
"test: screenToDocument with soft wrap and multi byte characters": function() {
session = new EditSession(["ぁ a"]);
session.setUseWrapMode(true);
session.adjustWrapLimit(80);
@ -257,6 +257,16 @@ module.exports = {
assert.position(session.screenToDocumentPosition(0, 4), 0, 3);
assert.position(session.screenToDocumentPosition(0, 5), 0, 3);
},
"test: screenToDocument should clip position to the document boundaries": function() {
var session = new EditSession("foo bar\njuhu kinners");
assert.position(session.screenToDocumentPosition(-1, 4), 0, 0);
assert.position(session.screenToDocumentPosition(0, -1), 0, 0);
assert.position(session.screenToDocumentPosition(0, 30), 0, 7);
assert.position(session.screenToDocumentPosition(2, 4), 1, 12);
assert.position(session.screenToDocumentPosition(1, 30), 1, 12);
},
"test: wrapLine split function" : function() {
var splits;

View file

@ -297,7 +297,8 @@ var Selection = function(session) {
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) {
}
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);
}

View file

@ -368,6 +368,26 @@ module.exports = {
selection.moveCursorLineStart();
assert.position(selection.getCursor(), 1, 4);
},
"test go line up when in the middle of the first line should go to document start": function() {
var session = new EditSession("juhu kinners");
var selection = session.getSelection();
selection.moveCursorTo(0, 4);
selection.moveCursorUp();
assert.position(selection.getCursor(), 0, 0);
},
"test go line down when in the middle of the last line should go to document end": function() {
var session = new EditSession("juhu kinners");
var selection = session.getSelection();
selection.moveCursorTo(0, 4);
selection.moveCursorDown();
assert.position(selection.getCursor(), 0, 12);
}
};