refactor searching and add findAll method
This commit is contained in:
parent
a62062e576
commit
000a81da7f
2 changed files with 149 additions and 53 deletions
|
|
@ -27,63 +27,106 @@ ace.Search.SELECTION = 2;
|
|||
return null;
|
||||
|
||||
if (this.$options.backwards) {
|
||||
return this.$findBackward(doc);
|
||||
var iterator = this.$backwardMatchIterator(doc);
|
||||
} else {
|
||||
return this.$findForward(doc);
|
||||
}
|
||||
};
|
||||
|
||||
this.$findForward = function(doc) {
|
||||
var re = this.$assembleRegExp();
|
||||
var match = null;
|
||||
var matchedRow = -1;
|
||||
|
||||
this.$forwardLineIterator(doc).forEach(function(line, startIndex, row) {
|
||||
re.lastIndex = startIndex;
|
||||
match = re.exec(line);
|
||||
|
||||
if (match) {
|
||||
matchedRow = row;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
if (!match)
|
||||
return null;
|
||||
|
||||
return this.$rangeFromMatch(matchedRow, match.index, match[0].length);
|
||||
};
|
||||
|
||||
this.$findBackward = function(doc) {
|
||||
var re = this.$assembleRegExp();
|
||||
|
||||
var found = false;
|
||||
var lastOffset = 0;
|
||||
var lastRow = -1;
|
||||
var match = "";
|
||||
|
||||
this.$backwardLineIterator(doc).forEach(function(line, startIndex, row) {
|
||||
if (startIndex) {
|
||||
line = line.substring(startIndex);
|
||||
}
|
||||
line.replace(re, function(str, offset) {
|
||||
match = str;
|
||||
found = true;
|
||||
lastOffset = startIndex + offset;
|
||||
lastRow = row;
|
||||
return str;
|
||||
});
|
||||
|
||||
if (found) return true;
|
||||
});
|
||||
|
||||
if (!found) {
|
||||
return null;
|
||||
var iterator = this.$forwardMatchIterator(doc);
|
||||
}
|
||||
|
||||
return this.$rangeFromMatch(lastRow, lastOffset, match.length);
|
||||
var firstRange = null;
|
||||
iterator.forEach(function(range) {
|
||||
firstRange = range;
|
||||
return true;
|
||||
});
|
||||
|
||||
return firstRange;
|
||||
};
|
||||
|
||||
this.findAll = function(doc) {
|
||||
var needle = this.$options.needle;
|
||||
if (!this.$options.needle)
|
||||
return [];
|
||||
|
||||
if (this.$options.backwards) {
|
||||
var iterator = this.$backwardMatchIterator(doc);
|
||||
} else {
|
||||
var iterator = this.$forwardMatchIterator(doc);
|
||||
}
|
||||
|
||||
var ranges = [];
|
||||
iterator.forEach(function(range) {
|
||||
ranges.push(range);
|
||||
});
|
||||
|
||||
return ranges;
|
||||
};
|
||||
|
||||
this.$forwardMatchIterator = function(doc) {
|
||||
var re = this.$assembleRegExp();
|
||||
var self = this;
|
||||
|
||||
return {
|
||||
forEach: function(callback) {
|
||||
self.$forwardLineIterator(doc).forEach(function(line, startIndex, row) {
|
||||
if (startIndex) {
|
||||
line = line.substring(startIndex);
|
||||
}
|
||||
|
||||
var matches = [];
|
||||
|
||||
line.replace(re, function(str, offset) {
|
||||
matches.push({
|
||||
str: str,
|
||||
offset: startIndex + offset
|
||||
});
|
||||
return str;
|
||||
});
|
||||
|
||||
for (var i=0; i<matches.length; i++) {
|
||||
var match = matches[i];
|
||||
var range = self.$rangeFromMatch(row, match.offset, match.str.length);
|
||||
if (callback(range))
|
||||
return true;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
this.$backwardMatchIterator = function(doc) {
|
||||
var re = this.$assembleRegExp();
|
||||
var self = this;
|
||||
|
||||
return {
|
||||
forEach: function(callback) {
|
||||
self.$backwardLineIterator(doc).forEach(function(line, startIndex, row) {
|
||||
if (startIndex) {
|
||||
line = line.substring(startIndex);
|
||||
}
|
||||
|
||||
var matches = [];
|
||||
|
||||
line.replace(re, function(str, offset) {
|
||||
matches.push({
|
||||
str: str,
|
||||
offset: startIndex + offset
|
||||
});
|
||||
return str;
|
||||
});
|
||||
|
||||
for (var i=matches.length-1; i>= 0; i--) {
|
||||
var match = matches[i];
|
||||
var range = self.$rangeFromMatch(row, match.offset, match.str.length);
|
||||
if (callback(range))
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
this.$rangeFromMatch = function(row, column, length) {
|
||||
var range = {
|
||||
start: {
|
||||
|
|
@ -99,7 +142,12 @@ ace.Search.SELECTION = 2;
|
|||
};
|
||||
|
||||
this.$assembleRegExp = function() {
|
||||
var needle = ace.escapeRegExp(this.$options.needle);
|
||||
if (this.$options.regExp) {
|
||||
var needle = this.$options.needle;
|
||||
} else {
|
||||
var needle = ace.escapeRegExp(this.$options.needle);
|
||||
}
|
||||
|
||||
if (this.$options.wholeWord) {
|
||||
needle = "\\b" + needle + "\\b";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -203,5 +203,53 @@ var SearchTest = new TestCase("SearchTest", {
|
|||
var range = search.find(doc);
|
||||
assertPosition(2, 0, range.start);
|
||||
assertPosition(2, 4, range.end);
|
||||
},
|
||||
|
||||
"test: find using a regular expression" : function() {
|
||||
var doc = new ace.Document(["abc123 123 cd", "abc"]);
|
||||
|
||||
var search = new ace.Search().set({
|
||||
needle: "\\d+",
|
||||
regExp: true
|
||||
});
|
||||
|
||||
var range = search.find(doc);
|
||||
assertPosition(0, 3, range.start);
|
||||
assertPosition(0, 6, range.end);
|
||||
},
|
||||
|
||||
"test: find using a regular expression and whole word" : function() {
|
||||
var doc = new ace.Document(["abc123 123 cd", "abc"]);
|
||||
|
||||
var search = new ace.Search().set({
|
||||
needle: "\\d+\\b",
|
||||
regExp: true,
|
||||
wholeWord: true
|
||||
});
|
||||
|
||||
var range = search.find(doc);
|
||||
assertPosition(0, 7, range.start);
|
||||
assertPosition(0, 10, range.end);
|
||||
},
|
||||
|
||||
"test: find all matches in selection" : function() {
|
||||
var doc = new ace.Document(["juhu", "juhu", "juhu", "juhu"]);
|
||||
|
||||
var search = new ace.Search().set({
|
||||
needle: "uh",
|
||||
wrap: true,
|
||||
scope: ace.Search.SELECTION
|
||||
});
|
||||
|
||||
doc.getSelection().setSelectionAnchor(0, 2);
|
||||
doc.getSelection().selectTo(3, 2);
|
||||
|
||||
var ranges = search.findAll(doc);
|
||||
|
||||
assertEquals(2, ranges.length);
|
||||
assertPosition(1, 1, ranges[0].start);
|
||||
assertPosition(1, 3, ranges[0].end);
|
||||
assertPosition(2, 1, ranges[1].start);
|
||||
assertPosition(2, 3, ranges[1].end);
|
||||
}
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue