mxw / vim-jsx

React JSX syntax highlighting and indenting for vim.
1.59k stars 95 forks source link

Fix matchit bug with special-named JSX elements #186

Closed richin13 closed 1 year ago

richin13 commented 5 years ago

Details

With JSX elements named with special character dot [.], the matchit integration does not work properly

Consider the following example that uses Semantic-UI-React:

import React from 'react'
import { Container, Grid, Label } from 'semantic-ui-react'

const Details = ({ name }) => (
    <Container>
      <Grid
        divided='vertically'
      >
        <Grid.Column float='left' width='14'>
          <h1>Process: {name}</h1>
        </Grid.Column>
        <Grid.Column floated='right'>
          <Label color='green'>Succeeded</Label>
        </Grid.Column>
        <Grid.Column width='16'>
          {/* Some content here */}
        </Grid.Column>
      </Grid>
    </Container>
)

export default Details

Problem

The problem with the current regex is that it does not consider this special cases with the element's name. The first part <\@<=\([^/][^ \t>]*\) will basically match any < followed by any non-tab character (words and dots) so if I were to type % while my cursor is in </Grid> it'll take me to <Grid.Column width='16'> three lines above because that matches the criteria <Grid followed by whatever character as long as it's not a / or a <TAB> and indeed <Grid.Column width='16'> is a match.

Moreover, the documentation for /\@<= states the following:

    In the old regexp engine the part of the pattern after "\@<=" and
    "\@<!" are checked for a match first, thus things like "\1" don't work
    to reference \(\) inside the preceding atom.  It does work the other
    way around:
    Bad example         matches ~
    \%#=1\1\@<=,\([a-z]\+\)     ",abc" in "abc,abc"

    However, the new regexp engine works differently, it is better to not
    rely on this behavior, do not use \@<= if it can be avoided:
    Example             matches ~
    \([a-z]\+\)\zs,\1       ",abc" in "abc,abc"

Also, I removed these groups ('(:),\[:\],{:},<:>,') as they are already bundled with matchit

Disclaimer

The code and tests discussed here were tested under NVIM v0.3.1