'use strict'; const { NumberIsNaN, } = primordials; const { codes: { ERR_INVALID_ARG_VALUE, ERR_INVALID_CURSOR_POS, }, } = require('internal/errors'); const { validateFunction, } = require('internal/validators'); const { CSI, } = require('internal/readline/utils'); const { kClearLine, kClearScreenDown, kClearToLineBeginning, kClearToLineEnd, } = CSI; /** * moves the cursor to the x and y coordinate on the given stream */ function cursorTo(stream, x, y, callback) { if (callback !== undefined) { validateFunction(callback, 'callback'); } if (typeof y === 'function') { callback = y; y = undefined; } if (NumberIsNaN(x)) throw new ERR_INVALID_ARG_VALUE('x', x); if (NumberIsNaN(y)) throw new ERR_INVALID_ARG_VALUE('y', y); if (stream == null || (typeof x !== 'number' && typeof y !== 'number')) { if (typeof callback === 'function') process.nextTick(callback, null); return true; } if (typeof x !== 'number') throw new ERR_INVALID_CURSOR_POS(); const data = typeof y !== 'number' ? CSI`${x + 1}G` : CSI`${y + 1};${x + 1}H`; return stream.write(data, callback); } /** * moves the cursor relative to its current location */ function moveCursor(stream, dx, dy, callback) { if (callback !== undefined) { validateFunction(callback, 'callback'); } if (stream == null || !(dx || dy)) { if (typeof callback === 'function') process.nextTick(callback, null); return true; } let data = ''; if (dx < 0) { data += CSI`${-dx}D`; } else if (dx > 0) { data += CSI`${dx}C`; } if (dy < 0) { data += CSI`${-dy}A`; } else if (dy > 0) { data += CSI`${dy}B`; } return stream.write(data, callback); } /** * clears the current line the cursor is on: * -1 for left of the cursor * +1 for right of the cursor * 0 for the entire line */ function clearLine(stream, dir, callback) { if (callback !== undefined) { validateFunction(callback, 'callback'); } if (stream === null || stream === undefined) { if (typeof callback === 'function') process.nextTick(callback, null); return true; } const type = dir < 0 ? kClearToLineBeginning : dir > 0 ? kClearToLineEnd : kClearLine; return stream.write(type, callback); } /** * clears the screen from the current position of the cursor down */ function clearScreenDown(stream, callback) { if (callback !== undefined) { validateFunction(callback, 'callback'); } if (stream === null || stream === undefined) { if (typeof callback === 'function') process.nextTick(callback, null); return true; } return stream.write(kClearScreenDown, callback); } module.exports = { clearLine, clearScreenDown, cursorTo, moveCursor, };