(cm, query, pos, caseFold)
| 2 | var Pos = CodeMirror.Pos; |
| 3 | |
| 4 | function SearchCursor(cm, query, pos, caseFold) { |
| 5 | this.atOccurrence = false; this.cm = cm; |
| 6 | if (caseFold == null && typeof query == "string") caseFold = false; |
| 7 | |
| 8 | pos = pos ? cm.clipPos(pos) : Pos(0, 0); |
| 9 | this.pos = {from: pos, to: pos}; |
| 10 | |
| 11 | // The matches method is filled in based on the type of query. |
| 12 | // It takes a position and a direction, and returns an object |
| 13 | // describing the next occurrence of the query, or null if no |
| 14 | // more matches were found. |
| 15 | if (typeof query != "string") { // Regexp match |
| 16 | if (!query.global) query = new RegExp(query.source, query.ignoreCase ? "ig" : "g"); |
| 17 | this.matches = function(reverse, pos) { |
| 18 | if (reverse) { |
| 19 | query.lastIndex = 0; |
| 20 | var line = cm.getLine(pos.line).slice(0, pos.ch), match = query.exec(line), start = 0; |
| 21 | while (match) { |
| 22 | start += match.index + 1; |
| 23 | line = line.slice(start); |
| 24 | query.lastIndex = 0; |
| 25 | var newmatch = query.exec(line); |
| 26 | if (newmatch) match = newmatch; |
| 27 | else break; |
| 28 | } |
| 29 | start--; |
| 30 | } else { |
| 31 | query.lastIndex = pos.ch; |
| 32 | var line = cm.getLine(pos.line), match = query.exec(line), |
| 33 | start = match && match.index; |
| 34 | } |
| 35 | if (match && match[0]) |
| 36 | return {from: Pos(pos.line, start), |
| 37 | to: Pos(pos.line, start + match[0].length), |
| 38 | match: match}; |
| 39 | }; |
| 40 | } else { // String query |
| 41 | if (caseFold) query = query.toLowerCase(); |
| 42 | var fold = caseFold ? function(str){return str.toLowerCase();} : function(str){return str;}; |
| 43 | var target = query.split("\n"); |
| 44 | // Different methods for single-line and multi-line queries |
| 45 | if (target.length == 1) { |
| 46 | if (!query.length) { |
| 47 | // Empty string would match anything and never progress, so |
| 48 | // we define it to match nothing instead. |
| 49 | this.matches = function() {}; |
| 50 | } else { |
| 51 | this.matches = function(reverse, pos) { |
| 52 | var line = fold(cm.getLine(pos.line)), len = query.length, match; |
| 53 | if (reverse ? (pos.ch >= len && (match = line.lastIndexOf(query, pos.ch - len)) != -1) |
| 54 | : (match = line.indexOf(query, pos.ch)) != -1) |
| 55 | return {from: Pos(pos.line, match), |
| 56 | to: Pos(pos.line, match + len)}; |
| 57 | }; |
| 58 | } |
| 59 | } else { |
| 60 | this.matches = function(reverse, pos) { |
| 61 | var ln = pos.line, idx = (reverse ? target.length - 1 : 0), match = target[idx], line = fold(cm.getLine(ln)); |
nothing calls this directly
no outgoing calls
no test coverage detected