.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / slice-ansi / index.js
1 'use strict';
2 const isFullwidthCodePoint = require('is-fullwidth-code-point');
3 const astralRegex = require('astral-regex');
4 const ansiStyles = require('ansi-styles');
5
6 const ESCAPES = [
7         '\u001B',
8         '\u009B'
9 ];
10
11 const wrapAnsi = code => `${ESCAPES[0]}[${code}m`;
12
13 const checkAnsi = (ansiCodes, isEscapes, endAnsiCode) => {
14         let output = [];
15         ansiCodes = [...ansiCodes];
16
17         for (let ansiCode of ansiCodes) {
18                 const ansiCodeOrigin = ansiCode;
19                 if (ansiCode.includes(';')) {
20                         ansiCode = ansiCode.split(';')[0][0] + '0';
21                 }
22
23                 const item = ansiStyles.codes.get(Number.parseInt(ansiCode, 10));
24                 if (item) {
25                         const indexEscape = ansiCodes.indexOf(item.toString());
26                         if (indexEscape === -1) {
27                                 output.push(wrapAnsi(isEscapes ? item : ansiCodeOrigin));
28                         } else {
29                                 ansiCodes.splice(indexEscape, 1);
30                         }
31                 } else if (isEscapes) {
32                         output.push(wrapAnsi(0));
33                         break;
34                 } else {
35                         output.push(wrapAnsi(ansiCodeOrigin));
36                 }
37         }
38
39         if (isEscapes) {
40                 output = output.filter((element, index) => output.indexOf(element) === index);
41
42                 if (endAnsiCode !== undefined) {
43                         const fistEscapeCode = wrapAnsi(ansiStyles.codes.get(Number.parseInt(endAnsiCode, 10)));
44                         output = output.reduce((current, next) => next === fistEscapeCode ? [next, ...current] : [...current, next], []);
45                 }
46         }
47
48         return output.join('');
49 };
50
51 module.exports = (string, begin, end) => {
52         const characters = [...string];
53         const ansiCodes = [];
54
55         let stringEnd = typeof end === 'number' ? end : characters.length;
56         let isInsideEscape = false;
57         let ansiCode;
58         let visible = 0;
59         let output = '';
60
61         for (const [index, character] of characters.entries()) {
62                 let leftEscape = false;
63
64                 if (ESCAPES.includes(character)) {
65                         const code = /\d[^m]*/.exec(string.slice(index, index + 18));
66                         ansiCode = code && code.length > 0 ? code[0] : undefined;
67
68                         if (visible < stringEnd) {
69                                 isInsideEscape = true;
70
71                                 if (ansiCode !== undefined) {
72                                         ansiCodes.push(ansiCode);
73                                 }
74                         }
75                 } else if (isInsideEscape && character === 'm') {
76                         isInsideEscape = false;
77                         leftEscape = true;
78                 }
79
80                 if (!isInsideEscape && !leftEscape) {
81                         visible++;
82                 }
83
84                 if (!astralRegex({exact: true}).test(character) && isFullwidthCodePoint(character.codePointAt())) {
85                         visible++;
86
87                         if (typeof end !== 'number') {
88                                 stringEnd++;
89                         }
90                 }
91
92                 if (visible > begin && visible <= stringEnd) {
93                         output += character;
94                 } else if (visible === begin && !isInsideEscape && ansiCode !== undefined) {
95                         output = checkAnsi(ansiCodes);
96                 } else if (visible >= stringEnd) {
97                         output += checkAnsi(ansiCodes, true, ansiCode);
98                         break;
99                 }
100         }
101
102         return output;
103 };