moveVertically function

SelectionRange moveVertically(
  1. EditorState state,
  2. SelectionRange start,
  3. bool forward, {
  4. int? distance,
  5. int? goalColumn,
})

Move vertically by one line.

The distance parameter can specify a custom vertical distance, otherwise the default line height is used.

Implementation

SelectionRange moveVertically(
  EditorState state,
  SelectionRange start,
  bool forward, {
  int? distance,
  int? goalColumn,
}) {
  final startPos = start.head;

  // At document boundary?
  if (startPos == (forward ? state.doc.length : 0)) {
    return EditorSelection.cursor(startPos, assoc: start.assoc);
  }

  final line = state.doc.lineAt(startPos);
  final goal = goalColumn ?? start.goalColumn ?? (startPos - line.from);

  // Find target line
  final targetLineNum = line.number + (forward ? 1 : -1);
  if (targetLineNum < 1 || targetLineNum > state.doc.lines) {
    // Stay on current line but move to end
    return EditorSelection.cursor(
      forward ? line.to : line.from,
      assoc: forward ? -1 : 1,
    );
  }

  final targetLine = state.doc.line(targetLineNum);
  final targetPos = targetLine.from + goal.clamp(0, targetLine.length);

  return EditorSelection.cursor(
    targetPos,
    assoc: forward ? -1 : 1,
    goalColumn: goal,
  );
}