Add support for setting tabs/spaces preference in Tools->Options#3317
Conversation
ryanbrandenburg
left a comment
There was a problem hiding this comment.
Looks good overall, some questions about tests but if you're confident in the answers no need to block on it.
| { | ||
| [PackageRegistration(UseManagedResourcesOnly = true)] | ||
| [AboutDialogInfo(PackageGuidString, "ASP.NET Core Razor Language Services", "#110", "#112", IconResourceID = "#400")] | ||
| [AboutDialogInfo(PackageGuidString, "Razor (ASP.NET Core)", "#110", "#112", IconResourceID = "#400")] |
There was a problem hiding this comment.
I assume this name is #PMApproved?
There was a problem hiding this comment.
Yep. There was an email thread a few weeks back and this was the decided upon name.
| { | ||
| // Arrange | ||
| var expectedOptions = new RazorLSPOptions(Trace.Messages, enableFormatting: false, autoClosingTags: true); | ||
| var expectedOptions = new RazorLSPOptions(Trace.Messages, enableFormatting: false, autoClosingTags: true, insertSpaces: true, tabSize: 4); |
There was a problem hiding this comment.
I expected some settings other than insertSpaces:true, tabSize: 4 to be tested here, is the actual value of the properties just not doing anything interesting at this layer?
There was a problem hiding this comment.
Good point! I added some other tests in my latest push.
NTaylorMullen
left a comment
There was a problem hiding this comment.
Oh man this is exciting, really awesome to see this flow through! 👏
| { | ||
| // JToken.ToObject could potentially throw here if the user provides malformed options. | ||
| // If this occurs, catch the exception and return the default value. | ||
| return token.ToObject<T>(); |
There was a problem hiding this comment.
I forget if it's possible for this to return null. If so, would:
| return token.ToObject<T>(); | |
| return token.ToObject<T>() ?? defaultValue; |
be preferable?
There was a problem hiding this comment.
Hmm, the docs don't specify whether it can return null - I guess it wouldn't hurt to include just in case.
NTaylorMullen
left a comment
There was a problem hiding this comment.
90% there and looking awesome! One last blocking comment would be how you manage the attaching/unattaching from the ITextView state
| { | ||
| // JToken.ToObject could potentially throw here if the user provides malformed options. | ||
| // If this occurs, catch the exception and return the default value. | ||
| return token.ToObject<T>(); |
There was a problem hiding this comment.
Hmm, the docs don't specify whether it can return null - I guess it wouldn't hurt to include just in case.
|
@dotnet/razor-tooling @NTaylorMullen I've pushed some changes that update the behavior in the TextViewConnectionListener. Would appreciate any feedback! Also, I mentioned in the PR description that the active spaces/tabs option (https://github.com/dotnet/aspnetcore/issues/28003) wasn't working, but it seems I was mistaken. The user just has to type a bit in the document before being able to freely toggle between tabs/spaces. (The same behavior is observed in C#.) I've updated the PR description accordingly. |
NTaylorMullen
left a comment
There was a problem hiding this comment.
Overall looks great wooohooo!! I just had some suggestions for cleanup that might be valuable / reduce the amount of work going on in the textviewconnection listener.
| // All TextViews share the same options, so we only need to listen to changes for one. | ||
| _textBuffer.Properties[RazorEditorTrackedView] = textView; | ||
|
|
||
| var razorEditorTextViewOptions = _editorOptionsFactory.GetOptions(textView); |
There was a problem hiding this comment.
Could you elaborate on why we need both the textview options here and the buffer ones above? Also, given that you only track one textview at a time, and assuming it's needed, it'll be important to have a good comment explaining why we only ever update options on one and not all
There was a problem hiding this comment.
Added these comments to the code:
// We need to keep track of and update both the TextView and TextBuffer options. Updating
// the TextView's options is necessary so 'SPC'/'TABS' in the bottom right corner of the
// view displays the right setting. Updating the TextBuffer is necessary since it's where
// LSP pulls settings from when sending us requests.
// A change in Tools->Options settings only kicks off an options changed event in the view
// and not the buffer, i.e. even if we listened for TextBuffer option changes, we would never
// be notified. As a workaround, we listen purely for TextView changes, and update the
// TextBuffer options in the TextView listener as well.
^this latter issue was discovered via testing. I'm not sure why a Tools->Options change doesn't kick off a TextBuffer option changed event even if we listen for it, but I think this workaround works.
There was a problem hiding this comment.
@gundermanc lol VS' details make me sad
| var updatedTextView = _activeTextViews[0]; | ||
| _textBuffer.Properties[RazorEditorTrackedView] = updatedTextView; | ||
|
|
||
| var updatedRazorEditorTextViewOptions = _editorOptionsFactory.GetOptions(updatedTextView); |
There was a problem hiding this comment.
Very interesting, so it definitely seems like the TextView option tracking is important. Will be curious to understand what this piece does. I'm sure this was a fun one to optimize against 😆
|
Hello @allisonchou! Because this pull request has the p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (
|
Summary of the changes
Razor (ASP.NET Core)section. This replaces the existingASP.NET Core Razor Language Servicesin Tools->Options, which previously wasn't hooked up to anything.VS PR: https://dev.azure.com/devdiv/DevDiv/_git/VS/pullrequest/309612 (needs to go in first before this PR)
Roslyn PR: [LSP] Respect settings passed in by LSP in format handlers roslyn#52044
ASPNetCore PR: Allow Razor generated documents to respect tabs/spaces settings aspnetcore#31211
A couple of notes about what currently doesn't work:
In the lower right-hand corner of the editor, the correct current TABS/SPC option is displayed. However, switching between tabs and spaces by clicking on a different option is still not currently supported, and the current option isn't "checked" like it should be. I'm not sure why, but this will probably take more time digging into the VS side to investigate. I don't think this is is a major blocker since users can just set their preference in Tools->Options, but it's something we should look into in the future. https://github.com/dotnet/aspnetcore/issues/28003 has already been created for this.Fixes:
https://github.com/dotnet/aspnetcore/issues/30254
https://github.com/dotnet/aspnetcore/issues/27101
https://github.com/dotnet/aspnetcore/issues/28003