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