|
19 | 19 | + (regexp.multiline ? "m" : "") |
20 | 20 | } |
21 | 21 |
|
22 | | - function ensureGlobal(regexp) { |
23 | | - return regexp.global ? regexp : new RegExp(regexp.source, regexpFlags(regexp) + "g") |
| 22 | + function ensureFlags(regexp, flags) { |
| 23 | + var current = regexpFlags(regexp), target = current |
| 24 | + for (var i = 0; i < flags.length; i++) if (target.indexOf(flags.charAt(i)) == -1) |
| 25 | + target += flags.charAt(i) |
| 26 | + return current == target ? regexp : new RegExp(regexp.source, target) |
24 | 27 | } |
25 | 28 |
|
26 | 29 | function maybeMultiline(regexp) { |
27 | 30 | return /\\s|\\n|\n|\\W|\\D|\[\^/.test(regexp.source) |
28 | 31 | } |
29 | 32 |
|
30 | 33 | function searchRegexpForward(doc, regexp, start) { |
31 | | - regexp = ensureGlobal(regexp) |
| 34 | + regexp = ensureFlags(regexp, "g") |
32 | 35 | for (var line = start.line, ch = start.ch, last = doc.lastLine(); line <= last; line++, ch = 0) { |
33 | 36 | regexp.lastIndex = ch |
34 | 37 | var string = doc.getLine(line), match = regexp.exec(string) |
|
42 | 45 | function searchRegexpForwardMultiline(doc, regexp, start) { |
43 | 46 | if (!maybeMultiline(regexp)) return searchRegexpForward(doc, regexp, start) |
44 | 47 |
|
45 | | - regexp = ensureGlobal(regexp) |
| 48 | + regexp = ensureFlags(regexp, "gm") |
46 | 49 | var string, chunk = 1 |
47 | 50 | for (var line = start.line, last = doc.lastLine(); line <= last;) { |
48 | 51 | // This grows the search buffer in exponentially-sized chunks |
|
51 | 54 | // searching for something that has tons of matches), but at the |
52 | 55 | // same time, the amount of retries is limited. |
53 | 56 | for (var i = 0; i < chunk; i++) { |
| 57 | + if (line > last) break |
54 | 58 | var curLine = doc.getLine(line++) |
55 | 59 | string = string == null ? curLine : string + "\n" + curLine |
56 | 60 | } |
|
81 | 85 | } |
82 | 86 |
|
83 | 87 | function searchRegexpBackward(doc, regexp, start) { |
84 | | - regexp = ensureGlobal(regexp) |
| 88 | + regexp = ensureFlags(regexp, "g") |
85 | 89 | for (var line = start.line, ch = start.ch, first = doc.firstLine(); line >= first; line--, ch = -1) { |
86 | 90 | var string = doc.getLine(line) |
87 | 91 | if (ch > -1) string = string.slice(0, ch) |
|
94 | 98 | } |
95 | 99 |
|
96 | 100 | function searchRegexpBackwardMultiline(doc, regexp, start) { |
97 | | - regexp = ensureGlobal(regexp) |
| 101 | + regexp = ensureFlags(regexp, "gm") |
98 | 102 | var string, chunk = 1 |
99 | 103 | for (var line = start.line, first = doc.firstLine(); line >= first;) { |
100 | 104 | for (var i = 0; i < chunk; i++) { |
|
213 | 217 | return (reverse ? searchStringBackward : searchStringForward)(doc, query, pos, caseFold) |
214 | 218 | } |
215 | 219 | } else { |
216 | | - query = ensureGlobal(query) |
| 220 | + query = ensureFlags(query, "gm") |
217 | 221 | if (!options || options.multiline !== false) |
218 | 222 | this.matches = function(reverse, pos) { |
219 | 223 | return (reverse ? searchRegexpBackwardMultiline : searchRegexpForwardMultiline)(doc, query, pos) |
|
0 commit comments