-
Notifications
You must be signed in to change notification settings - Fork 195
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
Get snippets working in Razor #9327
Conversation
Converting to Draft as there are known test breaks, and need to add unit tests. Finalizing the list of snippets we need to test with PM. |
@@ -117,6 +127,8 @@ internal partial class RazorCustomMessageTarget | |||
_telemetryReporter = telemetryReporter; | |||
_languageServerFeatureOptions = languageServerFeatureOptions; | |||
_projectSnapshotManagerAccessor = projectSnapshotManagerAccessor; | |||
_snippetCache = snippetCache; | |||
_xmlSnippetParser = xmlSnippetParser ?? new XmlSnippetParser(null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure why the [Export] didn't work here, but as long as we're always using the same cache it's okay. Also unsure why we don't have ILoggerFactory
here but I'm guessing that's just client vs server stuff.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have just enough understanding of our logging to make things appear in logs when I want them, and to recognize that its all weird and probably wrong, but sadly not enough to know how to fix the wrongness :)
I think we would ideally have an ILoggerFactory
here, and each method in this class would construct its own logger, since they are each endpoints. I'm sure there is an issue logged for better logging somewhere
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The "Kind" is ignored. This treats all snippets like "any". We could potentially add support for this syntactically, but right now it's not added.
No Function, Declarations, Id, Import(s), Keyword(s), Literal, Namespace, Object, Reference(s), or Command support. These are in the snippet documentation. If needed we could address each of these individually.
As someone not super well versed in snippets, what are the implications of leaving out these properties? Do we end up getting snippets offered in places where they might not be valid?
Also, you mentioned that snippets already provided by the C# language server have been excluded. Which new C# ones are being provided with this change?
...azor/src/Microsoft.AspNetCore.Razor.LanguageServer/Completion/RazorCompletionListProvider.cs
Outdated
Show resolved
Hide resolved
/// Shamelessly copied from the editor | ||
/// https://devdiv.visualstudio.com/DevDiv/_git/VS-Platform?path=/src/Editor/VisualStudio/Impl/Snippet/CodeSnippet.cs | ||
/// </summary> | ||
internal class CodeSnippet |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Long term I wonder if we could convince the Editor to ship this class so we wouldn't have to make a copy
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, and now that there are two repo's that have copies of it (Roslyn and Razor) it would add weight to the argument for making a service of some kind to expose this info
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, we might be able to ask them to ship it. I can bring up in an LSP sync
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a few comments, but I wouldn't be surprised if the answer to some or all of them was "yes it's odd but this just how VS/snippets work"
src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/Common/LanguageServerConstants.cs
Outdated
Show resolved
Hide resolved
...azor/src/Microsoft.AspNetCore.Razor.LanguageServer/Completion/RazorCompletionListProvider.cs
Outdated
Show resolved
Hide resolved
src/Razor/src/Microsoft.VisualStudio.Editor.Razor/Snippets/SnippetInfo.cs
Outdated
Show resolved
Hide resolved
src/Razor/src/Microsoft.VisualStudio.Editor.Razor/Snippets/SnippetInfo.cs
Show resolved
Hide resolved
src/Razor/src/Microsoft.VisualStudio.Editor.Razor/Snippets/SnippetCache.cs
Outdated
Show resolved
Hide resolved
src/Razor/src/Microsoft.VisualStudio.RazorExtension/Snippets/SnippetService.cs
Outdated
Show resolved
Hide resolved
src/Razor/src/Microsoft.VisualStudio.RazorExtension/Snippets/SnippetService.cs
Outdated
Show resolved
Hide resolved
src/Razor/src/Microsoft.VisualStudio.RazorExtension/Snippets/SnippetService.cs
Show resolved
Hide resolved
s_CSharpLanguageId, | ||
ImmutableHashSet.Create( | ||
"~", "Attribute", "checked", "class", "ctor", "cw", "do", "else", "enum", "equals", "Exception", "for", "foreach", "forr", | ||
"if", "indexer", "interface", "invoke", "iterator", "iterindex", "lock", "mbox", "namespace", "#if", "#region", "prop", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not for now, but I'm excited by the prospect that removing "if" from this list might solve #6927 and let us turn on semantic snippets
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ooo, maybe.
{ | ||
{ | ||
// These are identified as the snippets that are provided by the C# Language Server. The list is found | ||
// in https://github.com/dotnet/roslyn/blob/8eb40e64564a2a8d44be2fde9b079605f1f10e0f/src/Features/LanguageServer/Protocol/Handler/InlineCompletions/InlineCompletionsHandler.cs#L41 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm curious why we are doing snippets in normal completion, when Roslyn does them in inline completion?
(Note I am basing this question entirely off the filename in the comment here. I have no idea what the difference between the two is, or how the Roslyn code actually works 😛)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TBH I don't know the difference between normal and inline either :/
Co-authored-by: David Wengier <david.wengier@microsoft.com>
private static readonly Dictionary<Guid, ImmutableHashSet<string>> s_ignoredSnippets = new() | ||
{ | ||
{ | ||
// These are identified as the snippets that are provided by the C# Language Server. The list is found |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Random thought: Should we remove the restriction on the Roslyn side, and let them give us all C# snippets, and then contribute this code, or some form of it, to Web Tools for html snippets?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe. I think if we can get the editor to allow access to the snippet parsing code for everyone, then adding them to the html server and csharp server likely would be the right move.
These properties give a more complex way of providing snippets, and making sure they only show up in certain contexts. So yes, in some cases we will show snippets that are invalid for the location. No new C# built in snippets are provided, but if a user provides a custom snippet they will now be included. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good, pending tests and/or integration tests.
Still not sure about whether this will pass RPS either, so perhaps a validation insertion?
...zor/src/Microsoft.AspNetCore.Razor.LanguageServer/Completion/RazorSnippetCompletionParams.cs
Outdated
Show resolved
Hide resolved
src/Razor/src/Microsoft.VisualStudio.RazorExtension/Snippets/SnippetService.cs
Outdated
Show resolved
Hide resolved
src/Razor/src/Microsoft.VisualStudio.RazorExtension/Snippets/SnippetService.cs
Outdated
Show resolved
Hide resolved
...test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Completion/TestDocumentMappingService.cs
Show resolved
Hide resolved
…nippetService.cs Co-authored-by: David Wengier <david.wengier@microsoft.com>
Waiting on RPS Validation before I merge |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very glad to see this happening?
src/Razor/src/Microsoft.VisualStudio.Editor.Razor/Snippets/SnippetCache.cs
Show resolved
Hide resolved
src/Razor/src/Microsoft.VisualStudio.Editor.Razor/Snippets/SnippetCache.cs
Outdated
Show resolved
Hide resolved
src/Razor/src/Microsoft.VisualStudio.Editor.Razor/Snippets/XmlSnippetParser.CodeSnippet.cs
Outdated
Show resolved
Hide resolved
src/Razor/src/Microsoft.VisualStudio.Editor.Razor/Snippets/XmlSnippetParser.CodeSnippet.cs
Outdated
Show resolved
Hide resolved
src/Razor/src/Microsoft.VisualStudio.Editor.Razor/Snippets/XmlSnippetParser.CodeSnippet.cs
Outdated
Show resolved
Hide resolved
src/Razor/src/Microsoft.VisualStudio.RazorExtension/Snippets/SnippetService.cs
Outdated
Show resolved
Hide resolved
src/Razor/src/Microsoft.VisualStudio.RazorExtension/Snippets/SnippetService.cs
Outdated
Show resolved
Hide resolved
src/Razor/src/Microsoft.VisualStudio.RazorExtension/Snippets/SnippetService.cs
Outdated
Show resolved
Hide resolved
using System; | ||
using System.Collections.Generic; | ||
|
||
namespace Microsoft.AspNetCore.Razor; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change namespace to System.Collections.Generic
as we've done for other extension methods in Shared.Utilties
to facilitate discoverability.
dictionary[key] = defaultValue; | ||
return dictionary[key]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid a double-lookup in the dictionary:
dictionary[key] = defaultValue; | |
return dictionary[key]; | |
dictionary.Add(key, defaultValue); | |
return defaultValue; |
Co-authored-by: Dustin Campbell <dustin@teamcampbell.org>
This reverts commit b95f430.
@ryzngard Just found the limitations listed in this PR here. The listed limitations only apply to custom snippets, correct? For custom snippets, if they have a |
@Herdo: could you file a new issue that references this pull request? Questions on a PR resolved 10 months ago might easily be missed! |
Adds support for the razor LSP to get snippets defined in VS under the following conditions:
Caveats here: