readline: consider newlines for cursor position

Fixes #7266.
Closes #7279.
This commit is contained in:
Yazhong Liu 2014-03-09 14:46:54 +08:00 committed by Nathan Rajlich
parent 9bd934cb96
commit 93c3674ff7
2 changed files with 33 additions and 1 deletions

View File

@ -563,6 +563,7 @@ Interface.prototype._historyPrev = function() {
Interface.prototype._getDisplayPos = function(str) {
var offset = 0;
var col = this.columns;
var row = 0;
var code;
str = stripVTControlCharacters(str);
for (var i = 0, len = str.length; i < len; i++) {
@ -570,6 +571,11 @@ Interface.prototype._getDisplayPos = function(str) {
if (code >= 0x10000) { // surrogates
i++;
}
if (code === 0x0a) { // new line \n
offset = 0;
row += 1;
continue;
}
if (isFullWidthCodePoint(code)) {
if ((offset + 1) % col === 0) {
offset++;
@ -580,7 +586,7 @@ Interface.prototype._getDisplayPos = function(str) {
}
}
var cols = offset % col;
var rows = (offset - cols) / col;
var rows = row + (offset - cols) / col;
return {cols: cols, rows: rows};
};

View File

@ -206,6 +206,32 @@ FakeInput.prototype.end = function() {};
assert.equal(callCount, 1);
rli.close();
if (terminal) {
// question
fi = new FakeInput();
rli = new readline.Interface({ input: fi, output: fi, terminal: terminal });
expectedLines = ['foo'];
rli.question(expectedLines[0], function() {
rli.close();
});
var cursorPos = rli._getCursorPos();
assert.equal(cursorPos.rows, 0);
assert.equal(cursorPos.cols, expectedLines[0].length);
rli.close();
// sending a multi-line question
fi = new FakeInput();
rli = new readline.Interface({ input: fi, output: fi, terminal: terminal });
expectedLines = ['foo', 'bar'];
rli.question(expectedLines.join('\n'), function() {
rli.close();
});
var cursorPos = rli._getCursorPos();
assert.equal(cursorPos.rows, expectedLines.length - 1);
assert.equal(cursorPos.cols, expectedLines.slice(-1)[0].length);
rli.close();
}
// wide characters should be treated as two columns.
assert.equal(readline.isFullWidthCodePoint('a'.charCodeAt(0)), false);
assert.equal(readline.isFullWidthCodePoint('あ'.charCodeAt(0)), true);