Skip to content

Commit

Permalink
Merge pull request #75364 from dotnet/dev/jorobich/escape-backtick
Browse files Browse the repository at this point in the history
LSP hover responses escape backticks within inline code
  • Loading branch information
JoeRobich authored Oct 3, 2024
2 parents 7f22c9d + 43ecd72 commit 281f841
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 4 deletions.
9 changes: 5 additions & 4 deletions src/LanguageServer/Protocol/Extensions/ProtocolConversions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -213,9 +213,9 @@ public static Uri CreateAbsoluteUri(string absolutePath)

internal static Uri CreateRelativePatternBaseUri(string path)
{
// According to VSCode LSP RelativePattern spec,
// According to VSCode LSP RelativePattern spec,
// found at https://github.com/microsoft/vscode/blob/9e1974682eb84eebb073d4ae775bad1738c281f6/src/vscode-dts/vscode.d.ts#L2226
// the baseUri should not end in a trailing separator, nor should it
// the baseUri should not end in a trailing separator, nor should it
// have any relative segmeents (., ..)
if (path[^1] == System.IO.Path.DirectorySeparatorChar)
{
Expand Down Expand Up @@ -969,7 +969,7 @@ static string GetStyledText(TaggedText taggedText, bool isInCodeBlock)
if (!string.IsNullOrEmpty(taggedText.NavigationHint) && taggedText.NavigationHint == taggedText.NavigationTarget)
return $"[{text}]({taggedText.NavigationHint})";

// Markdown ignores spaces at the start of lines outside of code blocks,
// Markdown ignores spaces at the start of lines outside of code blocks,
// so we replace regular spaces with non-breaking spaces to ensure structural space is retained.
// We want to use regular spaces everywhere else to allow the client to wrap long text.
if (!isCode && taggedText.Tag is TextTags.Space or TextTags.ContainerStart)
Expand All @@ -981,7 +981,8 @@ static string GetStyledText(TaggedText taggedText, bool isInCodeBlock)
TaggedTextStyle.Strong => $"**{text}**",
TaggedTextStyle.Emphasis => $"_{text}_",
TaggedTextStyle.Underline => $"<u>{text}</u>",
TaggedTextStyle.Code => $"`{text}`",
// Use double backticks to escape code which contains a backtick.
TaggedTextStyle.Code => text.Contains('`') ? $"``{text}``" : $"`{text}`",
_ => text,
};
}
Expand Down
33 changes: 33 additions & 0 deletions src/LanguageServer/ProtocolUnitTests/Hover/HoverTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,39 @@ void A.AMethod(int i)
Assert.Equal(expectedMarkdown, results.Contents.Fourth.Value);
}

[Theory, CombinatorialData, WorkItem("https://github.com/microsoft/vscode-dotnettools/issues/1499")]
public async Task TestGetHoverAsync_UsingMarkupContentEscapesBacktickInCode(bool mutatingLspWorkspace)
{
var markup =
@"class A
{
/// <summary>
/// Hello <c>A`1[B,C]</c>
/// </summary>
void {|caret:AMethod|}(int i)
{
}
}";
var clientCapabilities = new LSP.ClientCapabilities
{
TextDocument = new LSP.TextDocumentClientCapabilities { Hover = new LSP.HoverSetting { ContentFormat = [LSP.MarkupKind.Markdown] } }
};
await using var testLspServer = await CreateTestLspServerAsync(markup, mutatingLspWorkspace, clientCapabilities);
var expectedLocation = testLspServer.GetLocations("caret").Single();

var expectedMarkdown = @"```csharp
void A.AMethod(int i)
```
Hello&nbsp;``A`1[B,C]``
";

var results = await RunGetHoverAsync(
testLspServer,
expectedLocation).ConfigureAwait(false);
Assert.Equal(expectedMarkdown, results.Contents.Fourth.Value);
}

[Theory, CombinatorialData, WorkItem("https://github.com/dotnet/vscode-csharp/issues/6577")]
public async Task TestGetHoverAsync_UsesInlineCodeFencesInAwaitReturn(bool mutatingLspWorkspace)
{
Expand Down

0 comments on commit 281f841

Please sign in to comment.