[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Comprehensive JSX support in Emacs

From: Jackson Ray Hamilton
Subject: Comprehensive JSX support in Emacs
Date: Wed, 27 Mar 2019 01:03:21 -0700
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.5.1

Hello Emacs maintainers,

Following up on my long email from a month ago, wherein I announced my plan to fully support editing JSX in js-mode…

After many mornings and evenings of hacking (and many moonlight-melted candlesticks, and many moments spent meandering and muttering), I’ve finally got the _javascript_+JSX implementation to a state where I feel it’s worth sharing again.

I’ve added pretty comprehensive indentation and font-locking support, along with relatively simple automatic JSX detection support.

The indentation and font-locking code complimented each other well.  In order to fix issues like the one with an unterminated quote inside JSX (https://github.com/mooz/js2-mode/issues/409) (which truly haunted me for the past years) I had to thoroughly parse the JSX code.  The information I gained from parsing eventually led to the resolution of all the failing indentation test cases I compiled, and some new ones I added along the way.

js-mode no longer relies on sgml-mode for any parsing or indentation.  It’s all performed precisely according to the semantics of JSX now, borrowing just two blocks of code from sgml-mode as a basis for overlapping indentation logic.  Also, the JSX code has pretty colors now.  And, a single unterminated quote doesn’t wreak havoc on the buffer any more.

I implemented pretty much all of the JSX detection logic I proposed, at least in spirit.  I immediately found that using a list called “js-syntax-extensions” would be inferior to the alternative of using a boolean called “js-jsx-syntax”.  Booleans are simpler, and easier for users to set given all the available methods, plus they’re fun to check-off in Customize.

I mentioned that a “js-syntax-extensions” list might have some esoteric advantage by its ordering resolving theoretical conflicts between multiple syntax extensions, but I figure 1) we can cross that bridge when we get there, and 2) if we did add more syntax extensions for JS and those syntax extensions did partially conflict and users wanted to use conflicting extensions simultaneously, perhaps it’d be better to add some booleans that would resolve such conflicts on a case-by-case basis, anyway.

Taking into consideration Dmitry’s ambivalence on deprecating js-jsx-mode and js-jsx-indent-line, I figured we could strike a compromise.  We can keep these APIs without marking them obsolete.  However, I’ve tried to make the automatic detection of JSX—and the viable alternatives to manually enabling JSX support—so effective and numerous as to render these functions superfluous relics.  The go-forward answer to “how to enable JSX support in Emacs?” should be “upgrade to Emacs 27—now it just works™”.

I also addressed the spelling / naming items that Stefan brought up.

I had a chance to play with the code in a few projects of mine over the past week, and generally it is working well for me—much better than before, in all the previously painful cases.  However, there is a noticeable delay when editing some lines in my 1000-line monolith.jsx file, and in some rare cases I am seeing font-locking not working for JS embedded in JSX, and font-locking could probably be more graceful when typing new JSX code, too.  So there are still some improvements that can be made, but they may be entering the territory of “maintenance.”  Therefore, we might be willing to unleash this beast sooner rather than later, in spite of some imperfections.

Time for the good part: a whole bunch of patches, freshly rebased on master (see attached).  The first 4 patches should be the same as the ones in my original “announcement” email (except for one merge conflict I fixed), and the following 15 patches add up to some pretty kick-butt “HTML-in-_javascript_” splendiferousness (IMHO).

(Note that the patch “0015-Indent-broken-arrow-function-bodies-as-an-N-1th-arg.patch” isn’t really related to the JSX feature.  I was just editing some code in a project of mine, and found that this change provided more desirable behavior with the code I was writing then.  A lot of my code using JSX also uses arrow functions, so this was a convenient patch for me to lump in.)

I invite people to provide feedback as I continue to battle-test and optimize the code.  Feedback regarding improving the reliability and performance of parsing and font-locking would be especially appreciated.



Attachment: 0001-Add-failing-tests-for-JSX-indentation-bugs.patch
Description: Text Data

Attachment: 0002-Refactor-JSX-indentation-code-to-improve-enclosing-J.patch
Description: Text Data

Attachment: 0003-Add-new-failing-unclosed-JSX-test-and-separate-such-.patch
Description: Text Data

Attachment: 0004-js-syntax-propertize-Disambiguate-JS-from-JSX-fixing.patch
Description: Text Data

Attachment: 0005-Use-js-jsx-prefix-for-functions-and-variables.patch
Description: Text Data

Attachment: 0006-Add-basic-JSX-font-locking.patch
Description: Text Data

Attachment: 0007-Font-lock-JSX-while-editing-it-by-extending-regions.patch
Description: Text Data

Attachment: 0008-Propertize-and-font-lock-JSXText-and-JSXExpressionCo.patch
Description: Text Data

Attachment: 0009-Update-expectations-for-JSX-indentation-in-JSXAttrib.patch
Description: Text Data

Attachment: 0010-Indent-JSX-as-parsed-in-a-JS-context.patch
Description: Text Data

Attachment: 0011-Finish-replacing-SGML-based-JSX-detection-with-js-mo.patch
Description: Text Data

Attachment: 0012-Automatically-detect-JSX-in-JavaScript-files.patch
Description: Text Data

Attachment: 0013-Improve-JSX-syntax-propertization.patch
Description: Text Data

Attachment: 0014-Rename-tests-to-use-the-.jsx-file-extension.patch
Description: Text Data

Attachment: 0015-Indent-broken-arrow-function-bodies-as-an-N-1th-arg.patch
Description: Text Data

Attachment: 0016-Fix-counting-of-nested-self-closing-JSXOpeningElemen.patch
Description: Text Data

Attachment: 0017-Indent-expressions-in-JSXAttributes-relative-to-the-.patch
Description: Text Data

Attachment: 0018-Split-JSX-indentation-calculation-into-several-funct.patch
Description: Text Data

Attachment: 0019-Add-tests-for-miscellaneous-JSX-parsing-feats.patch
Description: Text Data

reply via email to

[Prev in Thread] Current Thread [Next in Thread]