var format = require('util').format, cliUtils = require('../reporters/cli/cli-utils'), SPC = ' ', BS = '\b', LF = '\n', WAIT_FRAMES = (/^win/).test(process.platform) ? ['\u2015', '\\', '|', '/'] : ['⠄', '⠆', '⠇', '⠋', '⠙', '⠸', '⠰', '⠠', '⠰', '⠸', '⠙', '⠋', '⠇', '⠆'], WAIT_FRAMES_SIZE = WAIT_FRAMES.length - 1, WAIT_FRAMERATE = 100, print; /** * Function that prints to stdout using standard NodeJS util.format, without end newline. * * @returns {print} - The result of context bound call to the run context, with all arguments passed. * @chainable */ print = function () { return print.print.apply(this, arguments); }; /** * Function that prints to stdout using standard NodeJS util.format, without end newline. * * @returns {print} - The updated print module wrapper, with unwait and unbuffer methods invoked. * @chainable */ print.print = function () { print.waiting && print.unwait(); print._buffer && print.unbuffer(); process.stdout.write(format.apply(this, arguments)); return print; }; /** * Print with a line feed at the end. * * @returns {print} - The updated print module wrapper, with unwait and unbuffer methods invoked. * @chainable */ print.lf = function () { print.waiting && print.unwait(); print._buffer && print.unbuffer(); process.stdout.write(format.apply(this, arguments) + LF); return print; }; // store the starting frame during wait print._waitPosition = 0; /** * Draw a spinner until next print statement is received. * * @param {Function=} color - Optional color function from `colors` module. * @returns {print} - The print module wrapper, with a key set as a setInterval label. * @chainable */ print.wait = function (color) { print.unwait(); if (cliUtils.noTTY()) { return print; } process.stdout.write(SPC); print.waiting = setInterval(function () { process.stdout.write(BS + (color ? color(WAIT_FRAMES[print._waitPosition++]) : WAIT_FRAMES[print._waitPosition++])); (print._waitPosition > WAIT_FRAMES_SIZE) && (print._waitPosition = 0); // move frame }, WAIT_FRAMERATE); return print; }; /** * Stops a running spinner on CLI. It is automatically taken care of in most cases. * * @returns {print} - Returns the updated print module wrapper, with the cleared waiting label. * @chainable * @see print.wait */ print.unwait = function () { if (print.waiting) { print.waiting = clearInterval(print.waiting); print._waitPosition = 0; process.stdout.write('\b'); } return print; }; print._buffer = undefined; /** * Prints a message between start and end text. Consequent buffer calls does not print the start text and any other * unbuffered call or a delay of time prints the end text. * * @param {String} startText - The text to begin printing with. * @param {String} endText - The text that marks the end of the print routine. * @returns {print} - The update print module wrapper with internal buffer and buffering members redefined. * @chainable */ print.buffer = function (startText, endText) { (print._buffer === undefined) && process.stdout.write(startText); print._buffer = endText; print._buferring && (print._buferring = clearTimeout(print._buferring)); print._buferring = setTimeout(print.unbuffer, 500); process.stdout.write(format.apply(this, Array.prototype.splice.call(arguments, 2))); return print; }; /** * Prints text without flushing the buffer. * * @returns {print} - The update print module wrapper with unwait called. * @chainable * @see print.buffer */ print.nobuffer = function () { print.unwait(); process.stdout.write(format.apply(this, arguments)); return print; }; /** * Flushes the buffer. * * @returns {print} - The print module wrapper with internal private members: buffer, and buffering redefined. * @chainable * @see print.buffer */ print.unbuffer = function () { print._buferring && (print._buferring = clearTimeout(print._buferring)); if (print._buffer) { process.stdout.write(print._buffer); print._buffer = undefined; } return print; }; module.exports = print;