Skip to content
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

Incorrect (potentially) indentation of function arguments spanning multiple lines #11629

Open
waderyan opened this issue Oct 14, 2016 · 25 comments
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Domain: Formatter The issue relates to the built-in formatter Suggestion An idea for TypeScript VS Code Tracked There is a VS Code equivalent to this issue

Comments

@waderyan
Copy link

From @nomaed on October 14, 2016 10:40

  • VSCode Version: 1.6.1
  • OS Version: macOS Sierra 10.12

Steps to Reproduce:

  • Write a function (or a method) with several arguments (I did it with JavaScript and TypeScript files, but I believe any would work).
function myFunc(arg1, arg2, arg3, ...args) {
}
  • Split arguments to several lines by hitting Enter before arguments
function myFunc(arg1,
arg2,
arg3,
...args) {
}

Auto-formatting produces this result:

function myFunc(arg1,
    arg2,
    arg3,
    ...args) {
}

I would expect to see this result instead though:

function myFunc(arg1,
                arg2,
                arg3,
                ...args) {
}

Also, when manually formatting the arguments to appear in the same column (note: this is also the default/recommended setting in tslint and maybe other linters), then further lines will start with wrong indentation:

function myFunc(arg1,
                arg2,
                arg3,
                ...args) {
                    console.log('huh...');
}

vscode-multi-line-args-indent

Copied from original issue: microsoft/vscode#13748

@waderyan
Copy link
Author

@nomaed thank you for opening this issue.

@dbaeumer can I get some other eyes on this? I think I actually prefer this result with auto formatting:

function myFunc(arg1,
    arg2,
    arg3,
    ...args) {
}

But that might simply be my preference. Possibly there should be an option for OP to customize the auto formatting for his preference?

@waderyan
Copy link
Author

@bowdenk7 if you have a thought on this too that would be helpful. Don't know if this has come up much in your user studies...

@waderyan waderyan self-assigned this Oct 14, 2016
@waderyan waderyan added the js label Oct 14, 2016
@waderyan
Copy link
Author

From @dbaeumer on October 14, 2016 15:4

@waderyan I prefer yours as well. Agree that this should be a setting in the TS formatter. The good thing is if you formatted it once it will leave it as is.

@waderyan
Copy link
Author

From @nomaed on October 14, 2016 15:8

It definitely shouldn't be the only option. I personally grew to like it a lot (it's the default setting in JetBrains' IDEs) and since it's a default for TSLint (https://github.com/palantir/tslint/blob/master/src/rules/alignRule.ts), I am thinking that it's not uncommon to use this setting.

@waderyan
Copy link
Author

Moving this to TS language service to address adding the setting. Thank you for your feedback @nomaed. It is valued very highly.

@MichalLytek
Copy link

MichalLytek commented Oct 15, 2016

I have a related question about good practice in formatting: what about the returned type? It should be indent, in next line, or how?

class Example {
    public method(arg1: string,
                  arg2: number,
                  arg3: boolean)
                  : ReturnType {
        const result = doSomething();
        return new ReturnType(result);
    }
}

or maybe:

public method(arg1: string,
              arg2: number
              ): ReturnType {
    ...
}

@nomaed
Copy link

nomaed commented Oct 15, 2016

@19majkel94 Option no. 2 probably.
Return type (at last the semicolon) is immediately following the args closing parenthesis, so to make it appear in a new line, the closing parenthesis should be moved down too.

I think that these should all be valid:

/**
* #1
 * If first arg is on the same line as the function decl/name,
 * all args are lined up with the first one.
 */
function funcName(arg1: string,
─────────────────┤arg2: number,
─────────────────┤arg3: any): ReturnType {
   console.log('Hello world');
}

/**
 * #2
 * If first arg is newlined, it is double-indented so it remains 1 indent 
 * level in front of impl., and all args are lined up.
 */
function funcName(
      arg1: string,
      arg2: number,
      arg3: any): ReturnType {
   console.log('Hello world');
}

/**
 * #3
 * In case first arg is newlined like in #2, allow closing parenthesis
 * to be newlined too (outdent once) with return type following it
 */
function funcName(
      arg1: string,
      arg2: number,
      arg3: any
   ): ReturnType {
   console.log('Hello world');
}

The reason why I don't like the way it is now is that the argument aren't aligned and it's decreasing readability.

@MichalLytek
Copy link

In case no. 3, the return type indent once is decreasing readability. So I prefer my option no. 2 but it's
sensitive to function rename - we have to indent all again.

@rozzzly
Copy link

rozzzly commented Oct 16, 2016

My prefered style for large method/function signatures:

class Example {
    public method(
        arg1: string,
        arg2: number,
        arg3: boolean
    ): ReturnType {
        const result = doSomething();
        return new ReturnType(result);
    }
}

@waderyan waderyan added the Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature label Nov 18, 2016
@JohannesRudolph
Copy link

I'd like to add that the current indentation rule appear to work incorrectly when combined wth multiple nesting levels. In a naked VSCode install, auto format produces this:

this.client
      .getContinents()
      .subscribe(
      x => this.continents = x,
      e => this.errorMessage = e
      );

instead of:

this.client
      .getContinents()
      .subscribe(
          x => this.continents = x,
          e => this.errorMessage = e
      );

@eliprand
Copy link

eliprand commented Aug 22, 2017

Maybe I am missing something, but my project has the following tslint.json file:

{
    "defaultSeverity": "error",
    "extends": [
        "tslint:recommended"
    ],
    "jsRules": {},
    "rules": {
        "quotemark": [
            "single"
        ],
        "no-console": [
            false
        ],
        "arrow-parens": false,
        "no-string-literal": false,
        "no-namespace": [
            "allow-declarations"
        ],
        "interface-name": [
            "never-prefix"
        ],
        "no-trailing-whitespace": [true, "ignore-comments"]
    },
    "rulesDirectory": []
}

And TSLint does complain about parameters not being aligned after I auto format (using default settings, I am pretty sure since I am not overriding anything with typescript.format).
I know I can turn off TSLint's rule, but I would prefer to control settings for this...
I find what seems the default to not be the most readable option:
screen shot 2017-08-22 at 2 03 33 pm

@mhegazy mhegazy added Suggestion An idea for TypeScript Domain: Formatter The issue relates to the built-in formatter labels Aug 29, 2017
anler pushed a commit to anler/sheikah that referenced this issue Jun 14, 2018
the tslint rule for aligning blocks of code and typescript-formatter
are in conflict because the formatter doesn't like aligning parameters
of a function, see microsoft/TypeScript#11629
anler pushed a commit to anler/sheikah that referenced this issue Jun 14, 2018
the tslint rule for aligning blocks of code and typescript-formatter
are in conflict because the formatter doesn't like aligning parameters
of a function, see microsoft/TypeScript#11629
anler added a commit to witnet/sheikah that referenced this issue Jun 15, 2018
* refactor(file name): implement project layout defined in #126

BREAKING CHANGE: everyone need to update what they are working on in order to follow the new project
structure

fix #144

* chore(tslint): turn off align rule due to conflict

the tslint rule for aligning blocks of code and typescript-formatter
are in conflict because the formatter doesn't like aligning parameters
of a function, see microsoft/TypeScript#11629
@gauravmahto
Copy link

It would be best to provide a configuration so a user can choose which way to go.

simark pushed a commit to simark/cdt-gdb-adapter that referenced this issue Nov 16, 2018
I see quite a of bit of inconsistency in the formatting.  Let's add a
.editorconfig file, so the code we write uses the right whitespacing
regardless of the editor we use.  I just copied the one I wrote earlier
for Theia to get started, but it doesn't have to be identical.

I used Theia to auto-format all ts and json files and then tslint --fix
to fixup any warnings that it would have inserted.

For example, I the Typescript formatter handles quite badly (IMO) wrapping long
parameter lists, and produces code that result in a warning according to
our current tslint config.  The Typescript formatter will do this:

```
export class Bob {
    constructor(a: number, b: number, c: number, d: number,
        e: number, f: number) {
        console.log('Hello');
    }
}
```

where the second line of parameters is indented with 4 spaces.  I think
is not very readable, because it's easily confused with the first line
of code.  I prefer our current tslint setting, which requires it to be
aligned like this:

```
export class Bob {
    constructor(a: number, b: number, c: number, d: number,
i               e: number, f: number) {
        console.log('Hello');
    }
}
```

This means that formatting entire documents will always change the code
to look like the first snippet above.  It's a minor annoyance, and
hopefully there will be a setting for that one day in the Typescript
formatter.  There is an issue about that here:

microsoft/TypeScript#11629
Signed-off-by: Simon Marchi <simon.marchi@ericsson.com>
simark pushed a commit to simark/cdt-gdb-adapter that referenced this issue Nov 19, 2018
I see quite a of bit of inconsistency in the formatting.  Let's add a
.editorconfig file, so the code we write uses the right whitespacing
regardless of the editor we use.  I just copied the one I wrote earlier
for Theia to get started, but it doesn't have to be identical.

I used Theia to auto-format all ts and json files and then tslint --fix
to fixup any warnings that it would have inserted.

For example, I the Typescript formatter handles quite badly (IMO) wrapping long
parameter lists, and produces code that result in a warning according to
our current tslint config.  The Typescript formatter will do this:

```
export class Bob {
    constructor(a: number, b: number, c: number, d: number,
        e: number, f: number) {
        console.log('Hello');
    }
}
```

where the second line of parameters is indented with 4 spaces.  I think
is not very readable, because it's easily confused with the first line
of code.  I prefer our current tslint setting, which requires it to be
aligned like this:

```
export class Bob {
    constructor(a: number, b: number, c: number, d: number,
i               e: number, f: number) {
        console.log('Hello');
    }
}
```

This means that formatting entire documents will always change the code
to look like the first snippet above.  It's a minor annoyance, and
hopefully there will be a setting for that one day in the Typescript
formatter.  There is an issue about that here:

microsoft/TypeScript#11629
Signed-off-by: Simon Marchi <simon.marchi@ericsson.com>
simark pushed a commit to simark/cdt-gdb-adapter that referenced this issue Nov 26, 2018
I see quite a of bit of inconsistency in the formatting.  Let's add a
.editorconfig file, so the code we write uses the right whitespacing
regardless of the editor we use.  I just copied the one I wrote earlier
for Theia to get started, but it doesn't have to be identical.

I used Theia to auto-format all ts and json files and then tslint --fix
to fixup any warnings that it would have inserted.

For example, I the Typescript formatter handles quite badly (IMO) wrapping long
parameter lists, and produces code that result in a warning according to
our current tslint config.  The Typescript formatter will do this:

```
export class Bob {
    constructor(a: number, b: number, c: number, d: number,
        e: number, f: number) {
        console.log('Hello');
    }
}
```

where the second line of parameters is indented with 4 spaces.  I think
is not very readable, because it's easily confused with the first line
of code.  I prefer our current tslint setting, which requires it to be
aligned like this:

```
export class Bob {
    constructor(a: number, b: number, c: number, d: number,
i               e: number, f: number) {
        console.log('Hello');
    }
}
```

This means that formatting entire documents will always change the code
to look like the first snippet above.  It's a minor annoyance, and
hopefully there will be a setting for that one day in the Typescript
formatter.  There is an issue about that here:

microsoft/TypeScript#11629
Signed-off-by: Simon Marchi <simon.marchi@ericsson.com>
simark pushed a commit to simark/cdt-gdb-adapter that referenced this issue Nov 27, 2018
I see quite a of bit of inconsistency in the formatting.  Let's add a
.editorconfig file, so the code we write uses the right whitespacing
regardless of the editor we use.  I just copied the one I wrote earlier
for Theia to get started, but it doesn't have to be identical.

I used Theia to auto-format all ts and json files and then tslint --fix
to fixup any warnings that it would have inserted.

For example, I the Typescript formatter handles quite badly (IMO) wrapping long
parameter lists, and produces code that result in a warning according to
our current tslint config.  The Typescript formatter will do this:

```
export class Bob {
    constructor(a: number, b: number, c: number, d: number,
        e: number, f: number) {
        console.log('Hello');
    }
}
```

where the second line of parameters is indented with 4 spaces.  I think
is not very readable, because it's easily confused with the first line
of code.  I prefer our current tslint setting, which requires it to be
aligned like this:

```
export class Bob {
    constructor(a: number, b: number, c: number, d: number,
i               e: number, f: number) {
        console.log('Hello');
    }
}
```

This means that formatting entire documents will always change the code
to look like the first snippet above.  It's a minor annoyance, and
hopefully there will be a setting for that one day in the Typescript
formatter.  There is an issue about that here:

microsoft/TypeScript#11629
Signed-off-by: Simon Marchi <simon.marchi@ericsson.com>
dschaefer pushed a commit to eclipse-cdt-cloud/cdt-gdb-adapter that referenced this issue Nov 27, 2018
I see quite a of bit of inconsistency in the formatting.  Let's add a
.editorconfig file, so the code we write uses the right whitespacing
regardless of the editor we use.  I just copied the one I wrote earlier
for Theia to get started, but it doesn't have to be identical.

I used Theia to auto-format all ts and json files and then tslint --fix
to fixup any warnings that it would have inserted.

For example, I the Typescript formatter handles quite badly (IMO) wrapping long
parameter lists, and produces code that result in a warning according to
our current tslint config.  The Typescript formatter will do this:

```
export class Bob {
    constructor(a: number, b: number, c: number, d: number,
        e: number, f: number) {
        console.log('Hello');
    }
}
```

where the second line of parameters is indented with 4 spaces.  I think
is not very readable, because it's easily confused with the first line
of code.  I prefer our current tslint setting, which requires it to be
aligned like this:

```
export class Bob {
    constructor(a: number, b: number, c: number, d: number,
i               e: number, f: number) {
        console.log('Hello');
    }
}
```

This means that formatting entire documents will always change the code
to look like the first snippet above.  It's a minor annoyance, and
hopefully there will be a setting for that one day in the Typescript
formatter.  There is an issue about that here:

microsoft/TypeScript#11629
Signed-off-by: Simon Marchi <simon.marchi@ericsson.com>
@johncrim
Copy link

This is still an open issue in VS code 1.30.1 - the TS autoformatter removes leading whitespace, even if the tslint config is:

 "rules": {
    "align": [
      true,
      "parameters",
      "arguments",
      "statements",
      "members",
      "elements"
    ],

The comments above RE "I prefer a single tab indent when continuing the parameter list on a newline" aren't particularly useful - this is still a bug.

@biagruot
Copy link

What about this issue?

Same problem here.

@Liero
Copy link

Liero commented Oct 17, 2019

+1 for adding this formatting option in settings

@mightymatth
Copy link

+1 for this. Just migrating from Intellij to VS Code and this is one of the things that bothers me a lot. There are so many ways to configure the editor, but this simple logic requirement is not configurable. Any progress about that?

@eliprand
Copy link

eliprand commented Sep 3, 2020

FWIW, we have been using prettier now for a couple of years. Really helped with this and other code formatting consistency issues across our teams/products.

@NikelausM
Copy link

+1 for adding this formatting option in settings

@guillermosaez
Copy link

+1. I would like to be able to set it the same way as my TSLint is configured.

@user72356
Copy link

user72356 commented Mar 5, 2022

FWIW, we have been using prettier now for a couple of years. Really helped with this and other code formatting consistency issues across our teams/products.

Prettier moves all the args on the same line... So it's not helpful at all with this.

@merqrial
Copy link

FWIW, we have been using prettier now for a couple of years. Really helped with this and other code formatting consistency issues across our teams/products.

prettier is opinionated. We need to fix this in vscode if possible.

@starball5
Copy link

@CryptoCrocodile
Copy link

I'd also like to +1 this. Our team uses parenthesis aligned parameters for all other programming languages and it's a pain to work with TS due to this issue. We need a way to control parameter alignment on newlines.

@dptr
Copy link

dptr commented Jun 26, 2023

hi, did this issue fixed?

@CendioOssman
Copy link

Has anyone figured out a workaround until this can get resolved?

The biggest issue, IMO, is the fact that following lines also get their indentation messed up. So even if you indent things manually, you end up fighting the editor for the next line.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Domain: Formatter The issue relates to the built-in formatter Suggestion An idea for TypeScript VS Code Tracked There is a VS Code equivalent to this issue
Projects
None yet
Development

No branches or pull requests