Skip to content

Commit

Permalink
readline: support TERM=dumb
Browse files Browse the repository at this point in the history
When TERM=dumb and .isTTY=true don't use ANSI escape codes
and ignore all keys, except 'escape', 'return' and 'ctrl-c'.

Fixes: nodejs#26187
  • Loading branch information
wlodzislav committed Mar 5, 2019
1 parent 1c0ba10 commit 1b7434d
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 3 deletions.
61 changes: 58 additions & 3 deletions lib/readline.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down
21 changes: 21 additions & 0 deletions test/pseudo-tty/readline-dumb-tty.js
Original file line number Diff line number Diff line change
@@ -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' });
3 changes: 3 additions & 0 deletions test/pseudo-tty/readline-dumb-tty.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
text
text
text

0 comments on commit 1b7434d

Please sign in to comment.