GithubHelp home page GithubHelp logo

Comments (13)

hick209 avatar hick209 commented on July 27, 2024 1

I prefer option 1 for the ones you presented.

But also, if it's formatted differently, I'd go with option 3.

For example:

list.asSequence()
    .map { i ->
      i * 2
    }
    .also {
      println(it)
    }

from ktfmt.

cgrushko avatar cgrushko commented on July 27, 2024 1

@JavierSegoviaCordoba - GitHub Discussions enabled

from ktfmt.

strulovich avatar strulovich commented on July 27, 2024

@hick209, there is indeed no dilemma in the case where the lambda call is not the first one in the chain, since it then looks similar to your example (4 spaces, not 2 though).

from ktfmt.

cgrushko avatar cgrushko commented on July 27, 2024

This is relevant again now that we're looking into placing the closing paren on the next line when formatting using --google-style.

Option 4

doIt(
    foo1,
    foo2,
    foo3
).doThat()
.foo()
.bar(
    foo1,
    foo2,
    foo3
).doThat(
    foo1,
    foo2,
    foo3
)

To me this looks bad because some lines start with a dot, some with closing parent.

Option 5

doIt(
        foo1,
        foo2,
        foo3
    )
    .doThat()
    .foo()
    .bar(
        foo1,
        foo2,
        foo3
    )
    .doThat(
        foo1,
        foo2,
        foo3
    )

It's wasteful for the first call.

Option 6

doIt(
    foo1,
    foo2,
    foo3
)
    .doThat()
    .foo()
    .bar(
        foo1,
        foo2,
        foo3
    )
    .doThat(
        foo1,
        foo2,
        foo3
    )

This makes it easy to miss that we have a chain here at all.

Kotlin source code has a bit of Option 4 and a bit of Option 5:

FunctionDescriptor toStringDescriptor = receiverClassDescriptor.getUnsubstitutedMemberScope()
        …
        .filter(
                f -> f.getValueParameters().size() == 0
                     && KotlinBuiltIns.isString(f.getReturnType())
                     && f.getDispatchReceiverParameter() != null
                     && f.getExtensionReceiverParameter() == null
        )
        .findFirst()
        .orElseThrow(() -> new AssertionError("'toString' not found in member scope of " + receiverClassDescriptor));

but,

 SimpleFunctionDescriptorImpl.create(
    classDescriptor, Annotations.EMPTY, Name.identifier(name), CallableMemberDescriptor.Kind.DECLARATION,
    funDescriptor.source
).apply {
    initialize(
        null,
        …
    )
}

and even

StackValue.field(
    AsmTypes.OBJECT_TYPE, Type.getObjectType(v.thisName), languageVersionSettings.dataFieldName(), false,
    StackValue.LOCAL_0
).store(StackValue.local(1, AsmTypes.OBJECT_TYPE), codegen.v)

(what is this)

cc @bethcutler

from ktfmt.

bethcutler avatar bethcutler commented on July 27, 2024

I'm not sure what cases these options would trigger in. I would prefer same line as long as everything fits on the same line:

doIt(
    foo1,
    foo2,
    foo3
).doThat().foo().bar(foo1)

And in fact I like the look of single chained calls like this:

doIt(
    foo1,
    foo2,
    foo3
).doThat(
    foo1,
    foo2
).bar(
    foo1,
    foo2
)

So maybe the option I prefer the most is

Option 7

doIt(
    foo1,
    foo2,
    foo3
).doThat().foo().bar(
   foo1,
   foo2,
   foo3
).member.method(argument)

Having to choose from the above options, I would probably prefer 4 or 5, but only in exceptional cases where the chained calls can't fit on the same line as the closing paren.

from ktfmt.

cgrushko avatar cgrushko commented on July 27, 2024

We try to maintain the Rectangle rule, so I think Option 5 is the way to go.

The RFC commit 675edab implements it.

from ktfmt.

JavierSegoviaCordoba avatar JavierSegoviaCordoba commented on July 27, 2024

Currently I am seeing a floating dot some times but it feels pretty unnatural.

Is that intended or just a bug?

from ktfmt.

cgrushko avatar cgrushko commented on July 27, 2024

@JavierSegoviaCordoba can you give an example?

from ktfmt.

JavierSegoviaCordoba avatar JavierSegoviaCordoba commented on July 27, 2024

@cgrushko sorry about my late response but I am waiting until I can reproduce it again, but no luck until now :/

Can you enable GitHub discussions? I was thinking of opening an issue about Jetpack Compose formatting and should be great to do in Discussions instead of opening it as an issue :)

from ktfmt.

JavierSegoviaCordoba avatar JavierSegoviaCordoba commented on July 27, 2024

@cgrushko .dropLastWhile is correct?

    val changelogToWrite =
        buildString {
            filteredChangelog.onEachIndexed { index, line ->
                when {
                    h1Regex.matches(line) -> appendLine("$line\n")
                    h2Regex.matches(line) -> appendLine("$line")
                    h3Regex.matches(line) &&
                        filteredChangelog.size != index + 1 &&
                        !h3Regex.matches(filteredChangelog[index + 1]) -> appendLine("\n$line\n")
                    else -> appendLine(line)
                }
            }
        }
            .dropLastWhile { it.isWhitespace() } + " \n"

I think this should be

    val changelogToWrite =
        buildString {
            filteredChangelog.onEachIndexed { index, line ->
                when {
                    h1Regex.matches(line) -> appendLine("$line\n")
                    h2Regex.matches(line) -> appendLine("$line")
                    h3Regex.matches(line) &&
                        filteredChangelog.size != index + 1 &&
                        !h3Regex.matches(filteredChangelog[index + 1]) -> appendLine("\n$line\n")
                    else -> appendLine(line)
                }
            }
        }
        .dropLastWhile { it.isWhitespace() } + " \n"

from ktfmt.

cgrushko avatar cgrushko commented on July 27, 2024

I think that in order to be consistent with Option 5, the lambda passed to buildString should be indented extra 4 spaces, and so the floating dot stops floating.

from ktfmt.

JavierSegoviaCordoba avatar JavierSegoviaCordoba commented on July 27, 2024

But it is not looking strange for you? I think the second one is more readable, the first one can lead to thinking that dropLastWhile is for filteredChangelog... instead of buildString

from ktfmt.

hick209 avatar hick209 commented on July 27, 2024

Closing this as it's an old discussion and @davidtorosyan has made significant contributions on this space that might have met some of the concerns raised here.

Feel free to reopen if you feel there's more to be discussed here

from ktfmt.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.