-
Notifications
You must be signed in to change notification settings - Fork 785
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
VS2017 RC - Edit.CompleteWord should not block #1825
Comments
@vladima Any pointers on this? Thanks |
I think we should have no problem making this command asynchronous. Note, we should not use a cancelable wait dialog here. It would massively impede topping, possibly capturing keystrokes. We may simply want to put a timeout for the blocking here. I'd like it if could also listen for esc, but I'm not sure how we'd do that if we're currently blocked waiting for completion to complete. Can we somehow still register and hear about those keystrokes if we've blocked the UI thread? |
I'm also thinking we might need a way for a completion service to say that it should never block. For providers that simply can't guarantee fast completion time. I know Venus wants this as they may make network calls when trying to compute completion items. |
The same applies to F# type providers What is Venus? |
Exactly. The Azure Storage TP can sometimes take a few seconds to return depending on number of blobs in a folder etc. so you won't want that to block whilst it's waiting to return. |
'Venus' is the MS name for the web stack technologies. So things like HTML/json/CSS completions. |
Ok. I've investigated this a bit. While i don't think it would be hard, we def need to do some cleanup in completion around where we do blocking. I think Ravi, Matt or myself could definitely do this (though Ravi might be best as he's done a lot of recent work in the completion controller). Right now we've scattered 'blocking' functionality in a few places in completion, and we likely would need to carefully unify these areas, and ensure acceptable behavior with a host language that wanted to never block. The places where we block today are: First, some clarifying terms:
Completion has a few 'State's which can generally be expressed in terms of the above two concepts. These states are not explicitly called out in code (but would likely be valuable to do so).
Ok, given the above, here the places where we currently block:
Ok, given the above, i think we should change our behavior specifically in the "Active, no-initial-model" state. Recall, this is the state where the completion service is computing items, but has not returned anything yet. In this state the user effectively thinks there is no completion and they'll have a very bad experience if completion takes many seconds and we end up blocking. We should allow specific completion servics to opt out of the blocking experience while in this state. So, if we're in "Active, no-initial-model" and any of the first three places where we block happens, then we just immediately cancel completion so that we don't end up blocking for something which may take a long time. This leaves the fourth case ("Complete-Word" is invoked). If we have an , this is simple, we're in "Active, initial-model-computed" then we just commit the single selected item if it has one. However, if we're in Inactive, what should we do? The user has invoked the keystroke which is them telling us "i want to complete out this word" but in order to do that, we need to actually compute the completions in order to determine what to commit to. Perhaps with languages like F#, this command is simply not supported while completion is Inactive or is in "Active, no-initial-model". Or maybe it does not have any effect but to kick off the completion work. Then, once we get to "Active, initial-model-computed" the user can hit complete-word again to actually commit. This means that in F# you'd need to hit complete-word twice if completion wasn't active. In essence complete-word would act like "list members" initially. And only if you had the list up would it commit. |
@CyrusNajmabadi Super analysis, thanks
In VS2015 I think the behaviour for Ctrl-Space is that, if the user types something else or does anything to move away before the completion is committed, then the completion request is ignored and cancelled. There is no blocking up to that point So from our perspective it feels like we want to do the part "actually compute the completions in order to determine what to commit to" asynchronously,. Then check the cursor location and document version are still matching on async-completion of the request |
Hey @dsyme . That makes a lot of sense. And i think we should be able to provide that without too much difficulty. Thanks! |
I have a PR out for this now. Will try to get it in soon! |
That's great! Could you take a,look at #1808 (comment) too please? We basically need a way to request an on-idle re-analysis of a file due to a detected change outside of Roslyn. Something that triggers semantic error checking to happen again. |
Fixed with dotnet/roslyn#15572 |
@brettfo This got auto-closed - I think we still need to do this once we pick up the new Roslyn packages:
|
And auto-closed again. |
The flag is in "approved for RC3" status dotnet/roslyn#15572 (comment) We must not forget to set it to |
See what I've found dotnet/roslyn#15924 |
A good news is that the blocking autocomplete is definitely a problem for us: and I hope dotnet/roslyn#15572 (comment) will fix it. |
@vasily-kirichenko would it be possible to grab the option by reflection and set it to validate before the API makes it to F#? |
Alternatively, try updating the Roslyn packages to some newer version on https://dotnet.myget.org/F/roslyn to get at the option? |
Repro steps
Edit.CompleteWord
(Ctrl+Space)Expected behavior
It asynchronously computes completion.
Actual behavior
It synchonously blocks
Known workarounds
Using
Edit.ListMembers
(Ctrl+J) instead should start an asynchronous computation, but not block until commit happens.Related information
We can/should tweak the command handler to just do the ListMembers behavior.
A further concern however is that Roslyn doesn't have any cancellation support in completion once an operation has triggered a commit - it will block until it knows what to commit. Given the existence of type providers, we may need to change Roslyn to accommodate that.
Tagging @CyrusNajmabadi and @rchande for thoughts.
The text was updated successfully, but these errors were encountered: