readline: make \r\n emit one 'line' event

Make lines ending \r\n emit one 'line' event, not two (where the second
one is an empty string).

This adds a new keypress name: 'return' (as in: 'carriage return').

Fixes #3305.
This commit is contained in:
Ben Noordhuis 2013-01-28 13:13:28 +01:00
parent bda45a8be1
commit 9bd9c546c8
2 changed files with 21 additions and 3 deletions

View File

@ -303,7 +303,7 @@ Interface.prototype._normalWrite = function(b) {
} }
if (string.indexOf('\n') !== -1) { if (string.indexOf('\n') !== -1) {
// got one or more newlines; process into "line" events // got one or more newlines; process into "line" events
var lines = string.split('\n'); var lines = string.split(/\r?\n/);
// either '' or (concievably) the unfinished portion of the next line // either '' or (concievably) the unfinished portion of the next line
string = lines.pop(); string = lines.pop();
this._line_buffer = string; this._line_buffer = string;
@ -758,6 +758,7 @@ Interface.prototype._ttyWrite = function(s, key) {
this._moveCursor(+1); this._moveCursor(+1);
break; break;
case 'return': // carriage return, i.e. \r
case 'home': case 'home':
this._moveCursor(-Infinity); this._moveCursor(-Infinity);
break; break;
@ -885,8 +886,12 @@ function emitKey(stream, s) {
key.sequence = s; key.sequence = s;
if (s === '\r' || s === '\n') { if (s === '\r') {
// enter // carriage return
key.name = 'return';
} else if (s === '\n') {
// enter, should have been called linefeed
key.name = 'enter'; key.name = 'enter';
} else if (s === '\t') { } else if (s === '\t') {

View File

@ -113,6 +113,19 @@ FakeInput.prototype.end = function() {};
assert.equal(callCount, expectedLines.length - 1); assert.equal(callCount, expectedLines.length - 1);
rli.close(); rli.close();
// \r\n should emit one line event, not two
fi = new FakeInput();
rli = new readline.Interface({ input: fi, output: fi, terminal: terminal });
expectedLines = ['foo', 'bar', 'baz', 'bat'];
callCount = 0;
rli.on('line', function(line) {
assert.equal(line, expectedLines[callCount]);
callCount++;
});
fi.emit('data', expectedLines.join('\r\n'));
assert.equal(callCount, expectedLines.length - 1);
rli.close();
// sending a multi-byte utf8 char over multiple writes // sending a multi-byte utf8 char over multiple writes
var buf = Buffer('☮', 'utf8'); var buf = Buffer('☮', 'utf8');
fi = new FakeInput(); fi = new FakeInput();