index.js 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. 'use strict';
  2. const ansiEscapes = require('ansi-escapes');
  3. const cliCursor = require('cli-cursor');
  4. const wrapAnsi = require('wrap-ansi');
  5. const sliceAnsi = require('slice-ansi');
  6. const defaultTerminalHeight = 24;
  7. const getWidth = stream => {
  8. const {columns} = stream;
  9. if (!columns) {
  10. return 80;
  11. }
  12. return columns;
  13. };
  14. const fitToTerminalHeight = (stream, text) => {
  15. const terminalHeight = stream.rows || defaultTerminalHeight;
  16. const lines = text.split('\n');
  17. const toRemove = lines.length - terminalHeight;
  18. if (toRemove <= 0) {
  19. return text;
  20. }
  21. return sliceAnsi(
  22. text,
  23. lines.slice(0, toRemove).join('\n').length + 1,
  24. text.length);
  25. };
  26. const main = (stream, {showCursor = false} = {}) => {
  27. let previousLineCount = 0;
  28. let previousWidth = getWidth(stream);
  29. let previousOutput = '';
  30. const render = (...args) => {
  31. if (!showCursor) {
  32. cliCursor.hide();
  33. }
  34. let output = args.join(' ') + '\n';
  35. output = fitToTerminalHeight(stream, output);
  36. const width = getWidth(stream);
  37. if (output === previousOutput && previousWidth === width) {
  38. return;
  39. }
  40. previousOutput = output;
  41. previousWidth = width;
  42. output = wrapAnsi(output, width, {
  43. trim: false,
  44. hard: true,
  45. wordWrap: false
  46. });
  47. stream.write(ansiEscapes.eraseLines(previousLineCount) + output);
  48. previousLineCount = output.split('\n').length;
  49. };
  50. render.clear = () => {
  51. stream.write(ansiEscapes.eraseLines(previousLineCount));
  52. previousOutput = '';
  53. previousWidth = getWidth(stream);
  54. previousLineCount = 0;
  55. };
  56. render.done = () => {
  57. previousOutput = '';
  58. previousWidth = getWidth(stream);
  59. previousLineCount = 0;
  60. if (!showCursor) {
  61. cliCursor.show();
  62. }
  63. };
  64. return render;
  65. };
  66. module.exports = main(process.stdout);
  67. module.exports.stderr = main(process.stderr);
  68. module.exports.create = main;