From f5d0a5768938cf72b754c2d8048ae84a1bedbda3 Mon Sep 17 00:00:00 2001 From: Matt Parker <61717342+MattParkerDev@users.noreply.github.com> Date: Sun, 7 Dec 2025 18:40:57 +1000 Subject: [PATCH] display diagnostic info on hover in document --- .../SharpIdeCodeEdit_SymbolHover.cs | 26 ++++++++++++++++++- .../SymbolTooltips/DiagnosticTooltip.cs | 18 +++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 src/SharpIDE.Godot/Features/CodeEditor/SymbolTooltips/DiagnosticTooltip.cs diff --git a/src/SharpIDE.Godot/Features/CodeEditor/SharpIdeCodeEdit_SymbolHover.cs b/src/SharpIDE.Godot/Features/CodeEditor/SharpIdeCodeEdit_SymbolHover.cs index 864ded5..baaba95 100644 --- a/src/SharpIDE.Godot/Features/CodeEditor/SharpIdeCodeEdit_SymbolHover.cs +++ b/src/SharpIDE.Godot/Features/CodeEditor/SharpIdeCodeEdit_SymbolHover.cs @@ -1,6 +1,7 @@ using Godot; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Text; +using Roslyn.Utilities; using Timer = Godot.Timer; namespace SharpIDE.Godot.Features.CodeEditor; @@ -23,12 +24,19 @@ public partial class SharpIdeCodeEdit var lineHeight = GetLineHeight(); GD.Print($"Symbol hovered: {symbol} at line {line}, column {column}"); - var (roslynSymbol, linePositionSpan) = await _roslynAnalysis.LookupSymbol(_currentFile, new LinePosition((int)line, (int)column)); + var linePosition = new LinePosition((int)line, (int)column); + var (roslynSymbol, linePositionSpan) = await _roslynAnalysis.LookupSymbol(_currentFile, linePosition); if (roslynSymbol is null || linePositionSpan is null) { return; } + + var diagnostics = _fileDiagnostics.AsEnumerable().Concat(_fileAnalyzerDiagnostics).Concat(_projectDiagnosticsForFile); + var diagnosticsForLinePosition = diagnostics.FirstOrNull(s => s.Span.Start.Line == linePosition.Line && + s.Span.Start.Character <= linePosition.Character && + s.Span.End.Character >= linePosition.Character); + var symbolNameHoverWindow = new Window(); symbolNameHoverWindow.WrapControls = true; symbolNameHoverWindow.Unresizable = true; @@ -123,6 +131,21 @@ public partial class SharpIdeCodeEdit }; var panel = new PanelContainer(); panel.AddThemeStyleboxOverride(ThemeStringNames.Panel, styleBox); + + var diagnosticNode = diagnosticsForLinePosition is not null + ? SymbolInfoComponents.GetDiagnostic(diagnosticsForLinePosition.Value) + : null; + diagnosticNode?.FitContent = true; + diagnosticNode?.AutowrapMode = TextServer.AutowrapMode.Off; + diagnosticNode?.SetAnchorsPreset(Control.LayoutPreset.FullRect); + var diagnosticPanel = diagnosticNode switch + { + not null => new PanelContainer(), + _ => null + }; + diagnosticPanel?.AddThemeStyleboxOverride(ThemeStringNames.Panel, styleBox); + diagnosticPanel?.AddChild(diagnosticNode); + var symbolInfoNode = roslynSymbol switch { @@ -141,6 +164,7 @@ public partial class SharpIdeCodeEdit panel.AddChild(symbolInfoNode); var vboxContainer = new VBoxContainer(); vboxContainer.AddThemeConstantOverride(ThemeStringNames.Separation, 0); + if (diagnosticPanel is not null) vboxContainer.AddChild(diagnosticPanel); vboxContainer.AddChild(panel); tooltipWindow.AddChild(vboxContainer); tooltipWindow.ChildControlsChanged(); diff --git a/src/SharpIDE.Godot/Features/CodeEditor/SymbolTooltips/DiagnosticTooltip.cs b/src/SharpIDE.Godot/Features/CodeEditor/SymbolTooltips/DiagnosticTooltip.cs new file mode 100644 index 0000000..1a0048f --- /dev/null +++ b/src/SharpIDE.Godot/Features/CodeEditor/SymbolTooltips/DiagnosticTooltip.cs @@ -0,0 +1,18 @@ +using Godot; +using SharpIDE.Application.Features.Analysis; + +namespace SharpIDE.Godot.Features.CodeEditor; + +public static partial class SymbolInfoComponents +{ + public static RichTextLabel GetDiagnostic(SharpIdeDiagnostic diagnostic) + { + var label = new RichTextLabel(); + label.PushColor(CachedColors.White); + label.PushFont(MonospaceFont); + label.AddText(diagnostic.Diagnostic.GetMessage()); + label.Pop(); // font + label.Pop(); + return label; + } +} \ No newline at end of file