searchReverse method
bool
searchReverse(
- Searcher searcher, {
- Position? startPosition,
- int offsetBackward = 0,
- Position? hitPosition,
- RelativePosition relativePosition = RelativePosition.onFirst,
Searches a pattern from a given position in reverse direction.
startPosition
defines the start. If null the currentPosition is taken.
offsetBackward
: the start position is moved this count of characters
in direction to the text start before searching. This is meaningful if
the start position is the region end: Otherwise nothing will be found.
searcher
specifies the kind of pattern: regular expression, raw string...
hitPosition
: OUT: the position of the hit. If result is false the value
is not changed. If null the currentPosition is used.
relativePosition
defines the result position relative to the found pattern.
Returns true if the pattern is found.
Implementation
bool searchReverse(
Searcher searcher, {
Position? startPosition,
int offsetBackward = 0,
Position? hitPosition,
RelativePosition relativePosition = RelativePosition.onFirst,
}) {
var rc = false;
tempPosition.clone(startPosition ??= currentPosition);
if (offsetBackward != 0) {
tempPosition.backward(offsetBackward);
}
if (currentRegion.contains(tempPosition)) {
int? start;
/// Is the region exactly one line?
if (tempPosition.line == currentRegion.start.line) {
final line = lines[tempPosition.line]
.substring(currentRegion.start.column, tempPosition.column);
lastMatch.position.line = currentPosition.line;
rc = (start = searcher.previous(line)) != null;
if (rc) {
tempPosition.addColumn(-start! - lastMatch.length());
}
} else {
var currentLine = tempPosition.line;
// special handling of the first line: respect the column in previous():
if (tempPosition.column > 0) {
rc = (start =
searcher.previous(lines[currentLine], tempPosition.column)) !=
null;
if (rc) {
tempPosition.column = start!;
} else {
currentLine--;
}
}
if (!rc) {
final lastLine = currentRegion.start.line +
(currentRegion.start.column > 0 ? 1 : 0);
// inspect the full lines:
while (currentLine >= lastLine) {
lastMatch.position.line = currentLine;
rc = (start = searcher.previous(lines[currentLine])) != null;
if (rc) {
tempPosition.set(currentLine, start!);
break;
}
currentLine--;
}
// special handling of the last line (if incomplete):
if (!rc &&
currentLine == currentRegion.start.line &&
currentRegion.start.column > 0) {
final line =
lines[currentLine].substring(currentRegion.start.column);
rc = (start = searcher.previous(line)) != null;
if (rc) {
tempPosition.set(
currentLine, currentRegion.start.column + start!);
}
}
}
}
if (rc) {
switch (relativePosition) {
case RelativePosition.aboveFirst:
tempPosition.backward(1);
break;
case RelativePosition.onFirst:
break;
case RelativePosition.onLast:
tempPosition.addColumn(lastMatch.length() - 1);
break;
case RelativePosition.belowLast:
tempPosition.addColumn(lastMatch.length());
break;
}
hitPosition ??= currentPosition;
hitPosition.clone(tempPosition);
}
}
return rc;
}