sublime-text-plugin icon indicating copy to clipboard operation
sublime-text-plugin copied to clipboard

JSX Element as props will replace tag after jsx Element prop has expanded.

Open iahu opened this issue 1 year ago • 7 comments

Firstly, thanks your great work.

I hit a issue everyday, which for example, I have some jsx code, looks like below:

<Card title={<Button|}></Card>

my cursor is placed after <Button|, and I press Tab to expand the <Button tag, the result will be:

<Button></Card>

but not

<Card title={<Button><Button>}></Card>

as expected.

Hope this can be solved, thank you.

iahu avatar Dec 12 '23 06:12 iahu

Writing tags inside attributes is a bit awkward and invalid in HTML (Emmet was developed for HTML), yet in JSX it’s perfectly valid. Will try to figure out how to make it work in Sublime Text

sergeche avatar Dec 12 '23 08:12 sergeche

Hi. Let me add to this instead of creating a separate issue cause it seems related. Looks like pressing Tab while cursor is anywhere on the line that starts with < produces weird behavior.

https://github.com/user-attachments/assets/4bcc1ef9-5b2a-4595-8da0-e217575da234

Regarding the example above, even render <Card title="test"></Card>; is being replaced with return <test></test>"></Card>; is the cursor is before the closing quote. I've also noticed this weird replacement:

https://github.com/user-attachments/assets/e5f1184e-38f3-434f-8d53-0bb8077aeac7

Though this might help in debugging

vizvamitra avatar Jul 31 '24 23:07 vizvamitra

As a temporary solution that both gets rid of the bug and keeps emmet usable with jsx, I've used OverrideAudit plugin to change my local copy of emmet plugin, overriding jsx prefix here with ±. (rare in code, easy to type on mac).

vizvamitra avatar Aug 01 '24 03:08 vizvamitra

@vizvamitra it seems like a bug in abbreviation detection logic that detects if you’re typing abbreviation or just a regular word. In your first video, detected abbreviation is <div class="flex (yellow underline) which is invalid since it should reset abbreviation after space. Looks like you’re using some plugins or completions with that. Can you create a full video how you typed that div and received broken abbreviation?

sergeche avatar Aug 01 '24 08:08 sergeche

Sure. First video shows behavior with all my completions plugins (LSP-copilot, LSP-tailwindcss) enabled, on the second one I've disabled those two but the bug persisted

https://github.com/user-attachments/assets/a8d35ae0-4958-43d4-9a3f-ca3c18160068

https://github.com/user-attachments/assets/a68cfb08-14b0-4781-9216-42b729aff9c7

vizvamitra avatar Aug 01 '24 11:08 vizvamitra

Some insights here.

I guess one thing that goes wrong is that py-emmet's extract, when called here with a prefix, recognizes as abbreviation the whole line starting with that prefix instead of just the last word:

from emmet import extract

extract('      <div.foo test', 19, {
  'type': 'markup',
  'lookAhead': True,
  'prefix': '<'
})

# => {'abbreviation': 'test', 'location': 15, 'start': 6, 'end': 19}

extract('      div.foo test', 19, {
  'type': 'markup',
  'lookAhead': True,
  'prefix': ''
})

# => {'abbreviation': 'test', 'location': 14, 'start': 14, 'end': 18}

I guess this is being called when user presses Tab while no active tracker, and the fact that resulting start..end range starts from <div causes plugin to replace the whole line.

But I guess this is not what happens on my video, cause there seem to be an existing tracker at that moment (according to the logging I've put into the code while debugging)

vizvamitra avatar Aug 01 '24 13:08 vizvamitra

Thanks, that helps a lot!

sergeche avatar Aug 01 '24 14:08 sergeche

Both issues should be fixed in v.2.4.4

sergeche avatar Aug 06 '24 20:08 sergeche