Flutter-intellij: Insert a child: (or children: placeholder list) for Widgets on code completion

Created on 21 Nov 2016  路  23Comments  路  Source: flutter/flutter-intellij

_From @HansMuller on February 19, 2016 0:18_

It would be nice if adding an element that has List children parameter automatically formatted the and selected the children boilerplate.

For example, you type:

    new Flexible(
      child: new Row
    ) // I'm imagining that this close paren was added per 'new Flexible'

and Atom adds the boilerplate:

    new Flexible(
      child: new Row(
        children: <Widget>[
        ]
      )
    )

By automatically selecting the two lines begining with "children:" the developer can easily delete the boilerplate and substitute a list valued expression.

_Copied from original issue: flutter/flutter#2018_

adoption-blocker enhancement study topic-editing

All 23 comments

_From @sethladd on February 19, 2016 0:21_

If we have cases that aren't "smart" and we just want to add a snippet of code, I think we can do this easily.

net-net: should be possible with the current completion API

Nice, shall we get it assigned?

We saw similar issues in the study.

I did some implementing to improve codegen for @required args with List value types but then discovered that in the cases discussed children arguments are _not_ required. :confused: In fact, they are optional (see for example Row) but defined with a default empty list. Anyway, do we want to pursue the boilerplate @HansMuller is describing above for children? If we do, let's discuss how generalized we want this to be.

@devoncarew @mit-mit for thoughts.

FYI @Hixie

Browsing through widgets/basic.dart, it looks like child is required in a few cases like Positioned, Flexible, Expanded, and DefaultAssetBundle but otherwise not. @Hixie is this intentional?

Popping up there's a larger question around whether we cue smart code completion of boiler plate for method/constructor arguments exclusively off of whether they are annotated @required. That's how things are currently implemented but as @mit-mit points out the value is limited to places where the APIs use the annotation and won't, for example, address @HansMuller's motivating case (Row children).

Question for a broader audience:

"When is generating boilerplate on a code completion valuable? How generalizable is this? Besides lists of children, are there other places we should be looking?"

(Adding @sethladd @abarth @eseidelGoogle @Hixie as a representative sample.)

FYI @devoncarew

A bit of context from a conversation over on chat.

@InMatrix asked:

Are there any side effects of having an empty children list before I know what I want to have?

@Hixie responded:

if you omit the children list, it defaults to an empty list so the only side-effect would be that the list becomes non-const (since the default is const and the autogenerated one would presumably not be const)

@InMatrix concluded:

Good to know that. Automatically inserting children could possibly create a subtle sense of urgency of coming up with children to fill in the blank. Not sure if that will be felt and whether that's what we'd like to encourage or discourage in the dev flow.

My take is that this definitely could use some more consideration before we just implement eager generation of empty lists. Moreover, in the meantime, @sethladd opened another which suggests we do the boilerplate generation if we ask for a completion of the children parameter explicitly (see #832).

@mit-mit you OK with us closing this out in favor of looking into #832?

I'd suggest we implement this feature but don't make it the default behavior just yet. We can do some user testing with this feature enabled, and/or ask a few existing Flutter app developers to enable and try this feature before making it the default for all.

@InMatrix : would this be for all widgets with children or just a select few?

@pq I would assume we should offer this convenience consistently for all widgets with children, unless we know some of those widgets have good use cases of having empty children.

Atom might support snippets, which we could add.

Regarding Atom snippets (http://flight-manual.atom.io/using-atom/sections/snippets/), they look to be a lot like IDEA live templates (https://www.jetbrains.com/help/idea/2016.3/live-templates-2.html); @stevemessick is looking at using those for Stateful/Stateless widget boilerplate in #800.

Although it's possible that developers will create widgets with empty children lists , that seems like an uncommon case. The advantage of automatically generating three additional lines of text is that inserting and formatting the boilerplate is at least tedious.

    new Flexible(
      child: new Row( // presto
    ),
    new Flexible(
      child: new Row(
        children: <Widget>[
          // the cursor lands here
        ],
      ),
    ),

If the entire <Widget>[ ] expression is initially selected then it's easy to replace the entire thing with myListOfWidgetChildren.

Browsing through widgets/basic.dart, it looks like child is required in a few cases like Positioned, Flexible, Expanded, and DefaultAssetBundle but otherwise not. @Hixie is this intentional?

Yes. The child is required for widgets where not providing the child would prevent the widget in question from returning a non-null value from its build function. If the widget is a render object widget, then it doesn't have a build function and it can terminate a branch. If the widget is a leaf that builds its own subtree using render object widgets, it can terminate a branch. If the widget is just a wrapper, then it doesn't make sense for it to terminate a branch and it needs a child.

basic.dart is mostly full of render object widgets so most of them don't require a child. The ones you listed are all InheritedWidgets, which are used for conveying information down the tree and therefore need a tree to convey the information to.

From discussions, this is unlikely to land for the adoption-blocker milestone, and we need more clarity on the actual desired behavior (how much we should insert).

A little status update...

Currently behind a flag we have children generated for constructor completions. That looks like this:

children_gen

We are currently conservative about when we generate this boilerplate (only for subclasses of Widget with a children named Constructor parameter but since this logic lives in server we can iterate).

Next step (and easy) is to generate the boilerplate for named parameter completions. This is less controversial I think and I hope not something we should put behind a flag.

In case it's not obvious what I mean, the following

named_p

would generate <Widget>[] (instead of empty).

Widget details for Flutter children: param completions (https://codereview.chromium.org/2855883003/):

children_bp

I can't resist, that looks mighty nice! ;)

@devoncarew, @mit-mit : this is done but behind a flag. The open question is whether to enable this by default and I think we need to do some user testing (cc @InMatrix).

In any event, we've made a ton of progress on completions for arguments (for example #975 and #551 ) that make this issue different enough that maybe we should collect some more user study feedback to see if generating more boilerplate is still an adoption-blocker.

Thoughts?

If we're comfortable with the implementation, I would be OK w/ enabling it by default, and adjusting it iteratively as we get feedback.

That (https://github.com/flutter/flutter-intellij/issues/463#issuecomment-298737723) looks pretty slick. Less typing is more!

Closing this in favor of a follow-up issue to vet the more aggressive option (https://github.com/flutter/flutter-intellij/issues/1005).

@patelkrunal78 - please stop spamming our repos. You've commented on dozens of issues w/ off-topic or low value comments, in order to drive traffic to your web site.

Was this page helpful?
0 / 5 - 0 ratings