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;
|
return null;
|
||||||
|
|
||||||
if (this.$options.backwards) {
|
if (this.$options.backwards) {
|
||||||
return this.$findBackward(doc);
|
var iterator = this.$backwardMatchIterator(doc);
|
||||||
} else {
|
} else {
|
||||||
return this.$findForward(doc);
|
var iterator = this.$forwardMatchIterator(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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
this.$rangeFromMatch = function(row, column, length) {
|
||||||
var range = {
|
var range = {
|
||||||
start: {
|
start: {
|
||||||
|
|
@ -99,7 +142,12 @@ ace.Search.SELECTION = 2;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.$assembleRegExp = function() {
|
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) {
|
if (this.$options.wholeWord) {
|
||||||
needle = "\\b" + needle + "\\b";
|
needle = "\\b" + needle + "\\b";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -203,5 +203,53 @@ var SearchTest = new TestCase("SearchTest", {
|
||||||
var range = search.find(doc);
|
var range = search.find(doc);
|
||||||
assertPosition(2, 0, range.start);
|
assertPosition(2, 0, range.start);
|
||||||
assertPosition(2, 4, range.end);
|
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