fix some key navigation issues
This commit is contained in:
parent
742f04b407
commit
b6223bc801
4 changed files with 61 additions and 22 deletions
|
|
@ -56,7 +56,6 @@ var EditSession = function(text, mode) {
|
||||||
this.$backMarkers = {};
|
this.$backMarkers = {};
|
||||||
this.$markerId = 1;
|
this.$markerId = 1;
|
||||||
this.$rowCache = [];
|
this.$rowCache = [];
|
||||||
this.$rowCacheSize = 1000;
|
|
||||||
this.$wrapData = [];
|
this.$wrapData = [];
|
||||||
this.$foldData = [];
|
this.$foldData = [];
|
||||||
this.$foldData.toString = function() {
|
this.$foldData.toString = function() {
|
||||||
|
|
@ -1352,6 +1351,9 @@ var EditSession = function(text, mode) {
|
||||||
return [screenColumn, column];
|
return [screenColumn, column];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of rows required to render this row on the screen
|
||||||
|
*/
|
||||||
this.getRowLength = function(row) {
|
this.getRowLength = function(row) {
|
||||||
if (!this.$useWrapMode || !this.$wrapData[row]) {
|
if (!this.$useWrapMode || !this.$wrapData[row]) {
|
||||||
return 1;
|
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) {
|
this.getRowHeight = function(config, row) {
|
||||||
return this.getRowLength(row) * config.lineHeight;
|
return this.getRowLength(row) * config.lineHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.getScreenLastRowColumn = function(screenRow) {
|
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)
|
return this.screenToDocumentColumn(screenRow, Number.MAX_VALUE / 10)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1405,6 +1407,13 @@ var EditSession = function(text, mode) {
|
||||||
};
|
};
|
||||||
|
|
||||||
this.screenToDocumentPosition = function(screenRow, screenColumn) {
|
this.screenToDocumentPosition = function(screenRow, screenColumn) {
|
||||||
|
if (screenRow < 0) {
|
||||||
|
return {
|
||||||
|
row: 0,
|
||||||
|
column: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var line;
|
var line;
|
||||||
var docRow = 0;
|
var docRow = 0;
|
||||||
var docColumn = 0;
|
var docColumn = 0;
|
||||||
|
|
@ -1412,7 +1421,6 @@ var EditSession = function(text, mode) {
|
||||||
var foldLineRowLength;
|
var foldLineRowLength;
|
||||||
var row = 0;
|
var row = 0;
|
||||||
var rowLength = 0;
|
var rowLength = 0;
|
||||||
var splits = null;
|
|
||||||
|
|
||||||
var rowCache = this.$rowCache;
|
var rowCache = this.$rowCache;
|
||||||
var doCache = !rowCache.length;
|
var doCache = !rowCache.length;
|
||||||
|
|
@ -1423,21 +1431,18 @@ var EditSession = function(text, mode) {
|
||||||
doCache = i == rowCache.length - 1;
|
doCache = i == rowCache.length - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var docRowCacheLast = docRow;
|
|
||||||
// clamp row before clamping column, for selection on last line
|
// clamp row before clamping column, for selection on last line
|
||||||
var maxRow = this.getLength() - 1;
|
var maxRow = this.getLength() - 1;
|
||||||
|
|
||||||
var foldLine = this.getNextFold(docRow);
|
var foldLine = this.getNextFold(docRow);
|
||||||
var foldStart = foldLine ?foldLine.start.row :Infinity;
|
var foldStart = foldLine ? foldLine.start.row : Infinity;
|
||||||
|
|
||||||
while (row <= screenRow) {
|
while (row <= screenRow) {
|
||||||
if (doCache
|
if (doCache) {
|
||||||
&& docRow - docRowCacheLast > this.$rowCacheSize) {
|
|
||||||
rowCache.push({
|
rowCache.push({
|
||||||
docRow: docRow,
|
docRow: docRow,
|
||||||
screenRow: row
|
screenRow: row
|
||||||
});
|
});
|
||||||
docRowCacheLast = docRow;
|
|
||||||
}
|
}
|
||||||
rowLength = this.getRowLength(docRow);
|
rowLength = this.getRowLength(docRow);
|
||||||
if (row + rowLength - 1 >= screenRow || docRow >= maxRow) {
|
if (row + rowLength - 1 >= screenRow || docRow >= maxRow) {
|
||||||
|
|
@ -1445,10 +1450,10 @@ var EditSession = function(text, mode) {
|
||||||
} else {
|
} else {
|
||||||
row += rowLength;
|
row += rowLength;
|
||||||
docRow++;
|
docRow++;
|
||||||
if(docRow > foldStart) {
|
if (docRow > foldStart) {
|
||||||
docRow = foldLine.end.row+1;
|
docRow = foldLine.end.row+1;
|
||||||
foldLine = this.getNextFold(docRow);
|
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;
|
foldLine = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var splits = [];
|
||||||
if (this.$useWrapMode) {
|
if (this.$useWrapMode) {
|
||||||
splits = this.$wrapData[docRow];
|
splits = this.$wrapData[docRow];
|
||||||
if (splits) {
|
if (splits) {
|
||||||
|
|
@ -1473,6 +1479,10 @@ var EditSession = function(text, mode) {
|
||||||
|
|
||||||
docColumn += this.$getStringScreenWidth(line, screenColumn)[1];
|
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.
|
// Need to do some clamping action here.
|
||||||
if (this.$useWrapMode) {
|
if (this.$useWrapMode) {
|
||||||
if (docColumn >= column) {
|
if (docColumn >= column) {
|
||||||
|
|
@ -1539,7 +1549,6 @@ var EditSession = function(text, mode) {
|
||||||
doCache = i == rowCache.length - 1;
|
doCache = i == rowCache.length - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var docRowCacheLast = row;
|
|
||||||
|
|
||||||
var foldLine = this.getNextFold(row);
|
var foldLine = this.getNextFold(row);
|
||||||
var foldStart = foldLine ?foldLine.start.row :Infinity;
|
var foldStart = foldLine ?foldLine.start.row :Infinity;
|
||||||
|
|
@ -1554,13 +1563,11 @@ var EditSession = function(text, mode) {
|
||||||
} else {
|
} else {
|
||||||
rowEnd = row + 1;
|
rowEnd = row + 1;
|
||||||
}
|
}
|
||||||
if (doCache
|
if (doCache) {
|
||||||
&& row - docRowCacheLast > this.$rowCacheSize) {
|
|
||||||
rowCache.push({
|
rowCache.push({
|
||||||
docRow: row,
|
docRow: row,
|
||||||
screenRow: screenRow
|
screenRow: screenRow
|
||||||
});
|
});
|
||||||
docRowCacheLast = row;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
screenRow += this.getRowLength(row);
|
screenRow += this.getRowLength(row);
|
||||||
|
|
@ -1586,7 +1593,8 @@ var EditSession = function(text, mode) {
|
||||||
screenRowOffset++;
|
screenRowOffset++;
|
||||||
}
|
}
|
||||||
textLine = textLine.substring(
|
textLine = textLine.substring(
|
||||||
wrapRow[screenRowOffset - 1] || 0, textLine.length);
|
wrapRow[screenRowOffset - 1] || 0, textLine.length
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
|
|
@ -233,9 +233,7 @@ module.exports = {
|
||||||
assert.equal(session.screenToDocumentColumn(0, 14), 13);
|
assert.equal(session.screenToDocumentColumn(0, 14), 13);
|
||||||
},
|
},
|
||||||
|
|
||||||
"test: screenToDocument with soft wrap and multi byte characters": function() {
|
"test: screenToDocument with soft wrap": function() {
|
||||||
var tabSize = 4;
|
|
||||||
var wrapLimit = 12;
|
|
||||||
var session = new EditSession(["foo bar foo bar"]);
|
var session = new EditSession(["foo bar foo bar"]);
|
||||||
session.setUseWrapMode(true);
|
session.setUseWrapMode(true);
|
||||||
session.setWrapLimitRange(12, 12);
|
session.setWrapLimitRange(12, 12);
|
||||||
|
|
@ -246,7 +244,9 @@ module.exports = {
|
||||||
// Check if the position is clamped the right way.
|
// Check if the position is clamped the right way.
|
||||||
assert.position(session.screenToDocumentPosition(0, 12), 0, 11);
|
assert.position(session.screenToDocumentPosition(0, 12), 0, 11);
|
||||||
assert.position(session.screenToDocumentPosition(0, 20), 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 = new EditSession(["ぁ a"]);
|
||||||
session.setUseWrapMode(true);
|
session.setUseWrapMode(true);
|
||||||
session.adjustWrapLimit(80);
|
session.adjustWrapLimit(80);
|
||||||
|
|
@ -258,6 +258,16 @@ module.exports = {
|
||||||
assert.position(session.screenToDocumentPosition(0, 5), 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() {
|
"test: wrapLine split function" : function() {
|
||||||
var splits;
|
var splits;
|
||||||
var c = 0;
|
var c = 0;
|
||||||
|
|
|
||||||
|
|
@ -297,7 +297,8 @@ var Selection = function(session) {
|
||||||
fold;
|
fold;
|
||||||
if (fold = this.session.getFoldAt(cursor.row, cursor.column, 1)) {
|
if (fold = this.session.getFoldAt(cursor.row, cursor.column, 1)) {
|
||||||
this.moveCursorTo(fold.end.row, fold.end.column);
|
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) {
|
if (this.selectionLead.row < this.doc.getLength() - 1) {
|
||||||
this.moveCursorTo(this.selectionLead.row + 1, 0);
|
this.moveCursorTo(this.selectionLead.row + 1, 0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -368,6 +368,26 @@ module.exports = {
|
||||||
selection.moveCursorLineStart();
|
selection.moveCursorLineStart();
|
||||||
|
|
||||||
assert.position(selection.getCursor(), 1, 4);
|
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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue