dotnet / fsharp

The F# compiler, F# core library, F# language service, and F# tooling integration for Visual Studio
https://dotnet.microsoft.com/languages/fsharp
MIT License
3.9k stars 783 forks source link

Autocompletion Behavior #2432

Closed cartermp closed 7 years ago

cartermp commented 7 years ago

Autocompletion for F# code in VS 2017 is one of the remaining and very visible areas where we're not at "parity" with C#/VB in VS. This is less of a problem in F# due to the brevity of many language constructs, but it is a very noticable part of using .NET in the IDE, and helps reduce typing time. @vasily-kirichenko took a quick crack at it in #1842 and the results already looked promising, but there is some more detailed behavior which we should nail down.

Autocompletion should be able to be turned off in settings. Different "levels" of automplete should also be configurable (such as for operators or keywords).

Below is an attempt to describe what I think some of the behavior of autocomplete should look like and hopefully start a discussion which hammers this out a bit further. Would love to get more suggestions, feedback, and dissenting opinions.

Literals

No completion for literals.

Identifiers - Locals and Parameters

Locals are straightforward. There should be completion when they are used, but no completion at the declaration site:

let foo() =
    let // No completion after typing 'let'.

let bar() =
    let res = 1 + 2
    r // Completion here.

Additionally, we should preselect a local in completion. Examples:

let (>>=) intOpt f =
    i // Preselect `intOpt` in the completion list here.

let foo x y =
    let resultOfX = x |> ProcessX
    let resultOfY = y |> ProcessY

    r // Preselect `resultOfX`, since it's a local and alphabetically before the other one.

This may be annoying if you have a codebase with lots of one- or two-letter identifiers, but it's quite a boon to everyone else. Like all of this, it should be able to be toggled.

Identifiers - Functions and Parameters

General behavior for functions and parameters should be pretty straightfoward.

Completion

No completion

Examples:

module Functions =
    let // No completion.

    // No completion.
    let myIncompleteFuncti 

    // No completion.
    let myFunction incompleteParame

    // Completion constrained to types and type aliases.
    let theFunction (param1: 

    // Completion constrained to types and type aliases.
    let functionWithReturnAnnotation x y z : 

    let square x = x ** 2

    let useSquare() =
        let r = // No completion.
        let squareOf2 = s // Completion for `s`.

        let number = 12
        let squareOf12 = square n // Completion for `n`.  `number` should be preselected.

        // Completion constrained to types and type aliases.
        let foo: 

Types - Records and DUs

Completion

No Completion

Note that in DUs, it's perfectly valid to provide an identifier for the type (or each tupled type) as such:

type Foo =
    | Bar of bar: int
    | Baz of baz: double

Even though it's likely more common to not do so:

type Foo =
    | Bar of int
    | Baz of double

This makes the notion of showing autocompletion difficult, and it would be annoying for people who know they're writing a type of the first kind, but they're getting completion for types and type aliases. Thus, I think no completion should be offered.

Types - Classes, Abstract Classes, Interfaces, Structs

Completion

No completion

Keywords

All F# keywords should show up in autocompletion. Some may object to this and think it's noisy. An example is VS for Mac:

screen shot 2017-02-13 at 1 46 47 pm

I think that one way to handle this is to not show the monadic variants of keywords if they are not enclosed by a computation expression which has the appropriate member defined. For example (| indicates the caret position):

let foo x y =
    l // `let!` does not show in autocompletion. Enclosing scope is not a CE.

let fooAsync x y = async {
    l // `let!` shows in autocompletion
}

Similarily:

let FooBuilder() =
    member self.Bind() = ...
    member self.Return() = ...

let foo = FooBuilder()

let useFoo = foo {
    l // `let!` shows in autocompletion
    y // Neither `yield` nor `yield!` show in autocompletion. Neither is defined for a FooBuilder.
    r // `return` shows in autocompletion, but `return!` does not
}

Here some places where keywords should not show completion for keywords:

Operators - infix ops and pipelines

Infix operators should show in completion after a valid identifier, but only if the left-hand type matches the input type for the operator. This should be relatively straightfoward if the types are annotated.

let ``compositions should show 1`` (f: 'a -> 'b) (g: 'b -> 'c) =
    f // `>>` and `<<` are in the completion list

let ``compositions should show 2`` (f: 'a -> 'b) (g: 'b -> 'c) =
    f >// `>>` is in the completion list, but `>` only shows if `f` supports comparison

let (>>=) = Option.bind

let ``same for user-defined operators`` (opt: Option<int>) (parse: (int -> string)) =
    opt // `>>=` is in the completion list

let ``pipe-forward`` (xs: List<int>) =
    xs // `|>` is in the completion list

If input types to functions still have yet to be inferred, we should only show completion when one of the operators is in the process of being typed. Examples:

let ``only when typed 1`` f g =
    f // No completion yet.

let ``only when typed 2`` f g =
    f > // `>>`, `>`, and any user-defined operators starting with `>` are in the completion list.

This could prove annoying, because there are plenty of operators with only one or two characters. However, one of the benefits of IntelliSense is a sort of guarantee that your code is being written in a way which will be accepted by the compiler. This may be particularly useful to newcomers who don't necessarily know the ins and outs of different parts of the language.

Any completion with operators should be optional. Conservatively, I think it should be turned off by default.

Pipelines and composition

"IntelliSense for Pipes" straddles the line between useful and completely untoolable. For example, no meaningful completion can be provided for the following:

let foo xs = xs |>

Perhaps there are a few conventions which could be hard-coded into the engine (such as xs meaning a collection type), but we don't know any types which could give us a hint at what should come after the |>. However, things change if a second pipe is introduced:

We now know that xs and the output of the filter call is of type int list. Thus, we can provide some meaningful completions which match the input. That's easier said than done, though...

For example, the List module name may most likely be expected at the top of the completion list after the second |> because it's the module which the first pipe came from. Such behavior makes sense for List, Seq, Array, and a few others, but it's a bit less obvious what the correct behavior is for the general case. For example:

module Foo =
    let addOne x = x + 1

module Bar =
    let double x = x * 2

let addOneAndDouble x =
    x |> Bar.double |>

Placing Bar at the top of the completion list is definitely not the correct behavior. Given this, I propose that we don't try to be too "smart". Module names in autocompletion should be available, so if this pattern is used a lot in someone's code, then they still get some completion in the IDE.

Similarily, >> can work the same way:

let foo = List.filter (fun x -> x > 0) >>

We know that the left-hand side is int list -> int list, so we can compose that with another List function. (Note that chaining Seq functions with >> can produce a value restriction [or as I like to call it, being too generic for your own good])

Left pipe and composition operators

Pipe-left and compose-left operators should provide completion after they're typed, because the resultant "place" where they'll be "piped into" has a known type (aside from %A format strings). They have the same issue regarding Module names in the Completion list, but that's less of a problem. Example:

let square (x: float) = x ** 2
let triple (x: float) = n * 3
let tripledSquare (x: float) = square >> triple // Note that autocomplete could happen after `>>`

let print x =
    printfn "Tripled square of 12  is: %f" <| // Completion can include all of the above.

For left pipes<||, <||| is tricky. Because the input type is a tuple, it's perfectly valid to construct it ad-hoc rather than call a function which returns a correct tuple. I propose no completion in this case.

Operators - Casting

There should be auotocompletion after typing a casting operator, constrained to a valid type. Examples:

open System

let tryDivide x y =
   try
      Some (x / y)
   with
      | :? // Completion list shows, constrained to exception types.

type Base() =
    abstract member M: unit -> unit
    default self.M() = printfn "bananas"

type Derived() =
    inherit Base()

    override self.M() = printfn "Doggies"

let upCastToBase (d: Derived) = d :> // Completion shows, constrained to types.
let upDowncastToDerived (b: Base) = b :?> // Completions hows, constrained to types.

Note that in the first example, I stated that the completion list should be constrained to Exception types and not just types. I'm positive that this is a more difficult problem to solve.

Snippets

Snippets can also be suggested for completion when typing certain constructs. For example, the for keyword can lead to three templates:

  1. for item in expression do
  2. for identifier = start to finish do
  3. for identifier = start downto finish do

These three snippets can be in the completion list, similar to VS for Mac:

screen shot 2017-02-13 at 9 50 58 pm

This is obviously dependent on snippet support and the F# snippets being authored (which should include all of the snippets in VS for Mac, IMO - pinging @nosami).

Misc

vasily-kirichenko commented 7 years ago

About keywords, do not forget to add the proper tag, see http://source.roslyn.io/#Microsoft.CodeAnalysis.Features/Completion/CommonCompletionService.cs,36

isaacabraham commented 7 years ago

One other bit is member suggestions when inside a ctor (sort of F# equivalent to object initialiser syntax). This has never worked in VS2015.

vasily-kirichenko commented 7 years ago

@cartermp about special behavior on the pipe and function composition operators, I don't agree, because completion should not behave differently for those and user defined "pipe-like" operators, like >>=, >=> and |>>.

vasily-kirichenko commented 7 years ago

Also we should distinguish two issues with completion:

The latter one is not as obvious, see what C# editor does http://source.roslyn.io/#Microsoft.CodeAnalysis.Features/Completion/CommonCompletionProvider.cs,54b4ce43ce7c9a05,references

dsyme commented 7 years ago

@cartermp about special behavior on the pipe and function composition operators, I don't agree, because completion should not behave differently for those and user defined "pipe-like" operators, like >>=, >=> and |>>.

I think |> is prominent enough that we should consider it separately and as a special case. It occurs like 100x more often than even >>

Pipe-left and compose-left operators ...

It's well-known I'm not a fan of the pipe-left operator except in relatively rare circumstances, for reasons I won't go into here, but mostly to do with readability and beginners-not-having-a-clue-what's-going-on. So I would not recommend any special tooling effort for these unless it drops out of something more general

I think the priorities here would be

  1. keywords
  2. snippets
  3. automatic-popup-more-often (e.g. pop up on space in a curried argument list, but not every use of space)
smoothdeveloper commented 7 years ago

Want to add that snippets or rather intelligent code generation (like Resharper does) for class members would be great. I can't recall the correct way to define CLI events or even properties with get/set (in various shapes), mainly because I don't use those often, but I'd like the tooling to help me introduce properties, interface implementation (not like current codefix which implies I know how to add the beginning of interface implementation), events, with wizard based workflow.

For completion, I'd like the items proposed to be enhanced with preference to those that are of valid types for insertion point (Resharper has smart completion https://www.jetbrains.com/help/resharper/2016.3/Coding_Assistance__Code_Completion__Smart.html).

Resharper is also experimenting with postfix completion (https://www.jetbrains.com/help/resharper/2016.3/Reference__Options__Environment__Postfix_Templates.html), and I believe there are opportunities for tooling to go even beyond that (that feature of Resharper is based on templates right now).

Function application should provide better feedback in terms of remaining parameters or indicating the function is curried.

majocha commented 7 years ago

Generally speaking Intellisense ideally should kick in automatically in every situation, the only exception being when declaring an identifier. Because all else is reusing already declared things. We can only take away from that ideal for performance reasons. That's how I see it.

cartermp commented 7 years ago

Updated the original text quite a bit. @vasily-kirichenko I'd love some more feedback on the keyword section w.r.t what you're planning to do.

@dsyme Regarding the left pipes, I certainly wouldn't say it's a high priority to get good completion, but since we do have typing information needed to present a good completion list, I think it's worth getting it in there.

dsyme commented 7 years ago

@dsyme Regarding the left pipes...

Well, I have to admit that I dislike the over-use of left-pipes so much that I would actively advocate deliberately not doing any tooling to support their use :)

I really, really don't like the routine over-use of left-piping that we sometimes see in F# code. I almost regret putting the operator in the F# core library. I would also advocate deprecating <|| and <||| altogether :)

smoothdeveloper commented 7 years ago

Thinking about two things I'd like with match:

nosami commented 7 years ago

Xamarin Studio's F# snippets can be found here https://github.com/mono/monodevelop/blob/8b17d75ff2dc26c5aa1a6246f6a2ce7d4f65e3be/main/external/fsharpbinding/MonoDevelop.FSharpBinding/Templates/FSharp-templates.xml

banshee commented 7 years ago

"IntelliSense for Pipes" straddles the line between useful and completely untoolable. For example, no meaningful completion can be provided for the following:

let foo xs = xs |>

What would be very handy after I type |> would be to just show me the type that you know about. In your first example, showing me something like 'a would be just fine, or Seq<'a>, or whatever it is you've got. Information, not really autocompletion.

banshee commented 7 years ago

This may be annoying if you have a codebase with lots of one- or two-letter identifiers

You just described the typical F# codebase, IMHO. In general, you have to play very well with one-letter identifiers, and letter-plus-s.

banshee commented 7 years ago

Additionally, we should preselect a local in completion. Examples:

let (>>=) intOpt f = i // Preselect intOpt in the completion list here.

let foo x y = let resultOfX = x |> ProcessX let resultOfY = y |> ProcessY

r // Preselect `resultOfX`, since it's a local and alphabetically before the other one.

This seems problematic. If the user types m at that point, you can't put up autocomplete for variables starting with m since it's likely to be match. Likewise l doesn't work.

banshee commented 7 years ago

All F# keywords should show up in autocompletion. Some may object to this and think it's noisy.

No no no no no no a thousand times no no no no. Please no. I beg you. You cannot put up autocomplete for let.

banshee commented 7 years ago

This makes the notion of showing autocompletion difficult, and it would be annoying for people who know they're writing a type of the first kind, but they're getting completion for types and type aliases. Thus, I think no completion should be offered.

I don't know how far you're extending the idea of "after of", but it would be nice to get autocompletion in those types:

| BoxOfStuff of widgets: SomeWidgetT<show autocomplete for SomeWidgetTypeThatIsReallyLong>

FYI, our older code doesn't include identifiers, but we'll almost always include them in newer code. Easier to get to from C#.

banshee commented 7 years ago

Thinking about two things I'd like with match:

if I type match propose me a list of things available locally that can be matched, and put the with already, when I pick an item from the list, if possible, propose to fill up the cases for me

+1 to @smoothdeveloper 's match suggestion. If I start with

let x: Foo // Where Foo is from your example above
match x with <suggest inserting match statements | Bar(bar) | Baz(baz)>

And

let x: Foo // Where Foo is from your example above
match x with 
| Bar(bar) -> ...
| <suggest a list of Baz(baz) etc, and prioritize the types that don't have any match case yet>

The second one seems harder, but a heuristic of prioritizing anything that hasn't shown up in any form in a match case (ignoring guards) seems useful.

banshee commented 7 years ago

Annotations at the declaration site, constrainted to only type names and aliases (triggered by :).

A refinement of this that would be nice is to further constrain the types to what's already known (this might be what you meant, of course):

type SomeBigLongType
...
let applyLeftHandBlivetWrench (a: SomeBigLongType) =
  let b = a

If I put my cursor at right after the b in let b, then type :, I'd like the type SomeBigLongTime suggested first, followed by its parent types (ignoring obj).

I don't know if you include this in intellisense, but it'd be nice to just select the line and hit something that says "fill in the explicit type for my identifier for me." Scala on Intellij does this; it's useful. Same for the function declaration; if the cursor's in a function, hit something that fills in the return type of the function.

cartermp commented 7 years ago

@banshee - Just to be clear on terminology, Autocompletion doesn't mean "filling in stuff for me". It's the various ways that the Completion List (typically referred to as IntelliSense) can be automatically brought up. Thanks for the feedback. Here are my replies:

What would be very handy after I type |> would be to just show me the type that you know about. In your first example, showing me something like 'a would be just fine, or Seq<'a>, or whatever it is you've got. Information, not really autocompletion.

I think what you're getting at is "make a best effort to show me something valid". When it's a generic type, that's anything which can accept any value as input. The completion list could be constrained in some way, but there's simply no telling what should come next. It's no different than offering completion at the call site for passing a parameter to a generic function.

You just described the typical F# codebase, IMHO. In general, you have to play very well with one-letter identifiers, and letter-plus-s.

Can't say one way or another. We don't have, nor collect, data on this. There's also more of a skew towards library code in the open source, where identifiers can be shorter because of a high percentage of very generic code. Our own codebase runs the gamut between one-letter identifiers and very long identifiers. Autocompletion for the VisualFSharp repo would likely be a boon. This is also why the intention is to make it entirely toggle-able. Those who don't like it would be able to turn it off.

This seems problematic. If the user types m at that point, you can't put up autocomplete for variables starting with m since it's likely to be match. Likewise l doesn't work.

How would this be problematic? There are numerous situations in C# code where a local is preselected, but that local isn't the intended identifier. That's perfectly alright, because as you type, the completion list changes (and often preselection changes to what you may have intended). It's impossible to always select the correct identifier, but that doesn't mean we shouldn't make a best-effort guess in this circumstance.

No no no no no no a thousand times no no no no. Please no. I beg you. You cannot put up autocomplete for let.

Could you explain why?

I don't know how far you're extending the idea of "after of", but it would be nice to get autocompletion in those types:

| BoxOfStuff of widgets: SomeWidgetT<show autocomplete for SomeWidgetTypeThatIsReallyLong>

FYI, our older code doesn't include identifiers, but we'll almost always include them in newer code. Easier to get to from C#.

I've modified to specify that completion after < in all circumstances should be offered. Good feedback!

+1 to @smoothdeveloper 's match suggestion. If I start with

let x: Foo // Where Foo is from your example above match x with <suggest inserting match statements | Bar(bar) | Baz(baz)> And

let x: Foo // Where Foo is from your example above match x with | Bar(bar) -> ... | <suggest a list of Baz(baz) etc, and prioritize the types that don't have any match case yet> The second one seems harder, but a heuristic of prioritizing anything that hasn't shown up in any form in a match case (ignoring guards) seems useful.

What's being described is a mixture of a template and code generation via codefix/lightbulb from the VisualFSharp Power Tools. Finding a way to get that to happen "with IntelliSense" is likely going to be a gesture along the lines of:

match --> (autocompletion shows match template) --> enter (cursor between match and with) --> x --> ctrl+. --> Generate Case (if it is a DU) --> enter

Getting autocompletion to auto-fill cases may not be the intended behavior. It's perfectly valid for someone to use _ to catch the rest of the cases that don't matter, and they'd likely find that annoying. Having the option available as a codefix + having a template show up in autocompletion so you don't have to type the with boilerplate is a good approach here.

A refinement of this that would be nice is to further constrain the types to what's already known (this might be what you meant, of course):

Yup, that's what I mean. We can't constrain to anything unknown at this time. Eventually we'd like to have a way to allow you to specify types in your solution which live in another project, and have it auto-import the namespace + add the project reference when you hit enter, but that would be a while from now and very much a v2 kind of concept. C#/VB are looking to support this sort of thing eventually as well.

If I put my cursor at right after the b in let b, then type :, I'd like the type SomeBigLongTime suggested first, followed by its parent types (ignoring obj).

That's actually quite a tall order which borders of predictive IntelliSense. Note that preselection (which I propose we do for locals) is a beginning step towards that, but analyzing the usage of things to further inform what shows in a Completion List is very much a v2 or v3 sort of thing. It also has the prerequisite that this sort of information can be computed very fast, because completion itself needs to be fast to be seen as useful. If we appear to lag, then autocompletion becomes very annoying.

I don't know if you include this in intellisense, but it'd be nice to just select the line and hit something that says "fill in the explicit type for my identifier for me." Scala on Intellij does this; it's useful. Same for the function declaration; if the cursor's in a function, hit something that fills in the return type of the function.

This actually sounds like a separate feature request which could be serviced by a lightbulb popping up. Could you create a separate issue for this? Thanks!

CyberQin commented 7 years ago

UpperCase Filter

UpperCase Char can be used as filter to select the most likely words. "SenmenticModel" can be choosed after "SM" is typed. another c# feature :)

smoothdeveloper commented 7 years ago

@Huqin-China AFAIK this works already (to some extent) in VS2015 and probably before.

image

CyberQin commented 7 years ago

@smoothdeveloper tks,i can see that in vs2017 rc4 now

cartermp commented 7 years ago

@Huqin-China Yup! That kind of matching works in vs2017 today. One of the features we get for free 😄

smoothdeveloper commented 7 years ago

Having good intellisense support for xml documentation would be great addition to come on parity with C#/VB.NET on that front.

vasily-kirichenko commented 7 years ago

@cartermp the feature uses the same PatternMatcher that we now use in Go to Everything (former Navigate To).

banshee commented 7 years ago

Just to be clear on terminology, Autocompletion doesn't mean "filling in stuff for me". It's the various ways that the Completion List (typically referred to as IntelliSense) can be automatically brought up.

Got it, I think I'm lumping things into IntelliSense that aren't part of it.

I think what you're getting at is "make a best effort to show me something valid". When it's a generic type, that's anything which can accept any value as input. The completion list could be constrained in some way, but there's simply no telling what should come next. It's no different than offering completion at the call site for passing a parameter to a generic function.

I think I want something here that isn't IntelliSense. If my cursor is after |>, I want a tooltip telling me the type to the left of the |>. I don't think there's much value in trying to figure out what I'm about to type next, since the decision space is so huge at that point.

How would this be problematic?

I'm not a fan of the way the current editors like to constantly pop up completion windows. Visual Studio for Mac is probably the most annoying editor I've had to work with for many years (and I was a Ruby NetBeans user way back in the day, so it has serious competition for that award). Maybe it wouldn't be so bad if it were right sometimes, but the C# editor in particular essentially spends its time pulling up random junk to suggest when I'm naming variables, and then inserting that random junk when I hit the spacebar. Drives me crazy.

Maybe I'd change my mind if the current editors were decent; I used to use Intellij/Android Studio too, and it pops up quite a few things, but the level of quality over there is so much higher than Visual Studio for Mac that it feels like the popups belong. (I actually think the F# editor today is much better than the C# editor; F# doesn't have as many features, but the C# editor compensates by implementing its features badly.)

No no no no no no a thousand times no no no no. Please no. I beg you. You cannot put up autocomplete for let. Could you explain why?

Prefilling 'let' or 'match' is just distracting me for no useful purpose; you're really trying to save me the fractions of a second it takes to finish typing let? I don't understand. Showing me a popup has a cost in my attention; please don't do it when it's not useful.

banshee commented 7 years ago

match --> (autocompletion shows match template) --> enter (cursor between match and with) --> x --> ctrl+. --> Generate Case (if it is a DU) --> enter

Getting autocompletion to auto-fill cases may not be the intended behavior. It's perfectly valid for someone to use _ to catch the rest of the cases that don't matter, and they'd likely find that annoying. Having the option available as a codefix + having a template show up in autocompletion so you don't have to type the with boilerplate is a good approach here.

Totally agree that I don't always want all of the cases filled out; it's one option that would be nice to suggest as a (snippet? not sure what they're called).

I think the part that perhaps fits into IntelliSense is suggesting elements from an ADT when you're matching against one:

match x with
| Bar(bar) -> ...
| **cursor here**

when my cursor is at cursor here, I'd really like you to pull up Baz and Bar. Intellisense would get a gold star if it could figure out that I've already used Bar, so it's less likely (but still possible, of course). It'd also be nice if it showed me Active Patterns that had a type that would be useful here.

banshee commented 7 years ago

A refinement of this that would be nice is to further constrain the types to what's already known (this might be what you meant, of course): Yup, that's what I mean. We can't constrain to anything unknown at this time.

Heh - I think I misphrased that.

I mean I'd like IntelliSense to use the type inference that's already there; basically, if I can hover over the identifier in a let (with something already in the file off to the right that has a type), and get a tooltip window with the inferred type, it'd be nice to have that type filled in by IntelliSense if I type a : after the identifier.

smoothdeveloper commented 7 years ago

@banshee VFPT (and VS2017 thanks to contributors) has that match case filler completion, the drawback of suggestions that were brought in comments is they take long for to show up in editor, what I'm looking for is more like resharper live templates, foreach for example will guide me with a bunch of tab and completions:

I agree with your sentiment on let, but I really feel the experience on match with could be closer to that resharper experience with foreach, upfront, and it really helps beginner to pick-up the right syntax, make that construct appealing to newcomers.

Whenever I want to put a match with, I'd like to focus on typing/picking the right value, and don't have to type the whole keywords / indentation all that often.

I agree with the sentiment of "too much completion", I've had many X509Certificate pop in my way when doing simple x => in C#.

I want completion to propose me prioritized values / members that match the type expected at insertion point, or at least have those being highlighted in some manner.

banshee commented 7 years ago

I agree with your sentiment on let, but I really feel the experience on match with could be closer to that resharper experience with foreach, upfront, and it really helps beginner to pick-up the right syntax, make that construct appealing to newcomers.

OK, I think you could sell me on match. I'd probably prefer that it didn't kick in with just an m or ma (wait for matc, maybe). Others are problematic though; d shouldn't get me do.

smoothdeveloper commented 7 years ago

One very simple feature: when I type ``, complete to ```` putting the carret in the middle.

smoothdeveloper commented 7 years ago

Supporting auto-complete for type providers method with static parameters (a feature added in F# 4.0) is something we are still missing.

jeroldhaas commented 7 years ago

This would be desirable:

[<AbstractClass>]
type Bar() =
  abstract Foo : int

let b = { new Bar() with member x.■ }

(missing autocomplete behavior at the black square)

Note that when 2nd member is being set/configured, the autocompletion behavior is working, but it would be nice to have the first one working. 😄

@smoothdeveloper mentioned: "it might be possible to reuse logic from VFPT which implements interface to have a codefix also, we could have a dialog showing list of overrideable members"

smoothdeveloper commented 7 years ago

In places where a boolean is expected (like if or while, and possibly places taking a boolean value), resharper lists members returning bool first:

image

This might be generalized to other types, but I think it is useful features.

cartermp commented 7 years ago

Closing old discussion; this should really go into the RFC repo as a pull request.