mxw / vim-jsx

React JSX syntax highlighting and indenting for vim.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Airbnb guidelines for auto-closing tag sequence alignment break indentation

tymarats opened this issue · comments

Airbnb guidelines for alignment of React auto-closing tags (https://github.com/airbnb/javascript/tree/master/react#alignment) breaks indentation, as in the following example

export default <cx>
    <MyComponent
        that={1}
        has={2}
        closing={3}
        tag={4}
        in={5}
        new={6}
        line={7}
    />

<OtherComponent
    should={1}
    be={2}
    indented={3}
/>
    </cx>

while this one works fine:

/* Ok indentation */
export default <cx>
    <MyComponent
        that={1}
        has={2}
        closing={3}
        tag={4}
        in={5}
        same={6}
        line={7} />

    <OtherComponent
        indents={1}
        ok={2} />
</cx>

This seems to happen only in cases when there is an empty line between the auto-closing tag sequence and the next tag, so this seems to work fine:

export default <cx>
    <MyComponent
        that={1}
        has={2}
        closing={3}
        tag={4}
        in={5}
        new={6}
        line={7}
    />
    <OtherComponent
        indents={1}
        ok={2}
    />
</cx>

I don't really know vim script, but something along these lines might make things better in this scenario:

    " Align '/>' and '>' with '<' for multiline tags.
    if getline(v:lnum) =~? s:endtag
      let ind = ind - &sw
    endif

    " Then correct the indentation of any JSX following '/>' or '>'.
    " Skip empty lines
    let i = 1
    while ((v:lnum - i) != a:firstline && getline(v:lnum - i) =~? '^\s*$')
       let i = i + 1
    endwhile

    if getline(v:lnum - i) =~? s:endtag
      let ind = ind + &sw
    endif

Obviously, one needs to be aware of {/* ... */} multi-line blocks as well, but I have no idea how to handle that.

I have exactly the same issue; when can we get the pull request processed? I'm forced to manually indent many lines to pass the validations so that I can push my code.
I've read the README -- thanks for a great plugin!
I'm using pangloss/vim-javascript and mxw/vim-jsx.

When I define a component as follows:

    return (
      <div className="App-intro">
        <div className="page-container">
          <PageHeader title={`${view} Template Selection`} request={currentRequest} />
          <ErrorMsg errorMsg='Waiting for update to template request' />
          <FooterNavButtonGroup backButton={null} nextButton={this.pageValidation} />
          <TextField id="search-query-field" label="Filter by" value={searchQuery} onChange={this.handleSearchQueryChange} style={{ marginBottom: '1em' }} >
          </TextField>
          <ErrorMsg errorMsg={pageErrorMessage} />
          <div style={{ marginBottom: '1em', fontWeight: 'bold', fontStyle: 'italic' }}>
            {pageInfoMessage}
          </div>
          <TemplatesTable templatesObject={allTemplates} handleChange={this.handleChange} handleDelete={this.handleDelete} />
        </div>
        <FooterNavButtonGroup backButton={null} nextButton={this.pageValidation} />
      </div>
    );

image

everything works OK.
But the airbnb eslint rules require that I code it like this:

    return (
      <div className="App-intro">
        <div className="page-container">
          <PageHeader title={`${view} Template Selection`} request={currentRequest} />
          <ErrorMsg errorMsg='Waiting for update to template request' />
          <FooterNavButtonGroup backButton={null} nextButton={this.pageValidation} />
          <TextField
            id="search-query-field"
            label="Filter by"
            value={searchQuery}
            onChange={this.handleSearchQueryChange}
            style={{ marginBottom: '1em' }}
          />
          </TextField>
          <ErrorMsg errorMsg={pageErrorMessage} />
          <div style={{ marginBottom: '1em', fontWeight: 'bold', fontStyle: 'italic' }}>
            {pageInfoMessage}
          </div>
          <TemplatesTable templatesObject={allTemplates} handleChange={this.handleChange} handleDelete={this.handleDelete} />
        </div>
        <FooterNavButtonGroup backButton={null} nextButton={this.pageValidation} />
      </div>
    );

which winds up being formatted like this:
image

The problem seems to hit with I have a /> or > on a line by themselves to close the tag.

I'm working on a minimal .vimrc, but figured I'd send this your way and see if it made sense.