groupAt function
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);
}