-
Notifications
You must be signed in to change notification settings - Fork 784
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
Trigger completion optimistically #2594
Trigger completion optimistically #2594
Conversation
Glad to see this revived and working well :) this is great. |
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 great
Awesome, now it only needs more logic to filter out incorrect suggestions based on syntax, for example after |
Yeah, it should not show anything right after let and let! However... What about |
Yes, it would be perfect to include only correct destructuring constructs. In C# it seems there is a lot of logic of this kind to make the experience fluid. |
@majocha That's correct, there is a lot of logic in there. Completion for destructuring is tricky. It would definitely be annoying if I had completion trigger for the following: let (x And my intention was to use pattern matching to form a tuple, with one of the names being |
@cartermp or you may want to write something like In short, in F# we can restrict completion list after dot only. |
Certainly some details to work out. I'll see if I can write anything useful down in #2432 |
@cartermp that thread is about what to show in completion. The problem we are discussing in this PR is when to auto trigger completion. Those are completely different things. Currently we use simple parsing (was the last entered char a dot? is it a single dot? etc) and the lexer (are we inside a comment or excluded block? etc). To provide good auto-triggering experience (i.e. non obtrusive), we'd have to use parse tree and a special worker, similar to the one used in filling the completion list (are we at argument position? are we in record construction? etc), but the logic would be different. So I think we should do not trigger completion anywhere, other then few very specific places in parse tree, which should be formalized. The first obvious place is on dot. Please, suggest other places. |
@cartermp @Pilchie could you please help to find the code in C# editor which is responsible for triggering completion? All these http://source.roslyn.io/#Microsoft.CodeAnalysis.Features/Completion/CommonCompletionProvider.cs,54b4ce43ce7c9a05,references overrides do not have any real logic. |
I've played with C# editor a bit. Completion triggers all the time. The only place that this PR's behavior is different is after |
Another that comes to mind is after |
@majocha Yeah. The problem here is that completion list is not empty at |
…optimistically Conflicts: vsintegration/src/FSharp.Editor/Completion/CompletionProvider.fs
I turned off completion at the following points: type |
type M|
let |
let f|
let f (|
let f(a|
let f(a, |
let f(a, b: int, |, c)
...
member __.M(|
member __.M(a, b|: int, c: int)
...
Please test for usability. |
@vasily-kirichenko Here's where I'd look: https://github.com/dotnet/roslyn/tree/master/src/Features/CSharp/Portable/Completion I haven't pulled it down yet (not at my desktop), but my only other suggestion for not offering completion would be after the member __.| // No completion Also, I'm not sure if this is the PR for it, but we should also have preselection for locals that are in scope. |
Some more cases that are accounted for in XS let! |
override |
for |
[1..|
module |
(fun |
1u| Not sure if you have these covered. XS doesn't handle record labels but it probably should. Anywhere where you can type an identifier IMO should not offer completions. Some tests here |
@nosami I think all these covered, except |
@cartermp it does not offer completion at the point you mention. I think it does not in master, too. |
@vasily-kirichenko good question - no idea! |
OK, I added a property page and a setting to turn auto triggering on and off. It's on by default. Should we make it disabled? If no, then this PR is ready. |
If we have setting, lets keep it on :) Thanks! |
I turned off committing on space in auto triggering mode, so even though it pops up in some inappropriate places, it's not annoying because you don't have to press |
|
||
static member ProvideCompletionsAsyncAux(checker: FSharpChecker, sourceText: SourceText, caretPosition: int, options: FSharpProjectOptions, filePath: string, textVersionHash: int) = | ||
asyncMaybe { | ||
let! parseResults, parsedInput, checkFileResults = checker.ParseAndCheckDocument(filePath, textVersionHash, sourceText.ToString(), options, allowStaleResults = true) | ||
|
||
//Logging.Logging.logInfof "AST:\n%+A" parsedInput |
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.
Commented code
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. It will be very useful in further work on completion.
In the moment we can use this in Visual Studio, you have recruited a new F# community member. I have never learned F# because it was so annoying when you have a C# Visual Studio Background and its also much easier to learn a new language with IntelliSense than without. So, thank you @vasily-kirichenko for your work! |
@VSDekar Intellisense has worked since VS 2010, but it was not triggered automatically, except after dot. So saying that F# did not have intellisense is not fair. |
@vasily-kirichenko You are right, but thats why i said that when you come from C# and Visual Studio. The experience is (was :-) ) much better with C#. |
@VSDekar I think each language has it's advantage, but confinning the overal experience to intellisense (which is working in F# since day 1) is short sighted, I also experience better error prone code constructs in C# and a greater need for heavy tooling to perform simple refactorings 😄 So you have to factor the whole experience with language and then draw a conclusion, but stopping at intellisense doesn't look as fancy as in other language is too early. |
@VSDekar Welcome to the team, we are very proud of the contributions of @vasily-kirichenko, @smoothdeveloper, @cloudRoutine and our other community members they are truly allowing our tooling to catch up with the C# and VB experience. Kevin |
@KevinRansom I'm not contributing to VS much, I'd need some help with #2351 if possible to try to help with IDE features at some point. |
* port Roslyn's C# completion triggering logic as is * fixed: completion do not trigger at all * fix position * fix a test * do not provide completion on certain places * fix muting completion on Named(Wild) pat in binding * do not provide completion on ctor / lambda parameter names + tests * fix binding traversing in completion * fix tests * fix the last failing test * "trigger completion after a character is typed" setting in a new completion property page * force intellisense property page loading * do not commit completion on space in auto triggering mode * fix completion list ordering
The current (vs2017) trigger conditions are shit. Autocompletion triggers in places where syntax expects a new identifier (e.g. variable/type/member name/type parameter declaration) making it impossible to write a new identifier without pressing "esc" to close autocompletion. Try to declare a type parameter, such as in |
There is no reason for type name completion anywhere else than after a colon ( |
@pqnet Could you please open a new issue for that, with as many examples as you can? thanks |
Also @pqnet ensure you're on the latest VS (15.3.3) when you test, as there are changes there to not commit autocompletion except for a small number of cases, fixing some annoyances in this space. In general please do be respectful here; autocompletion is difficult stuff and represents a lot of time and energy from @vasily-kirichenko and others. |
@dsyme, @vasily-kirichenko The same holds for trying to type an escaped identifier with Don't get me wrong, in any other code it usually works wonderfully and saves a lot of typing! But since 99% of my tests are written with this syntax, it makes writing them rather painful at the moment. |
@cartermp thank you, I was actually on 15.2 (didn't see any notification that a new version was available - I thought some would appear if my version were to be old) so probably my observation is obsolete. I'm sorry if my choice of words was a bit aggressive, I was frustrated and ended up being impolite. In my defense I tried to keep the criticism constructive and to give my contribution to the discussion: a concrete test case and my opinion about autocompletion triggering rules (there is no reason for it to trigger after every word, in particular after tokens which introduce a new name, like |
The way C# handles this is with 'builders'.i.e. try writing:
We will pop up completion because you may want to refer to something with 's' in it. However completion will be in 'builder' mode. In this mode we do not commit by default. Instead the user has to explicitly pick an item and commit it themselves. The builder message also says that we're in a special mode because you may be about to write a lambda. Basically the rules are: |
* port Roslyn's C# completion triggering logic as is * fixed: completion do not trigger at all * fix position * fix a test * do not provide completion on certain places * fix muting completion on Named(Wild) pat in binding * do not provide completion on ctor / lambda parameter names + tests * fix binding traversing in completion * fix tests * fix the last failing test * "trigger completion after a character is typed" setting in a new completion property page * force intellisense property page loading * do not commit completion on space in auto triggering mode * fix completion list ordering
I've tested it on
TypeChecker.fs
. No UI freezes at all (but completion appeared after ~2-3 seconds delay, however I expect it to be exactly 1 second, but it's another issue).(no
Ctrl+Space
were used)