diff --git a/doc/api/readline.md b/doc/api/readline.md index 767f8ccefc..085ac88540 100644 --- a/doc/api/readline.md +++ b/doc/api/readline.md @@ -369,7 +369,9 @@ changes: * `crlfDelay` {number} If the delay between `\r` and `\n` exceeds `crlfDelay` milliseconds, both `\r` and `\n` will be treated as separate end-of-line input. Default to `100` milliseconds. - `crlfDelay` will be coerced to `[100, 2000]` range. + `crlfDelay` will be coerced to a number no less than `100`. It can be set to + `Infinity`, in which case `\r` followed by `\n` will always be considered a + single newline. * `removeHistoryDuplicates` {boolean} If `true`, when a new input line added to the history list duplicates an older one, this removes the older line from the list. Defaults to `false`. diff --git a/lib/readline.js b/lib/readline.js index fb6ffb8f06..57f9e7d6e8 100644 --- a/lib/readline.js +++ b/lib/readline.js @@ -50,7 +50,6 @@ const { const kHistorySize = 30; const kMincrlfDelay = 100; -const kMaxcrlfDelay = 2000; // \r\n, \n, or \r followed by something other than \n const lineEnding = /\r?\n|\r(?!\n)/; @@ -125,8 +124,8 @@ function Interface(input, output, completer, terminal) { this.input = input; this.historySize = historySize; this.removeHistoryDuplicates = !!removeHistoryDuplicates; - this.crlfDelay = Math.max(kMincrlfDelay, - Math.min(kMaxcrlfDelay, crlfDelay >>> 0)); + this.crlfDelay = crlfDelay ? + Math.max(kMincrlfDelay, crlfDelay) : kMincrlfDelay; // Check arity, 2 - for async, 1 for sync if (typeof completer === 'function') { diff --git a/test/parallel/test-readline-interface.js b/test/parallel/test-readline-interface.js index 9ce978b86e..e73481d429 100644 --- a/test/parallel/test-readline-interface.js +++ b/test/parallel/test-readline-interface.js @@ -63,14 +63,26 @@ function isWarned(emitter) { } { - // Maximum crlfDelay is 2000ms + // set crlfDelay to float 100.5ms const fi = new FakeInput(); const rli = new readline.Interface({ input: fi, output: fi, - crlfDelay: 1 << 30 + crlfDelay: 100.5 }); - assert.strictEqual(rli.crlfDelay, 2000); + assert.strictEqual(rli.crlfDelay, 100.5); + rli.close(); +} + +{ + // set crlfDelay to 5000ms + const fi = new FakeInput(); + const rli = new readline.Interface({ + input: fi, + output: fi, + crlfDelay: 5000 + }); + assert.strictEqual(rli.crlfDelay, 5000); rli.close(); } @@ -248,7 +260,7 @@ function isWarned(emitter) { rli.close(); // Emit two line events when the delay - // between \r and \n exceeds crlfDelay + // between \r and \n exceeds crlfDelay { const fi = new FakeInput(); const delay = 200; @@ -270,8 +282,55 @@ function isWarned(emitter) { }), delay * 2); } + // Emit one line events when the delay between \r and \n is + // over the default crlfDelay but within the setting value + { + const fi = new FakeInput(); + const delay = 200; + const crlfDelay = 500; + const rli = new readline.Interface({ + input: fi, + output: fi, + terminal: terminal, + crlfDelay + }); + let callCount = 0; + rli.on('line', function(line) { + callCount++; + }); + fi.emit('data', '\r'); + setTimeout(common.mustCall(() => { + fi.emit('data', '\n'); + assert.strictEqual(callCount, 1); + rli.close(); + }), delay); + } + + // set crlfDelay to `Infinity` is allowed + { + const fi = new FakeInput(); + const delay = 200; + const crlfDelay = Infinity; + const rli = new readline.Interface({ + input: fi, + output: fi, + terminal: terminal, + crlfDelay + }); + let callCount = 0; + rli.on('line', function(line) { + callCount++; + }); + fi.emit('data', '\r'); + setTimeout(common.mustCall(() => { + fi.emit('data', '\n'); + assert.strictEqual(callCount, 1); + rli.close(); + }), delay); + } + // \t when there is no completer function should behave like an ordinary - // character + // character fi = new FakeInput(); rli = new readline.Interface({ input: fi, output: fi, terminal: true }); called = false; @@ -513,7 +572,7 @@ function isWarned(emitter) { assert.strictEqual(isWarned(process.stdout._events), false); } - //can create a new readline Interface with a null output arugument + // can create a new readline Interface with a null output arugument fi = new FakeInput(); rli = new readline.Interface({ input: fi, output: null, terminal: terminal });