All files / lib/internal/readline callbacks.js

100% Statements 132/132
100% Branches 57/57
100% Functions 4/4
100% Lines 132/132

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 1332x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 1165x 1165x 4x 4x 1164x 1165x 1x 1x 1x 1164x 1165x 1165x 1161x 1165x 44x 44x 44x 1117x 1131x 1116x 1165x 1165x 1165x 2x 2x 2x 2x 2x 979x 979x 12x 12x 978x 979x 611x 611x 611x 367x 367x 367x 795x 47x 795x 33x 33x 367x 794x 204x 795x 91x 91x 367x 367x 979x 2x 2x 2x 2x 2x 2x 2x 2x 152x 152x 4x 4x 151x 152x 4x 4x 4x 147x 147x 152x 152x 152x 2x 2x 2x 2x 2x 480x 480x 4x 4x 479x 480x 21x 21x 21x 458x 458x 480x 2x 2x 2x 2x 2x 2x 2x  
'use strict';
 
const {
  NumberIsNaN,
} = primordials;
 
const {
  codes: {
    ERR_INVALID_ARG_VALUE,
    ERR_INVALID_CURSOR_POS,
  },
} = require('internal/errors');
 
const {
  validateCallback,
} = 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) {
    validateCallback(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) {
    validateCallback(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) {
    validateCallback(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) {
    validateCallback(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,
};