Tslint: Add fixer for max-line-length rule

Created on 15 Dec 2017  路  8Comments  路  Source: palantir/tslint

Bug Report

  • __TSLint version__: 5.8.0
  • __TypeScript version__: 2.5.3
  • __Running TSLint via__: VSCode

TypeScript code being linted

  constructor(private server: PurchaseInvoiceService, private activatedRoute: ActivatedRoute, private dialog: MatDialog, private snackBar: MatSnackBar) {
  }

with tslint.json configuration:

{
  "rulesDirectory": [
    "node_modules/codelyzer"
  ],
  "rules": {
    "arrow-return-shorthand": true,
    "callable-types": true,
    "class-name": true,
    "comment-format": [
      true,
      "check-space"
    ],
    "curly": true,
    "eofline": true,
    "forin": true,
    "import-blacklist": [
      true,
      "rxjs",
      "rxjs/Rx"
    ],
    "import-spacing": true,
    "indent": [
      true,
      "spaces"
    ],
    "interface-over-type-literal": true,
    "label-position": true,
    "max-line-length": [
      true,
      140
    ],
    "member-access": false,
    "member-ordering": [
      true,
      {
        "order": [
          "static-field",
          "instance-field",
          "static-method",
          "instance-method"
        ]
      }
    ],
    "no-arg": true,
    "no-bitwise": true,
    "no-console": [
      true,
      "debug",
      "info",
      "time",
      "timeEnd",
      "trace"
    ],
    "no-construct": true,
    "no-debugger": true,
    "no-duplicate-super": true,
    "no-empty": false,
    "no-empty-interface": true,
    "no-eval": true,
    "no-inferrable-types": [
      true,
      "ignore-params"
    ],
    "no-misused-new": true,
    "no-non-null-assertion": true,
    "no-shadowed-variable": true,
    "no-string-literal": false,
    "no-string-throw": true,
    "no-switch-case-fall-through": true,
    "no-trailing-whitespace": true,
    "no-unnecessary-initializer": true,
    "no-unused-expression": true,
    "no-use-before-declare": true,
    "no-var-keyword": true,
    "object-literal-sort-keys": false,
    "one-line": [
      true,
      "check-open-brace",
      "check-catch",
      "check-else",
      "check-whitespace"
    ],
    "prefer-const": true,
    "quotemark": [
      true,
      "single"
    ],
    "radix": true,
    "semicolon": [
      true,
      "always"
    ],
    "triple-equals": [
      true,
      "allow-null-check"
    ],
    "typedef-whitespace": [
      true,
      {
        "call-signature": "nospace",
        "index-signature": "nospace",
        "parameter": "nospace",
        "property-declaration": "nospace",
        "variable-declaration": "nospace"
      }
    ],
    "typeof-compare": true,
    "unified-signatures": true,
    "variable-name": false,
    "whitespace": [
      true,
      "check-branch",
      "check-decl",
      "check-operator",
      "check-separator",
      "check-type"
    ],
    "directive-selector": [
      true,
      "attribute",
      "app",
      "camelCase"
    ],
    "component-selector": [
      true,
      "element",
      "app",
      "kebab-case"
    ],
    "use-input-property-decorator": true,
    "use-output-property-decorator": true,
    "use-host-property-decorator": true,
    "no-input-rename": true,
    "no-output-rename": true,
    "use-life-cycle-interface": true,
    "use-pipe-transform-interface": true,
    "component-class-suffix": true,
    "directive-class-suffix": true
  }
}

Actual behavior

TSLint gives [tslint] Exceeds maximum line length of 140 (max-line-length) error, but does not provide any fixers.

Expected behavior

It would be great if TSLint could provide ability to break a line into separate lines, where possible. For a given example ts line, the fix should convert it to something like:

  constructor(
    private server: PurchaseInvoiceService,
    private activatedRoute: ActivatedRoute,
    private dialog: MatDialog,
    private snackBar: MatSnackBar
  ) {
  }
Hard Formatting rule Declined Rule Enhancement

Most helpful comment

In my setup I use tslint, codelyzer, VSCode with .editorconfig extension. I definitely don't want to use a yet another formatter!

Originally, I thought this should be handled by VSCode itself.

But since:

  • there's a corresponding max-line-length tslint rule, which also accepts the max line width setting value,
  • tslint is specific to typescript files,
  • tslint already supports a concept of "fixers"

I believe that tslint should handle this.

All 8 comments

Probably not what you want to hear, but you may use Prettier in addition to your rules.

In my setup I use tslint, codelyzer, VSCode with .editorconfig extension. I definitely don't want to use a yet another formatter!

Originally, I thought this should be handled by VSCode itself.

But since:

  • there's a corresponding max-line-length tslint rule, which also accepts the max line width setting value,
  • tslint is specific to typescript files,
  • tslint already supports a concept of "fixers"

I believe that tslint should handle this.

I definitely don't want to use a yet another formatter!

Just a heads up, I've mentioned this in other threads (https://github.com/palantir/tslint/issues/2814#issuecomment-331173600, https://github.com/palantir/tslint/pull/3395#issuecomment-347967428), but my general advice to users looking for formatting has been to redirect them to prettier. It's pretty easy to use as a tslint plugin if you don't want to have to think about another CLI or editor plugin. I've gone ahead and filed an issue to signal this intent to TSLint users: https://github.com/palantir/tslint/issues/3592.

Judging by how hard it's been to implement https://github.com/palantir/tslint/pull/3395 (still not yet merged), I think a fixer for max-line-length would require a similar amount of work.

Thanks for reply, I see your idea. But currently there's a problem with using the tslint-plugin-prettier in that it does not convert tslint.json rules to prettier's and therefore it's impossible to simply use that plugin - you have to manually create a prettier settings file and mirror all the formatting rules of tslint there.

you have to manually create a prettier settings file and mirror all the formatting rules of tslint there.

yeah, fair point. but part of the idea of prettier is that it's opinionated so you can't have much config. in practice it's less than 10 lines, for example https://github.com/palantir/blueprint/blob/master/packages/tslint-config/index.js#L60-L66

I agree, this would be awesome to have and would be trivial to implement. Some of us don't have the freedom to use Prettier in our projects, as much as we'd want it.

My problem with Prettier is that I cannot use it for max-width reformatting without it also forcing 'else' statements to be on the same line as the closing brackets from the previous block while supporting newer typescript language features properly.

  • Prettier: forces style } else { as a single line (same with any other similar conditional blocks).
  • Prettier Miscellaneous: hasn't had any commits since July last year so is now more than 800 commits behind Prettier master, does not support newer typescript language features such as number separators like 1_000_000, react fragments, etc.
  • prettier-tslint: forces the } else { format style.
  • tslint-plugin-prettier & tslint-config-prettier: forces } else { format style.

Since the team at prettier have rejected _multiple repeated_ requests to permit customising/overriding the } else { formatting rule and the "just use prettier miscellaneous instead" advice that they have suggested as the alternative is no longer an option, I am actually attempting to move _away_ from using prettier at all.

People at work have come to hate the way prettier inserts semi-colons in random places any time they save a file with an accidental syntax error (prettier starts inserting semis into random bits of jsx statements, completely screwing the file up - often turning a single syntax error into a dozen syntax errors), and the only alternatives are to set prettier to rip _all_ semi-colons out instead (also extremely undesirable) or to simply stop using prettier. So there's a fairly strong desire to dump prettier entirely.

Max width reformatting (aka 'condense to all as one line if it fits, or split to one line per field/item if not') is pretty much the _only_ thing that prettier still offers us that can't be done with tslint alone.

Given #4534 and the lack of activity on this issue for the last year, closing as out of scope. There are only two part-time TSLint maintainers and our efforts are not focused on formatting rules.

If you _need_ this, you can always fork the core TSLint max-line-length rule to separate repository and publish the custom rule there.

Again, we understand that not everyone can or wants to be on Prettier, but we just don't have the bandwidth to support this fixer.

Was this page helpful?
0 / 5 - 0 ratings