Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Configurable delay option
  • Loading branch information
princejwesley committed Aug 21, 2016
commit a13083d334e7e253a6b7406d0630f69b4fb76d7d
3 changes: 3 additions & 0 deletions doc/api/readline.md
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,9 @@ added: v0.1.98
only if `terminal` is set to `true` by the user or by an internal `output`
check, otherwise the history caching mechanism is not initialized at all.
* `prompt` - the prompt string to use. Default: `'> '`
* `crLfDelay` {number} If the delay between `\r` and `\n` exceeds
`crLfDelay`, both `\r` and `\n` will be treated as separate end-of-line
input. Default to `100` milliseconds.

The `readline.createInterface()` method creates a new `readline.Interface`
instance.
Expand Down
24 changes: 18 additions & 6 deletions lib/readline.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,20 @@ const isFullWidthCodePoint = internalReadline.isFullWidthCodePoint;
const stripVTControlCharacters = internalReadline.stripVTControlCharacters;


exports.createInterface = function(input, output, completer, terminal) {
exports.createInterface = function(input, output, completer, terminal,
crLfDelay = kCRLFDelayInMillis) {
var rl;
if (arguments.length === 1) {
rl = new Interface(input);
} else {
rl = new Interface(input, output, completer, terminal);
rl = new Interface(input, output, completer, terminal, crLfDelay);
}
return rl;
};


function Interface(input, output, completer, terminal) {
function Interface(input, output, completer, terminal,
crLfDelay = kCRLFDelayInMillis) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO this should line up with the input parameter.

if (!(this instanceof Interface)) {
// call the constructor preserving original number of arguments
const self = Object.create(Interface.prototype);
Expand All @@ -57,6 +59,9 @@ function Interface(input, output, completer, terminal) {
if (input.prompt !== undefined) {
prompt = input.prompt;
}
if (input.crLfDelay !== undefined) {
crLfDelay = input.crLfDelay;
}
input = input.input;
}

Expand All @@ -74,6 +79,12 @@ function Interface(input, output, completer, terminal) {
throw new TypeError('Argument "historySize" must be a positive number');
}

if (typeof crLfDelay !== 'number' ||
isNaN(crLfDelay) ||
crLfDelay <= 0) {
throw new TypeError('Argument "crLfDelay" must be a positive number > 0');
}

// backwards compat; check the isTTY prop of the output stream
// when `terminal` was not specified
if (terminal === undefined && !(output === null || output === undefined)) {
Expand All @@ -85,6 +96,7 @@ function Interface(input, output, completer, terminal) {
this.output = output;
this.input = input;
this.historySize = historySize;
this.crLfDelay = crLfDelay;

// Check arity, 2 - for async, 1 for sync
if (typeof completer === 'function') {
Expand Down Expand Up @@ -343,7 +355,7 @@ Interface.prototype._normalWrite = function(b) {
}
var string = this._decoder.write(b);
if (this._sawReturnAt &&
Date.now() - this._sawReturnAt <= kCRLFDelayInMillis) {
Date.now() - this._sawReturnAt <= this.crLfDelay) {
string = string.replace(/^\n/, '');
this._sawReturnAt = 0;
}
Expand Down Expand Up @@ -854,9 +866,9 @@ Interface.prototype._ttyWrite = function(s, key) {
break;

case 'enter':
// When key interval > kCRLFDelayInMillis
// When key interval > crLfDelay
if (this._sawReturnAt === 0 ||
Date.now() - this._sawReturnAt > kCRLFDelayInMillis) {
Date.now() - this._sawReturnAt > this.crLfDelay) {
this._line();
}
this._sawReturnAt = 0;
Expand Down
15 changes: 11 additions & 4 deletions test/parallel/test-readline-interface.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ function isWarned(emitter) {
rli = new readline.Interface({ input: fi, output: fi, terminal: terminal});
assert.strictEqual(rli.historySize, 30);

// default crLfDelay is 100ms
fi = new FakeInput();
rli = new readline.Interface({ input: fi, output: fi, terminal: terminal});
assert.strictEqual(rli.crLfDelay, 100);

fi.emit('data', 'asdf\n');
assert.deepStrictEqual(rli.history, terminal ? ['asdf'] : undefined);
rli.close();
Expand Down Expand Up @@ -199,14 +204,16 @@ function isWarned(emitter) {
assert.equal(callCount, expectedLines.length);
rli.close();

// Emit two line events where there is a delay
// between \r and \n
// Emit two line events when the delay
// between \r and \n exceeds crLFDelay
{
const fi = new FakeInput();
const delay = 200;
const rli = new readline.Interface({
input: fi,
output: fi,
terminal: terminal
terminal: terminal,
crLfDelay: delay
});
let callCount = 0;
rli.on('line', function(line) {
Expand All @@ -217,7 +224,7 @@ function isWarned(emitter) {
fi.emit('data', '\n');
assert.equal(callCount, 2);
rli.close();
}, 200);
}, delay * 2);
}

// \t when there is no completer function should behave like an ordinary
Expand Down