refactor searching and add findAll method

This commit is contained in:
Fabian Jakobs 2010-04-28 17:37:04 +02:00
commit 000a81da7f
2 changed files with 149 additions and 53 deletions

View file

@ -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";
}

View file

@ -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);
}
});