-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
Implementation of new editor completion API #29016
Conversation
What is the relationship of this PR to #25770? What's new here? #Resolved |
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.
Marking as request changes for the sole purpose of making sure I don't forget to review this one.
@tmat , this is a merge of #25770 with recent biths of master-vs-deps. I'll close #25770 as soon as I'll merge this one and migrate another PR depending on #25770 to new master-bs-deps bits. @sharwell , an interesting approach to make notes :-) So, could you please review? @jasonmalinowski , @jinujoseph, @dotnet/roslyn-ide , pinging ... do we have reasons to keep this work pending for a long time once again? #Resolved |
src/EditorFeatures/Core.Wpf/InlineRename/InlineRenameSession.cs
Outdated
Show resolved
Hide resolved
src/EditorFeatures/Core.Wpf/Microsoft.CodeAnalysis.EditorFeatures.Wpf.csproj
Outdated
Show resolved
Hide resolved
src/EditorFeatures/Core/Implementation/IntelliSense/Completion/AsyncCompletionService.cs
Outdated
Show resolved
Hide resolved
src/EditorFeatures/Core/Implementation/IntelliSense/Completion/AsyncCompletionService.cs
Outdated
Show resolved
Hide resolved
src/EditorFeatures/Core/Implementation/IntelliSense/Completion/AsyncCompletionService.cs
Outdated
Show resolved
Hide resolved
src/EditorFeatures/Test2/Microsoft.CodeAnalysis.EditorFeatures2.UnitTests.vbproj
Outdated
Show resolved
Hide resolved
src/EditorFeatures/Test2/IntelliSense/VisualBasicCompletionCommandHandlerTests.vb
Outdated
Show resolved
Hide resolved
src/EditorFeatures/Test2/IntelliSense/VisualBasicCompletionCommandHandlerTests.vb
Outdated
Show resolved
Hide resolved
src/EditorFeatures/Test2/IntelliSense/VisualBasicCompletionCommandHandlerTests.vb
Outdated
Show resolved
Hide resolved
src/EditorFeatures/Test2/IntelliSense/VisualBasicCompletionCommandHandlerTests.vb
Outdated
Show resolved
Hide resolved
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.
Comments so far. I still need to review EditorAsyncCompletionItemManager.cs.
The custom commit code to me is particularly worrisome -- at first glance it has a number of bugs around handling of snapshots. If it's right I'd appreciate a lot more comments as to why it's right.
For the tests, I think we should figure out a better way to share the test assets rather than a copy/paste. xunit allows (among other things) you to use inherited test classes to try running the same tests with some different context. It might require a bit of adding a layer of indirection, but I think it'll make it a lot easier to understand this PR and maintain this code even in the short term. I'm guessing we won't be deprecating the old one for a few previews, and in that time we might have other work to be doing for language support.
src/EditorFeatures/Core/CommandHandlers/SignatureHelpCommandHandler.cs
Outdated
Show resolved
Hide resolved
src/EditorFeatures/Core/Implementation/IntelliSense/Completion/AsyncCompletionService.cs
Outdated
Show resolved
Hide resolved
src/EditorFeatures/Core/Implementation/IntelliSense/Completion/Controller.cs
Outdated
Show resolved
Hide resolved
...mplementation/IntelliSense/EditorCompletionImplementation/CompletionCommitManagerProvider.cs
Outdated
Show resolved
Hide resolved
...mplementation/IntelliSense/EditorCompletionImplementation/CompletionCommitManagerProvider.cs
Outdated
Show resolved
Hide resolved
|
||
public async Task<object> GetDescriptionAsync(EditorCompletion.CompletionItem item, CancellationToken cancellationToken) | ||
{ | ||
// TODO: Should string.Empty returns here be null to avoid an empty popup? https://github.com/dotnet/roslyn/issues/27420 |
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.
Makes sense to me. Why the bug? #Resolved
return string.Empty; | ||
} | ||
|
||
var documentId = workspace.GetDocumentIdInCurrentContext(triggerBuffer.AsTextContainer()); |
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.
Isn't this all just triggerBuffer.CurrentSnapshot.GetDocumentInCurrentContext()? #WontFix
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.
Could not find GetDocumentInCurrentContext in CurrentSnapshot
In reply to: 208429747 [](ancestors = 208429747)
return string.Empty; | ||
} | ||
|
||
var service = (CompletionServiceWithProviders)document.GetLanguageService<CompletionService>(); |
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.
Same as next function below? Can we reuse? #Resolved
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.
return (CompletionServiceWithProviders)document.GetLanguageService<CompletionService>(); | ||
} | ||
|
||
public Task HandleViewClosedAsync(ITextView view) => Task.CompletedTask; |
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.
What should we be doing here? Anything? #Resolved
|
||
private RoslynCompletionItem GetOrCreateRoslynItem(EditorCompletion.CompletionItem item) | ||
{ | ||
if (item.Properties.TryGetProperty<RoslynCompletionItem>("RoslynItem", out var roslynItem)) |
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.
Constant since I'm guessing this is hardcoded in other places? #Resolved
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 only other instance is in test state. so, it think constant is not necessary.
In reply to: 208430212 [](ancestors = 208430212)
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.
@ivanbasov Still having a constant would mean that's possible to determine. #Resolved
d25db1a
to
8b0988d
Compare
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 pull request should not be merged until we fix the rename tracking for items in the OldCompletion
folder. I implemented the change locally and am working with @ivanbasov to correct the pull request.
...s/Core/Implementation/IntelliSense/EditorCompletionImplementation/CompletionCommitManager.cs
Outdated
Show resolved
Hide resolved
src/EditorFeatures/TestUtilities/ExperimentationService/TestExperimentationServiceInternal.cs
Show resolved
Hide resolved
src/EditorFeatures/Test2/IntelliSense/OldCompletion/CSharpCompletionCommandHandlerTests.vb
Outdated
Show resolved
Hide resolved
@ivanbasov I figured out the file copy tracking, but it's not the most pleasant thing ever. This pull request is blocked on #29166; after that is merged I'll update this pull request and it will be much better. #Resolved |
...plementation/IntelliSense/EditorCompletionImplementation/EditorAsyncCompletionItemManager.cs
Outdated
Show resolved
Hide resolved
{ | ||
if (!IsAfterDot(data.Snapshot, session.ApplicableToSpan)) | ||
{ | ||
return Task.FromResult(new EditorCompletion.FilteredCompletionModel(ImmutableArray<EditorCompletion.CompletionItemWithHighlight>.Empty, 0)); |
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.
Should the editor provide a FilteredCompletionModel.Empty? #Pending
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.
} | ||
|
||
// We need to filter if a non-empty strict subset of filters are selected | ||
var selectedFilters = data.SelectedFilters.Where(f => f.IsSelected).Select(f => f.Filter).ToImmutableArray(); |
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.
.SelectedFilters isn't the filters that are selected? @AmadeusW? #Resolved
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 is complete set of filters, specifically CompletionFilterWithState
s. I see how "SelectedFilters" is a poor name for "all filters"
Each element of this enumeration has a reference to the CompletionFilter
and two bools: IsAvailable
and IsSelected
Language service is expected to
- Filter the completion items based on typed text,
which determines theIsAvailable
property (true if at least one completion item of that filter is present) - Filter the results based on filter's
IsSelected
property (value is set by user) #Resolved
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.
So are we renaming this? 😄 #Resolved
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.
Yes, copying the original response by @amwieczo@microsoft.com
This is complete set of filters, specifically CompletionFilterWithStates. I see how "SelectedFilters" is a poor name for "all filters"
Each element of this enumeration has a reference to the CompletionFilter and two bools: IsAvailable and IsSelected
Language service is expected to
- Filter the completion items based on typed text,
which determines the IsAvailable property (true if at least one completion item of that filter is present) - Filter the results based on filter's IsSelected property (value is set by user)
In reply to: 208708695 [](ancestors = 208708695)
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.
yes, here are our selectedFilters. And there are Editor's selected filters which are all filters. ugh
In reply to: 221393614 [](ancestors = 221393614)
} | ||
else | ||
{ | ||
if (data.InitialTrigger.Reason == EditorCompletion.InitialTriggerReason.Deletion || |
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.
Do this check first before MatchesFilterText since it's a lot cheaper? #ByDesign
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.
It seems that MatchFilterText should have another priority over the reasons comparison: if there is a Match, we set matchedFilterText: true even if it is the deletion. So, we cannot swap condition checks.
In reply to: 208709031 [](ancestors = 208709031)
29d5f57
to
54c1e92
Compare
e78363e
to
e57a325
Compare
Can there be a general 'ping' when this is ready for reviewing? #Resolved |
…e with no call to get
6c94b68
to
85273b2
Compare
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.
Looks good enough for an initial merge, with the understanding we still have a lot to clean up. A few last questions, but I don't think that'll result in any changes needed at this point.
I am still very concerned about the editor API's design around us having to be responsible for filtering and sorting other items that aren't our own in the projection case. It seems like that's still going to require some redesigns, but that's not really a problem with this PR per se but rather something they'll need to address.
if (change.NewPosition.HasValue) | ||
{ | ||
view.TryMoveCaretToAndEnsureVisible(new SnapshotPoint(updatedCurrentSnapshot, change.NewPosition.Value)); | ||
view.TryMoveCaretToAndEnsureVisible(new SnapshotPoint(subjectBuffer.CurrentSnapshot, change.NewPosition.Value)); |
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.
Shouldn't this also be making a snapshot point against the appropriate snapshot and translating it forward? i.e. the updatedCurrentSnapshot was correct here but not further below? (This also presumes TryMoveCaretAndEnsureVisible translates forward instead of crashing.) #Resolved
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.
{ | ||
// Need the trigger snapshot to calculate the span when the commit changes to be applied. | ||
// It should be inserted into a property bag within GetCompletionContextAsync for each item created by Roslyn. | ||
// If not found here, Roslyn should not make a commit. |
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.
How would we get here in the first place? You already filtered non-Roslyn items earlier? #Resolved
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.
-
We can miss to provide triggerSnapshot by mistake.
-
Let us assume there is another provider wants Roslyn to perform a commit and provided CompletionSource.RoslynItem above. We can proceed but we also need triggerSnapshot in the case.
In reply to: 236497307 [](ancestors = 236497307)
return CommitResultUnhandled; | ||
} | ||
|
||
// Commit with completion serivce assumes that null is provided is case of invoke. VS provides '\0' in the case. |
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.
// Commit with completion serivce assumes that null is provided is case of invoke. VS provides '\0' in the case. | |
// Commit with completion service assumes that null is provided is case of invoke. VS provides '\0' in the case. | |
``` #Resolved |
if (textTypedSoFar.Length > 0) | ||
{ | ||
return item.DisplayText.StartsWith(textTypedSoFar, StringComparison.CurrentCultureIgnoreCase) || | ||
item.FilterText.StartsWith(textTypedSoFar, StringComparison.CurrentCultureIgnoreCase); |
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.
Didn't we also do filtering explicitly in en-us for people using non-English things trying to type English framework names? #Resolved
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.
Agreed. In the meantime though, would it be better for us to not filter/sort these items? I ask because otherwise we know how this will likely pan out. We'll have the code for it, dependencies will be taken on it, and it will taken 15+ years to finally get removed. :) Basically, if this is merged in, i put odds at 99% that it never ever gets removed. But if we don't add it, it will force the issue of implementing things in a proper fashion. Thoughts @jasonmalinowski |
No description provided.