tty: expose stream API from readline methods

This commit exposes the return value and callback of the
underlying readline APIs from the tty module.

PR-URL: https://github.com/nodejs/node/pull/28721
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
This commit is contained in:
cjihrig 2019-07-16 11:46:59 -04:00
parent 3da44b0b52
commit d0894773a4
No known key found for this signature in database
GPG Key ID: 7434390BDBE9B9C5
3 changed files with 70 additions and 18 deletions

View File

@ -99,24 +99,41 @@ process.stdout.on('resize', () => {
}); });
``` ```
### writeStream.clearLine(dir) ### writeStream.clearLine(dir[, callback])
<!-- YAML <!-- YAML
added: v0.7.7 added: v0.7.7
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/28721
description: The stream's write() callback and return value are exposed.
--> -->
* `dir` {number} * `dir` {number}
* `-1` - to the left from cursor * `-1` - to the left from cursor
* `1` - to the right from cursor * `1` - to the right from cursor
* `0` - the entire line * `0` - the entire line
* `callback` {Function} Invoked once the operation completes.
* Returns: {boolean} `false` if the stream wishes for the calling code to wait
for the `'drain'` event to be emitted before continuing to write additional
data; otherwise `true`.
`writeStream.clearLine()` clears the current line of this `WriteStream` in a `writeStream.clearLine()` clears the current line of this `WriteStream` in a
direction identified by `dir`. direction identified by `dir`.
### writeStream.clearScreenDown() ### writeStream.clearScreenDown([callback])
<!-- YAML <!-- YAML
added: v0.7.7 added: v0.7.7
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/28721
description: The stream's write() callback and return value are exposed.
--> -->
* `callback` {Function} Invoked once the operation completes.
* Returns: {boolean} `false` if the stream wishes for the calling code to wait
for the `'drain'` event to be emitted before continuing to write additional
data; otherwise `true`.
`writeStream.clearScreenDown()` clears this `WriteStream` from the current `writeStream.clearScreenDown()` clears this `WriteStream` from the current
cursor down. cursor down.
@ -128,13 +145,21 @@ added: v0.7.7
A `number` specifying the number of columns the TTY currently has. This property A `number` specifying the number of columns the TTY currently has. This property
is updated whenever the `'resize'` event is emitted. is updated whenever the `'resize'` event is emitted.
### writeStream.cursorTo(x, y) ### writeStream.cursorTo(x, y[, callback])
<!-- YAML <!-- YAML
added: v0.7.7 added: v0.7.7
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/28721
description: The stream's write() callback and return value are exposed.
--> -->
* `x` {number} * `x` {number}
* `y` {number} * `y` {number}
* `callback` {Function} Invoked once the operation completes.
* Returns: {boolean} `false` if the stream wishes for the calling code to wait
for the `'drain'` event to be emitted before continuing to write additional
data; otherwise `true`.
`writeStream.cursorTo()` moves this `WriteStream`'s cursor to the specified `writeStream.cursorTo()` moves this `WriteStream`'s cursor to the specified
position. position.
@ -220,13 +245,21 @@ added: v0.5.8
A `boolean` that is always `true`. A `boolean` that is always `true`.
### writeStream.moveCursor(dx, dy) ### writeStream.moveCursor(dx, dy[, callback])
<!-- YAML <!-- YAML
added: v0.7.7 added: v0.7.7
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/28721
description: The stream's write() callback and return value are exposed.
--> -->
* `dx` {number} * `dx` {number}
* `dy` {number} * `dy` {number}
* `callback` {Function} Invoked once the operation completes.
* Returns: {boolean} `false` if the stream wishes for the calling code to wait
for the `'drain'` event to be emitted before continuing to write additional
data; otherwise `true`.
`writeStream.moveCursor()` moves this `WriteStream`'s cursor *relative* to its `writeStream.moveCursor()` moves this `WriteStream`'s cursor *relative* to its
current position. current position.

View File

@ -137,21 +137,21 @@ WriteStream.prototype._refreshSize = function() {
}; };
// Backwards-compat // Backwards-compat
WriteStream.prototype.cursorTo = function(x, y) { WriteStream.prototype.cursorTo = function(x, y, callback) {
if (readline === undefined) readline = require('readline'); if (readline === undefined) readline = require('readline');
readline.cursorTo(this, x, y); return readline.cursorTo(this, x, y, callback);
}; };
WriteStream.prototype.moveCursor = function(dx, dy) { WriteStream.prototype.moveCursor = function(dx, dy, callback) {
if (readline === undefined) readline = require('readline'); if (readline === undefined) readline = require('readline');
readline.moveCursor(this, dx, dy); return readline.moveCursor(this, dx, dy, callback);
}; };
WriteStream.prototype.clearLine = function(dir) { WriteStream.prototype.clearLine = function(dir, callback) {
if (readline === undefined) readline = require('readline'); if (readline === undefined) readline = require('readline');
readline.clearLine(this, dir); return readline.clearLine(this, dir, callback);
}; };
WriteStream.prototype.clearScreenDown = function() { WriteStream.prototype.clearScreenDown = function(callback) {
if (readline === undefined) readline = require('readline'); if (readline === undefined) readline = require('readline');
readline.clearScreenDown(this); return readline.clearScreenDown(this, callback);
}; };
WriteStream.prototype.getWindowSize = function() { WriteStream.prototype.getWindowSize = function() {
return [this.columns, this.rows]; return [this.columns, this.rows];

View File

@ -1,6 +1,8 @@
// Flags: --expose-internals // Flags: --expose-internals
'use strict'; 'use strict';
const common = require('../common'); const common = require('../common');
const assert = require('assert');
const readline = require('readline');
const noop = () => {}; const noop = () => {};
const { internalBinding } = require('internal/test/binding'); const { internalBinding } = require('internal/test/binding');
@ -13,15 +15,32 @@ TTY.prototype = {
const { WriteStream } = require('tty'); const { WriteStream } = require('tty');
const methods = [ [
'cursorTo', 'cursorTo',
'moveCursor', 'moveCursor',
'clearLine', 'clearLine',
'clearScreenDown' 'clearScreenDown'
]; ].forEach((method) => {
readline[method] = common.mustCall(function() {
const lastArg = arguments[arguments.length - 1];
methods.forEach((method) => { if (typeof lastArg === 'function') {
require('readline')[method] = common.mustCall(); process.nextTick(lastArg);
const writeStream = new WriteStream(1); }
writeStream[method](1, 2);
return true;
}, 2);
}); });
const writeStream = new WriteStream(1);
// Verify that the corresponding readline methods are called, that the return
// values are propagated, and any callbacks are invoked.
assert.strictEqual(writeStream.cursorTo(1, 2), true);
assert.strictEqual(writeStream.cursorTo(1, 2, common.mustCall()), true);
assert.strictEqual(writeStream.moveCursor(1, 2), true);
assert.strictEqual(writeStream.moveCursor(1, 2, common.mustCall()), true);
assert.strictEqual(writeStream.clearLine(1), true);
assert.strictEqual(writeStream.clearLine(1, common.mustCall()), true);
assert.strictEqual(writeStream.clearScreenDown(), true);
assert.strictEqual(writeStream.clearScreenDown(common.mustCall()), true);