Forge
csharpdeeb25a2
1namespace CascadeIDE.Features.Editor.Application.Monaco;
2
3/// <summary>Line/column ↔ offset mapping for <see cref="EditorNavigationService"/> (testable).</summary>
4public static class EditorNavigationLineMapping
5{
6 public static (int start, int length) SelectionOffsetsFromLines(
7 string text,
8 int startLine,
9 int startColumn,
10 int endLine,
11 int? endColumn)
12 {
13 var start = OffsetFromLineColumn(text, startLine, startColumn);
14 var endCol = endColumn ?? int.MaxValue;
15 var end = OffsetFromLineColumn(text, endLine, endCol, endOfLineIfOverflow: true);
16 return (start, Math.Max(0, end - start));
17 }
18
19 public static int OffsetFromLineColumn(
20 string text,
21 int lineOneBased,
22 int columnOneBased,
23 bool endOfLineIfOverflow = false)
24 {
25 if (string.IsNullOrEmpty(text) || lineOneBased < 1)
26 return 0;
27
28 var lineStart = 0;
29 var line = 1;
30 for (var i = 0; i < text.Length && line < lineOneBased; i++)
31 {
32 if (text[i] == '\n')
33 {
34 line++;
35 lineStart = i + 1;
36 }
37 }
38
39 if (line != lineOneBased)
40 return text.Length;
41
42 var lineEnd = text.IndexOf('\n', lineStart);
43 if (lineEnd < 0)
44 lineEnd = text.Length;
45 var lineLen = lineEnd - lineStart;
46 var col = Math.Max(1, columnOneBased);
47 if (endOfLineIfOverflow && col > lineLen + 1)
48 return lineEnd;
49 var offset = lineStart + Math.Min(col - 1, lineLen);
50 return Math.Min(offset, text.Length);
51 }
52}
53
View only · write via MCP/CIDE