diff --git a/lib/readline.js b/lib/readline.js index 0983f3ab615916..aa394022176127 100644 --- a/lib/readline.js +++ b/lib/readline.js @@ -181,7 +181,11 @@ function Interface(input, output, completer, terminal) { } function onkeypress(s, key) { - self._ttyWrite(s, key); + if (process.env.TERM === 'dumb') { + self._ttyWriteDumb(s, key); + } else { + self._ttyWrite(s, key); + } if (key && key.sequence) { // If the key.sequence is half of a surrogate pair // (>= 0xd800 and <= 0xdfff), refresh the line so @@ -276,7 +280,7 @@ Interface.prototype._setRawMode = function(mode) { Interface.prototype.prompt = function(preserveCursor) { if (this.paused) this.resume(); - if (this.terminal) { + if (this.terminal && process.env.TERM !== 'dumb') { if (!preserveCursor) this.cursor = 0; this._refreshLine(); } else { @@ -417,7 +421,15 @@ Interface.prototype.resume = function() { Interface.prototype.write = function(d, key) { if (this.paused) this.resume(); - this.terminal ? this._ttyWrite(d, key) : this._normalWrite(d); + if (this.terminal) { + if (process.env.TERM === 'dumb') { + this._ttyWriteDumb(d, key); + } else { + this._ttyWrite(d, key); + } + } else { + this._normalWrite(d); + } }; Interface.prototype._normalWrite = function(b) { @@ -789,6 +801,49 @@ Interface.prototype._moveCursor = function(dx) { } }; +Interface.prototype._ttyWriteDumb = function(s, key) { + key = key || {}; + + if (key.name === 'escape') return; + + if (this._sawReturnAt && key.name !== 'enter') + this._sawReturnAt = 0; + + if (key.ctrl && key.name === 'c') { + if (this.listenerCount('SIGINT') > 0) { + this.emit('SIGINT'); + } else { + // This readline instance is finished + this.close(); + } + } + + switch (key.name) { + case 'return': // carriage return, i.e. \r + this._sawReturnAt = Date.now(); + this._line(); + break; + + case 'enter': + // When key interval > crlfDelay + if (this._sawReturnAt === 0 || + Date.now() - this._sawReturnAt > this.crlfDelay) { + this._line(); + } + this._sawReturnAt = 0; + break; + + default: + if (s instanceof Buffer) + s = s.toString('utf-8'); + + if (s) { + this.line += s; + this.cursor += s.length; + this._writeToOutput(s); + } + } +}; // handle a write from the tty Interface.prototype._ttyWrite = function(s, key) { diff --git a/test/pseudo-tty/readline-dumb-tty.js b/test/pseudo-tty/readline-dumb-tty.js new file mode 100644 index 00000000000000..6b9a3b59ad96e8 --- /dev/null +++ b/test/pseudo-tty/readline-dumb-tty.js @@ -0,0 +1,21 @@ +'use strict'; +require('../common'); + +process.env.TERM = 'dumb'; + +const readline = require('readline'); + +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout +}); + +rl.write('text'); +rl.write(null, { ctrl: true, name: 'u' }); +rl.write(null, { name: 'return' }); +rl.write('text'); +rl.write(null, { name: 'backspace' }); +rl.write(null, { name: 'escape' }); +rl.write(null, { name: 'enter' }); +rl.write('text'); +rl.write(null, { ctrl: true, name: 'c' }); diff --git a/test/pseudo-tty/readline-dumb-tty.out b/test/pseudo-tty/readline-dumb-tty.out new file mode 100644 index 00000000000000..6841116ad12836 --- /dev/null +++ b/test/pseudo-tty/readline-dumb-tty.out @@ -0,0 +1,3 @@ +text +text +text