groupAt function

SelectionRange groupAt(
  1. EditorState state,
  2. int pos, [
  3. int bias = 1
])

Get a selection range covering the word/group at the given position.

This is used for double-click word selection and similar operations. The bias parameter indicates the preferred direction when at a boundary (-1 = prefer left, 1 = prefer right).

Implementation

SelectionRange groupAt(EditorState state, int pos, [int bias = 1]) {
  final categorize = state.charCategorizer(pos);
  final line = state.doc.lineAt(pos);
  final linePos = pos - line.from;

  if (line.length == 0) {
    return EditorSelection.cursor(pos);
  }

  // Adjust bias at line boundaries
  int adjustedBias = bias;
  if (linePos == 0) {
    adjustedBias = 1;
  } else if (linePos == line.length) {
    adjustedBias = -1;
  }

  // Find the starting character
  var from = linePos;
  var to = linePos;

  if (adjustedBias < 0) {
    from = findClusterBreak(line.text, linePos, false);
  } else {
    to = findClusterBreak(line.text, linePos, true);
  }

  // Categorize the character we're on
  final cat = categorize(line.text.substring(from, to));

  // Extend backward while same category
  while (from > 0) {
    final prev = findClusterBreak(line.text, from, false);
    if (categorize(line.text.substring(prev, from)) != cat) break;
    from = prev;
  }

  // Extend forward while same category
  while (to < line.length) {
    final next = findClusterBreak(line.text, to, true);
    if (categorize(line.text.substring(to, next)) != cat) break;
    to = next;
  }

  return EditorSelection.range(from + line.from, to + line.from);
}