dprint-plugin-typescript icon indicating copy to clipboard operation
dprint-plugin-typescript copied to clipboard

Option to control the indent level of hanging / wrapped lines

Open declanvong opened this issue 3 years ago • 0 comments

This is called "continuation indent" in formatters such as:

and would be needed to satisfy style guides such as Google's JS style guide.

Such an option would satisfy a test such as this:

Click to expand
~~ lineWidth: 20, hangingIndentTimes: 2, preferHanging: true ~~
== should indent a hanging parameter list twice ==
foo(one, two, three, four, five);

[expect]
foo(one, two, three,
        four, five);

== should indent a hanging array expression twice ==
const t = [other, otherTest, other];

[expect]
const t = [other,
        otherTest,
        other];

== should indent a hanging binary expression twice ==
const x = 123 + 456 - foo - bar + baz;

[expect]
const x = 123 + 456
        - foo - bar
        + baz;

== should indent a hanging for statement header twice ==
for (let i = 0; i < 5; i++) {
    x;
}

[expect]
for (let i = 0;
        i < 5; i++)
{
    x;
}

== should indent a hanging arrow function body twice ==
const a = () => somethingLong;

[expect]
const a = () =>
        somethingLong;

== should indent a multi-line conditional twice ==
const a = test
? something
: somethingElse;

[expect]
const a = test
        ? something
        : somethingElse;

== should indent a multi-line multi-level conditional twice at every level ==
const a = a
? b
  ? c
  : d
: c;

[expect]
const a = a
        ? b
                ? c
                : d
        : c;

== should indent a hanging arrow expression twice inside a parameter list  ==
foo(x => somethingOrRather);

[expect]
foo(x =>
        somethingOrRather
);

== should indent a hanging extends / implements clause twice ==
class SomeClass extends B { }

[expect]
class SomeClass
        extends B
{}

== should indent an assignment expression twice ==
const a = someReallyLongExpression;

[expect]
const a =
        someReallyLongExpression;

== should indent each line of an invocation chain twice ==
foo(something)
.chain1(a)
.chain2(b)
.chain3(c);

[expect]
foo(something)
        .chain1(a)
        .chain2(b)
        .chain3(c);

== should indent each line of a computed invocation chain twice ==
foo(something)
[1+1](a)
["c2"](b)
["c3"](c);

[expect]
foo(something)
        [1 + 1](a)
        ["c2"](b)
        ["c3"](c);

== should indent each line of a union or intersection type twice ==
type SomeType =
| FooBarBaz
| SomeOtherType;

[expect]
type SomeType =
        | FooBarBaz
        | SomeOtherType;

Happy to raise a PR for this one if you think it's appropriate :)

In our fork, we have this implemented as an option hanging.indentTimes, which is just a multiplier against indentWidth. There might be value in having it specified as something like hanging.indentWidth instead, which takes an actual width instead of a multiplier, but just a multiplier has worked very well for us so far.

declanvong avatar Sep 03 '21 05:09 declanvong