123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- 'use strict';
-
- const isTerm = process.env.TERM_PROGRAM === 'Apple_Terminal';
- const colors = require('ansi-colors');
- const utils = require('./utils');
- const ansi = module.exports = exports;
- const ESC = '\u001b[';
- const BEL = '\u0007';
- let hidden = false;
-
- const code = ansi.code = {
- bell: BEL,
- beep: BEL,
- beginning: `${ESC}G`,
- down: `${ESC}J`,
- esc: ESC,
- getPosition: `${ESC}6n`,
- hide: `${ESC}?25l`,
- line: `${ESC}2K`,
- lineEnd: `${ESC}K`,
- lineStart: `${ESC}1K`,
- restorePosition: ESC + (isTerm ? '8' : 'u'),
- savePosition: ESC + (isTerm ? '7' : 's'),
- screen: `${ESC}2J`,
- show: `${ESC}?25h`,
- up: `${ESC}1J`
- };
-
- const cursor = ansi.cursor = {
- get hidden() {
- return hidden;
- },
-
- hide() {
- hidden = true;
- return code.hide;
- },
- show() {
- hidden = false;
- return code.show;
- },
-
- forward: (count = 1) => `${ESC}${count}C`,
- backward: (count = 1) => `${ESC}${count}D`,
- nextLine: (count = 1) => `${ESC}E`.repeat(count),
- prevLine: (count = 1) => `${ESC}F`.repeat(count),
-
- up: (count = 1) => count ? `${ESC}${count}A` : '',
- down: (count = 1) => count ? `${ESC}${count}B` : '',
- right: (count = 1) => count ? `${ESC}${count}C` : '',
- left: (count = 1) => count ? `${ESC}${count}D` : '',
-
- to(x, y) {
- return y ? `${ESC}${y + 1};${x + 1}H` : `${ESC}${x + 1}G`;
- },
-
- move(x = 0, y = 0) {
- let res = '';
- res += (x < 0) ? cursor.left(-x) : (x > 0) ? cursor.right(x) : '';
- res += (y < 0) ? cursor.up(-y) : (y > 0) ? cursor.down(y) : '';
- return res;
- },
-
- restore(state = {}) {
- let { after, cursor, initial, input, prompt, size, value } = state;
- initial = utils.isPrimitive(initial) ? String(initial) : '';
- input = utils.isPrimitive(input) ? String(input) : '';
- value = utils.isPrimitive(value) ? String(value) : '';
-
- if (size) {
- let codes = ansi.cursor.up(size) + ansi.cursor.to(prompt.length);
- let diff = input.length - cursor;
- if (diff > 0) {
- codes += ansi.cursor.left(diff);
- }
- return codes;
- }
-
- if (value || after) {
- let pos = (!input && !!initial) ? -initial.length : -input.length + cursor;
- if (after) pos -= after.length;
- if (input === '' && initial && !prompt.includes(initial)) {
- pos += initial.length;
- }
- return ansi.cursor.move(pos);
- }
- }
- };
-
- const erase = ansi.erase = {
- screen: code.screen,
- up: code.up,
- down: code.down,
- line: code.line,
- lineEnd: code.lineEnd,
- lineStart: code.lineStart,
- lines(n) {
- let str = '';
- for (let i = 0; i < n; i++) {
- str += ansi.erase.line + (i < n - 1 ? ansi.cursor.up(1) : '');
- }
- if (n) str += ansi.code.beginning;
- return str;
- }
- };
-
- ansi.clear = (input = '', columns = process.stdout.columns) => {
- if (!columns) return erase.line + cursor.to(0);
- let width = str => [...colors.unstyle(str)].length;
- let lines = input.split(/\r?\n/);
- let rows = 0;
- for (let line of lines) {
- rows += 1 + Math.floor(Math.max(width(line) - 1, 0) / columns);
- }
- return (erase.line + cursor.prevLine()).repeat(rows - 1) + erase.line + cursor.to(0);
- };
|