Skip to content

Allow inline method chaining if line length does not exceed printWidth #3107

@sharmilajesupaul

Description

@sharmilajesupaul

Just to give you some context on this, I've been working with @ljharb to bring prettier to @airbnb.
We noticed a few cases where Prettier’s formatting could be adjusted to more closely align with our style guide.

cc. @vjeux

Prettier 1.7.4

If a method chain has more than 1 method, Prettier creates a linebreak after each chained method, increasing the indentation in the method body.

Playground link

# Options (if any):
--single-quote
--print-width 100
--trailing-comma "all"

Input:

function HelloWorld() {
  window.FooClient.setVars({
    locale: getFooLocale({ page }),
    authorizationToken: data.token,
  }).initVerify('foo_container');

  fejax.ajax({
    url: '/verification/',
    dataType: 'json',
  }).then(
    (data) => {
      this.setState({ isLoading: false });
      this.initWidget(data);
    },
    (data) => {
      this.logImpression('foo_fetch_error', data);
      Flash.error(I18n.t('offline_identity.foo_issue'));
    },
  );
}

Output:

function HelloWorld() {
  window.FooClient
    .setVars({
      locale: getFooLocale({ page }),
      authorizationToken: data.token,
    })
    .initVerify('foo_container');

  fejax
    .ajax({
      url: '/verification/',
      dataType: 'json',
    })
    .then(
      data => {
        this.setState({ isLoading: false });
        this.initWidget(data);
      },
      data => {
        this.logImpression('foo_fetch_error', data);
        Flash.error(I18n.t('offline_identity.foo_issue'));
      },
    );
}

Desired behavior:
Creating a line break after chained methods can increase the indentation of multiline function bodies. It would help to allow chaining to be inline until it exceeds the printWidth. This shouldn't cause a readability issue since multiline blocks will still be encapsulated.

eg:

function HelloWorld() {
  window.FooClient.setVars({
    locale: getFooLocale({ page }),
    authorizationToken: data.token,
  }).initVerify('foo_container');

  fejax.ajax({
    url: '/verification/',
    dataType: 'json',
  }).then(
    (data) => {
      this.setState({ isLoading: false });
      this.initWidget(data);
    },
    (data) => {
      this.logImpression('foo_fetch_error', data);
      Flash.error(I18n.t('offline_identity.foo_issue'));
    },
  );
}

Diff between Prettier & desired output:

*** prettier.js	2017-10-25 16:40:41.000000000 -0700
--- desired.js	2017-10-25 16:40:39.000000000 -0700
***************
*** 1,24 ****
  function HelloWorld() {
!   window.FooClient
!     .setVars({
!       locale: getFooLocale({ page }),
!       authorizationToken: data.token,
!     })
!     .initVerify('foo_container');
  
!   fejax
!     .ajax({
!       url: '/verification/',
!       dataType: 'json',
!     })
!     .then(
!       data => {
!         this.setState({ isLoading: false });
!         this.initWidget(data);
!       },
!       data => {
!         this.logImpression('foo_fetch_error', data);
!         Flash.error(I18n.t('offline_identity.foo_issue'));
!       },
!     );
  }
--- 1,20 ----
  function HelloWorld() {
!   window.FooClient.setVars({
!     locale: getFooLocale({ page }),
!     authorizationToken: data.token,
!   }).initVerify('foo_container');
  
!   fejax.ajax({
!     url: '/verification/',
!     dataType: 'json',
!   }).then(
!     (data) => {
!       this.setState({ isLoading: false });
!       this.initWidget(data);
!     },
!     (data) => {
!       this.logImpression('foo_fetch_error', data);
!       Flash.error(I18n.t('offline_identity.foo_issue'));
!     },
!   );
  }

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions