TextRange (int from, int to) { int curOffset = startPrefixLength; int charsSoFar = 0; int mappedFrom = -1; for (int i = 0; i < lines.length; i++) { String line = lines[i]; int linePrefixLength = findLinePrefixLength(line, indent); line = line.substring(linePrefixLength); boolean isLastLine = i == lines.length - 1; int lineSuffixLength = findLineSuffixLength(line, isLastLine); line = line.substring(0, line.length() - lineSuffixLength); if (!isLastLine) line += '\n'; curOffset += linePrefixLength; int nextIdx = 0; while (true) { if (from == charsSoFar) { mappedFrom = curOffset + nextIdx; } if (to == charsSoFar) { return new TextRange(mappedFrom, curOffset + nextIdx); } int charIdx = nextIdx; nextIdx = getCharEndIndex(line, charIdx); if (nextIdx == -1) break; charsSoFar++; if (nextIdx == line.length()) curOffset += lineSuffixLength; } curOffset += line.length(); } return null; }