readline: expose stream API in moveCursor()
This commit adds an optional callback to moveCursor(), which is passed to the stream's write() method. It also exposes the return value of write(). PR-URL: https://github.com/nodejs/node/pull/28674 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
This commit is contained in:
parent
79cc8bb241
commit
795c7482f2
@ -525,14 +525,22 @@ if (process.stdin.isTTY)
|
||||
process.stdin.setRawMode(true);
|
||||
```
|
||||
|
||||
## readline.moveCursor(stream, dx, dy)
|
||||
## readline.moveCursor(stream, dx, dy[, callback])
|
||||
<!-- YAML
|
||||
added: v0.7.7
|
||||
changes:
|
||||
- version: REPLACEME
|
||||
pr-url: https://github.com/nodejs/node/pull/28674
|
||||
description: The stream's write() callback and return value are exposed.
|
||||
-->
|
||||
|
||||
* `stream` {stream.Writable}
|
||||
* `dx` {number}
|
||||
* `dy` {number}
|
||||
* `callback` {Function} Invoked once the operation completes.
|
||||
* Returns: {boolean} `false` if `stream` wishes for the calling code to wait for
|
||||
the `'drain'` event to be emitted before continuing to write additional data;
|
||||
otherwise `true`.
|
||||
|
||||
The `readline.moveCursor()` method moves the cursor *relative* to its current
|
||||
position in a given [TTY][] `stream`.
|
||||
|
@ -1210,21 +1210,31 @@ function cursorTo(stream, x, y) {
|
||||
* moves the cursor relative to its current location
|
||||
*/
|
||||
|
||||
function moveCursor(stream, dx, dy) {
|
||||
if (stream === null || stream === undefined)
|
||||
return;
|
||||
function moveCursor(stream, dx, dy, callback) {
|
||||
if (callback !== undefined && typeof callback !== 'function')
|
||||
throw new ERR_INVALID_CALLBACK(callback);
|
||||
|
||||
if (stream == null || !(dx || dy)) {
|
||||
if (typeof callback === 'function')
|
||||
process.nextTick(callback);
|
||||
return true;
|
||||
}
|
||||
|
||||
let data = '';
|
||||
|
||||
if (dx < 0) {
|
||||
stream.write(CSI`${-dx}D`);
|
||||
data += CSI`${-dx}D`;
|
||||
} else if (dx > 0) {
|
||||
stream.write(CSI`${dx}C`);
|
||||
data += CSI`${dx}C`;
|
||||
}
|
||||
|
||||
if (dy < 0) {
|
||||
stream.write(CSI`${-dy}A`);
|
||||
data += CSI`${-dy}A`;
|
||||
} else if (dy > 0) {
|
||||
stream.write(CSI`${dy}B`);
|
||||
data += CSI`${dy}B`;
|
||||
}
|
||||
|
||||
return stream.write(data, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -83,10 +83,28 @@ assert.strictEqual(readline.clearLine(undefined, 0, common.mustCall()), true);
|
||||
[1, -1, '\x1b[1C\x1b[1A'],
|
||||
].forEach((set) => {
|
||||
writable.data = '';
|
||||
readline.moveCursor(writable, set[0], set[1]);
|
||||
assert.strictEqual(readline.moveCursor(writable, set[0], set[1]), true);
|
||||
assert.deepStrictEqual(writable.data, set[2]);
|
||||
writable.data = '';
|
||||
assert.strictEqual(
|
||||
readline.moveCursor(writable, set[0], set[1], common.mustCall()),
|
||||
true
|
||||
);
|
||||
assert.deepStrictEqual(writable.data, set[2]);
|
||||
});
|
||||
|
||||
// Verify that moveCursor() throws on invalid callback.
|
||||
assert.throws(() => {
|
||||
readline.moveCursor(writable, 1, 1, null);
|
||||
}, /ERR_INVALID_CALLBACK/);
|
||||
|
||||
// Verify that moveCursor() does not throw on null or undefined stream.
|
||||
assert.strictEqual(readline.moveCursor(null, 1, 1), true);
|
||||
assert.strictEqual(readline.moveCursor(undefined, 1, 1), true);
|
||||
assert.strictEqual(readline.moveCursor(null, 1, 1, common.mustCall()), true);
|
||||
assert.strictEqual(readline.moveCursor(undefined, 1, 1, common.mustCall()),
|
||||
true);
|
||||
|
||||
// Undefined or null as stream should not throw.
|
||||
readline.cursorTo(null);
|
||||
readline.cursorTo();
|
||||
|
Loading…
x
Reference in New Issue
Block a user