.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / fast-glob / node_modules / expand-brackets / lib / parsers.js
1 'use strict';
2
3 var utils = require('./utils');
4 var define = require('define-property');
5
6 /**
7  * Text regex
8  */
9
10 var TEXT_REGEX = '(\\[(?=.*\\])|\\])+';
11 var not = utils.createRegex(TEXT_REGEX);
12
13 /**
14  * Brackets parsers
15  */
16
17 function parsers(brackets) {
18   brackets.state = brackets.state || {};
19   brackets.parser.sets.bracket = brackets.parser.sets.bracket || [];
20   brackets.parser
21
22     .capture('escape', function() {
23       if (this.isInside('bracket')) return;
24       var pos = this.position();
25       var m = this.match(/^\\(.)/);
26       if (!m) return;
27
28       return pos({
29         type: 'escape',
30         val: m[0]
31       });
32     })
33
34     /**
35      * Text parser
36      */
37
38     .capture('text', function() {
39       if (this.isInside('bracket')) return;
40       var pos = this.position();
41       var m = this.match(not);
42       if (!m || !m[0]) return;
43
44       return pos({
45         type: 'text',
46         val: m[0]
47       });
48     })
49
50     /**
51      * POSIX character classes: "[[:alpha:][:digits:]]"
52      */
53
54     .capture('posix', function() {
55       var pos = this.position();
56       var m = this.match(/^\[:(.*?):\](?=.*\])/);
57       if (!m) return;
58
59       var inside = this.isInside('bracket');
60       if (inside) {
61         brackets.posix++;
62       }
63
64       return pos({
65         type: 'posix',
66         insideBracket: inside,
67         inner: m[1],
68         val: m[0]
69       });
70     })
71
72     /**
73      * Bracket (noop)
74      */
75
76     .capture('bracket', function() {})
77
78     /**
79      * Open: '['
80      */
81
82     .capture('bracket.open', function() {
83       var parsed = this.parsed;
84       var pos = this.position();
85       var m = this.match(/^\[(?=.*\])/);
86       if (!m) return;
87
88       var prev = this.prev();
89       var last = utils.last(prev.nodes);
90
91       if (parsed.slice(-1) === '\\' && !this.isInside('bracket')) {
92         last.val = last.val.slice(0, last.val.length - 1);
93         return pos({
94           type: 'escape',
95           val: m[0]
96         });
97       }
98
99       var open = pos({
100         type: 'bracket.open',
101         val: m[0]
102       });
103
104       if (last.type === 'bracket.open' || this.isInside('bracket')) {
105         open.val = '\\' + open.val;
106         open.type = 'bracket.inner';
107         open.escaped = true;
108         return open;
109       }
110
111       var node = pos({
112         type: 'bracket',
113         nodes: [open]
114       });
115
116       define(node, 'parent', prev);
117       define(open, 'parent', node);
118       this.push('bracket', node);
119       prev.nodes.push(node);
120     })
121
122     /**
123      * Bracket text
124      */
125
126     .capture('bracket.inner', function() {
127       if (!this.isInside('bracket')) return;
128       var pos = this.position();
129       var m = this.match(not);
130       if (!m || !m[0]) return;
131
132       var next = this.input.charAt(0);
133       var val = m[0];
134
135       var node = pos({
136         type: 'bracket.inner',
137         val: val
138       });
139
140       if (val === '\\\\') {
141         return node;
142       }
143
144       var first = val.charAt(0);
145       var last = val.slice(-1);
146
147       if (first === '!') {
148         val = '^' + val.slice(1);
149       }
150
151       if (last === '\\' || (val === '^' && next === ']')) {
152         val += this.input[0];
153         this.consume(1);
154       }
155
156       node.val = val;
157       return node;
158     })
159
160     /**
161      * Close: ']'
162      */
163
164     .capture('bracket.close', function() {
165       var parsed = this.parsed;
166       var pos = this.position();
167       var m = this.match(/^\]/);
168       if (!m) return;
169
170       var prev = this.prev();
171       var last = utils.last(prev.nodes);
172
173       if (parsed.slice(-1) === '\\' && !this.isInside('bracket')) {
174         last.val = last.val.slice(0, last.val.length - 1);
175
176         return pos({
177           type: 'escape',
178           val: m[0]
179         });
180       }
181
182       var node = pos({
183         type: 'bracket.close',
184         rest: this.input,
185         val: m[0]
186       });
187
188       if (last.type === 'bracket.open') {
189         node.type = 'bracket.inner';
190         node.escaped = true;
191         return node;
192       }
193
194       var bracket = this.pop('bracket');
195       if (!this.isType(bracket, 'bracket')) {
196         if (this.options.strict) {
197           throw new Error('missing opening "["');
198         }
199         node.type = 'bracket.inner';
200         node.escaped = true;
201         return node;
202       }
203
204       bracket.nodes.push(node);
205       define(node, 'parent', bracket);
206     });
207 }
208
209 /**
210  * Brackets parsers
211  */
212
213 module.exports = parsers;
214
215 /**
216  * Expose text regex
217  */
218
219 module.exports.TEXT_REGEX = TEXT_REGEX;