Skip to content

Commit

Permalink
Implement LSP hover info for code windows #686
Browse files Browse the repository at this point in the history
  • Loading branch information
falko17 committed Jul 19, 2024
1 parent 78f5b94 commit 7e1dcfa
Show file tree
Hide file tree
Showing 10 changed files with 215 additions and 110 deletions.
4 changes: 2 additions & 2 deletions Assets/Resources/Prefabs/UI/CodeWindowContent.prefab
Original file line number Diff line number Diff line change
Expand Up @@ -684,7 +684,7 @@ MonoBehaviour:
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_enableWordWrapping: 1
m_enableWordWrapping: 0
m_wordWrappingRatios: 0.413
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
Expand Down Expand Up @@ -722,7 +722,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 3245ec927659c4140ac4f8d17403cc18, type: 3}
m_Name:
m_EditorClassIdentifier:
m_HorizontalFit: 0
m_HorizontalFit: 2
m_VerticalFit: 2
--- !u!1 &8823517661321162182
GameObject:
Expand Down
59 changes: 11 additions & 48 deletions Assets/SEE/DataModel/DG/IO/LSPImporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using Cysharp.Threading.Tasks;
using Markdig;
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
using OmniSharp.Extensions.LanguageServer.Server;
using SEE.Tools;
using SEE.Tools.LSP;
using SEE.Utils;
Expand Down Expand Up @@ -394,7 +393,11 @@ private async UniTask HandleCallHierarchyAsync(Node node, Graph graph, Cancellat
{
throw new OperationCanceledException();
}
Node targetNode = FindNodesByLocation(item.Uri.Path, Range.FromLspRange(item.Range)).First();
Node targetNode = FindNodesByLocation(item.Uri.Path, Range.FromLspRange(item.Range)).FirstOrDefault();
if (targetNode == null)
{
continue;
}
Edge edge = AddEdge(node, targetNode, LSP.Call, false, graph);
edge.SetRange(SelectionRangeAttribute, Range.FromLspRange(item.SelectionRange));
}
Expand Down Expand Up @@ -422,7 +425,11 @@ private async UniTask HandleTypeHierarchyAsync(Node node, Graph graph, Cancellat
{
throw new OperationCanceledException();
}
Node targetNode = FindNodesByLocation(item.Uri.Path, Range.FromLspRange(item.Range)).First();
Node targetNode = FindNodesByLocation(item.Uri.Path, Range.FromLspRange(item.Range)).FirstOrDefault();
if (targetNode == null)
{
continue;
}
Edge edge = AddEdge(node, targetNode, LSP.Extend, false, graph);
edge.SetRange(SelectionRangeAttribute, Range.FromLspRange(item.SelectionRange));
}
Expand Down Expand Up @@ -494,7 +501,7 @@ private async UniTask AddSymbolNodeAsync(DocumentSymbol symbol, string path, Gra
Hover hover = await Handler.HoverAsync(path, node.SourceLine - 1 ?? 0, node.SourceColumn - 1 ?? 0);
if (hover != null)
{
node.SetString("HoverText", MarkupToRichText(hover.Contents));
node.SetString("HoverText", hover.Contents.ToRichText());
}
}

Expand Down Expand Up @@ -524,50 +531,6 @@ private async UniTask AddSymbolNodeAsync(DocumentSymbol symbol, string path, Gra
}
}

/// <summary>
/// Converts the given <paramref name="content"/> to TextMeshPro-compatible rich text.
/// </summary>
/// <param name="content">The content to convert.</param>
/// <returns>The converted rich text.</returns>
private static string MarkupToRichText(MarkedStringsOrMarkupContent content)
{
string markdown;
if (content.HasMarkupContent)
{
MarkupContent markup = content.MarkupContent!;
switch (markup.Kind)
{
case MarkupKind.PlainText: return $"<noparse>{markup.Value}</noparse>";
case MarkupKind.Markdown:
markdown = markup.Value;
break;
default:
Debug.LogError($"Unsupported markup kind: {markup.Kind}");
return string.Empty;
}
}
else
{
// This is technically deprecated, but we still need to support it,
// since some language servers still use it.
Container<MarkedString> strings = content.MarkedStrings!;
markdown = string.Join("\n", strings.Select(x =>
{
if (x.Language != null)
{
return $"```{x.Language}\n{x.Value}\n```";
}
else
{
return x.Value;
}
}));
}

// TODO (#728): Parse markdown to TextMeshPro rich text (custom MarkDig parser).
return Markdown.ToPlainText(markdown);
}

/// <summary>
/// Adds a node for the given <paramref name="directoryPath"/> to the given <paramref name="graph"/>.
/// If the node already exists, it is returned immediately.
Expand Down
22 changes: 11 additions & 11 deletions Assets/SEE/UI/DebugAdapterProtocol/DebugAdapterProtocolSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -336,11 +336,11 @@ private void OnDestroy()
{
Destroyer.Destroy(controls);
}
if (adapterProcess != null && !adapterProcess.HasExited)
if (adapterProcess is { HasExited: false })
{
adapterProcess.Kill();
}
if (adapterHost != null && adapterHost.IsRunning)
if (adapterHost is { IsRunning: true })
{
adapterHost.Stop();
}
Expand All @@ -349,12 +349,12 @@ private void OnDestroy()
/// <summary>
/// Creates the process for the debug adapter.
/// </summary>
/// <returns>Whether the creation was sucessful.</returns>
/// <returns>Whether the creation was successful.</returns>
private bool CreateAdapterProcess()
{
adapterProcess = new Process
{
StartInfo = new ProcessStartInfo()
StartInfo = new ProcessStartInfo
{
FileName = Adapter.AdapterFileName,
Arguments = Adapter.AdapterArguments,
Expand All @@ -371,8 +371,8 @@ private bool CreateAdapterProcess()
},
EnableRaisingEvents = true
};
adapterProcess.Exited += (_, args) => ConsoleWindow.AddMessage($"Process: Exited! ({(!adapterProcess.HasExited ? adapterProcess.ProcessName : null)})");
adapterProcess.Disposed += (_, args) => ConsoleWindow.AddMessage($"Process: Exited! ({(!adapterProcess.HasExited ? adapterProcess.ProcessName : null)})");
adapterProcess.Exited += (_, _) => ConsoleWindow.AddMessage($"Process: Exited! ({(!adapterProcess.HasExited ? adapterProcess.ProcessName : null)})");
adapterProcess.Disposed += (_, _) => ConsoleWindow.AddMessage($"Process: Exited! ({(!adapterProcess.HasExited ? adapterProcess.ProcessName : null)})");
adapterProcess.OutputDataReceived += (_, args) => ConsoleWindow.AddMessage($"Process: OutputDataReceived! ({adapterProcess.ProcessName})\n\t{args.Data}");
adapterProcess.ErrorDataReceived += (_, args) =>
{
Expand Down Expand Up @@ -410,7 +410,7 @@ private bool CreateAdapterProcess()
private bool CreateAdapterHost()
{
adapterHost = new DebugProtocolHost(adapterProcess.StandardInput.BaseStream, adapterProcess.StandardOutput.BaseStream);
adapterHost.DispatcherError += (sender, args) =>
adapterHost.DispatcherError += (_, args) =>
{
string message = $"DispatcherError - {args.Exception}";
ConsoleWindow.AddMessage(message + "\n", "Adapter", "Error");
Expand Down Expand Up @@ -451,7 +451,7 @@ private void UpdateStackFrames()
return;
}

stackFrames = adapterHost.SendRequestSync(new StackTraceRequest() { ThreadId = MainThread.Id }).StackFrames;
stackFrames = adapterHost.SendRequestSync(new StackTraceRequest { ThreadId = MainThread.Id }).StackFrames;
}


Expand All @@ -474,7 +474,7 @@ private void UpdateVariables()

foreach (StackFrame stackFrame in stackFrames)
{
List<Scope> stackScopes = adapterHost.SendRequestSync(new ScopesRequest() { FrameId = stackFrame.Id }).Scopes;
List<Scope> stackScopes = adapterHost.SendRequestSync(new ScopesRequest { FrameId = stackFrame.Id }).Scopes;
Dictionary<Scope, List<Variable>> stackVariables = stackScopes.ToDictionary(scope => scope, scope => RetrieveNestedVariables(scope.VariablesReference));
threadVariables.Add(stackFrame, stackVariables);
}
Expand All @@ -499,7 +499,7 @@ private List<Variable> RetrieveNestedVariables(int variablesReference)
{
return new();
}
return adapterHost.SendRequestSync(new VariablesRequest() { VariablesReference = variablesReference }).Variables;
return adapterHost.SendRequestSync(new VariablesRequest { VariablesReference = variablesReference }).Variables;
}

/// <summary>
Expand All @@ -512,7 +512,7 @@ private string RetrieveVariableValue(Variable variable)
{
if (IsRunning && variable.EvaluateName != null)
{
EvaluateResponse value = adapterHost.SendRequestSync(new EvaluateRequest()
EvaluateResponse value = adapterHost.SendRequestSync(new EvaluateRequest
{
Expression = variable.EvaluateName,
FrameId = IsRunning ? null : StackFrame.Id
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,16 @@ private void OnBreakpointsChanged(string path, int line)
{
actions.Enqueue(() =>
{
adapterHost.SendRequest(new SetBreakpointsRequest()
adapterHost.SendRequest(new SetBreakpointsRequest
{
Source = new Source() { Path = path, Name = path },
Source = new Source { Path = path, Name = path },
Breakpoints = DebugBreakpointManager.Breakpoints[path].Values.ToList(),
}, _ => { });
});
}

/// <summary>
/// Handles the begining of hovering a word.
/// Handles the beginning of hovering a word.
/// </summary>
/// <param name="codeWindow">The code window containing the hovered word.</param>
/// <param name="wordInfo">The info of the hovered word.</param>
Expand Down Expand Up @@ -66,11 +66,11 @@ private void UpdateHoverTooltip()
return;
}

string expression = ((TMP_WordInfo)hoveredWord).GetWord();
string expression = hoveredWord.Value.GetWord();

try
{
EvaluateResponse result = adapterHost.SendRequestSync(new EvaluateRequest()
EvaluateResponse result = adapterHost.SendRequestSync(new EvaluateRequest
{
Expression = expression,
Context = capabilities.SupportsEvaluateForHovers == true ? EvaluateArguments.ContextValue.Hover : null,
Expand Down Expand Up @@ -133,14 +133,14 @@ private void OnInitializedEvent(InitializedEvent initializedEvent)
adapterHost.SendRequest(Adapter.GetLaunchRequest(), _ => IsRunning = true);
foreach ((string path, Dictionary<int, SourceBreakpoint> breakpoints) in DebugBreakpointManager.Breakpoints)
{
adapterHost.SendRequest(new SetBreakpointsRequest()
adapterHost.SendRequest(new SetBreakpointsRequest
{
Source = new Source() { Path = path, Name = path },
Source = new Source { Path = path, Name = path },
Breakpoints = breakpoints.Values.ToList(),
}, _ => { });
}
adapterHost.SendRequest(new SetFunctionBreakpointsRequest() { Breakpoints = new() }, _ => { });
adapterHost.SendRequest(new SetExceptionBreakpointsRequest() { Filters = new() }, _ => { });
adapterHost.SendRequest(new SetFunctionBreakpointsRequest { Breakpoints = new() }, _ => { });
adapterHost.SendRequest(new SetExceptionBreakpointsRequest { Filters = new() }, _ => { });
if (capabilities.SupportsConfigurationDoneRequest == true)
{
adapterHost.SendRequest(new ConfigurationDoneRequest(), _ => { });
Expand Down Expand Up @@ -227,7 +227,7 @@ private void OnStoppedEvent(StoppedEvent stoppedEvent)
return;
}

ExceptionInfoResponse exceptionInfo = adapterHost.SendRequestSync(new ExceptionInfoRequest()
ExceptionInfoResponse exceptionInfo = adapterHost.SendRequestSync(new ExceptionInfoRequest
{
ThreadId = MainThread.Id,
});
Expand Down Expand Up @@ -358,7 +358,7 @@ private void OnConsoleInput(string text)
/// <summary>
/// Queues a continue request.
/// </summary>
void OnContinue()
private void OnContinue()
{
actions.Enqueue(() =>
{
Expand All @@ -373,7 +373,7 @@ void OnContinue()
/// <summary>
/// Queues a pause request.
/// </summary>
void OnPause()
private void OnPause()
{
actions.Enqueue(() =>
{
Expand All @@ -388,7 +388,7 @@ void OnPause()
/// <summary>
/// Queues a reverse continue request.
/// </summary>
void OnReverseContinue()
private void OnReverseContinue()
{
actions.Enqueue(() =>
{
Expand All @@ -403,7 +403,7 @@ void OnReverseContinue()
/// <summary>
/// Queues a next request.
/// </summary>
void OnNext()
private void OnNext()
{
actions.Enqueue(() =>
{
Expand All @@ -418,7 +418,7 @@ void OnNext()
/// <summary>
/// Queues a step back request.
/// </summary>
void OnStepBack()
private void OnStepBack()
{
actions.Enqueue(() =>
{
Expand All @@ -433,7 +433,7 @@ void OnStepBack()
/// <summary>
/// Queues a step in request.
/// </summary>
void OnStepIn()
private void OnStepIn()
{
actions.Enqueue(() =>
{
Expand All @@ -448,7 +448,7 @@ void OnStepIn()
/// <summary>
/// Queues a step out request.
/// </summary>
void OnStepOut()
private void OnStepOut()
{
actions.Enqueue(() =>
{
Expand All @@ -463,7 +463,7 @@ void OnStepOut()
/// <summary>
/// Queues a restart request.
/// </summary>
void OnRestart()
private void OnRestart()
{
actions.Enqueue(() =>
{
Expand All @@ -474,7 +474,7 @@ void OnRestart()
/// <summary>
/// Queues a terminate request.
/// </summary>
void OnStop()
private void OnStop()
{
actions.Enqueue(() =>
{
Expand All @@ -487,6 +487,7 @@ void OnStop()
Disconnect();
}
});
return;

// Tries to stop the debuggee gracefully.
void Terminate()
Expand Down
6 changes: 6 additions & 0 deletions Assets/SEE/UI/Tooltip.cs
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,12 @@ public static void ActivateWith(string text, AfterShownBehavior afterShownBehavi
Instance.ChangeText(text, afterShownBehavior);
}

/// <summary>
/// Whether the tooltip is currently active.
/// Note that "active" does not necessarily mean that the tooltip is currently visible.
/// </summary>
public static bool IsActivated => Instance.text != null;

/// <summary>
/// Will hide the tooltip by fading it out if it's currently visible.
/// If <see cref="FadeIn"/> has been called prior to this and is active, it will be halted.
Expand Down
1 change: 1 addition & 0 deletions Assets/SEE/UI/Window/CodeWindow/CodeWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ private float ImmediateVisibleLine
else
{
scrollRect.verticalNormalizedPosition = 1 - value / (lines - 1 - excessLines);
scrollRect.horizontalNormalizedPosition = 0;
}
}
}
Expand Down
Loading

0 comments on commit 7e1dcfa

Please sign in to comment.