Skip to content

Commit d3a62fe

Browse files
wlodzislavBridgeAR
authored andcommitted
readline: support TERM=dumb
When TERM=dumb and .isTTY=true don't use ANSI escape codes and ignore all keys, except 'escape', 'return' and 'ctrl-c'. PR-URL: #26261 Fixes: #26187 Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Roman Reiss <[email protected]> Reviewed-By: Rich Trott <[email protected]> Reviewed-By: Jeremiah Senkpiel <[email protected]>
1 parent 9952375 commit d3a62fe

File tree

3 files changed

+75
-7
lines changed

3 files changed

+75
-7
lines changed

lib/readline.js

+51-7
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ const {
3434
const { validateString } = require('internal/validators');
3535
const { inspect } = require('util');
3636
const { emitExperimentalWarning } = require('internal/util');
37-
const { Buffer } = require('buffer');
3837
const EventEmitter = require('events');
3938
const {
4039
CSI,
@@ -161,6 +160,10 @@ function Interface(input, output, completer, terminal) {
161160

162161
this.terminal = !!terminal;
163162

163+
if (process.env.TERM === 'dumb') {
164+
this._ttyWrite = _ttyWriteDumb.bind(this);
165+
}
166+
164167
function ondata(data) {
165168
self._normalWrite(data);
166169
}
@@ -276,7 +279,7 @@ Interface.prototype._setRawMode = function(mode) {
276279

277280
Interface.prototype.prompt = function(preserveCursor) {
278281
if (this.paused) this.resume();
279-
if (this.terminal) {
282+
if (this.terminal && process.env.TERM !== 'dumb') {
280283
if (!preserveCursor) this.cursor = 0;
281284
this._refreshLine();
282285
} else {
@@ -417,7 +420,11 @@ Interface.prototype.resume = function() {
417420

418421
Interface.prototype.write = function(d, key) {
419422
if (this.paused) this.resume();
420-
this.terminal ? this._ttyWrite(d, key) : this._normalWrite(d);
423+
if (this.terminal) {
424+
this._ttyWrite(d, key);
425+
} else {
426+
this._normalWrite(d);
427+
}
421428
};
422429

423430
Interface.prototype._normalWrite = function(b) {
@@ -789,6 +796,46 @@ Interface.prototype._moveCursor = function(dx) {
789796
}
790797
};
791798

799+
function _ttyWriteDumb(s, key) {
800+
key = key || {};
801+
802+
if (key.name === 'escape') return;
803+
804+
if (this._sawReturnAt && key.name !== 'enter')
805+
this._sawReturnAt = 0;
806+
807+
if (key.ctrl && key.name === 'c') {
808+
if (this.listenerCount('SIGINT') > 0) {
809+
this.emit('SIGINT');
810+
} else {
811+
// This readline instance is finished
812+
this.close();
813+
}
814+
}
815+
816+
switch (key.name) {
817+
case 'return': // carriage return, i.e. \r
818+
this._sawReturnAt = Date.now();
819+
this._line();
820+
break;
821+
822+
case 'enter':
823+
// When key interval > crlfDelay
824+
if (this._sawReturnAt === 0 ||
825+
Date.now() - this._sawReturnAt > this.crlfDelay) {
826+
this._line();
827+
}
828+
this._sawReturnAt = 0;
829+
break;
830+
831+
default:
832+
if (typeof s === 'string' && s) {
833+
this.line += s;
834+
this.cursor += s.length;
835+
this._writeToOutput(s);
836+
}
837+
}
838+
}
792839

793840
// handle a write from the tty
794841
Interface.prototype._ttyWrite = function(s, key) {
@@ -1007,10 +1054,7 @@ Interface.prototype._ttyWrite = function(s, key) {
10071054
// falls through
10081055

10091056
default:
1010-
if (s instanceof Buffer)
1011-
s = s.toString('utf-8');
1012-
1013-
if (s) {
1057+
if (typeof s === 'string' && s) {
10141058
var lines = s.split(/\r\n|\n|\r/);
10151059
for (var i = 0, len = lines.length; i < len; i++) {
10161060
if (i > 0) {

test/pseudo-tty/readline-dumb-tty.js

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
'use strict';
2+
require('../common');
3+
4+
process.env.TERM = 'dumb';
5+
6+
const readline = require('readline');
7+
8+
const rl = readline.createInterface({
9+
input: process.stdin,
10+
output: process.stdout
11+
});
12+
13+
rl.write('text');
14+
rl.write(null, { ctrl: true, name: 'u' });
15+
rl.write(null, { name: 'return' });
16+
rl.write('text');
17+
rl.write(null, { name: 'backspace' });
18+
rl.write(null, { name: 'escape' });
19+
rl.write(null, { name: 'enter' });
20+
rl.write('text');
21+
rl.write(null, { ctrl: true, name: 'c' });

test/pseudo-tty/readline-dumb-tty.out

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
text
2+
text
3+
text

0 commit comments

Comments
 (0)