.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / glob-to-regexp / index.js
1 module.exports = function (glob, opts) {
2   if (typeof glob !== 'string') {
3     throw new TypeError('Expected a string');
4   }
5
6   var str = String(glob);
7
8   // The regexp we are building, as a string.
9   var reStr = "";
10
11   // Whether we are matching so called "extended" globs (like bash) and should
12   // support single character matching, matching ranges of characters, group
13   // matching, etc.
14   var extended = opts ? !!opts.extended : false;
15
16   // When globstar is _false_ (default), '/foo/*' is translated a regexp like
17   // '^\/foo\/.*$' which will match any string beginning with '/foo/'
18   // When globstar is _true_, '/foo/*' is translated to regexp like
19   // '^\/foo\/[^/]*$' which will match any string beginning with '/foo/' BUT
20   // which does not have a '/' to the right of it.
21   // E.g. with '/foo/*' these will match: '/foo/bar', '/foo/bar.txt' but
22   // these will not '/foo/bar/baz', '/foo/bar/baz.txt'
23   // Lastely, when globstar is _true_, '/foo/**' is equivelant to '/foo/*' when
24   // globstar is _false_
25   var globstar = opts ? !!opts.globstar : false;
26
27   // If we are doing extended matching, this boolean is true when we are inside
28   // a group (eg {*.html,*.js}), and false otherwise.
29   var inGroup = false;
30
31   // RegExp flags (eg "i" ) to pass in to RegExp constructor.
32   var flags = opts && typeof( opts.flags ) === "string" ? opts.flags : "";
33
34   var c;
35   for (var i = 0, len = str.length; i < len; i++) {
36     c = str[i];
37
38     switch (c) {
39     case "\\":
40     case "/":
41     case "$":
42     case "^":
43     case "+":
44     case ".":
45     case "(":
46     case ")":
47     case "=":
48     case "!":
49     case "|":
50       reStr += "\\" + c;
51       break;
52
53     case "?":
54       if (extended) {
55         reStr += ".";
56             break;
57       }
58
59     case "[":
60     case "]":
61       if (extended) {
62         reStr += c;
63             break;
64       }
65
66     case "{":
67       if (extended) {
68         inGroup = true;
69             reStr += "(";
70             break;
71       }
72
73     case "}":
74       if (extended) {
75         inGroup = false;
76             reStr += ")";
77             break;
78       }
79
80     case ",":
81       if (inGroup) {
82         reStr += "|";
83             break;
84       }
85       reStr += "\\" + c;
86       break;
87
88     case "*":
89       // Move over all consecutive "*"'s.
90       // Also store the previous and next characters
91       var prevChar = str[i - 1];
92       var starCount = 1;
93       while(str[i + 1] === "*") {
94         starCount++;
95         i++;
96       }
97       var nextChar = str[i + 1];
98
99       if (!globstar) {
100         // globstar is disabled, so treat any number of "*" as one
101         reStr += ".*";
102       } else {
103         // globstar is enabled, so determine if this is a globstar segment
104         var isGlobstar = starCount > 1                      // multiple "*"'s
105           && (prevChar === "/" || prevChar === undefined)   // from the start of the segment
106           && (nextChar === "/" || nextChar === undefined)   // to the end of the segment
107
108         if (isGlobstar) {
109           // it's a globstar, so match zero or more path segments
110           reStr += "(?:[^/]*(?:\/|$))*";
111           i++; // move over the "/"
112         } else {
113           // it's not a globstar, so only match one path segment
114           reStr += "[^/]*";
115         }
116       }
117       break;
118
119     default:
120       reStr += c;
121     }
122   }
123
124   // When regexp 'g' flag is specified don't
125   // constrain the regular expression with ^ & $
126   if (!flags || !~flags.indexOf('g')) {
127     reStr = "^" + reStr + "$";
128   }
129
130   return new RegExp(reStr, flags);
131 };