searchReverse method

bool searchReverse(
  1. Searcher searcher, {
  2. Position? startPosition,
  3. int offsetBackward = 0,
  4. Position? hitPosition,
  5. 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;
}