Forge
csharpdeeb25a2
1using CascadeIDE.Services;
2using CascadeIDE.ViewModels;
3
4namespace CascadeIDE.Features.Editor.Application.Monaco;
5
6/// <summary>Maps navigation-map CFG nodes to Monaco CodeLens (ADR 0163 M9).</summary>
7public static class MonacoEditorCodeLensComposer
8{
9 public static IReadOnlyList<CideEditorCodeLensItem> FromNavigationScene(
10 string? filePath,
11 CodeNavigationMapGraphSceneVm? scene)
12 {
13 if (string.IsNullOrWhiteSpace(filePath) || scene is null || scene.IsEmpty)
14 return [];
15
16 var list = new List<CideEditorCodeLensItem>(scene.Nodes.Count);
17 foreach (var node in scene.Nodes)
18 {
19 if (!EditorTextCoordinateUtilities.PathsReferToSameFile(node.FullPath, filePath))
20 continue;
21 if (node.LineStart is not int line || line < 1)
22 continue;
23
24 var title = node.LegendIndex is int idx
25 ? $"{idx}: {node.Label}"
26 : node.Label;
27 if (string.IsNullOrWhiteSpace(title))
28 continue;
29
30 list.Add(new CideEditorCodeLensItem(node.Id, line, 1, title.Trim()));
31 }
32
33 return list;
34 }
35
36 public static CodeNavigationMapNodeNavigatePayload? TryResolveNavigation(
37 string lensId,
38 CodeNavigationMapGraphSceneVm? scene)
39 {
40 if (string.IsNullOrWhiteSpace(lensId) || scene is null)
41 return null;
42
43 foreach (var node in scene.Nodes)
44 {
45 if (!string.Equals(node.Id, lensId, StringComparison.Ordinal))
46 continue;
47 return new CodeNavigationMapNodeNavigatePayload(
48 node.FullPath,
49 node.LineStart,
50 node.LineEnd,
51 node.LegendLine,
52 node.Kind);
53 }
54
55 return null;
56 }
57}
58
59public static class MonacoEditorInlayMapper
60{
61 public static IReadOnlyList<CideEditorInlayHint> ToHints(
62 string sourceText,
63 IReadOnlyList<EditorTrailingInlayPart> parts)
64 {
65 if (parts.Count == 0)
66 return [];
67
68 var list = new List<CideEditorInlayHint>(parts.Count);
69 foreach (var part in parts)
70 {
71 if (string.IsNullOrWhiteSpace(part.Label))
72 continue;
73 var (line, column) = LineColumnFromOffset(sourceText, part.AnchorOffset);
74 var kind = part.Label.TrimEnd().EndsWith(':') ? "parameter" : "type";
75 list.Add(new CideEditorInlayHint(line, column, part.Label, kind));
76 }
77
78 return list;
79 }
80
81 private static (int line, int column) LineColumnFromOffset(string text, int offset)
82 {
83 if (string.IsNullOrEmpty(text) || offset < 0)
84 return (1, 1);
85 offset = Math.Min(offset, text.Length);
86 var line = 1;
87 var lineStart = 0;
88 for (var i = 0; i < offset; i++)
89 {
90 if (text[i] == '\n')
91 {
92 line++;
93 lineStart = i + 1;
94 }
95 }
96
97 return (line, offset - lineStart + 1);
98 }
99}
100
View only · write via MCP/CIDE