Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LSP hover responses escape backticks within inline code #75364

Merged
merged 1 commit into from
Oct 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -216,9 +216,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 @@ -995,7 +995,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 @@ -1007,7 +1007,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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: raw strings are a lot nicer for tests.

{
/// <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]``
";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here as well.


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
Loading